FreeRTOS项目程序框架介绍(二)

FreeRTOS项目程序框架介绍(二) 接上篇FreeRTOS项目程序框架介绍一2 项目环境工程生成后先把项目工程结构搭建好然后设置项目环境。2.1 项目工程管理我们尽量要把用户代码与系统代码分离一是为了方便移植二是为了防止频繁地用CubeMX生成代码会修改到已经编辑好的代码。为了规范我们把所有了初始化函数用MSH库注册的放到一个init.c文件中应用程序代码所有的任务入口函数放到work.c文件中其它专用的模块可以另行创建源文件和头文件所有引用外部的库文件再放到一个文件夹中管理。如下项目结构Allpication/MDK_ARM文件夹我们自己编写的代码文件都放到这个文件夹中固定添加init.c和work.c、work.h三个文件init.c存放所有用MSH注册的初始化函数及初始化过程出错时的报警提示函数work.c所有的任务入口函数及项目相关的功能代码SeanLib存放外部库文件最好在项目文件夹中创建一个单独的文件夹将需要用到的外部库复制进来再在工程中添加一个文件夹引入所有需要使用的库.lib文件这样避免库文件更新时之前的项目无法顺利编译。2.2 环境设置记得勾选Use Micro LIB程序起始地址默认为0x8000000当使用bootloader时应设置成bootloader规定的程序起始地址。最大程序空间比如单片机的flash为2M就设置为0x200000当使用bootloader时应减去应用程序的起始地址应不大于0x180000。如果要在编译之后自动生成bin文件请点开user界面在After Build/Rebuild之后添加转换命令fromelf--bin--output./L/L.bin./L/L.axf这条命令已设计为通用的将编译生成的中间文件.axf转为.bin文件。”L“表示项目名称”.表示当前工程路径因此任何项目都可以直接使用这条命令。设置优化等级等如下最关键的是添加引用的文件夹否则编译时会找不到头文件设置编程选项擦除选项选择按扇区擦除可以节省擦除时间而且有bootloader的程序时一定不要擦除全片。勾选Reset and Run使程序下载完成后自动重启并开始运行否则下载完后单片机保持复位状态需要手动按复位按钮才能启动。下面的起始地址默认为0x08000000有bootloader时才需要修改。关于这部分的设置请参考BootloaderAPP调试技巧2.3 测试工程这些都设置完后先不急着编写程序目前我们还没有编写任何代码可以先编译一次看是否有错误理论上应该能顺利编译通过。避坑SysTick_HandlerFreeRTOS使用SysTick定时器产生时基但生成的代码可能有异常导致定时器中断发生后找不到中断入口而死机判断方法如下打开.s文件找到如下代码在SysTick_Handler语句上点击右键-Go to definition of “SysTick_Handler”正常的能跳转到中断入口函数应该在port.c文件中可以看到中断服务程序函数名为xPortSysTickHandler与SysTick_Handler并不相同这是因为FreeRTOS进行了宏定义只要能跳转过来就是正常的。如果无法跳转则需要我们自己添加这个宏定义打开FreeRTOSConfig.h文件找到下面位置添加画线的宏定义#definexPortSysTickHandlerSysTick_Handler这样做其实是把port.c中的xPortSysTickHandler函数名重命名为SysTick_Handler使SysTick中断发生时能跳转到这个中断服务函数。补充上一篇没有讲堆、栈的设置在FreeRTOS的设置中也没有讲TOTAL_HEAP_SIZE的设置这里进行补充。CubeMX中堆Heap和栈Stack的设置位置如下堆C库堆由malloc/free管理来源于启动文件中定义的Heap_Size。在FreeRTOS工程中所有RTOS对象任务、队列、信号量等都使用FreeRTOS自己的内存管理pvPortMalloc不调用C库的malloc。因此C库堆可以设置得很小如0x200字节仅用于避免某些库函数调用时报错。栈系统栈/MSP由启动文件中的Stack_Size定义用于存放中断服务函数和调度器启动前的代码HAL库的初始化代码中的局部变量。当FreeRTOS启动后任务的执行不再使用此栈因此栈也可以设置地很小一般0x200即够用。任务栈每个任务拥有独立的栈空间由xTaskCreate时从configTOTAL_HEAP_SIZE定义的FreeRTOS堆数组中分配。任务的局部变量、函数嵌套调用都使用此栈。任务切换时CPU的栈指针PSP会切换到当前任务的栈顶。configTOTAL_HEAP_SIZE定义了一个静态全局数组ucHeap[configTOTAL_HEAP_SIZE]位于静态存储区.bss段。FreeRTOS通过pvPortMalloc从这个数组中分配内存用于创建任务栈、任务TCB、队列、信号量等所有RTOS动态对象。关于任务栈的设置大家可能不知道需要设置多大以下是设置建议第一步初步估算任务栈大小 任务上下文(约128字) 局部变量总大小/4 函数调用深度×8 安全余量(20%)第二步先用较大值xTaskCreate(vMyTask, “MyTask”, 1024, NULL, 2, NULL); // 4KB栈第三步任务运行一段时间后覆盖所有执行路径查询栈的最小剩余值第四步根据结果调整栈大小最终栈大小 (任务实际使用栈大小 安全裕量)安全裕量建议为实际使用量的 20%-30%接下篇FreeRTOS项目程序框架介绍三