ST意法半导体
直播中

宋燕

7年用户 174经验值
私信 关注
[问答]

请问有人可以为我分解这行代码吗?

& sharpdefine tiM1_PSCRH(*(volatile uint8_t *)0x5260)
我明白,现在当我设置TIM1_PSCRH =<某个8位值>

定时器1预分频器高字节寄存器将被置位,因为它位于地址0x5260。我不明白的是,似乎可能是指向编译器定义的无符号8位整数指针的易失性指针一个恒定值,需要至少16位来表示。我不理解的是什么...因为上述说法可能没有意义,如果它确实有意义,那么我会说我更加困惑。

谢谢!
#address#stm8#compiler-def

以上来自于谷歌翻译


以下为原文




&sharpdefine TIM1_PSCRH (*(volatile uint8_t *)0x5260)
I understand that now when I set TIM1_PSCRH =

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-def

回帖(3)

符伯峪

2019-6-24 11:04:28
将绝对地址作为8位指针抛出。
用于向寄存器读取或写入8位。易失性外设寄存器可以在程序流程外改变,读/写可以是不同的寄存器。

以上来自于谷歌翻译


以下为原文




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.
举报

张莉

2019-6-24 11:23:55
它不是指向指针的指针。想一想:假设我们有一个指针:
uint8_t * cptr;
这可以是全局变量,也可以只是函数中的参数。
你怎么看它指出的价值?
c = * cptr;
如何将值写入其指向的位置?
* cptr = c;
所以这是第一个'*'
接下来是真正的“指针”演员(volatile uint8_t *)
需要强制转换,因为文字0x5260只是被编译器视为一个int,而不是指向SOMETHING的指针(SOMETHING非常重要,在我们的例子中是'uint8_t')。想一想:如果5260是指向uint8_t(一个字节)的指针,您将读/写一个字节。如果它是一个指向int的指针,你将读/写两个字节!等等。这就是为什么默认情况下不能将简单的int视为指针。指针是什么?
关于'volatile':这只是告诉编译器生成代码,每隔一段时间就读取(或写入)地址。因为今天的编译器非常智能,通常以非常意想不到的方式优化内存读/写。

以上来自于谷歌翻译


以下为原文




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.
举报

李淳鑫

2019-6-24 11:41:21
正如其他人已经说明了这条线的作用,我将重点讨论为什么人们会想要这条线。
它是一个显示TIM1_PSCRH I / O寄存器的portable_way。从技术上讲,将整数转换为指针会调用实现定义的行为,但是所有针对STM8的4 C编译器都会实现相同的行为。
另一方面,每个STM8编译器也有自己的方式在特定位置暴露存储器映射的I / O寄存器(__at用于SDCC,@用于IAR,@用于Cosmic,用于Raisonance)。使用特定于编译器的方式有时会导致生成更好的代码,但这使得编写可移植代码变得更加困难。
菲利普

以上来自于谷歌翻译


以下为原文




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
举报

更多回帖

发帖
×
20
完善资料,
赚取积分