Porting codevision code to avr-gcc

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

Hello,
Is there somebody who know mains differences between CodeVision and Avr-Gcc code? I need to port somes routins written with CodeVision to WinAvr (GCC compiler).
thank

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

As with all C compilers the main difference is going to be the way you define an interrupt service routine - in avr-gcc it is ISR()

CV also allows for PORTB.3 to access bit 3 in PORTB. You cannot do that in avr-gcc as it conforms to the C standard. (see the 101 thread in the Tutorial forum to understand the C standard way to do bit access)

Cliff

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

thank you very clawson,
it's the second time you reply to my post... you're an very active poster in this forum, congratulations...

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

In fact, he is the number one poster, handily passing the former leader, theusch.

Regards,
Steve A.

The Board helps those that help themselves.

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

Quote:

CV also allows for PORTB.3 to access bit 3 in PORTB. You cannot do that in avr-gcc as it conforms to the C standard.

Yahknow, all of youse Whenever guys have been beating on that one for over 5 years on this site. It is actually quite interesting that some of the "beat up" topics from a few years back are now moot as Whenever now has equivalent mechanisms.

In particular to this one, there is no reason that PORTB.3 cannot be written as PORTB.PB3 or PORTB.PORTB3 which syntax-wise looks just like the bitfield-structure that is often used.

Now, let's see--are you implying that "PORTB |= (1 << PB3);" conforms to the C standard? I must be rusty; I've never seen sfr or sfrb or sfrw in a C standard. [Sound of rising howls of protest] "Yahbut, these are EXTENSIONS!" Right, to accomodate microcontrollers and the AVR's Harvard memory spaces. Cool. Then why can't PORTB.3 be an extension? You are allowed to write "PORTB |= (1 << PB3);" if you want to.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Lee,

Put it this way, Gimpels Lint (a tool I put a lot of faith in) would have no worries about PORTB |= (1<<PB3) or, for that matter, PORTB.PB3 but it would barf on PORTB.3 on the basis that the character after a . should be an alpha, not a numeric.

Having said that I actually really LIKE this non standard feature of CV - I think your PORTB.3 actually looks far more readable and self documenting than virtually any equivalent.

Cliff

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

>> Having said that I actually really LIKE this non standard feature
>> of CV - I think your PORTB.3 actually looks far more readable and
>> self documenting than virtually any equivalent.

Btw., how about the Codevision guys going to run this through the
standards committee? If the committee were agreeing on it, we could
have it within five minutes (OK, a few hours of work) in GCC as well.
As it is now though, it is so completely beyond the standard (because
it violates the given syntax) that I wouldn't even spend those few
hours as I simply know it would never make it into the official GCC
tree.

For things that *are* possible extensions even by the current C
standard rules, see the 0b binary constants. I'm almost through with
my implementation for this, i. e. it now ``only'' requires a prominent
committer to really put it into GCC's code base.

> On the other hand, I find the (1<<OCIE0) construct ugly. I only use
> it because it is the convention on the AVR. Pre-defined bit masks
> instead of bit numbers would be much easier to read.

We've been there before. I fully agree. It appears Atmel specified
it as bit numbers (instead of masks) so the same constants/header file
could be used for both, C and assembly, and in particular for the
SBI/CBI/SBIS/CBIS instructions in the latter case.

EDIT:

