_BV(nn) macro doesn't work correctly

Go To Last Post
19 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I noticed that the _BV(n) macro is not working. My main procedure has a couple of peripheral register init statements.

void Main ()
{
uint8_t temp;

temp = ( _BV(PA7) | _BV(PA6) );
DDRA = temp;
DDRB = _BV(PB2);
}

The disassembly of the build shows the assignment of a value to temp is ignored by the compiler. Putting a volatile keyword in the definition assembles the line, but temp gets assigned value of 0.
The DDRB = _BV(PB2) compiles OK. The assembly shows 0x04 being loaded.
I use #include .
Is there something that I'm not doing to get the AVRLIBc loaded and running?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Could it be that the compiler ignores temp and just does

DDRA = (_BV(PA7) | _BV(PA6) );

???

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is what the compiler produces (compiled for an ATmega1281):

Main:
/* prologue: function */
/* frame size = 0 */
        ldi r24,lo8(-64)
        out 33-32,r24
        ldi r24,lo8(4)
        out 36-32,r24
/* epilogue start */
        ret

So, if you want, r24 is your "temp" variable...

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

R24 is not the "temp" variable because "temp" should contain "-64" not "4".

R24 is a scratch register.
"temp" is optimised away.

But it is a fairly pointless exercise. A HLL must translate your source code instructions correctly according to the rules of that HLL. It has no obligation to produce pointless or un-executable code.

I would guess that making "temp" volatile would probably force the compiler to copy "-64" to a location somewhere.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> R24 is not the "temp" variable because "temp"
> should contain "-64" not "4".

Variable contents is no longer valid after its last use.

> R24 is a scratch register.
> "temp" is optimised away.

That depends on your point of view. Nobody says variables must
exist in memory, so there's one point of view where you could
state that "temp" lives in R24 for the entire duration where
it is valid (when R24 gets re-used for another temporary variable).
Another point of view is to state that "temp" has been optimized
away. Both views have a point. But the discussion is fairly
academic: what you could reasonably expect is that, after executing
that function Main(), your DDRA has the value 0xC0, and your DDRB
has 0x04. The generated code will do that.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
what you could reasonably expect is that, after executing
that function Main(), your DDRA has the value 0xC0, and your DDRB
has 0x04. The generated code will do that.

Yes. Exactly my point. A HLL does what it says on the tin.

When I first learned C, I would immediately look at the M68000 assembly instructions generated. I suppose it helped to explain pointers and arithmetic operators, but it is a large hindrance to learning a programming language.

You need to think only in the HLL. After all modern compilers do not make mistakes. If you try to think in two languages you just get confused.

Having said that. As a completely separate academic exercise it is interesting to see what a compiler generates.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I suppose it's worth mentioning that if OP wants to see a one-to-one correspondence between C statements and the blocks of Asm generated including the generation of bloated, pointless operations that any half decent asm programmer could see were pointless (and so can the optimiser) then he could always turn the optimiser off completely with -O0 though this really is a "BadIdea(tm)". But he would get what he expected from the code in the first post:

int main (void) 
{ 
  92:	df 93       	push	r29
  94:	cf 93       	push	r28
  96:	0f 92       	push	r0
  98:	cd b7       	in	r28, 0x3d	; 61
  9a:	de b7       	in	r29, 0x3e	; 62
  uint8_t temp; 

  temp = ( _BV(PA7) | _BV(PA6) ); 
  9c:	80 ec       	ldi	r24, 0xC0	; 192
  9e:	89 83       	std	Y+1, r24	; 0x01
  DDRA = temp; 
  a0:	ea e3       	ldi	r30, 0x3A	; 58
  a2:	f0 e0       	ldi	r31, 0x00	; 0
  a4:	89 81       	ldd	r24, Y+1	; 0x01
  a6:	80 83       	st	Z, r24
  DDRB = _BV(PB2); 
  a8:	e7 e3       	ldi	r30, 0x37	; 55
  aa:	f0 e0       	ldi	r31, 0x00	; 0
  ac:	84 e0       	ldi	r24, 0x04	; 4
  ae:	80 83       	st	Z, r24
  b0:	80 e0       	ldi	r24, 0x00	; 0
  b2:	90 e0       	ldi	r25, 0x00	; 0
}
  b4:	0f 90       	pop	r0
  b6:	cf 91       	pop	r28
  b8:	df 91       	pop	r29
  ba:	08 95       	ret

