2018-01-23 02:47 PM
&sharpdefine TIM1_PSCRH (*(volatile uint8_t *)0x5260)
I understand that now when I set TIM1_PSCRH = <some 8 bit value>
that the Timer 1 Prescaler High Byte register will be set because it is located at address 0x5260.What I don't understand is what appears to maybe be a volatile pointer to a pointer of an unsigned 8 bit integer that is defined to the compiler as a constant value requiring at least 16 bits to represent. What am I not understanding.. because the above statement probably makes no sense, and if it does make sense then I'd say I'm even more confused.
Thanks!#address #stm8 #compiler-def2018-01-23 04:01 PM
Throwing an absolute address as an 8-bit pointer.
Used to read or write 8 bits to a register. Volatile as peripheral register can change outside program flow and read/write can be different registers.
2018-01-23 10:52 PM
It's not pointer to a pointer. Think of that: suppose we have a pointer:
uint8_t *cptr;
This can be a global variable, or may be just a parameter in a function.
How do you read the value pointed by it?
c = *cptr;
How do you write a value to the location pointed by it?
*cptr = c;
So here is the first '*'
Followed by the real 'pointer' cast (volatile uint8_t *)
The cast is needed because the literal 0x5260 is just treated as an int by the compiler, not as a pointer to SOMETHING (SOMETHING being very important, in our case 'uint8_t'). Think of that: if 5260 is a pointer to an uint8_t (a byte), you will read/write a byte. If it is a pointer to int, you will read/write two bytes ! And so on. That's why a simple int cannot be treated as a pointer by default. A pointer to what?
About the 'volatile': this is just to tell the compiler to generate code that reads (or writes) to the address EVERY TIME you say so. Because today compilers are very smart and usually optimize the memory read/writes in very unexpected ways.
2018-01-25 01:36 AM
As others have already stated what this line does, I'll focus on why one would want that line.
It is a portable_way to expose the TIM1_PSCRH I/O register. Technically, casting the integer to a pointer invokes implementation-defined behaviour, but all 4 C compilers targeting the STM8 implement it the same.
On the other hand, every STM8 compiler also has their own way of exposing memory-mapped I/O registers at specific locations (__at for SDCC, @ for IAR, @ for Cosmic, at for Raisonance). Using that compiler-specific way sometimes results in better code being generated, but it makes it much harder to write portable code.
Philipp