Errm, I have to apologize. Somehow, I must have been really confused
yesterday. The above was not written by Koshchi but by Jörg Wunsch
(dl8dtl). I'm afraid I inadvertently destroyed Koshchi's article by
editing my onw into its place. :-( This was by no way my intention, but
I cannot revert the original article now either.

Regards,
Steve A.

The Board helps those that help themselves.

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

...C is portable......C is portable...C is portable...C is portable...it's easy :lol:
Well that's what I keep on hearing..

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Quote:

...C is portable......C is portable...C is portable...C is portable...

Yahknow, that is very interesting. Here is the #1 highlight from the Crossware x51 compiler blurb:
Quote:
The ANSI C compiler protects your investment by ensuring future portability of your C source.

Cool; just what you are saying. The VERY NEXT highlight:
Quote:
8051-specific extensions enable you to access all of the resources of the 8051 and its variants from C.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

theusch wrote:

Yahknow, all of youse Whenever guys have been beating on that one for over 5 years on this site. It is actually quite interesting that some of the "beat up" topics from a few years back are now moot as Whenever now has equivalent mechanisms.

Hi Lee,

If you cannot bring yourself to spell the product name correctly, then go back to posting about CodeVision in the AVR Forum. WinAVR is nothing more than toolchain distribution. GCC is the compiler. But you already know that.

I have no problems in discussing the relative merits of the various compilers. It helps everyone. And when you point out the various shortcomings of the open source tools it helps us by showing what needs improvement. And I'll be the first to admit that GCC has flaws too.

But consistently deriding a product name simultaneously with negative criticism is flamebaiting.

theusch wrote:

In particular to this one, there is no reason that PORTB.3 cannot be written as PORTB.PB3 or PORTB.PORTB3 which syntax-wise looks just like the bitfield-structure that is often used.

I agree with you completely. As others pointed out, it's the naming problem. PORTB.3 violates C's naming rules. I have no issues with changing it as you do above.

theusch wrote:

Now, let's see--are you implying that "PORTB |= (1 << PB3);" conforms to the C standard?

It does conform. No implication is needed.

theusch wrote:

I must be rusty; I've never seen sfr or sfrb or sfrw in a C standard.

Neither have I, and GCC (and avr-libc) don't use them. You will find those in the IAR compiler, not GCC. avr-libc declares a bunch of pre-processor macros, used for convenience in the IO header files to declare registers. But they all conform to the C language standard. The IAR compiler actually has 'sfrb' and 'sfrw' as extensions to the C language.

And regarding extensions to the C language, I generally have no issue with them as long as users are aware of the side effects of using them: it makes code less portable between compilers.

One last point. Using CodeVision's extensions in setting and clearing bits, such as PORTD.3 = 1, has one major drawback: You cannot modify multiple non-contiguous bits simultaneously. You *can* do this with standard C language bitwise operators, which are available in all standards-conforming compilers.

Eric Weddington

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

Quote:

If you cannot bring yourself to spell the product name correctly, then go back to posting about CodeVision in the AVR Forum.

Hey--IIRC it was >>you<< that first posted the "Whenever" moniker, as the pronunciation.

Quote:

But consistently deriding a product name ...

Again, the term was introduced by you as best as I can recall. And is still posted as the pronunciation. So, if you want to call it flamebaiting then I stand guilty, apologize, and will never Whenever whenever I post.
https://www.avrfreaks.net/index.p...

Quote:

...simultaneously with negative criticism

Now, THAT is the intersting part. AFAICR I have >>never<< jumped in to a post on this Forum just to criticize. When I >>do<< jump in it is on a topic of approach, or [especially] when I feel "the Emperor has no clothes". In this particular case, I replied to
Quote:

You cannot do that in avr-gcc as it conforms to the C standard.

I pointed out syntactic ways whereby it can be just as conforming as the bitfield/structure method that is often discussed. Re the multiple-bit: True, but no-one precludes you from doing the mask operation. Two single-bit SBI/CBI (when reachable) is shorter, faster, and more atomic than IN/mask/OUT; for three bits it is a wash.

I will stand behind the history of PORTB.3 = 1; discussions. The offshoot from the past was the evngelical determination that direct I/O register access was not a "good thing" and that right-thinking programmers used outb, outp, inb, inp. Then they were deprecated, in favour of direct access.

[For reference, y'all can take a trip in the time machine and see that Eric and I have been going back-and-forth on this for nearly 5 years. In particular, note how the politically-correct method changed between the 2002 and 2004 parts of the thread]
https://www.avrfreaks.net/index.p...

I find the whole question of "full portability" a bit ludicrous. Yes, the C code can be/should be/absolutely must be by corporate standard portable. But not the whole microcontroller app. Portable to what? Even porting to anoother AVR the I/O subsystem may have (say) timer control bits in different registers. Porting to another micro--timers (say) may need to have a whole different "driver".

So you put all that stuff into an area so it can be adjusted in one place. Whehter you call it a device file or abstraction layer or implementation map, I don't care. Put PORTB.3 =1; or PORTB |= (1 << PB3); in there; I don't care. Then the macro might read ERR_LED_ON(); in the "C" part, regardless of the underlying "primitive". I've seen a lot of elaborate macro schemes posted, most are quite elegant and many were on this Forum.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

theusch wrote:
Two single-bit SBI/CBI (when reachable) is shorter, faster, and more atomic than IN/mask/OUT; for three bits it is a wash.

Perhaps shorter, yes... but more atomic??? define "more atomic".. It either is atomic, or it isn't atomic. As soon as you move to multiple instructions to do something, it isn't. (unless you take additional steps to make it atomic again)

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

I can't claim to know the exact meaning of atomic, but here is what I meant:

If you do SBI on two different bits of the same port, it is two instructions. Let's say the sequence boils down to setting LEDs on bits 0 & 1 of port B. Let's also say that there is another LED or other output on bit 2, PB2, that is set inside an ISR.

With the SBI/SBI I don't care when the interrupt occurs--one or both of the SBIs can fire before or after the interrupt. But with IN/mask/OUT the sequence would need to be protected and the interrupt could occur after the IN or after the mask and before the OUT. The result could be fruit salad.

Of course, outside of SBI/CBI reach (such as port G stuff on the bigger processors) it is a consideration on every manipulation. I try to make it a habit to examine all ISRs after initial app development looking for all I/O references and asking "what could possibly go wrong?" I've found that time is well-spent compared to a long head-scratching session, 'cause eventually that interrupt WILL fire between any two instructions.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

An atomic operation is an operation that is performed without a break that could adversely affect the result. A single cycle instruction like SBI/CBI is a natural example of this, as it cannot be broken apart. Multi-byte reads, R-M-W operations are typical examples of non-atomic operations (without extra work)

In your case you're talking about two single atomic operations, not one overall atomic operation. Other than a time penalty the SBI/CBI sequence can be extended out for every bit in the register, because one bit does not depend on the next. So each bit is set or cleared atomically, in turn. Like using volatile in your code for a global altered by an ISR, you need to be aware of I/O's that are modified by ISR's, and peroperly protect your code from breaking if the ISR were to fire while you were working with the same register.

The most basic way to make an operation atomic is to disable interrupts before the operation, and re-enable them after... but depending on the hardware, this may not be enough. You may also need to temporarilly disable the particular sub-system so that the hardware does not alter the value before you can fully deal with it. This would be the case whenever you need to deal with multiple bits in an atomic fashion. SBI/CBI won't help you here, as they only work with a single bit at a time.

You also keep saying SBI/CBI... when talking about 'C'... SBI/CBI are NOT 'C' constructs, they are ASSEMBLY constructs. There is nothing stopping a compiler from turning "PORT |= (1<<BITn)" into a "SBI PORT, BITn" sequence. So please stop bringing up SBI/CBI when we're talking about the "portability" of "PORT.n" vs "PORT.BITn" or even "PORT |= (1<<BITn)" they are all equivalent (with the exception that the first is not compliant with the C language), and it's up to the compiler to choose what sequence of machine instructions to generate in order to implement that operation. And NONE are guarnateed to be atomic. (you can only predict that they will be, from familiarity with the output your compiler will generate)

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

Last Edited: Tue. May 1, 2007 - 08:39 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

Hey--IIRC it was >>you<< that first posted the "Whenever" moniker, as the pronunciation.

But that is not the product name and you know it.

theusch wrote:

I pointed out syntactic ways whereby it can be just as conforming as the bitfield/structure method that is often discussed. Re the multiple-bit: True, but no-one precludes you from doing the mask operation. Two single-bit SBI/CBI (when reachable) is shorter, faster, and more atomic than IN/mask/OUT; for three bits it is a wash.

I will stand behind the history of PORTB.3 = 1; discussions. The offshoot from the past was the evngelical determination that direct I/O register access was not a "good thing" and that right-thinking programmers used outb, outp, inb, inp. Then they were deprecated, in favour of direct access.

[For reference, y'all can take a trip in the time machine and see that Eric and I have been going back-and-forth on this for nearly 5 years. In particular, note how the politically-correct method changed between the 2002 and 2004 parts of the thread]

My argument has never changed.
- CodeVision uses a non-standard C construct.
- It is not portable across compilers.
- Using bit-wise operators allows compiler portability.
- Using bit-wise operators allows multiple, non-contiguous bit operations.

theusch wrote:

I find the whole question of "full portability" a bit ludicrous. ... Portable to what?

As I keep having to tell you: across *compilers*. We both know that porting to different micros is ludicrous as there are many other issues.

You know, the only time that we have this continual argument is when someone wants to port from CodeVision to GCC and they run across this same issue: "I've written my code as REGISTER.n = 1; but that doesn't work in GCC. Why is that?". And then the users here on the GCC Forum have to patiently explain, again, why such a construct is non-portable, across *compilers*, and what is the correct way to do it portably. Then you usually show up and chime in about how it's so much easier to do it the CodeVision way. And then we have this same argument all over again.

This has nothing to do with "political correctness", as if we were talking about geo-politics. I don't know why you think that all of us here are on high horses. The main issue has to do with the C language standard. If you have a problem with it, by all means, go get it changed.

Each compiler has it's own quirks and extensions. At one time those macros (outb, inb, outp, inp) were the only method to do assignments and reads in AVR GCC. (That was before I got involved in AVR GCC.) Then they were changed to use the simpler assignment operator, and the macros were deprecated. (IIRC, this was done by Ted Roth.) This has nothing to do with "right-thinking programmers". This has to do with toolchain improvements. Better constructs get introduced and older constructs get deprecated. Quit making technical issues into religious/political wars. Again this is just flamebait.

theusch wrote:

I've seen a lot of elaborate macro schemes posted, most are quite elegant and many were on this Forum.

And I agree with you completely. I've written them myself and they are preferable to reading register and bit names.

Eric

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

EW wrote:
But that is not the product name and you know it.

Eric,

As I think you know, I'm a great advocate for the use of WinAVR and avr-gcc but if you just type "WinAVR" into Google and take the very top link I can see how many people (me included) got the impression is WAS called "whenever" ;) :P

Cliff

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

clawson wrote:
EW wrote:
But that is not the product name and you know it.

Eric,

As I think you know, I'm a great advocate for the use of WinAVR and avr-gcc but if you just type "WinAVR" into Google and take the very top link I can see how many people (me included) got the impression is WAS called "whenever" ;) :P

Cliff

Indeed, but that is how it is pronounced (though even then tounge firmly in cheek)... not written. Writing it that way is in fact demeaning it. And I believe that is what Eric was getting to.

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

> (IIRC, this was done by Ted Roth.)

It's even been before Ted Roth became involved, I believe (or just
around that time). It's been deprecated by Marek Michalkiewicz as
soon as he had implemented the possibility to use the direct
assignment IO ports into AVR-GCC (and avr-libc), so GCC was *finally*
compatible with all other compilers (including the syntax used in the
Atmel demonstration code snippets). As the old workaround macros were
no longer needed then, he deprecated them.

I just reviewed GCC's ChangeLogs, this has been in May, 2002 -- five
years ago.

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

> Indeed, but that is how it is pronounced (though even then
> tounge firmly in cheek)... not written.

I guess Eric was also pointing out that the compiler in question is
called AVR-GCC, not WinAVR.

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:

This has nothing to do with "right-thinking programmers".

It sure does--the same evangelical arguments were used to defend/promote inb and friends as the "right" way.

PORTB.PB3, for single-bit manipulation, is just as legal and uses the same #define for PB3 that comes out of the Atmel xmlconvert that may very well be used for the WinAVR part include files. Whether it translates to 3, or is part of a structure, or gets chewed up by a macro, it is still on-the-face correct C syntax. And it was 5 years ago as well.

The multiple-bit topic is different. I didn't bring it up. I never claimed that PORTB.3 was intended for multiple-bit manipulations.

ISR declarations are different among the mainstream C compilers. Who is "standard" there?

Quote:

Then you usually show up and chime in about how it's so much easier to do it the CodeVision way.

I didn't say a THING about easier or better. I only addressed the non-standard part. AFAIK you (or OP or whoever) could do an elegant macro to handle the PORTB.PB3 syntax.

Quote:

[re portability] As I keep having to tell you: across *compilers*.

So the "standard" method of ISR syntax is ...?

You say that extensions are fine, so can't PORTB.3 be an extension that you can choose to use or not use as you see fit? Does that make it right or wrong?

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

theusch wrote:
Quote:

This has nothing to do with "right-thinking programmers".

It sure does--the same evangelical arguments were used to defend/promote inb and friends as the "right" way.

Arguments by whom? When?
I never promoted that. And as these constructs were normal so long ago, have been deprecated so long, just what in the past are you referring to?

theusch wrote:

PORTB.PB3, for single-bit manipulation, is just as legal ...

These discussions that we have been having in the past always referred to the PORTB.3 construct which is non-standard C because of naming conventions. Yes, I agree with you that the convention used above is legal C.

theusch wrote:

ISR declarations are different among the mainstream C compilers. Who is "standard" there?

Stay on topic. There is no standard and you know it.

theusch wrote:

AFAIK you (or OP or whoever) could do an elegant macro to handle the PORTB.PB3 syntax.

And probably will in the near future...

theusch wrote:

Quote:

[re portability] As I keep having to tell you: across *compilers*.


So the "standard" method of ISR syntax is ...?

Again, stay on topic. The issue has to do with bit manipulations not ISRs.

theusch wrote:

You say that extensions are fine, so can't PORTB.3 be an extension that you can choose to use or not use as you see fit? Does that make it right or wrong?

Why are you getting so hung up about "right or wrong"?
- PORTB.3 is an extension in the CodeVision compiler
- It is NOT an extension in GCC
- Ergo, if one uses that extension in CodeVision, then that particular code is non-portable to other compilers, such as GCC.
- There are methods to perform the same operation that conform to Standard C, that are available in all standards-conforming compilers.
- If one uses these standard methods, then it makes those portions of code easier to port to other compilers.

Because of this, I don't understand what the benefit is of using those said extensions in CodeVision. Lee, you yourself said that there is a portable way of doing this, e.g. PORTB.BIT3. I can understand if CodeVision decided to go this route. I don't understand why they created an extension that just confuses a lot of beginner end-users, that provides almost no benefit, when they could have done it differently.

Eric

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

glitch wrote:

Indeed, but that is how it is pronounced (though even then tounge firmly in cheek)... not written. Writing it that way is in fact demeaning it. And I believe that is what Eric was getting to.

Yes, just as those who write "Windoze" are intending to demean Microsoft Windows (whether the product deserves it or not is subject to debate). The two written forms are both pronounced the same way; the intention is unmistakable.

Alas, however, in life no one that I know of it actually pronounces it that way. Everyone seems to pronounce it as "Win-A-V-R". I've also come to pronounce it that way myself. I should remove the reference on the SF page.

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

Quote:
Arguments by whom? When?

Yahknow, I figgered that was coming. With Search broken it is impossible to pull up the backing information.

Quote:

Again, stay on topic.

Hey, c'mon. >>You<< were the one that threw-in the "multiple-bit" thingy, not me. And I was quoting you on the >>portability<< issue, where AFAIK the mainstream C compiler vendors all have a different syntax.

If you like, I'll keep digging as best I can for the old posts. Yes, it was a long time ago--us elephants are ponderous but we don't forget easily. Yes, that is why it rankles--I was lambasted JUST AS HARD THEN about the "goodness" of not having/using direct I/O access.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

The ISR thing is ugly... I wish C had a standard mechanism for that. However a series of preprocessor directives/macros can clean this up. Much easier than doing it for each and every I/O access.

I also have to agree with Eric... why create "PORT.3", when the standard syntax of "PORT.BIT3" already exists? I don't mind compiler extensions, they are often beneficial for an architecture or compiler... but creating ones to replace already standard constructs seems pointless to me.

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

theusch wrote:
Quote:
Arguments by whom? When?

Yahknow, I figgered that was coming. With Search broken it is impossible to pull up the backing information.

I'm sure Google has some advanced searching capabilities that could be applied.

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

aahhh nothing like a compiler war to instill confidence in me regarding using C... :lol: let me see what's happening in the other battle field...so many wars so little time :lol:

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Quote:

I'm sure Google has some advanced searching capabilities that could be applied.

Google has cataloged a lot of the posts, but not nearly all. I tried.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Quote:

why create "PORT.3", when the standard syntax of "PORT.BIT3"
Quote:
already exists
? I don't mind compiler extensions, they are often beneficial for an architecture or compiler... but creating ones to replace already standard constructs seems pointless to me.

[emphasis mine above] An interesting one. there was a nice discussion a while back on origins. IIRC, the first usable versions of CodeVision and ImageCraft and [AVR port of] GCC were within a few months of each other. As the history above indicates, GCC didn't have direct port access at that time. AVRs and their compilers were new. So my speculation is that Pavel "invented" the PORTB.3 since that was commonly used in datasheets. (Doesn't x51 have a syntax like that for bit access to bytes as well?)

So the "already exists" part isn't really black-and-white to me. But then again, I've only been doing C on AVRs since 2000 and not since day 1.

[edit] https://www.avrfreaks.net/index.p...
says that CV & ImageCraft were released about one month apart 9unknown date), and gives some dates of the early GCC for AVR releases. My earliest CVAVR.EXE files are dated mid-2000.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Tue. May 1, 2007 - 10:34 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

