完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1、源码准备
首先准备好我们下载好的FreeRTOS源码以及STM32F407的工程模板(这里以原子的F4跑马灯工程为例,可去原子的开源论坛自行下载),源码下载及参考请参考我的上一篇博客。 2、创建FreeRTOS文件夹 在工程中创建FreeRTOS文件夹,将FreeRTOS源码全部复制到该文件夹下 打开portable文件夹,删除没用的文件,留下如下文件即可 3、在工程中添加FreeRTOS源码 打开工程,在工程中新建FreeRTOS_CORE和FreeRTOS_PORTABLE,然后向着两个组中添加对应的文件,如下图所示: FreeRTOS_CORE的文件打开FreeRTOS就可看到,port.c是RVDS文件夹下的ARM_CM4F中的,因为STM32F407是Cortex-M4内核并且带FPU。Heap_4.c是MemMang文件夹中,这里有5个文件,是5个不同的内存管理方法,为什么选择第4个,因为FreeRTOS内存管理所决定。 4、添加对应的头文件路径 5、编译及错误解决 5.1 找不到FreeRTOSConfig.h文件 完成后编译一下,会出现如下错误 很明显是没有FreeRTOSConfig.h这个文件,那我们就把它添加进去,具体位置在FreeRTOS的DEMO中找到CORTEX_M4F_STM32F407ZG-SK文件,如下图所示 至于放到哪个位置自己随意,一般是放在FreeRTOS的include里面,而这个文件是FreeRTOS的配置文件,一般操作系统都有裁剪、配置功能,而这些都是通过一个文件内的宏定义来完成。 5.2 SystemCoreClock未定义 接着上面的步骤再编译一次,还会出现以下错误,意思是SystemCoreClock未定义 解决办法:修改条件编译 5.3 重复定义 接着再编译一下,发现还有错误,这次的错误是重复定义 解决办法: 屏蔽掉stm32f4xx_it.c中的PendSV_Handler(),SVC_Handler(),SysTick_Handler()这三个函数, 5.4 钩子函数未定义 继续编译一次,还是会有错,这次的错是函数未定义,他们都是Hook结尾的,称为钩子函数。 解决办法: 去FreeRTOSConfig.h中关闭这些钩子函数,他们都是宏定义决定,这里将configUSE_IDLE_HOOK、configUSE_TICK_HOOK、configUSE_MALLOC_FAILED_HOOK和configUSE_FOR_STACK_OVERFLOW定义为0. 再编译一下应该就没错了。 6、修改SYSTEM文件 因为原子的SYSTEM文件夹是针对UCOS编写的,所以要进行对应的修改 6.1 修改sys.h文件 把宏定义改为1即可,要支持OS,UCOS也一样的 6.2 修改usart.c文件 修改头文件为 修改串口中断服务函数为: 6.3 修改delay.c文件 同样先修改宏定义的头文件 接着修改systick中断服务函数为 在滴答定时器中断服务函数中调用FreeRTOS的API函数xPortSysTickHandler(); 在修改delay_init()函数,如下: 接下来就是延时函数的修改 修改完后再编译一下,会出现重复定义的错误,如下图: 解决办法:屏蔽FreeRTOSConfig.h掉底部的#define xPortSysTickHandler SysTick_Handler 7、修改main.c进行功能验证 主函数主要是实现实时系统多任务的创建,具体如下 #include “sys.h” #include “delay.h” #include “usart.h” #include “led.h” #include “FreeRTOS.h” #include “task.h” #define START_TASK_PRIO 1 #define START_STK_SIZE 120 void start_task(void * pvParameters); //任务函数 TaskHandle_t StartTask_Handler; //任务句柄 #define TASK1_TASK_PRIO 2 #define TASK1_STK_SIZE 120 void task1_task(void * pvParameters); TaskHandle_t Task1Task_Handler; //任务句柄 #define TASK2_TASK_PRIO 3 #define TASK2_STK_SIZE 120 void task2_task(void * pvParameters); TaskHandle_t Task2Task_Handler; //任务句柄 int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); delay_init(168); //初始化延时函数 LED_Init(); //初始化LED uart_init(115200); //初始化串口 xTaskCreate((TaskFunction_t ) start_task, (char* ) “start_task”, (uint16_t ) START_STK_SIZE, (void * ) NULL, (UBaseType_t ) START_TASK_PRIO, (TaskHandle_t* ) &StartTask_Handler); vTaskStartScheduler(); //开启任务调度 } void start_task(void * pvParameters) { //创建Task1 xTaskCreate((TaskFunction_t ) task1_task, (char* ) “task1_task”, (uint16_t ) TASK1_STK_SIZE, (void * ) NULL, (UBaseType_t ) TASK1_TASK_PRIO, (TaskHandle_t* ) &Task1Task_Handler); //创建Task2 xTaskCreate((TaskFunction_t ) task2_task, (char* ) “task2_task”, (uint16_t ) TASK1_STK_SIZE, (void * ) NULL, (UBaseType_t ) TASK2_TASK_PRIO, (TaskHandle_t* ) &Task2Task_Handler); vTaskDelete(StartTask_Handler); //NULL } void task1_task(void * pvParameters) { char task1_num=0; while(1) { task1_num++; LED0 = ~LED0; printf(“Task1 Runing %d !rn”,task1_num); vTaskDelay(1000); } } void task2_task(void * pvParameters) { char task2_num=0; while(1) { task2_num++; LED1 = ~LED1; printf(“Task2 Runing %d!rn”,task2_num); vTaskDelay(500); } } 实验现象; 开发板上LED0和LED1进行不同状态的闪烁,串口也会打印任务执行次数,很明显任务二的速度是任务一的两倍。 我这里使用的是STM32F407VET6,原理都差不多,用那块板子都一样。至此,FreeRTOS移植和任务创建成功。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1561 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1501 浏览 1 评论
933 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
665 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1555 浏览 2 评论
1848浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
610浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
504浏览 3评论
508浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
489浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-10 16:50 , Processed in 0.580821 second(s), Total 44, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号