FreeRTOS简单移植到STM32F103ZET6

一、从官网下载FreeRTOS源码,下载地址为:
Freertos源码

二、下载后进行解压缩,会得到以下文件:
这里写图片描述

进一步打开FreeRTOS会看到:
这里写图片描述

再打开Source文件夹:
这里写图片描述

以上就是FreeRTOS全部的源码。

三、移植到STM32
1、建立STM32的工程文件夹。
这里写图片描述

图中,使用keil5建立的工程。

2、FreeRTOS移植
这里写图片描述

下面对FreeRTOS文件夹下内容进行说明。
1)其中对移植起关键作用的是,list.c queue.c tasks.c 文件。该文件位于FreeRTOS/Source文件夹下。这里存放的是FreeRTOS内核相关的文件。
源代码

2)与内存分配有关的文件共有4个,分别是heap_1.c,heap_2.c,heap_3.c,heap_4.c。4个文件只需选择其中的1个,STM32选择heap_2.c。
该文件位于FreeRTOS\Source\portable\MemMang
这里写图片描述
3)与移植相关的代码包括port.c,portmacro.h。这些代码不但和编译器有关还和平台(MCU)有关。FreeRTOS先以编译器为大类,然后再以平台(MCU)为小类。在这里选择Keil编译器,平台为ARM_CM3。
该文件位于FreeRTOS\Source\portable\Keil下,会看到一个文件
这里写图片描述
所以,可以参考FreeRTOS\Source\portable\RVDS\ARM_CM3
这里写图片描述

4)除了上述内容之外,还包括FreeRTOS内核相关的头文件。
该文件FreeRTOS\Source\include
这里写图片描述

四、修改启动代码

打开startup_stm32f10x_hd.s文件,如图中所示进行修改。
这里写图片描述

这里写图片描述

注意:图中函数的位置不能变动,一定要在对应的函数下面进行修改,若改变位置,则程序无法正常运行。比如,我进行这样的修改,则程序无法正常运行。

这里写图片描述

五、编写任务函数。

主函数
任务函数

六、源代码示例

### FreeRTOS 移植STM32F103ZET6 的教程 #### 一、构建 STM32 运行环境 为了成功移植 FreeRTOSSTM32F103ZET6 微控制器,首先需要搭建一个完整的开发环境。这一步骤涉及硬件初始化以及软件工具链的设置。具体来说,开发者应完成以下操作: - 使用 Keil MDK 或其他支持 STM32 的 IDE 创建一个新的工程。 - 配置时钟树以确保系统时钟频率满足应用需求。 - 添加必要的外设驱动程序并验证其功能。 这些准备工作构成了后续工作的基础[^1]。 #### 二、下载 FreeRTOS 源码 从官方网站或其他可信渠道获取最新的 FreeRTOS 版本是非常重要的。官方发布的版本通常经过严格测试,并附带详细的文档说明。对于特定目标平台(如 STM32),可能还需要额外查找社区贡献的支持包或者补丁文件来简化移植过程[^4]。 #### 三、选择合适的内核文件 根据所使用的 MCU 型号筛选出匹配的核心组件至关重要。例如,在 `FreeRTOS/Source/portable/GCC/ARM_CM3` 路径下的端口层实现专为 ARM Cortex-M3 处理器设计,适用于 STM32F103 系列产品。因此需将此路径加入编译链接选项中以便访问底层寄存器定义及相关中断处理逻辑。 #### 四、配置项目结构 在现有工程项目基础上集成 FreeRTOS 库意味着调整目录布局和依赖关系: - 将整个 FreeRTOS 文件夹复制至工作区根目录; - 修改原有 main 函数入口点代码使其调用 RTOS 初始化接口而非传统裸机循环模式; - 定义堆管理策略通过指定不同的 heap_*.c 实现灵活控制内存分配行为。 以下是简单的启动模板示例: ```c #include "stm32f1xx_hal.h" #include "FreeRTOS.h" #include "task.h" void TaskBlink(void *pvParameters); int main(void){ HAL_Init(); xTaskCreate(TaskBlink,"BLINK",configMINIMAL_STACK_SIZE,NULL,tskIDLE_PRIORITY,&handle); vTaskStartScheduler(); while(1){}; } void TaskBlink(void *pvParameters){ TickType_t lastWakeTime=xLastTickCount; const portTickType period=500; GPIO_InitTypeDef LED={GPIO_PIN_SET,GPIO_MODE_OUTPUT_PP}; __HAL_RCC_GPIOA_CLK_ENABLE(); HAL_GPIO_Init(GPIOA,&LED); for (;;){ HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5); vTaskDelayUntil(&lastWakeTime,period); } } ``` 上述代码片段展示了如何创建基本的任务实例以及调度机制[^2]。 #### 五、自定义延迟函数 考虑到实时操作系统环境下精确计时不总是可行的情况,可以扩展标准库提供的延时方法。如下所示的例子实现了兼容普通阻塞型等待的同时保留了更高精度的需求[^3]: ```c #define fac_ms configTICK_RATE_HZ / 1000UL void delay_ms(uint32_t nms) { if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { // 如果RTOS已经开始运行 if (nms >= fac_ms) { // 并且请求的毫秒数大于等于最小时间片长度 vTaskDelay(nms / fac_ms); // 则利用vTaskDelay执行整数量级上的休眠 } uint32_t remainder = nms % fac_ms; // 计算剩余部分不足一个完整tick周期的部分 if (remainder > 0) // 若存在,则补充短时间间隔的传统忙等待 delay_us((uint32_t)(remainder * 1000)); } else { // 否则按常规手段模拟固定时间段内的停滞状态 delay_us((uint32_t)(nms * 1000)); } } ``` 以上改进能够更好地适应多线程并发场景中的资源竞争状况。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值