Quote:

Again, stay on topic.

Hey, c'mon. >>You<< were the one that threw-in the "multiple-bit" thingy, not me.

Which is relevant to bit operations in C. You strayed off into ISRs which have nothing to do with bit operations.

theusch wrote:

And I was quoting you on the >>portability<< issue,

Again, only portability between compilers, because, as the topic of the post says: "Porting codevision code to avr-gcc".

theusch wrote:

where AFAIK the mainstream C compiler vendors all have a different syntax.

... for ISRs, which we both know, there is no standard.

theusch wrote:

Yes, it was a long time ago--us elephants are ponderous but we don't forget easily. Yes, that is why it rankles--I was lambasted JUST AS HARD THEN about the "goodness" of not having/using direct I/O access.

So what I'm reading is that you are equating one argument (about the differences between bit operations between compilers) with another years-old argument ("not having/using direct I/O access") that is no longer valid?

I'm sorry you feel lambasted about this. I'm just repeating the same facts about bitwise operations between these two compilers that I always have.

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

theusch wrote:
An interesting one. there was a nice discussion a while back on origins. IIRC, the first usable versions of CodeVision and ImageCraft and [AVR port of] GCC were within a few months of each other. As the history above indicates, GCC didn't have direct port access at that time. AVRs and their compilers were new. So my speculation is that Pavel "invented" the PORTB.3 since that was commonly used in datasheets. (Doesn't x51 have a syntax like that for bit access to bytes as well?)

