Author Topic: [SAMC] pointer code only works within a function  (Read 5105 times)

0 Members and 1 Guest are viewing this topic.

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4206
  • Country: us
Re: [SAMC] pointer code only works within a function
« Reply #25 on: January 26, 2020, 12:53:08 am »
Quote
Code: [Select]
void pin_tgl(uint8_t port, uint8_t pin ){
( * ( uint32_t * )( PORT_BASE + PORT_PIN_TOGGLE + port * PORT_OFFSET ) ) = 0x1 << pin ;
}
That looks like a pretty convoluted and error-prone way of saying:
Code: [Select]
void pin_tgl(uint8_t port, uint8_t pin ){
  (PORT->Group[port].OUTTGL.reg) = 0x1 << pin ;
}
(and yes, that compiles to pretty optimal code, at least on a SAMD21.  (Which should be the same WRT general purpose IO as a SAMC20))(and also yes, whoever was at Atmel and come up with the name "PORT" for the start of the group of ports, and "Group" for each individual port, should be punished.  Sigh.)
I think in the more recent Microchip incarnations of CMSIS peripheral definitions for SAM*, you need to say:
Code: [Select]
void pin_tgl(uint8_t port, uint8_t pin ){
  (PORTS[port].PORT_OUTTGL) = 0x1 << pin ;
}
Which is a little better, ASIDE FROM COMPLETELY REDOING EVERYTHING.  Double Sigh. :palm:

 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11281
  • Country: us
    • Personal site
Re: [SAMC] pointer code only works within a function
« Reply #26 on: January 26, 2020, 12:57:05 am »
Simon likes to redo things. There is absolutely no reason for that, but I don't think we will change his mind any time soon.
Alex
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: [SAMC] pointer code only works within a function
« Reply #27 on: January 26, 2020, 01:24:08 am »
When you’re first learning, that’s often a good thing when the purpose is to aid understanding.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17829
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAMC] pointer code only works within a function
« Reply #28 on: January 26, 2020, 09:27:48 am »
Quote
Code: [Select]
void pin_tgl(uint8_t port, uint8_t pin ){
( * ( uint32_t * )( PORT_BASE + PORT_PIN_TOGGLE + port * PORT_OFFSET ) ) = 0x1 << pin ;
}
That looks like a pretty convoluted and error-prone way of saying:
Code: [Select]
void pin_tgl(uint8_t port, uint8_t pin ){
  (PORT->Group[port].OUTTGL.reg) = 0x1 << pin ;
}
(and yes, that compiles to pretty optimal code, at least on a SAMD21.  (Which should be the same WRT general purpose IO as a SAMC20))(and also yes, whoever was at Atmel and come up with the name "PORT" for the start of the group of ports, and "Group" for each individual port, should be punished.  Sigh.)
I think in the more recent Microchip incarnations of CMSIS peripheral definitions for SAM*, you need to say:
Code: [Select]
void pin_tgl(uint8_t port, uint8_t pin ){
  (PORTS[port].PORT_OUTTGL) = 0x1 << pin ;
}
Which is a little better, ASIDE FROM COMPLETELY REDOING EVERYTHING.  Double Sigh. :palm:



i got fed up with trawling through the header files trying to work out what to call stuff. This way it's self explanatory and i like self explanatory code as later I know what the heck I did. Given the 5 cycle run time in a while loop I'm sure the compiler does not give a fig how it's written as long as it's valid.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17829
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAMC] pointer code only works within a function
« Reply #29 on: January 26, 2020, 09:32:10 am »
Simon likes to redo things. There is absolutely no reason for that, but I don't think we will change his mind any time soon.

Nope, I have a short memory (probably ADD) so doing it myself helps it stick in memory to learn, means that what I have to remember is more like what I would naturally want to write and the code self documents, something the vendors rarely do as discussed many times. I try to write code that self explains itself as much as possible so that the day i have to figure out what the hell i did it's all laid bare there for me. I swapped from raw register name addresses to defining them so that at least on a same as but differently addressed chip i can simply change the address definitions.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17829
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAMC] pointer code only works within a function
« Reply #30 on: January 26, 2020, 09:33:32 am »
And of course in doing this i have learnt more about C the easier way, by doing it. i have come to appreciate the time it take to call a function and the fact that volatile was supposed to be used in any pointer to register is something I have never found explained.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17829
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAMC] pointer code only works within a function
« Reply #31 on: January 26, 2020, 02:50:14 pm »
looking at the clock controller. I don't think it's as complicated as people think it is. What's complicated is the way they describe it repeating themselves and using names in the text to talk about blocks in a diagram that instead have different names.

Several clock sources are available. you connect them to a pre-scaler or clock generator that in turn is connected to peripheral clock inputs.
 

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: [SAMC] pointer code only works within a function
« Reply #32 on: January 26, 2020, 06:38:04 pm »
While volatile is often used with variables shared between interrupts and user mode code, it is in fact not the right tool for that, since it doesn't protect you against race conditions. Instead, you should use atomic types, provided your compiler supports them.
Volatile should be used in addition to atomic access methods in this case.
Correct me if I'm wrong, but with sequentially consistent memory ordering, the volatile would be redundant.

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11281
  • Country: us
    • Personal site
