void指针和woid

C语言void与void*解析

void是指空,没有参数或者返回为空。

而void*则是void指针。可以是任意类型的指针,任何类型都可以赋值给他,但是他不能赋值给别的类型。也就是int*可以赋值给void*,但是void*不能赋值给int*。这儿void常用在一些需要类型转换指针的地方。


类似于无价到底是免费还是无穷大。

### Bootloader 与应用程序栈指针配置及内存布局 在嵌入式系统中,Bootloader 应用程序的栈指针配置以及内存布局是确保系统正确启动运行的关键部分。栈指针的设置决定了程序在执行过程中使用的堆栈区域,而内存布局则定义了代码、数据、堆栈等段的存放位置。 #### 栈指针配置 在系统启动时,Bootloader 应用程序都需要正确设置栈指针(SP),以确保函数调用、中断处理等机制正常工作。通常,栈指针的初始化是在启动文件(如`startup.s`)中完成的。Bootloader 应用程序的入口地址处都应包含一个向量表,其中第一个条目是初始栈指针值。 例如,Bootloader 的向量表可能如下所示: ```assembly __StackTop = 0x20010000; // 假设栈顶地址为SRAM的高端地址 .section .isr_vector,"a",%progbits .word __StackTop .word Reset_Handler ``` 应用程序的向量表也应以类似方式配置,但栈顶地址应指向应用程序可用的内存区域: ```assembly __AppStackTop = 0x20020000; .section .isr_vector_app,"a",%progbits .word __AppStackTop .word App_Reset_Handler ``` Bootloader 在跳转到应用程序之前,需要将栈指针设置为应用程序定义的栈顶地址。这一操作通常在跳转前通过汇编指令完成: ```c __set_MSP(*(__IO uint32_t*) 0x8002000); ``` 该操作从应用程序的向量表首地址读取栈顶值,并将其设置为主堆栈指针(MSP),从而确保应用程序的堆栈使用正确。 #### 内存布局 内存布局的配置决定了程序各部分在FlashRAM中的分布。Bootloader 通常位于Flash的起始地址(如`0x8000000`),而应用程序则位于Bootloader之后的地址(如`0x8002000`)。应用程序的Flash大小应根据Bootloader的大小进行调整,例如在本例中,IROM1的大小为`0x7E000`,以确保应用程序不会覆盖Bootloader。 典型的Flash布局如下: ``` |--------------------------| | Bootloader (10KB) | | (0x8000000 ~ 0x8002800) | |--------------------------| | Application (0x7E000) | | (0x8002000 ~ ...) | |--------------------------| ``` RAM的布局则通常分为多个区域,用于存放栈、堆、全局变量等。Bootloader 应用程序可以共享同一块RAM区域,但需确保在跳转时栈指针被正确设置。 #### 栈指针与内存布局的协调 在Bootloader跳转到应用程序时,栈指针的切换是关键步骤。Bootloader可能使用自己的栈空间,而应用程序需要使用独立的栈空间。为避免冲突,应在跳转前将栈指针重新定位到应用程序的栈顶地址,如前所述。 此外,应用程序的链接脚本或内存映射文件应确保栈空间不会与代码或数据段重叠。例如,在GCC的`.ld`脚本中,可以定义RAM的起始地址大小,并将`.stack`段放置在RAM的高端地址: ```ld MEMORY { FLASH (rx) : ORIGIN = 0x8002000, LENGTH = 0x7E000 RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x20000 } SECTIONS { .text : { *(.isr_vector) *(.text) *(.rodata) } > FLASH .data : { *(.data) } > RAM .bss : { *(.bss) } > RAM .stack : { . = ALIGN(8); . = . + 0x1000; /* 4KB 栈空间 */ . = ALIGN(8); } > RAM } ``` 上述配置确保了应用程序的栈空间不会与`.data`或`.bss`段发生冲突。 #### 栈指针配置与启动流程 在系统启动过程中,Bootloader的栈指针通常由启动文件初始化,而应用程序的栈指针则在跳转前由Bootloader设置。这一流程确保了应用程序能够立即使用正确的堆栈进行执行。 Bootloader跳转到应用程序的典型流程如下: ```c typedef void (*pFunction)(void); pFunction Jump_To_Application; uint32_t JumpAddress; // 读取应用程序的栈顶地址 __set_MSP(*(__IO uint32_t*) 0x8002000); // 获取应用程序的复位向量地址 JumpAddress = *(__IO uint32_t*) (0x8002000 + 4); Jump_To_Application = (pFunction) JumpAddress; // 跳转到应用程序 Jump_To_Application(); ``` 这段代码首先设置主堆栈指针(MSP)为应用程序的栈顶地址,然后获取应用程序的复位入口地址并跳转执行。 #### 总结 Bootloader 应用程序的栈指针配置及内存布局是嵌入式系统设计中的关键环节。栈指针的正确设置确保了函数调用中断处理的正常运行,而合理的内存布局则避免了代码、数据堆栈之间的冲突。在跳转过程中,Bootloader需将栈指针重新定位到应用程序的栈顶地址,以确保应用程序能够独立使用其内存空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值