So the "already exists" part isn't really black-and-white to me.

C bitwise operators have been around since K&R (AFAIK). And bit fields have been around a lot longer than the CodeVision compiler. There was never any need to invent anything new.

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

As far as I am aware teh documentation never used the PORT.n notation, bits were always named. CV is the only compiler to take a non-standard route here, and for the life of me I cannot fathom why, since bitfields in C have existed since day 1 of the language.

The AVR-GCC situation was a bit different... it's not that it didn't provide bit level access... you could always define a structure of bitfields... it was that AVR-GCC initially did not provide direct access to the AVR's I/O area, they have since corrected this shortcoming. (note that traditionally for GCC, when I/O space is a separate address space, special accessor functions are provided from the library.. this was the initial route for AVR-GCC)

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

OK, I'll just throw in the towel. You guys will split all my hairs till they are all frizzy.

--Eric came back and >>said<< that portability was the topic, but I was off-topic for bringing up ISR syntax which is CERTAINLY pertinent to porting from CV to GCC.

--So gitch reminds me that early GCC did not have a feature (direct access), CV did, CV direct access could >>always<< be done with (1 << PB3), CV gave another method PORTB.3, PORTB.3 can be written as PORTB.PB3 then and now. Who created or re-created what here?

Y'all have said everything often enough and loud enough and for long enough that you must be correct.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

