FreeRTOS是一个在单片机上使用很广泛的实时操作系统内核,是一个轻量级的系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等。
FreeRTOS操作系统是完全免费的操作系统,具有源码公开、可移植、可裁减、调度策略灵活的特点,可以方便地移植到各种单片机上运行。
MM32F5270功能比较多,芯片的性能也足够RTOS运行,一些比较大的项目,使用RTOS是事倍功半的。
首先,下载源码
这里使用的版本是FreeRTOS LTS 202012.04,这是一个长期支持版本,而且比较新,支持Armv8-M 架构。
由于MM32F5270芯片是Armv8-M 架构的,FreeRTOS也没有针对Arm China STAR-MC1的支持,从芯片的说明上,应该是没有TrustZone的。
所以,要使用的平台相关的文件,在FreeRTOS\FreeRTOS-Kernel\portable\ARMv8M中。
其中,portasm.c文件使用FreeRTOSv202012.04-LTS\FreeRTOS\FreeRTOS-Kernel\portable\ARMv8M\non_secure\portable\GCC\ARM_CM33_NTZ\non_secure中的相关文件。
工程目录下新建一个FreeRTOS的文件夹,把FreeRTOSv202012.04-LTS\FreeRTOS\FreeRTOS-Kernel中的文件复制到工程目录下。
在keil中添加相应的源文件,如下:
添加头文件路径:
默认是没有FreeRTOSConfig.h的,要手动进行添加。
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#define configENABLE_FPU 0
#define configENABLE_MPU 0
#define configENABLE_TRUSTZONE 0
#define INCLUDE_vTaskDelayUntil 1
#define configMAX_PRIORITIES ( 7 )
#define configUSE_PREEMPTION 1
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 60 )
#define configUSE_IDLE_HOOK 0
#ifndef configUSE_TICK_HOOK
#define configUSE_TICK_HOOK 0
#endif
#define configUSE_16_BIT_TICKS 0
#define configTICK_RATE_HZ ( 1000 )
#define configCPU_CLOCK_HZ (120000000)
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2* 1024U ) )
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define xPortSysTickHandler SysTick_Handler
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
#endif
在main函数中,增加一个任务
bool led=false;
void vTaskLED(void * pvParameters)
{
portTickType xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
while(1)
{
led=!led;
GPIO_WriteBit(BOARD_LED0_GPIO_PORT, BOARD_LED0_GPIO_PIN, led);
xTaskDelayUntil( &xLastWakeTime, ( 250 / portTICK_RATE_MS ) );
}
}
并在main函数中创建这个任务
int main(void)
{
BOARD_Init();
printf("\r\ngpio_basic example.\r\n");
xTaskCreate(vTaskLED, "LED", 128, NULL, 3, NULL);
vTaskStartScheduler();
while (1)
{
if ( GPIO_ReadInDataBit(BOARD_KEY0_GPIO_PORT, BOARD_KEY0_GPIO_PIN) )
{
GPIO_WriteBit(BOARD_LED0_GPIO_PORT, BOARD_LED0_GPIO_PIN, 1u);
GPIO_WriteBit(BOARD_LED1_GPIO_PORT, BOARD_LED1_GPIO_PIN, 0u);
}
else
{
GPIO_WriteBit(BOARD_LED0_GPIO_PORT, BOARD_LED0_GPIO_PIN, 0u);
GPIO_WriteBit(BOARD_LED1_GPIO_PORT, BOARD_LED1_GPIO_PIN, 1u);
}
}
}
完成看,开始编译,编译没有错误。
原作者:ifconfig