Re: [SAMC] pointer code only works within a function
« Reply #33 on: January 26, 2020, 06:40:18 pm »
Correct me if I'm wrong, but with sequentially consistent memory ordering, the volatile would be redundant.
No. Anything you change or access from main code and the interrupt has to be volatile, otherwise compiler is free to optimize either of those things out.

This has to be done in addition to any atomicity concerns.
Alex
 
The following users thanked this post: newbrain

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17829
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAMC] pointer code only works within a function
« Reply #34 on: January 27, 2020, 09:38:27 pm »
You better get microchip to update this page: https://microchipdeveloper.com/32arm:sam-bare-metal-c-programming not one mention of volatile.
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: [SAMC] pointer code only works within a function
« Reply #35 on: January 27, 2020, 10:33:49 pm »
You better get microchip to update this page: https://microchipdeveloper.com/32arm:sam-bare-metal-c-programming not one mention of volatile.
Won't be needed. Microchip already defines the access pointers to be volatile correctly:
https://github.com/avrxml/asf/blob/master/sam0/utils/cmsis/samd21/include/samd21j18a.h

RWReg is defined as:
Code: [Select]
typedef volatile       uint32_t RwReg;   /**< Read-Write 32-bit register (volatile unsigned int) */
 

Offline donotdespisethesnake

  • Super Contributor
  • ***
  • Posts: 1093
  • Country: gb
  • Embedded stuff
Re: [SAMC] pointer code only works within a function
« Reply #36 on: January 27, 2020, 10:36:03 pm »
You better get microchip to update this page: https://microchipdeveloper.com/32arm:sam-bare-metal-c-programming not one mention of volatile.

Yeah, that page is not well written. Probably written by technical authors with not much real C experience. Makes some very dubious claims about C, and completely skips over the importance of volatile. Sure they are buried in the header definitions, but a newcomer is not going to look there or understand the significance.
Bob
"All you said is just a bunch of opinions."
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4206
  • Country: us
Re: [SAMC] pointer code only works within a function
« Reply #37 on: January 27, 2020, 10:48:46 pm »
Quote
You better get microchip to update this page: https://microchipdeveloper.com/32arm:sam-bare-metal-c-programming not one mention of volatile.

For the "instance" and "component" .h files that they talk about, the "volatile" keywords are buried in the (not shown) definitions of RwReg, __IO, and etc.

But it does seem bad that they didn't mention it the section where they talk about defining them manually.
PIC32 doesn't have a corresponding section :-(


Who is this "you" that you talk about ?  :-)
 

Offline nigelwright7557

  • Frequent Contributor
  • **
  • Posts: 693
  • Country: gb
    • Electronic controls
Re: [SAMC] pointer code only works within a function
« Reply #38 on: January 27, 2020, 10:55:08 pm »
but volatile is for a variable that can be changed by another part of a program like an interrupt.
No. The volatile qualifier was added to the language as a tool for accessing hardware registers. The formal definition is something like "any expression referring to [a volatile-qualified object] shall be evaluated strictly according to the rules of the abstract machine". In practice it is a method of telling the compiler that touching some things has side-effects which it can't deduce from the code, and thus isn't allowed to eg. perform some types of optimizations. While volatile is often used with variables shared between interrupts and user mode code, it is in fact not the right tool for that, since it doesn't protect you against race conditions. Instead, you should use atomic types, provided your compiler supports them.

Excellent reply, very comprehensive.

 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17829
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAMC] pointer code only works within a function
« Reply #39 on: January 28, 2020, 07:23:47 am »
You better get microchip to update this page: https://microchipdeveloper.com/32arm:sam-bare-metal-c-programming not one mention of volatile.
Won't be needed. Microchip already defines the access pointers to be volatile correctly:
https://github.com/avrxml/asf/blob/master/sam0/utils/cmsis/samd21/include/samd21j18a.h

RWReg is defined as:
Code: [Select]
typedef volatile       uint32_t RwReg;   /**< Read-Write 32-bit register (volatile unsigned int) */

Yes but that page was supposed to be explaining the nuts and bolts of register addressing. At some point in there it actually explains what no book I have does which is how you use a pointer to address a register and put a value in it. Tha barest of code is in that page but without the volatile.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: [SAMC] pointer code only works within a function
« Reply #40 on: January 28, 2020, 09:34:24 am »
Their example is confusing.
To define a pointer to this specific memory address we can do the following:
And then proceed to name it PORT0_DIR_ptr instead of foo, as all examples do.

There was an attempt, unfortunately the code lies.

Correct would be, for addressing a register:
Code: [Select]
volatile unsigned int * const prt_register = (unsigned int *)0x41004400;Where the const makes the pointer itself immutable.
https://cdecl.org/?q=volatile+unsigned+int+*+const+prt_register