theusch wrote:

--Eric came back and >>said<< that portability was the topic, but I was off-topic for bringing up ISR syntax which is CERTAINLY pertinent to porting from CV to GCC.

Ok, point. And this where the C Standard drives me crazy. K&R created a language for systems software (like operating systems, and specifically Unix), but there is no standard for declaring an ISR?! Why couldn't the Standards Committee fix this in the decades that they've had to do so?

theusch wrote:

--So gitch reminds me that early GCC did not have a feature (direct access), CV did, CV direct access could >>always<< be done with (1 << PB3), CV gave another method PORTB.3, PORTB.3 can be written as PORTB.PB3 then and now.

Well you said it best. If PORTB.3 can be written as PORTB.PB3 then and now, then why did Pavel create the "PORTB.3" syntax? And more importantly, why hasn't he given it up and deprecated it? The only reason that I can come up with is that using that construct locks that user into the CodeVision compiler.

Eric

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

theusch wrote:
CV direct access could >>always<< be done with (1 << PB3), CV gave another method PORTB.3, PORTB.3 can be written as PORTB.PB3 then and now.

Then why offer, or use, PORTB.3 at all?? It must have be promoted heavily, because everyone who uses CV seems to use the non-standard notation instead of the standard methods. Now people are getting bitten in the arse when they decide to move to a different compiler. (not to mention the confusin it causes people trying to learn C on the AVR) From memory, that is the single most common stumbling block we see when people try to transition from one to the other. So it appears to me the only thing the PORTB.3 notation has done is to confuse people.