But I think most programmers would prefer to learn to debug optimised code (and understand about register usage etc) and have this generated to do the same:

00000092 
: int main (void) { uint8_t temp; temp = ( _BV(PA7) | _BV(PA6) ); DDRA = temp; 92: 80 ec ldi r24, 0xC0 ; 192 94: 8a bb out 0x1a, r24 ; 26 DDRB = _BV(PB2); 96: 84 e0 ldi r24, 0x04 ; 4 98: 87 bb out 0x17, r24 ; 23 } 9a: 80 e0 ldi r24, 0x00 ; 0 9c: 90 e0 ldi r25, 0x00 ; 0 9e: 08 95 ret

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

C language has a structural defect that seriously affects its ability to be used by people who have independently developing for microcontrollers.

This defect is that it amplifies the errors that beginners make and experienced programmers don't. Programmers develop the styles that make it possible to write efficient code for professional applications. Then they use these coding styles without thinking about the details.

Beginners don't have these styles absorbed into their coding practices. They make mistakes that the experienced coders don't. C amplifies these often simple mistakes by forcing the beginners to dive into the very deep and technical details of the compiler to try and correct these often simple syntactical errors. Beginners usually don't have the background to understand these levels of technical details. They come to a roadblock, and then abandon trying to get simple C code to compile. Sometimes they go into a different field altogether from programming.

This positive feedback loop of smothering beginners with increasing levels of technical detail to get their simple code working has been traditionally dealt with by having colleges have computer labs. Students and technical interns in the lab will look over the simple code, note the error, and usually make recommendations for quick corrections. The good students learn the 'correct' programming styles that don't generate syntactical errors. Then they learn the ways to develop efficient code for their host computers and algorythmic structures.

Several things disrupt this process of training programmers. One is that in the USA, schooling is expensive. Schools believe that because students already have powerful inexpensive computers, then they don't need computer labs. The function of the computer lab has switched from being a central location of a mainframe to a place where students can get computer answered. Programmers-in-training that don't have the funds to pay tuition don't have access to college computer labs. It's getting to be a problem in the USA.

So people turn to the web. There are many elementary tutorials, but no place to get questions about next-step simple programs (beyond LED-blinking tutorials) working. The CPU sites like this one offer lots of help on focused issues.

But beginners don't need deep technical discussions, important and welcome that they are. They just want to know why the simple code that they have written doesn't compile. When all the simple examples on the web using the same library functions and keywords does work.

For example, I tried to slow down the blinking of the LED in the simple beginning-WinAVR C demo by adding the line:

#include
_delay_ms(100);

I get an error: _delay_ms is not a function.

Brick wall.

I (and any other beginner) have no idea as to why this error happens. I have no idea of how to solve it. I'm not sure of where to look for a solution. The only thing that I can think to do is to come here and ask on this forum.

The structural defect that C has is that it is can't be learned independently without a computer lab, tutor, or tech support.

Microcontroller assembler doesn't have this problem. Whatever the problem is in assembler code, you can go to data sheets and simulators that go down to the clock cycle and register level to find out what is failing. It may take a long time, and it may require using a logic analyzer, but it can be done. There aren't the brick-wall barriers that high-level languages have.

This is why assembler is more advanced than C for microcontrollers. It is a programming tool that can be learned independently by people who no background in computer science. It is the reason why C will most likely be discarded in the future by microcontroller developers for either assembler or a more-advanced high-level programming tool.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There are learning curves to ANY language, spoken, or programming. And it is very hard to learn any language in an isolated manner, if not impossible.

There is nothing in unique in C that makes things more difficult than any other language. If you ask me C actually makes it easier than many other languages.

When learning a new language, you do need to read the documentation about it's vocabulary, and the rules to its syntax. You also need to read the documentation as to the provided library functions. You don't need to get into the low level stuff, C does not require this. But you will, if you want to write highly efficient code (same goes for any high-level language).

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

This is why assembler is more advanced than C for microcontrollers.

Utter bilge - IMHO.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@Simonetta: I think you'll find that assembler quickly loses it's shine once you get into larger more advanced applications.

I also find it odd that you complain about needing to learn the low level (assembler stuff) for writing efficient code in C... but then you go on to praise the benefits of assembler.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
The structural defect that C has is that it is can't be learned independently without a computer lab, tutor, or tech support.

Utter BS. Every computer language that I have ever learned except for FORTRAN I learned on my own, without any lab, tutor or tech support.

Quote:
Whatever the problem is in assembler code, you can go to data sheets and simulators that go down to the clock cycle and register level to find out what is failing.

And which of these can't you do with C?

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Simonetta wrote:
This is why assembler is more advanced than C for microcontrollers. It is a programming tool that can be learned independently by people who no background in computer science. It is the reason why C will most likely be discarded in the future by microcontroller developers for either assembler or a more-advanced high-level programming tool.
IRRC you posts are usually well thought out and helpful, so please excuse me for asking: what caused you to get off on this? You last statement doesn't correlate with anything I've observed over the past several decades of working with C or assembly. The flaws in your arguments are too numerous to address. C is the main professional microcontroller programming language - you need only look at the job descriptions for embedded systems engineers. C will dominate microcontrollers as long as we continue to use microcontrollers.

Smiley

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Certainly C will never be replaced by assembler simply for the fact that C is portable, assembler is not. Having to rewrite the entire code when moving from one platform to another is simply not an option.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Simonetta, part of your posting is rather vague, like

Quote:
This defect is that it amplifies the errors that beginners make and experienced programmers don't.
Other parts are plain wrong.
Quote:
The structural defect that C has is that it is can't be learned independently without a computer lab, tutor, or tech support.
Several generations of C programmers have learned the language from one particular single book. No tutor, no computer lab, no tech support. Just a computer (toy-sized by today's standards), a severely broken C compiler of some kind, an absolutely brain dead editor, and the K&R book.

Long before there was the web. And the web hasn't changed the language or difficulty to learn C. That book is still there and still valid. What has changed are today's students.

They think the world has to revolve around them. They want that everything is made to be exactly right for them. They want it now, instant gratification. They don't want to learn basics, nor fundamentals of their trade. They are so delicate, you have to fear they have a meltdown if you tell them to read a book or a datasheet.

Let me give you an example:

Quote:
I have no idea of how to solve it. I'm not sure of where to look for a solution. The only thing that I can think to do is to come here and ask on this forum.
The solution? I find it disturbing that it doesn't appear to you that the solution to your problem is to properly learn the basics of the language - by, for example, simply reading a book.

Stealing Proteus doesn't make you an engineer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can understand Simonetta's frustration, because I frequently experience it, first hand.

There are several things I have done to help solve this. I don't have a copy of K&R but I DO have links to several web sites with c tutorials. These are often, but not always, university sites. I've collected a few that have been useful and I tend to go back to them when I have questions, like I often do.

The other thing is the AVRLibC documentation. I could not live without it. Virtually everything that is unique about AVR coding is there. Including delay_ms.

Yes, its a pain to constantly have to look up stuff, but I put that responsibility to my aging mind (like its been since age 5 or 6) rather than flaws in c. For example, EVERY time I have to use pointers, I have to look up the proper use of "&" and "*". My mind just won't take it in. So, rather than throwing up my hands, I know that its a problem, and up come the tutorial sites.

Is this a flaw with c? Not in my mind! I have many of the same problems with other languages - even supposedly "easy" ones like RealBasic.

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Interesting discussion. I follow Simonetta's arguments and my first reaction was as the other old-timers here.

Then I remembered the recent experience of my brother-in-law. He is a math teacher at a local high school and teaches computer programming there (as well as all other math). He's tried Java, C, Pascal, with the very typical results -- confused students, a few bright students excelling and the others struggling through.

This year, he's tried Scheme. Yup, the Lisp dialect. When I heard he was going to try Scheme I thought, "Oh yeah. Riiiiiight. That'll be a disaster."

There is a program being run by several universities to build Scheme into a nice novice learning experience. Students get immediate feedback and can get programs up and running quickly. No describing of data structures before getting anywhere. No esoteric syntax (think about it -- C can be confusing to the newbie).

The results? He's a convert. All of his students come up to speed quickly and stay with him through the course. He's into describing algorithms quickly and the concepts flow naturally without weird, "ya gotta #include before you can use printf" rules.

Now, do I advocate a Scheme compiler for the AVR? Not at all. However, I worry that those of us who have C so ingrained in our psyches that reams of code unroll before our inner eyes when someone talks about a new function may be somewhat jaded about those trying to learn it.

I think there might be some advantage to re-thinking how students should be introduced to the Wonder World Of Microcontrollers. Radical ideas always look ridiculous at first blush.

Still, I doubt that assembly is a better choice than C for the beginner (despite protestations from John Samperi to the contrary). That's a bit like throwing the baby out with the bath water, eh what?

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

C is sometimes described as 'The portable assembly language' and as 'The programming language that is most like a general computer'. And in a way it is like the English language in that, sure it has lots of flaws, but if you and Abu Dhabi and see a Chinese manufacturer's rep talking to an Argentinian buyer, they will be speaking in English. English, for what ever reason - good or bad - has become >the< global language of commerce, science, and diplomacy. Likewise, C has become >the< language for microcontrollers and small embedded systems. I would never hire an embedded systems engineer that was not proficient in both C and at least one assembler.

That said, there is no reason that folks who want to play with microcontrollers shouldn't have easier systems to use such as BASIC. And the Arduino Way, which is very C-like, is up and coming as a real contender for the 'play at' crowd. Some people just want to blink a few LEDs and read a few switches, maybe they would like to make a line following robot, and if these kinds of activities are their end goal, then there is no reason for them to spend the time to develop serious expertise in either C or assembler.

Smiley

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Now, do I advocate a Scheme compiler for the AVR? Not at all. However, I worry that those of us who have C so ingrained in our psyches that reams of code unroll before our inner eyes when someone talks about a new function may be somewhat jaded about those trying to learn it.

Chuck be it "Scheme" or Algol68 or, in my case Pascal, it's all very well picking a "nicely structured" language to teach students (the set course work for 3 years of my degree included nothing but Pascal because of it's structure and hard typing which supposedly taught you structured programming) but exactly how useful is this when the students venture out into the real world and try to get jobs based on their "programming experience"?

Now I'm very much a advocate of the idea that once you know one Asm and one highlevel language it shouldn't take more than 2-4 weeks to grasp the essentials of any other Asm or HHL but equally I think one should start them off as they mean to go on. Teach one useful Asm (back in my day that was 68000 but these days I'd have said some RISC - preferably ARM) and C.

In fact it's (to my mind) best to start with Asm and move to C because in the Asm you'll probably already start building "larger consructs" using MACRO/ENDM and the step from there to C which isn't much more than a souped up Asm macro language than formalises the loop constructs and introduces "data types".

In fact I think the argument put forward by Simonetta is just plain wrong. If you stop thinking about C as an enemy but as a friend that builds on an Asm base then it's just adding a bit more than you could achieve in Asm alone (well without a lot of work). Even Asm programmers have their favourite way of doing for(;; ), while(){}, do{}while() loops and so on. C just hardens the structure in stone a little more.

If someone finds C "confusing" the chances are that the tutorial they are following simply isn't introducing the concepts in the right order or explaining them well. No one says you have to use every last feature of C on day one just as no one says you have to use every last .directive offered by your assembler on day one.