#使用STM32CUBEMX在STMF103C8T6上创建Freertos工程,并通过MDK的Debug功能逐句顺序分析程序的执行
以下将按代码执行顺序撰写内容,只展示了主要函数,具体实现代码未展示
一、LDR R0, =Systemint
将Systemint函数的地址装载到寄存器R0中
二、BLX R0
跳转到寄存器R0存放的地址处开始执行,并在连接寄存器中保存返回地址
三、LDR R0,=__main
将全局标识符“__main”的地址加载到R0中
四、BX R0
无条件跳转到R0地址处运行,且按照地址的最低为决定是否切换指令集(为1,则表示切换到Thumb指令集;为0,则表示继续在ARM指令集下运行
五、main()
(一)HAL_Init()
1.__HAL_FLASH_PREFETCH_BUFFER_ENABLE()
使能Flash
2.HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4)
设置中断优先级分组
(1)assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup))
#define assert_param(expr) ((void)0U) //实现断言功能
(2)NVIC_SetPriorityGrouping(PriorityGroup)
#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping
①__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
配置中断优先级分组
3.HAL_InitTick(TICK_INT_PRIORITY)
初始化系统时基
(1)HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U)
设置 SysTick 中断的优先级
(2)uwTickPrio = TickPriority;
将 TickPriority 值赋给全局变量 uwTickPrio,以备后续使用
4.HAL_MspInit()
(1)__HAL_RCC_AFIO_CLK_ENABLE()
使能复用IO的时钟
(2)__HAL_RCC_PWR_CLK_ENABLE()
使能电源(PWR)外设的时钟
(3)HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0)
设置 PendSV 异常的优先级
(4)__HAL_AFIO_REMAP_SWJ_NOJTAG()
禁用JTAG调试与监控接口
(二)SystemClock_Config()
配置系统时钟(System Clock)
(三)MX_GPIO_Init()
对启用的GPIO口进行初始化
(四)osKernelInitialize()
系统OS的核心初始化,分配堆内存区域,将内核状态更新为就绪
(五)MX_FREERTOS_Init()
STM32CUBEMX对Freertos的初始化,创建了一个默认任务,这个任务优先级最低,在其他任务都空闲的时候运行,默认任务通常在任务调度器开启前创建,当没有任何普通任务时,会直接运行默认任务
默认任务的创建是可选的,可以不创建这个默认任务,当整个rtos默认任务和普通任务都没创建时,系统会处于空闲状态,不执行任何任务,此时单片机会开启低功耗模式,如果有定时器中断或者外部中断之类的代码触发,则单片机会解除低功耗模式,进入回调函数中处理代码。
(六)osKernelStart()
启动系统核心,调度器将被开启,系统步入运行状态,将不会进入main中的while(1)
1.vTaskStartScheduler()
启动任务调度器,当运行到prvStartFirstTask()
的时候,程序会直接调用汇编来处理任务调度,汇编代码的运行速度极快,Debug无法一步一步的跟踪代码了,我没有创建任何普通任务,因此rtos中只有CUBEMX自动创建的默认任务,此时代码在默认任务中不断循环。默认任务是void StartDefaultTask(void *argument),在freertos.c中找到。