[edit] Eric was a bit quicker than me, again :)

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

EW wrote:
theusch wrote:

--Eric came back and >>said<< that portability was the topic, but I was off-topic for bringing up ISR syntax which is CERTAINLY pertinent to porting from CV to GCC.

Ok, point. And this where the C Standard drives me crazy. K&R created a language for systems software (like operating systems, and specifically Unix), but there is no standard for declaring an ISR?! Why couldn't the Standards Committee fix this in the decades that they've had to do so?

I have to agree... This has to be one of my pet peeves. I'm guessing that they left it up to the OS writer to do, since interrupts are very processor/hardware platform specific in how they are handled.

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

theusch wrote:
--So gitch reminds me that early GCC did not have a feature (direct access), CV did, CV direct access could >>always<< be done with (1 << PB3), CV gave another method PORTB.3, PORTB.3 can be written as PORTB.PB3 then and now. Who created or re-created what here?

Y'all have said everything often enough and loud enough and for long enough that you must be correct.

Lee

I don't understand what's so difficult to accept here...

The ".3" notation does violate specific restrictions on the legal naming schemes used in the definition of the C language.

The ".PB3" notation works equivalently without violating any aspect of the C language. It simply makes use of aspects of the language which have always existed.

The mechanisms to produce a construct which uses the ".PB3" syntax comes "built-in" to every C compiler, using bitfields. Specific instances of it are not currently predefined in avr-gcc to automatically refer to the I/O registers, but it's not too much trouble to cut-and-paste a template into your application. And I'm sure that, with consensus, somebody would be allowed to write a patch which *would* officially incorporate it into avr-libc. (So far that hasn't happened.)

AVR-GCC does extend the C standard in some areas where the standard simply cannot provide any conforming alternative to achieve necessary microcontroller functionality -- like dealing with interrupts.

And through its history, it has forced users to use some ugly kludges to deal with features which, while ideally perfectly allowable under the standard, weren't yet fully implemented in GCC. (The inb() and outb() macros come to mind here. Actually, this is an example of a feature of avr-libc which really wasn't in violation of any standards. It was just clumsy from an asthetic perspective.)

But I don't think anybody advocated using them as anything more than a temporary workaround until things could be fixed the right way. And all the documentation for AVR-GCC has advised against using the inb() and outb() macros since at least 2004 (when I first looked at avr-gcc). They were even removed from the library entirely, but subsequently re-introduced simply to provide compatibility with old software for which the individual developers couldn't be bothered to do a re-write.

But in the case of the ".3" notation, you're creating a non-conformance even though equivalent functionality can be achieved (".PB3") without violating any standards.

Last Edited: Wed. May 2, 2007 - 01:24 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

...then why did Pavel create the "PORTB.3" syntax?

Now my History Detectives streak is arising. Let me poke around ...

[edit] I might have the short answer for EW. I don't think Pavel >>created<< it. Rather it was "borrowed". Or, put another way, Pavel chose to use a method already used for sfr bit-level access (as well as variables of type "bit") from an existing system--IAR C compiler.

Check page 4 of this IAR x51 compiler brochure:
http://www.mhl.tuc.gr/data_books...

Quote:
Complete access to sfr and bit-addressable space

The IAR Systems 8051 C Compiler supports the extended sfr keyword to access the SFR map. Variables declared with the sfr keyword produce optimal assembly code:
sfr PO=0x80 /*def. Included in io51.h*/
if (PO)
{
PO=3; /*write value to port*/
}
PO |= 2; /*OR with a constant*/
generates the following assembly code:
MOV A,PO
JZ label
MOV PO,#3
label
ORL PO,#2

The bit-addressable SFR registers may also be accessed using the sfr.bit syntax:

PO.1; /*clears bit 1 of PO*/
The bit-extended keyword makes it possible to declare singlebit
variables:

bit bitvar1,bitvar2,bitvar3=PO.2;
bitvar1=bitvar2 & bitvar3;
bitvar3=0;

A bit declared variable could be placed anywhere within the bit addressable area of the 8051 memory (20H-2FH).

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Quote:
Two single-bit SBI/CBI (when reachable) is shorter, faster

It may be shorter, but it is not necessarily faster. Two SBIs in a row take 4 clocks, but IN, ORI, OUT takes 3 clocks. The same goes for two CBIs and IN, ANDI, OUT. Only if it is one SBI and one CBI would it be faster.

Also, using IN, AND/OR, OUT will ensure that all bits get changed at once which can often be the more desirable behavior. And as far as atomic behavior, it is actually more secure as far as the bits that you are changing. The problem is actually the other bits.

