[英]What's the meaning of this part of code?
有人可以说这段代码是什么意思吗?
void (* const rvt[])(void) = {
(void (*) (void))((unsigned long)&__STACK_END), // The initial stack pointer
xkg_som, // The reset handler
xnt_ISR, // The NMI handler
FaultISR, // The hard fault handler
IntDefaultHandler, // The MPU fault handler
bgs_stm, // The bus fault handler
IntDefaultHandler, // The usage fault handler
0, // Reserved
0, // Reserved
IntDefaultHandler, // The MPU fault handler
};
我真的不明白。
void (* const rvt[])(void)
均值(由cdecl.org提供 ):
将rvt声明为指向函数(void)的const指针数组,返回void
T foo = {
value1,
value2,
value3 // ...
};
这是数组的聚合初始化 [1]。 此外,这意味着rvt
的声明是一个定义。
&__STACK_END
addresof运算符获取变量的内存地址。
(unsigned long)&__STACK_END)
地址被强制转换为unsigned long
型。
(void (*) (void))((unsigned long)&__STACK_END)
转换后的值再次转换为指向函数(void)的指针,并返回void,这是存储在数组中的函数指针的类型。
数组的其余初始化值可以是函数名称,函数指针,也可以是可以隐式转换为lambda的函数指针。
void (* const rvt[])(void)
这定义了一个名为“ rvt”的常量数组。 它的元素是没有参数的void函数的指针。
然后用括号初始化列表初始化该数组。 因此,所有其他行都是此数组的元素。 第一个是指向__STACK_END的指针,该指针显然是错误的类型,因此需要转换为正确的类型(首先将其转换为无符号长型,然后转换为正确的函数类型指针)。
顺便说一句:代码不完整,因为大括号没有关闭,或者您的格式出错了,因为最后一个注释包含了大括号?
它定义了一个指向函数的指针数组,该函数不带任何参数并返回void。 然后,使用内存中某些寄存器的地址初始化该数组,并将其转换为函数指针。
它看起来像是用于嵌入式编程的中断向量表。
这似乎是ARM Cortex M微控制器的中断向量表。
与大多数其他MCU相比,ARM Cortex的一项特殊功能是在程序启动之前设置了堆栈指针。 其他MCU倾向于在运行时进行设置。
因此,表中的第一项就是在程序启动时应将堆栈指针设置为的值。 __STACK_END
可能是从链接程序获得的一些常数。 强制转换(void (*) (void))
将其转换为函数指针。 从指针到int的转换到函数指针有点可疑,但是尽管C标准对此并不满意,但它可能适用于大多数嵌入式C编译器。
其余条目是中断服务程序(功能)的功能地址。 也就是说,它们与函数指针相同。 您可以通过为其指定函数名称来初始化函数指针。
因此,整个向量表都声明为一个函数指针数组,其中每个函数都有签名void func (void)
。 *const
声明表示函数指针本身是只读的。 这意味着它们将在闪存中分配,这对于向量表是适当的。 向量表通常分配在Flash的固定保留地址中。
编写相同代码的更漂亮方法是:
typedef void (isr_t)(void);
isr_t* const [] = {
(isr_t* const)((uintptr_t)&__STACK_END), // The initial stack pointer
...
uintptr_t
是足够大的整数类型,与unsigned long
不同,它保证能够保存地址。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.