有人能说出这段代码的含义是什么吗?
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
};
我其实不明白。
答案 0 :(得分:8)
void (* const rvt[])(void)
手段(由cdecl.org提供):
声明rvt为const指针的函数(void)返回void
T foo = {
value1,
value2,
value3 // ...
};
这是数组的aggregate initialization [1]。此外,这意味着rvt
的声明是一个定义。
&__STACK_END
addresof运算符获取变量的内存地址。
(unsigned long)&__STACK_END)
地址已投放到unsigned long
类型。
(void (*) (void))((unsigned long)&__STACK_END)
转换后的值再次转换为指向函数(void)的指针返回void,这是存储在数组中的函数指针的类型。
数组的其余初始化值可以是函数名,函数指针,也可以是隐式转换为函数指针的函数,如lambdas。
答案 1 :(得分:3)
void (* const rvt[])(void)
这定义了一个名为" rvt"的const数组。它的元素是一个没有参数的void函数的指针。
然后使用大括号初始化列表初始化此数组。所以其他所有行都是这个数组的元素。第一个是指向__STACK_END的指针,它显然是错误的类型,因此需要被转换为正确的类型(它将首先被转换为无符号长整数然后进入正确的函数类型指针)。
Btw:代码不完整,因为大括号没有关闭,或者格式化错误,因为最后一条评论包含右括号?
答案 2 :(得分:1)
它定义了一个指向函数的指针数组,它不带参数并返回void。然后使用内存中某些寄存器的地址初始化数组,这些寄存器被转换为函数指针。
看起来像用于嵌入式编程的中断向量表。
答案 3 :(得分:0)
这似乎是ARM Cortex M微控制器的中断向量表。
与大多数其他MCU相比,ARM Cortex的一个特殊功能是它在程序启动之前设置了堆栈指针。其他MCU倾向于在运行时设置它。
因此,表中的第一个条目是在程序启动时堆栈指针应设置的值。 __STACK_END
可能是从链接器获得的常量。强制转换(void (*) (void))
将其转换为函数指针。从指向int的指针转换为函数指针有点值得怀疑,但它可能适用于大多数嵌入式C编译器,尽管C标准不满意。
其余条目是用于中断服务例程(函数)的函数地址。也就是说,它们与函数指针是一样的。您可以通过为函数指定名称来初始化函数指针。
因此,整个向量表被声明为函数指针数组,其中每个函数都具有签名void func (void)
。 *const
声明意味着函数指针本身是只读的。这意味着它们将在flash中分配,这对于向量表是合适的。向量表通常分配在flash中固定的保留地址。
编写相同代码的更漂亮的方法是:
typedef void (isr_t)(void);
isr_t* const [] = {
(isr_t* const)((uintptr_t)&__STACK_END), // The initial stack pointer
...
uintptr_t
是一个足够大的整数类型,保证能够保存地址,与unsigned long
不同。