Quote:
Errm, I have to apologize. Somehow, I must have been really confused
yesterday. The above was not written by Koshchi but by Jörg Wunsch
(dl8dtl). I'm afraid I inadvertently destroyed Koshchi's article by
editing my onw into its place. :-( This was by no way my intention, but
I cannot revert the original article now either.

Good thing that you added this. I thought that I was going crazy!

To restate what was lost, the PORTB.0 form has another drawback in that it is only bit numbers. With bit fields you can access a bit by its name (TIMSK.TOIE0), which is much clearer. Plus you can access more than one bit at a time (TCCR1B.CS = 6 to set the timer pre-scaler, for instance). Only non-contiguous bits can't be handled with bit fields.

Regards,
Steve A.

The Board helps those that help themselves.

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

I guess I must be the only one to side with Lee on this. In the context of C for embedded controllers I just find PORTB.3 = 1 more instantly readable than PORTB.PB3 = 1 and definitely more readable than PORTB |= (1<<PB3) though, through peversity, it's actually the latter that I use ;)

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

> I guess I must be the only one to side with Lee on this. In the
> context of C for embedded controllers I just find PORTB.3 = 1 more
> instantly readable than PORTB.PB3 = 1

I wouldn't even argue that, but then, the creator of that notation
should have had the heart to at least *try* pushing that through the C
standards committee.

(Similar would of course apply to any of those MCS51 compiler vendors
who apparently did that before. However, I don't know a controller I
could care less about. Ah well, maybe an 8031. :)

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

theusch wrote:

[edit] I might have the short answer for EW. I don't think Pavel >>created<< it. Rather it was "borrowed". Or, put another way, Pavel chose to use a method already used for sfr bit-level access (as well as variables of type "bit") from an existing system--IAR C compiler.

Check page 4 of this IAR x51 compiler brochure:
http://www.mhl.tuc.gr/data_books...

Quote:
Complete access to sfr and bit-addressable space

The IAR Systems 8051 C Compiler supports the extended sfr keyword to access the SFR map. Variables declared with the sfr keyword produce optimal assembly code:
sfr PO=0x80 /*def. Included in io51.h*/
if (PO)
{
PO=3; /*write value to port*/
}
PO |= 2; /*OR with a constant*/
generates the following assembly code:
MOV A,PO
JZ label
MOV PO,#3
label
ORL PO,#2

The bit-addressable SFR registers may also be accessed using the sfr.bit syntax:

PO.1; /*clears bit 1 of PO*/
The bit-extended keyword makes it possible to declare singlebit
variables:

bit bitvar1,bitvar2,bitvar3=PO.2;
bitvar1=bitvar2 & bitvar3;
bitvar3=0;

A bit declared variable could be placed anywhere within the bit addressable area of the 8051 memory (20H-2FH).

Wow. I wouldn't have guessed it, but now it makes sense. It's the IAR Compiler.

Thanks for tracking this down, Lee!

clawson wrote:

I guess I must be the only one to side with Lee on this. In the context of C for embedded controllers I just find PORTB.3 = 1 more instantly readable than PORTB.PB3 = 1 and definitely more readable than PORTB |= (1<<PB3) though, through peversity, it's actually the latter that I use

Well when it comes to readability, I prefer neither. I prefer an even greater abstraction through macros or another layer. I would much rather read/write:

external_interrupt_1_enable();

than:

EIMSK |= (1 << INT1);

(ATmega128)

I can see at a glance what the first line is doing. I still have to think about the second line, and more than likely go look it up in the datasheet to know what it is doing.

But readability is squarely in the eye of the beholder. YMMV. :)

Eric

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

theusch wrote:
Quote:

...then why did Pavel create the "PORTB.3" syntax?

Now my History Detectives streak is arising. Let me poke around ...

[edit] I might have the short answer for EW. I don't think Pavel >>created<< it. Rather it was "borrowed". Or, put another way, Pavel chose to use a method already used for sfr bit-level access (as well as variables of type "bit") from an existing system--IAR C compiler.

Check page 4 of this IAR x51 compiler brochure:
http://www.mhl.tuc.gr/data_books...

Quote:
Complete access to sfr and bit-addressable space

The IAR Systems 8051 C Compiler supports the extended sfr keyword to access the SFR map. Variables declared with the sfr keyword produce optimal assembly code:
sfr PO=0x80 /*def. Included in io51.h*/
if (PO)
{
PO=3; /*write value to port*/
}
PO |= 2; /*OR with a constant*/
generates the following assembly code:
MOV A,PO
JZ label
MOV PO,#3
label
ORL PO,#2

The bit-addressable SFR registers may also be accessed using the sfr.bit syntax:

PO.1; /*clears bit 1 of PO*/
The bit-extended keyword makes it possible to declare singlebit
variables:

bit bitvar1,bitvar2,bitvar3=PO.2;
bitvar1=bitvar2 & bitvar3;
bitvar3=0;

A bit declared variable could be placed anywhere within the bit addressable area of the 8051 memory (20H-2FH).

Note that that document is dated 1996! IAR might have created/used it back then, but as far as I am aware have long since abandoned it. (Probably for the very reasons we are discussing here) Perhaps Pavel should take another page from the IAR book, and abandon the non-standard notation as IAR did.

ftp://ftp.iar.se/WWWfiles/8051/g...

Ref pg 184... bit fields are now appear to be named in accordance with C standards.

