1. GD32F427和RTOS下载
FreeRTOS作为使用量比较多的实时系统,在小车控制、IOT领域都比较常见,而且由于开源免费,相对于其他系统,有更大的发展。在GDF4上移植,首先是下载RTOS内核,
我使用的是LTS长期支持版,也会比较稳定,下载之后的文件中包含多个文件,涉及到MQTT协议、HTTP等,用于物联网场景,我只需要RTOSKernel的文件内容。
kernel目录下包含源文件、头文件和Portable,源文件主要添加的文件如图所示。
其中heap_4.c在FreeRTOS_Kernel\portable\MemMang文件夹下,port.c在\FreeRTOS\Source\portable\RVDS\ARM_CM4F文件夹下,heap4是常用的内存管理设计,具体内容看手册。
在添加完所需的源文件之后,就是keil中添加os的头文件,头文件的路径分别在FreeRTOS_Kernel\include,FreeRTOS_Kernel\portable\RVDS\ARM_CM4F,这样编译之后还会显示不通过,是因为缺少FreeRTOSConfig.h文件,可以自己编写,也可以从FreeRTOS的demo中复制添加,我把我用的配置文件放在下面。
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#if defined(__CC_ARM) || defined(__ICCARM__)
#include <stdint.h>
extern uint32_t SystemCoreClock;
#endif
#define configUSE_PREEMPTION 1
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 8 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 130 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 16 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configUSE_QUEUE_SETS 0
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_MALLOC_FAILED_HOOK 0
#define configSUPPORT_STATIC_ALLOCATION 0
#define configUSE_TICKLESS_IDLE 0
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0
#define configUSE_TRACE_FACILITY 1
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
#define configGENERATE_RUN_TIME_STATS 0
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
#define portGET_RUN_TIME_COUNTER_VALUE() 0
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
#define configUSE_TIMERS 0
#define configTIMER_TASK_PRIORITY ( 2 )
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xTimerPendFunctionCall 0
#define INCLUDE_xSemaphoreGetMutexHolder 0
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_xTaskGetIdleTaskHandle 0
#define INCLUDE_xTaskAbortDelay 0
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#ifdef __NVIC_PRIO_BITS
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4
#endif
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
#endif
移植到这,差不多就可以了,编译一下,还有三个问题,重复定义的问题,关于void PendSV_Handler(void)、void SysTick_Handler(void)、void SVC_Handler(void)三个中断处理有重复定义,我是把gd32f4xx_it.c中的文件屏蔽掉,留下FreeRTOS中定义的几个函数。到此为止,基本移植就完成了,接下来创建几个任务试试。
2. 任务创建
之后任务创建就是调用task.c里面的函数
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName,
const configSTACK_DEPTH_TYPE usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask )
每创建一个任务,会分配两块内存区,用于任务控制块和stack区,任务采用抢占式调度。我把BSP相关的外设初始化放在一个BSP_Init函数中,任务函数则放在System文件夹下,目前设计了datatxrx.c,用于数据接收。
设计后的目录结构和任务。目前是编译通过了,具体的细节还在设计,下次整理一下rtos的手册和接收数据任务、存数据任务的调度再写一写。
原作者:夏漳
|