历史上的今天
今天是:2025年01月12日(星期日)
2020年01月12日 | 浅谈STM32堆栈与uCOS堆栈,其实是两码事
2020-01-12 来源:eefocus
本博文分为3部分,分别为启动代码篇,C堆栈篇,和STM32堆栈和uCOS堆栈区别篇.
***********************************************①启动代码篇***********************************************
前年毕业时,去了意法半导体工作,所以结识了STM32,先后学习了STM32和uCOS,在后边的学习中突然有了一个疑惑,就是堆栈的问题,在STM32的启动文件里定义的堆栈其实是很小的,但是,我写的uCOS程序其实占用了很大的堆栈空间,超过了启动代码中定义的堆栈大小,我们首先来看一下STM32的启动代码,这里以startup_stm32f10x_hd.s为例进行说明:
参考:https://www.cnblogs.com/afeibfp/archive/2013/01/08/2850408.html
;先在RAM中分配系统使用的栈,RAM的起始地址为0x2000_0000
;然后在RAM中分配变量使用的堆
;然后在CODE区(flash)分配中断向量表,flash的起始地址为0x0800_0000,该中断向量表就从这个起始地址开始分配
;分配完成后,再定义和实现相应的中断函数,
;所有的中断函数全部带有[weak]特性,即弱定义,如果编译器发现在别处文件中定义了同名函数,在链接时用别处的地址进行链接。
;中断函数仅仅实现了Reset_Handler,其他要么是死循环,要么仅仅定义了函数名称
;STM32被设置为从内部FLASH启动时(这也是最常见的一种情况),当STM32遇到复位信号后,
;从0x0800_0000处取出栈顶地址存放于MSP寄存器,从0x0800_0004处取出复位中断服务入口地址放入PC寄存器,
;继而执行复位中断服务程序Reset_Handler,
;Reset_Handler仅仅执行了两个函数调用,一个是SystemInit,另一个__main,
;SystemInit定义在system_stm32f10x.c中,主要初始化了STM的时钟系统:HSI,HSE,LSI,LSE,PLL,SYSCLK,USBCLK,APECLK等等.
;__main函数由编译器生成,负责初始化栈、堆等,并在最后跳转到用户自定义的main()函数,来到C的世界。
Stack_Size EQU 0x00000400 ;//定义堆栈大小
AREA STACK, NOINIT, READWRITE, ALIGN=3 ;//定义一个数据段 按8字节对齐 ;AREA 伪指令用于定义一个代码段或数据段 NOINIT:指定此数据段仅仅保留了内存单元,而没有将各初始值写入内存单元,或者将各个内存单元值初始化为0
Stack_Mem SPACE Stack_Size ;//保留Stack_Size大小的堆栈空间 分 配连续 Stack_Size 字节的存储单元并初始化为 0
__initial_sp ;//标号,代表堆栈顶部地址,后面有用
; // ; // ; //
Heap_Size EQU 0x00000200 ;//定义堆空间大小
AREA HEAP, NOINIT, READWRITE, ALIGN=3 ;//定义一个数据段,8字节对齐
__heap_base ;//标号,代表堆末底部地址,后面有用
Heap_Mem SPACE Heap_Size ;//保留Heap_Size的堆空间
__heap_limit ;//标号,代表堆界限地址,后面有用
;//PRESERVE8 指令指定当前文件保持堆栈八字节对齐。 它设置 PRES8 编译属性以通知链接器。
;//链接器检查要求堆栈八字节对齐的任何代码是否仅由保持堆栈八字节对齐的代码直接或间接地调用。
PRESERVE8 ;//指示编译器8字节对齐
THUMB ;//指示编译器以后的指令为THUMB指令
;中断向量表定义
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY ;//定义只读数据段,其实放在CODE区,位于0地址
EXPORT __Vectors ;//EXPORT:在程序中声明一个全局的标号__Vectors,该标号可在其他的文件中引用
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; //Top of Stack ;给__initial_sp分配4字节32位的地址0x0
DCD Reset_Handler ; //Reset Handler ; 给标号Reset Handler分配地址为0x00000004
DCD NMI_Handler ; //NMI Handler ; 给标号NMI Handler分配地址0x00000008
DCD HardFault_Handler ; //Hard Fault Handler
DCD MemManage_Handler ; //MPU Fault Handler
DCD BusFault_Handler ; //Bus Fault Handler
DCD UsageFault_Handler ; //Usage Fault Handler
DCD 0 ; //Reserved ; 这种形式就是保留地址,不给任何标号分配
DCD 0 ; //Reserved
DCD 0 ; //Reserved
DCD 0 ; //Reserved
DCD SVC_Handler ; //SVCall Handler
DCD DebugMon_Handler ; //Debug Monitor Handler
DCD 0 ; //Reserved
DCD PendSV_Handler ; //PendSV Handler
DCD SysTick_Handler ; //SysTick Handler
; External Interrupts
DCD WWDG_IRQHandler ; //Window Watchdog
DCD PVD_IRQHandler ; //PVD through EXTI Line detect
DCD TAMPER_IRQHandler ; //Tamper
DCD RTC_IRQHandler ; //RTC
DCD FLASH_IRQHandler ; //Flash
DCD RCC_IRQHandler ; //RCC
DCD EXTI0_IRQHandler ; //EXTI Line 0
DCD EXTI1_IRQHandler ; //EXTI Line 1
DCD EXTI2_IRQHandler ; //EXTI Line 2
DCD EXTI3_IRQHandler ; //EXTI Line 3
DCD EXTI4_IRQHandler ; //EXTI Line 4
DCD DMA1_Channel1_IRQHandler ; //DMA1 Channel 1
DCD DMA1_Channel2_IRQHandler ; //DMA1 Channel 2
DCD DMA1_Channel3_IRQHandler ; //DMA1 Channel 3
DCD DMA1_Channel4_IRQHandler ; //DMA1 Channel 4
DCD DMA1_Channel5_IRQHandler ; //DMA1 Channel 5
DCD DMA1_Channel6_IRQHandler ; //DMA1 Channel 6
DCD DMA1_Channel7_IRQHandler ; //DMA1 Channel 7
DCD ADC1_2_IRQHandler ; //ADC1 & ADC2
DCD USB_HP_CAN1_TX_IRQHandler ; //USB High Priority or CAN1 TX
DCD USB_LP_CAN1_RX0_IRQHandler ; //USB Low Priority or CAN1 RX0
DCD CAN1_RX1_IRQHandler ; //CAN1 RX1
DCD CAN1_SCE_IRQHandler ; //CAN1 SCE
DCD EXTI9_5_IRQHandler ; //EXTI Line 9..5
DCD TIM1_BRK_IRQHandler ; //TIM1 Break
DCD TIM1_UP_IRQHandler ; //TIM1 Update
DCD TIM1_TRG_COM_IRQHandler ; //TIM1 Trigger and Commutation
DCD TIM1_CC_IRQHandler ; //TIM1 Capture Compare
DCD TIM2_IRQHandler ; //TIM2
史海拾趣
|
This series of articles continues with an in-depth discussion of the classic Wilkinson divider, presenting typical methods of implementation, plus alternative methods that address specific problems … 查看全部问答> |
|
最近使用benq的m23,发现可以使用at$simtest来检测SIM卡是否已接入,返回1代表检测到,返回0代表没有检测到sim卡。现在我要使用TR800,可是没看到那个at$simtest指令,不知道它怎么检测sim卡插入了呢?还有其他模块怎么检测sim卡啊? 另外共享一下 ...… 查看全部问答> |
|
[hanker M4开发板试用]我的助手,我的虚拟串口 ——stellaris USB CDC应用 最后的试用期限就要到了。这两天也抓紧调试了USB库函数。在eeworld论坛上,小川 版主的帖子陪我走过这一周。现在将本周调试的虚拟串口程序与网友们分享。 摘要 本文首先简要介绍了Stellaris USB库的基本使用,在USB库函数下编写了虚拟串口程 ...… 查看全部问答> |
|
电源架构当然是要选择Power Architecture设计电源方案首先选择输入电源,和输出负载所需的电压和电流,可以添加多个电源和对应每个电源有多个负载 我这里就只用一个电源,一个负载来展示。 配置完参数后,提交所有的参数需求,让Webench后台选择 ...… 查看全部问答> |