Note that the prior notation the REG.n notation appears to have derived from the 8051 assembler notation. (still used today in IAR's 8051 assembler)

ftp://ftp.iar.se/WWWfiles/8051/A...

Does the word "lemming" come to mind for anyone else here?

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

Sighing. And ducking.

But the question I was asked was why Pavel "created" it. I could ask him, but it looks to me like it was "borrowed". That 1996! is just about when AVRs were born, right? Lots of us did/do x51 programming (except maybe Jorg from the comment above ;) ). I had done my share before starting on the AVRs and the .n notation was familiar and I didn't think twice about it.

I dug out several AVR-related old documents (not CV) that used the notation in discussing the AVR port pins and the attached devices. Kind of an interesting Web hit--the SDCC compiler AVR target (since abandoned) overloaded the "." operator to provide sfr.bit access. Same approach.

So why wasn't it abandoned? I dunno--for the same reason that inp() still lives, to avoid breaking existing code?

Conclusion 1: PORTx.n syntax must be addressed when porting from CodeVision to GCC.
Conclusion 2: ISR syntax must be addressed when porting from CodeVision to GCC.
Conclusion 3: "bit" variables must be addressed when porting from CodeVision to GCC.
Conclusion 4: Memory-space handling (flash, eeprom keywords) syntax must be addressed when porting from CodeVision to GCC.
Conclusion 5: None of the above are standard (ANSI/ISO) C and are extensions.
Conclusion 6: CodeVision project options under which the project was developed must be considered (as would compile-time switches for GCC).
Conclusion 7: Never, ever, say the "W....ver" word in these discussions.

Now, why didn't I just make that my first response in this thread?

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

nash911 wrote:
By using "PORT |= (1<<BITn)", for manipulating a single bit, it would not only be a non-atomic way, but would take more time than compared to the use of "SBI/CBI". Am I correct?

No you are not correct. When you use that construct the compiler WILL generate a single, atomic SBI/CBI if it can (as long as you don't build with -O0 !)

For example:

void c_fn(void){
  PORTB |= (1<<3);
}

just compiled to be:

3:        void c_fn(void){
+00000033:   9AC3        SBI     0x18,3           
+00000034:   9508        RET

Cliff

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

Quote:
There is nothing stopping a compiler from turning "PORT |= (1<<BITn)" into a "SBI PORT, BITn" sequence. So please stop bringing up SBI/CBI when we're talking about the "portability" of "PORT.n" vs "PORT.BITn" or even "PORT |= (1<<BITn)" they are all equivalent (with the exception that the first is not compliant with the C language)

Hi Eric,

Dose the above mean that I can use "PORT.BITn =1;" in my program? I tried it and got the following error,

PORTC.BIT2=1;
error: request for member 'BIT2' in something not a structure or union

If the answer to the above question is a "Yes", could you please post a code example of how to declare and use it, in here?

And if you could also explain how to use "SBI/CBI" instructions in WinAVR with a code example.

Sorry this might be an elementary question after all of these discussions on this thread.

By using "PORT |= (1<<BITn)", for manipulating a single bit, it would not only be a non-atomic way, but would take more time than compared to the use of "SBI/CBI". Am I correct?

Avinash

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

Thank You Cliff. I jus deleted my post coz i hadn't read all the posts on this thread.

Never expected such a fast responce. Thanks a lot.

Could you also answer the questions i directed towards Eric?

Thank You,
Avinash

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

Hey now THAT was clever. I just boarded my HG Wells MkIII designed time travelling machine. Travelled backwards in time and was able to post an answer to Avinash's message BEFORE he made it!!!!

(Now how on Earth did that happen???)

Cliff the Time Traveller

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

OK well you can't just use PORTC.BIT2 as the io.h header files will already be defining a "PORTC" object and you cannot easily overlay a sub-structure onto that existing definition. However it SHOULD be possible to come up with your own myPORTC.BIT2 by defining a 'myPORTC' bitfield structure and arranging for it to be located at the 'PORTC' memory address.

Personally I use a variant on this theme with something like:

#define ON 1
#define OFF 0

typedef struct 
{ 
  unsigned char bit0:1; 
  unsigned char bit1:1; 
  unsigned char bit2:1; 
  unsigned char bit3:1; 
  unsigned char bit4:1; 
  unsigned char bit5:1; 
  unsigned char bit6:1; 
  unsigned char bit7:1; 
}io_reg; 

#define BIT_orange_LED	((volatile io_reg*)_SFR_MEM_ADDR(PORTC))->bit0 
#define BIT_green_LED	((volatile io_reg*)_SFR_MEM_ADDR(PORTC))->bit1

Then in the program I can use:

BIT_orange_LED = ON;
BIT_green_LED = OFF;

and this produces single SBI and CBI instructions.

Cliff

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

Cliff,

I am unable to understand the use of ":1" in the following,

unsigned char bit0:1;

Why are you using bit field here?

Avinash

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

Avinash,

Well the use of a structure with packed single bit fields is the whole purpose of the exercise. You effectively want to take an 8 bit byte and be able to name the individual bits within it. By casting an 8 element structure of 8 single, named bits, onto the one byte you are devising a way to name and access the bits individually.

Cliff