什么是(void(*)(void))((uint32_t)& __ stack_end)?

发布于 2025-02-11 06:10:26 字数 565 浏览 1 评论 0原文

这是一些带有中断向量的启动文件摘录。

#pragma DATA_SECTION(interruptVectors, ".intvects")
void (* const interruptVectors[])(void) =
{
  (void (*) (void))((uint32_t)&__STACK_END),
  resetISR,
  nmi_ISR,
  fault_ISR,
  ... /* More interrupt vectors */

void(* const Interruptvectors [])(void) - 是必须包含函数名称的功能指针的数组,但是我不理解(void(*)(void)) ((UINT32_T)& __ stack_end)语法。

(void(*)(void))看起来像是一个指向函数的指针,该函数无需返回,没有参数,没有任何名称。是否可以?

(UINT32_T)& __ stack_end是指指针。为什么函数指针和指针在一起?

This is some startup file excerpt with interrupt vectors.

#pragma DATA_SECTION(interruptVectors, ".intvects")
void (* const interruptVectors[])(void) =
{
  (void (*) (void))((uint32_t)&__STACK_END),
  resetISR,
  nmi_ISR,
  fault_ISR,
  ... /* More interrupt vectors */

void (* const interruptVectors[])(void) - is an array of function pointers that must contain function names, but I can't understand the (void (*) (void))((uint32_t)&__STACK_END) syntax.

(void (*) (void)) looks like a pointer to a function that returns nothing, without arguments and doesn't have any name. Is it possible?

(uint32_t)&__STACK_END is a pointer. And why are the function pointer and pointer together?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冬天旳寂寞 2025-02-18 06:10:26

这看起来像是用于手臂处理器或类似的中断矢量表。中断矢量表包含中断处理程序的地址,因此本质上是功能指针的数组。

该表的第一个条目是堆栈指针的初始化值。这显然不是功能指针,而是数据指针,因此需要某种类型的转换。不是因为处理器关心类型,而是因为C确实如此。

因此,& __ stack_end是可以指向堆栈末端的数据地址的一些指针类型。然后将其转换为平原的32位编号,最后转换为函数指针。

如果编译器将其作为扩展名支持,则可以跳过第一个铸件到UINT32_T,并直接从数据指针铸造为函数指针。但是严格来说,在C标准转换中,直接从数据指针转换为函数指针是不合法的,并且必须将其施加到Interger。

还有其他插入定义的问题,程序员必须考虑使用此类转换以进行工作:类型和对齐方式的大小必须兼容,不得有陷阱表示等。当使用接近硬件的代码时,这都是正常的。

This looks like the interrupt vector table for an ARM processor or similar. The interrupt vector table contains the addresses of interrupt handlers, so it is essentially an array of function pointers.

The first entry of this table is the initialization value for the stack pointer. It's obviously not a function pointer, but a data pointer, so some type conversion is needed. Not because the processor cares about types, but because C does.

So &__STACK_END is presumable some pointer type which points to a data address at the end of the stack. This is then converted to a plain 32-bit number, and finally converted to a function pointer.

It might have been possible to skip the first cast to uint32_t and cast directly from a data pointer to a function pointer, if the compiler supported it as an extension. But strictly speaking, in the C standard conversion from a data pointer directly to a function pointer is not legal, and cast to interger is necessary.

There are also additional implemetation defined issues programmer must consider for this kind conversion to work: sizes of types and alignments must be compatible, there must not be trap representations, etc. This is all normal when working with code that is close to hardware.

滥情空心 2025-02-18 06:10:26

a

我个人认为,有更好的方法可以更清楚地定义此问题。

The first value of the vector table of a Cortex-M is the initial value of the stack pointer, and that looks like your case. This syntax is a hack to define the whole vector table as a constant array of function pointer of type void(*function)(void) while defining the first value as the stack pointer value as a constant.

Personally I think there are better ways to define this more clearly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文