繁体   English   中英

这部分代码是什么意思?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM