赞
踩
这个文章其实是在去年3月份准备电赛期间研究TI CC3200时写的,当时并没有想着往网上发,随着RTOS发展的越来越火热,我也想在这方面出点力,所有把这篇文章上传一下,方便大家在移植FreeRTOS时有个参考
https://github.com/ARM-software/CMSIS-FreeRTOS
如果实在无法在github上下载,请使用网盘
链接:https://pan.baidu.com/s/1XwJRH5a3zSkUHfDS09k6qQ?pwd=lksc
提取码:lksc
1.首先修改堆大小,即configTOTAL_HEAP_SIZE这个宏,根据自己所使用的MCU RAM资源确定,一般不推荐将RAM空间全部分配给这个堆,我给我的STM32F411设置的大小为((size_t)(64*1024)),实际可以更大一些。其次修改configCPU_CLOCK_HZ这个宏为自己MCU的主频,如果你使用CUBEMX生成工程,这一个宏可以不改
2.开启软件定时器,将configUSE_TIMERS设置为1
3.注意每个MCU设置中断优先级的bit不一定相同,例如STM32使用4个bit位,TI的CC3200使用3个bit位表示优先级,相应的configPRIO_BITS和configLIBRARY_LOWEST_INTERRUPT_PRIORITY这两个宏定义便需要修改,这里的宏的设置以STM32为例
注释掉 #include “freertos_evr.h”
位于source文件夹中的croutine.c ,event_groups.c ,list.c ,queue.c ,stream_buffer.c,tasks.c,timers.c,位于portable文件夹中MemMang里的heap4.c和对应IDE编译器(以keil的ARMClang为例)的port.c文件
如下图所示
1.如果你是使用STM32CUBEMX生成的工程,请在stm32fxxx_it.c中将SVC、PendSV、Systic这三个中断函数给注释掉,port.c中定义了这三个中断函数,用于设置任务切换和恢复任务的栈空间
2.由于FreeRTOS使用Systick作为整个系统的时基,所以我们需要更换一个定时器作为STM32的时基,以便我们使用HAL_GetTick()等函数,如果使用CUBEMX配置的话,在SYS中更改Timebase Source,选择任意一个基本定时器即可,以下图为例
以STM32F411和keil开发平台为例
添加/FREERTOS/Source/include和/FREERTOS/Source/portable/GCC/ARM_CM4F(此处为对应的内核),我这里使用的是相对路径。
//FreeRTOS includes #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include <stdio.h> #include "semphr.h" #include "event_groups.h" #include "timers.h" TaskHandle_t xHandleTask1; TaskHandle_t xHandleTask2; void Task1Funtion(void *param) { volatile int i; while(1) { } } void Task2Funtion(void *param) { volatile int i; while(1) { } } int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2*/ xTaskCreate(Task1Funtion,"TASK1",100,NULL,1,&xHandleTask1); xTaskCreate(Task2Funtion,"TASK2",100,NULL,1,&xHandleTask2); vTaskStartScheduler();//开启调度 /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
烧录好以后debug模式下在两个任务的while(1)里打断点,并全速运行,如果系统能在两个任务间切换即表示移植成功(以IAR平台为例)
若出现总是进入同一个任务的断点,可以先取消这个任务的断点,再全速运行,查看是否能进入另一个任务的断点(原因大概率是因为这个任务还没执行够1ms,所以并没有切换任务)
如果系统能在两个任务间切换即表示移植成功(以IAR平台为例)
若出现总是进入同一个任务的断点,可以先取消这个任务的断点,再全速运行,查看是否能进入另一个任务的断点(原因大概率是因为这个任务还没执行够1ms,所以并没有切换任务)
[外链图片转存中…(img-rwXIfIDl-1710139206540)]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。