« Last Edit: January 28, 2020, 09:37:49 am by Jeroen3 »
 

Offline nigelwright7557

  • Frequent Contributor
  • **
  • Posts: 693
  • Country: gb
    • Electronic controls
Re: [SAMC] pointer code only works within a function
« Reply #41 on: February 10, 2020, 01:15:57 am »
Yes that works, but volatile is for a variable that can be changed by another part of a program like an interrupt. what is the relevance here?

Volatile is relative to interrupt/main program data but also SFR's.
Anything that can change data without the cache knowing.

There can also be a problem with DMA and the cache where DMA-ing data doesnt update the cache on some micro's.

 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4206
  • Country: us
Re: [SAMC] pointer code only works within a function
« Reply #42 on: February 10, 2020, 06:15:32 am »
Quote
Anything that can change data without the cache knowing.
Anything that can change data without the COMPILER knowing.AFAIK, "volatile" won't help at all with cache management; that's a whole different can of worms!
 
The following users thanked this post: Siwastaja

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 3733
  • Country: us
Re: [SAMC] pointer code only works within a function
« Reply #43 on: February 10, 2020, 07:24:06 pm »
Quote
Anything that can change data without the cache knowing.
Anything that can change data without the COMPILER knowing.AFAIK, "volatile" won't help at all with cache management; that's a whole different can of worms!


That is correct.  Volatile prevents the compiler from combining, eliminating, duplicating, or reordering memory read/write CPU instructions.  That is all it does.  It doesn't guarantee atomiticity, it doesn't deal with any low level architectural details like cache and memory mapping units, and it doesn't guarantee that any other processor or peripheral in the system will see those access in any particular order.  If you are expecting any of those things (even if you don't realize it) volatile is not what you want, or at best part of what you want.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17829
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAMC] pointer code only works within a function
« Reply #44 on: February 10, 2020, 09:34:32 pm »
So what does one do? Does having a cache cause all of this trouble?
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11281
  • Country: us
    • Personal site
Re: [SAMC] pointer code only works within a function
« Reply #45 on: February 10, 2020, 09:37:09 pm »
So what does one do?
For what specifically? For memory mapped registers? Declare them volatile.

Does having a cache cause all of this trouble?
Cache causes a whole new level of issues, but volatile has nothing to do with them. Cache is dealt with cache maintenance operations.

But given the scope of the cache in the SAM C, you don't need to worry about it at all.
Alex
 
The following users thanked this post: Siwastaja

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8185
  • Country: fi
Re: [SAMC] pointer code only works within a function
« Reply #46 on: February 10, 2020, 09:51:49 pm »
Since a few microcontrollers with caches have come to market, discussions (and misconceptions) about caches blew out of proportion, they are discussed here almost every day.

Once again I repeat, most microcontrollers have no caches; and most of those few that do, boot all caches disabled by default, or at least you are very likely to know if you use one which has caches enabled.

If you are unsure, you can always check, and then just turn it off. In most microcontroller cases, cache won't make that much performance difference because you tend to have everything in on-chip SRAM anyway, and run code from the wide pre-fetched on-chip flash, or even better, RAM.
« Last Edit: February 10, 2020, 09:54:30 pm by Siwastaja »
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4206
  • Country: us
Re: [SAMC] pointer code only works within a function
« Reply #47 on: February 11, 2020, 12:29:59 am »
Quote
I repeat, most microcontrollers have no caches;


Many microcontrollers have some sort of cache in front of program memory.   ESP8266, ESP32, SAMD5x have real caches, which is how they manage to run adequately XIP Serial flash.  Fortunately, program memory isn't usually volatile.  Data cache is less common, but it's catching on.

Caching will likely be disabled on peripheral registers, in hardware.  Usually this will be on a per memory-region basis.  For example, The ARMv7m specification defines a "Device" memory type attribute, while only "normal" memory is cacheable (and even then it can have several types of cacheability.)   See Section A3.5.2 Summary of ARMv7 memory attributes
(Note that some caches may not be using the ARM cache design, though.)

The biggest problem with data caching is likely to show up when you're using peripherals with DMA.

 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17829
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [SAMC] pointer code only works within a function
« Reply #48 on: February 11, 2020, 07:32:28 am »
The only reason i can see for cache is fetching program instructions form ROM. even on the "simple" SAMD there are  wait states for running at 48MHz so does that mean that the ROM can supply instructions at 16MHz, what does the CPU do during the ROM wait states?
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11281
  • Country: us
    • Personal site
Re: [SAMC] pointer code only works within a function
« Reply #49 on: February 11, 2020, 07:34:37 am »
what does the CPU do during the ROM wait states?
Nothing. Just waits for the instructions to arrive. That's why you need caches and accelerators of all sorts.

In reality majority of Thumb-2 instructions are 16-bits, and Cortex-M0+ always fetches 32-bit word, so in most cases it fetches 2 instructions at the same time.

But generally yes, things get worse as clock frequency goes up, since flash is slow.
Alex
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf