Free RTOS移植到Infineon第二代Tricore处理器。主要完成三个工作:一、文件框架搭建;二、硬件移植文件修改;三、操作系统配置。
一、文件框架搭建
源文件必选:
- FreeRTOS/Source/tasks.c
- FreeRTOS/Source/queue.c
- FreeRTOS/Source/list.c
- FreeRTOS/Source/portable/[compiler]/[architecture]/port.c.
- FreeRTOS/Source/portable/MemMang/heap_x.c where ‘x’ is 1, 2, 3, 4 or 5.
源文件可选:
- software timer:FreeRTOS/Source/timers.c
- event group:FreeRTOS/Source/event_groups.c
- steam buffer or message buffer:FreeRTOS/Source/stream_buffer.c
- co-routine:FreeRTOS/Source/croutine.c(协程已启用)
头文件:
- FreeRTOS/Source/include
- FreeRTOS/Source/portable/[compiler]/[architecture]
配置文件:
- FreeRTOSConfig.h
软件框架如图:
二、硬件移植文件修改
硬件移植工作修改文件有两个:port.c和portmarco.h。主要实现三个任务切换方法:
2.1 任务中调用任务切换
切换函数:portYIELD()/portYIELD_WITHIN_API()/taskYEILD()
处理器资源:Trap_class6_TIN0
触发方式:_syscall(0)
2.2 普通中断中调用任务切换
切换函数:portYIELD_FROM_ISR()/taskYEILD_FROM_ISR()
处理器资源:GPSRx0
触发方式:GPSRx0.B.SETR = 1
2.3 systick中断中的任务切换
切换函数:在StmISR中进行
处理器资源:SysTimerx
触发方式:SysTimerx COMP0计数器溢出触发中断
三、配置文件修改
配置文件为:FreeRTOSConfig.h
/* 抢占式 任务调度。 */
#define configUSE_PREEMPTION 1
/* 0 - 通用的任务切换,全部用C实现,不限制最大优先级
* 1 - 处理器特定的任务切换,用汇编语言实现,高效,一般限制最大优先级数,譬如32
*/
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
/* low power tickless mode. */
#define configUSE_TICKLESS_IDLE 0
/* Timer 驱动时钟频率。 */
#define configCPU_CLOCK_HZ 100000000
/* RTOS时钟节拍频率 */
#define configTICK_RATE_HZ 1000
/* RTOS支持的最大任务优先级,每一个任务优先级都消耗RAM,因此,只设置实际需要的优先级数为最大优先级。 */
#define configMAX_PRIORITIES 8
/* Idle task stack size counted in words. */
#define configMINIMAL_STACK_SIZE 128
/* Task name length in chars. */
#define configMAX_TASK_NAME_LEN 16
/*System tick 计数器类型,每次system timer中断,计数器+1,
* 0 - 计数器类型为uint32_t, 1- uint16_t.
*/
#define configUSE_16_BIT_TICKS 0
/*此配置只影响运行在Idle优先级上的任务,因此只有满足两个条件时,此配置才有意义:
* 1-采用抢占式任务调度,2-有任务运行在Idle优先级上。
* 0 - Idle和Task平分时间片
* 1 - Task抢占Idle时间
* 其实,没必要把任务放在Idle优先级上,要在Idle处理的操作可以放在void vApplicationIdleHook( void )中实现
*/
#define configIDLE_SHOULD_YIELD 1
/* direct to task notification使能控制,使能后,每一个任务多消耗8Bytes ram。 */
#define configUSE_TASK_NOTIFICATIONS 1
/* MUTEX和Recursive MUTEX使能配置。 */
#define configUSE_MUTEXES 0
#define configUSE_RECURSIVE_MUTEXES 0
/* Semaphore 使能配置。*/
#define configUSE_COUNTING_SEMAPHORES 0
#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */
/* Queue registry,有两个用处,都用于kernel aware debugging.
* 1-用文本标记Queue名,在调试界面下显示
* 2-包含调试器需求信息,用于定位Queue和semaphore
*/
#define configQUEUE_REGISTRY_SIZE 10
/* queue set功能使能,阻塞和挂起多重队列和信号量。 */
#define configUSE_QUEUE_SETS 1
/* 事件分片功能
* 0-相同优先级的任务,在systick中断时,不切换,1-中断时,切换
*/
#define configUSE_TIME_SLICING 1
/*newlib功能,不推荐使用。*/
#define configUSE_NEWLIB_REENTRANT 0
/* 兼容8.0.0及之前的版本 */
#define configENABLE_BACKWARD_COMPATIBILITY 0
/* thread local storage array的索引数。 */
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5
/* 堆栈深度计数类型, configSTACK_DEPTH_TYPE usStackDepth,堆栈深度以Word计算。 */
#define configSTACK_DEPTH_TYPE uint16_t
/* FreeRTOS Message buffers 长度计数类型,message长度以Byte计算*/
#define configMESSAGE_BUFFER_LENGTH_TYPE uint16_t
/* Memory allocation related definitions. detail:FreeRTOS heap */
/* 0-RTOS objects 放在Heap中,因此必须使用一种内存管理方案,Heapx
* 1-由应用软件决定存放位置,必须实现两个回调函数, vApplicationGetIdleTaskMemory()提供Idle Task使用的Memory,vApplicationGetTimerTaskMemory()提供Daemon/Timer Service task使用的Memory(configUSE_TIMERS is set to 1)。
* Detail:Static Vs Dynamic Memory Allocation
*/
#define configSUPPORT_STATIC_ALLOCATION 0
#define configSUPPORT_DYNAMIC_ALLOCATION 1
/* configSUPPORT_DYNAMIC_ALLOCATION配置为1时,有效。
* detail: memory configuration
*/
#define configTOTAL_HEAP_SIZE 40960
#define configAPPLICATION_ALLOCATED_HEAP 1
/* Hook function related definitions. */
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_MALLOC_FAILED_HOOK 0
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
/* Run time and task stats gathering related definitions. */
#define configGENERATE_RUN_TIME_STATS 0
#define configUSE_TRACE_FACILITY 0
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
/* Co-routine related definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES 1
/* Software timer related definitions. Detail: FreeRTOS software timers */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY 3
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
/* Interrupt nesting behaviour configuration. */
/*支持RTOS的mcu可将中断分为三类:FreeRTOS使用两类中断,1、任务切换中断,其优先级为configKERNEL_INTERRUPT_PRIORITY,应配置为最低优先级。2、RTOS使用的,响应前台事件的中断,其优先级最小为configKERNEL_INTERRUPT_PRIORITY,最高为configMAX_API_CALL_INTERRUPT_PRIORITY(曾用名configMAX_SYSCALL_INTERRUPT_PRIORITY,只是不同的版本的命名),此ISR可以调用RTOS的API_FromISR。另外,configMAX_API_CALL_INTERRUPT_PRIORITY优先级之上的中断,不会被RTOS的中断行为影响,响应最实时的事件。
*/
#define configKERNEL_INTERRUPT_PRIORITY [dependent of processor]
#define configMAX_SYSCALL_INTERRUPT_PRIORITY [dependent on processor and application]
#define configMAX_API_CALL_INTERRUPT_PRIORITY [dependent on processor and application]
/* Define to trap errors during development. */
#define configASSERT( ( x ) ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )
/* FreeRTOS MPU specific definitions. */
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
/* Optional functions - most linkers will remove unused functions anyway. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_xResumeFromISR 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_uxTaskGetStackHighWaterMark 0
#define INCLUDE_xTaskGetIdleTaskHandle 0
#define INCLUDE_eTaskGetState 0
#define INCLUDE_xEventGroupSetBitFromISR 1
#define INCLUDE_xTimerPendFunctionCall 0
#define INCLUDE_xTaskAbortDelay 0
#define INCLUDE_xTaskGetHandle 0
#define INCLUDE_xTaskResumeFromISR 1
四、创建任务,开始执行任务
创建普通任务
xTaskCreate( vTask1, "LED1", 128, NULL, TASK1_PRIORITY, NULL);
创建软件定时器任务
pxTimer = xTimerCreate("timerTask_1s", configTICK_RATE_HZ, pdTRUE, 1000, vtimerTask_1s_callback);
启动软件定时器任务
if(pdPASS != xTimerStart(pxTimer, 100UL))
{
/* Timer task starts failed. */;
}
启动调度器,开始任务执行
vTaskStartScheduler();