HC32L021C8UB 移植 FreeRTOS

HC32L021C8UB 移植 FreeRTOS
FreeRTOS/Source/tasks.cFreeRTOS/Source/queue.cFreeRTOS/Source/list.cFreeRTOS/Source/portable/[compiler]/[architecture]/port.cFreeRTOS/Source/portable/MemMang/heap_x.c 其中 x 可以是 1、2、3、4 或 5。如果包含 port.c 文件的目录也包含程序集语言文件那么也必须使用程序集语言文件。可选源文件如果需要软件定时器功能请在项目中添加 FreeRTOS/Source/timers.c。如果需要事件组功能请在项目中添加 FreeRTOS/Source/event_groups.c。如果需要流缓冲区或消息缓冲区功能请在项目中添加 FreeRTOS/Source/stream_buffer.c。如果需要协程功能请在项目中添加 FreeRTOS/Source/croutine.c请注意协程已弃用 不推荐用于新设计。头文件以下目录必须位于编译器的 include 路径中必须告知编译器在这些目录中搜索 头文件FreeRTOS/Source/includeFreeRTOS/Source/portable/[compiler]/[architecture]。无论哪个目录包含要使用的 FreeRTOSConfig.h 文件请参阅下文“配置文件”段落。根据移植的不同也可能需要将相同的目录放在汇编器的 include 路径中。配置文件每个项目还需要一个名为 FreeRTOSConfig.h 的文件。 FreeRTOSConfig.h 它为正在构建的应用程序量身定制 RTOS 内核。因此它是取决于 应用程序的而不是 RTOS并且应位于应用程序目录中 而不是 RTOS 内核源代码目录中。如果您的项目包含 heap_1、heap_2、heap_4 或 heap_5则 FreeRTOSConfig.h 的 configTOTAL_HEAP_SIZE 定义将决定 FreeRTOS 堆的大小。如果 configTOTAL_HEAP_SIZE 设置得太高则您的应用程序将无法建立连接。FreeRTOSConfig.h 中的 configMINIMAL_STACK_SIZE 定义 设定了闲置任务使用的堆栈大小。如果 configMINIMAL_STACK_SIZE 设置得太低 则空闲任务将造成栈溢出。建议您找到 使用相同微控制架构的 FreeRTOS 官方演示 复制其中的 configMINIMAL_STACK_SIZE 设置。FreeRTOS 演示 项目存储在 FreeRTOS/Demo 目录的子目录中。 请注意一些演示项目的时间距离现在比较久因此不包含所有可用的 配置选项。开始裁剪移植把FreeRTOS配置模板FreeRTOS-Kernel\examples\template_configuration\FreeRTOSConfig.h拷贝到FreeRTOS-Kernel\include下。保留选中的文件和文件夹其他的都没用删掉。使用FreeRTOS-Kernel\portable\GCC\ARM_CM0替换FreeRTOS-Kernel\portable\RVDS\ARM_CM0 然后保留选中的文件夹其他删掉。FreeRTOS-Kernel\portable目录下保留刚才替换的文件夹其他删掉。‘工程添加工程是直接使用HC模板直接在模板上添加。heap_1—— 最简单不允许释放内存。heap_2—— 允许释放内存但不会合并相邻的空闲块。heap_3—— 简单包装了标准 malloc() 和 free()以保证线程安全。heap_4—— 合并相邻的空闲块以避免碎片化。包含绝对地址放置选项。heap_5—— 如同 heap_4能够跨越多个不相邻内存区域的堆。注意heap_1 不太有用因为 FreeRTOS 添加了静态分配支持。heap_2 现在被视为旧版因为较新的 heap_4 实现是首选。详细请点击查看FreeRTOS 堆内存管理FreeRTOSConfig.h#ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H /* ************************************************************************* * 1. 系统基础配置 * ************************************************************************/ /* 芯片内核时钟频率 - HC32L021 主频配置为 48MHz */ #define configCPU_CLOCK_HZ ( ( unsigned long ) 48000000 ) /* 系统时钟节拍频率 (1000Hz 1ms中断一次)是RTOS的时间基准 */ #define configTICK_RATE_HZ 1000 /* 最大任务优先级数数字越大优先级越高 (Cortex-M0推荐5~8级) */ #define configMAX_PRIORITIES 5 /* 空闲任务最小堆栈大小 (单位字1字4字节)M0小资源芯片精简配置 */ #define configMINIMAL_STACK_SIZE 64 /* 任务名称最大字符串长度精简内核可减小内存占用 */ #define configMAX_TASK_NAME_LEN 8 /* 系统节拍计数器位数32位适合长时间运行无溢出风险 */ #define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_32_BITS /* 空闲任务是否主动让出CPU1开启提高其他同优先级任务响应速度 */ #define configIDLE_SHOULD_YIELD 1 /* ************************************************************************* * 2. 调度器配置 * ************************************************************************/ /* 1抢占式调度(高优先级任务打断低优先级)0协作式调度FreeRTOS默认开启 */ #define configUSE_PREEMPTION 1 /* 时间片调度0关闭同优先级任务不会轮流执行适合小资源MCU */ #define configUSE_TIME_SLICING 0 /* 优化任务选择算法Cortex-M0不支持硬件优化必须关闭 */ #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 /* 低功耗tickless模式0关闭适合普通应用低功耗项目可开启 */ #define configUSE_TICKLESS_IDLE 0 /* ************************************************************************* * 3. 内存管理配置 * ************************************************************************/ /* 静态内存分配0关闭不使用静态创建任务/队列简化开发 */ #define configSUPPORT_STATIC_ALLOCATION 0 /* 动态内存分配1开启使用FreeRTOS内存堆创建任务/队列推荐新手使用 */ #define configSUPPORT_DYNAMIC_ALLOCATION 1 /* 动态内存堆总大小 (单位字节)HC32L021小RAM精简配置1.5KB */ #define configTOTAL_HEAP_SIZE 1536 /* 用户自定义内存堆0关闭使用FreeRTOS自带内存管理 */ #define configAPPLICATION_ALLOCATED_HEAP 0 /* ************************************************************************* * 4. 中断优先级配置 (Cortex-M0核心) * ************************************************************************/ /* 内核中断优先级 (PendSV/SysTick)设为最低优先级0不影响业务中断 */ #define configKERNEL_INTERRUPT_PRIORITY 0 /* 系统调用最高中断优先级Cortex-M0仅支持4级优先级0最低 */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY 0 /* API调用最高中断优先级同上述配置保持一致避免异常 */ #define configMAX_API_CALL_INTERRUPT_PRIORITY 0 /* ************************************************************************* * 5. 钩子函数(回调函数)配置 * ************************************************************************/ /* 空闲任务钩子0关闭空闲时执行自定义函数用于低功耗 */ #define configUSE_IDLE_HOOK 0 /* 时钟节拍钩子1开启每1ms执行一次自定义函数 */ #define configUSE_TICK_HOOK 1 /* 内存分配失败钩子1开启内存不足时触发方便调试 */ #define configUSE_MALLOC_FAILED_HOOK 1 /* 堆栈溢出检测1开启任务堆栈溢出时触发调试必备 */ #define configCHECK_FOR_STACK_OVERFLOW 1 /* ************************************************************************* * 6. 内核可选功能裁剪 * ************************************************************************/ /* 软件定时器0关闭小资源MCU无需使用 */ #define configUSE_TIMERS 0 /* 事件组0关闭精简内核 */ #define configUSE_EVENT_GROUPS 0 /* 流缓冲区0关闭串口/大量数据传输才使用 */ #define configUSE_STREAM_BUFFERS 0 /* 协程0关闭FreeRTOS废弃功能 */ #define configUSE_CO_ROUTINES 0 /* ************************************************************************* * 7. 硬件外设适配 (HC32L021专用) * ************************************************************************/ /* MPU内存保护单元0关闭HC32L021无MPU硬件必须关闭 */ #define configENABLE_MPU 0 /* MPU包装函数0关闭无MPU无需使用 */ #define configUSE_MPU_WRAPPERS_V1 0 /* FPU浮点单元0关闭Cortex-M0无硬件浮点 */ #define configENABLE_FPU 0 /* TrustZone安全扩展0关闭普通MCU无此功能 */ #define configENABLE_TRUSTZONE 0 /* 仅安全模式运行0关闭无TrustZone无需配置 */ #define configRUN_FREERTOS_SECURE_ONLY 0 /* MVE向量扩展0关闭芯片不支持 */ #define configENABLE_MVE 0 /* 中断处理安装检查0关闭适配GCC端口解决链接报错 */ #define configCHECK_HANDLER_INSTALLATION 0 /* ************************************************************************* * 8. 任务通信/同步功能 * ************************************************************************/ /* 任务通知1开启轻量级任务同步替代信号量/队列 */ #define configUSE_TASK_NOTIFICATIONS 1 /* 互斥锁1开启解决多任务资源竞争 */ #define configUSE_MUTEXES 1 /* 递归互斥锁0关闭精简内核 */ #define configUSE_RECURSIVE_MUTEXES 0 /* 计数信号量1开启用于资源计数、同步 */ #define configUSE_COUNTING_SEMAPHORES 1 /* 队列集0关闭精简内核 */ #define configUSE_QUEUE_SETS 0 /* ************************************************************************* * 9. 断言函数(调试专用) * ************************************************************************/ /* 断言宏参数不成立时关闭中断并死循环快速定位程序BUG */ #define configASSERT( x ) \ if( ( x ) 0 ) \ { \ taskDISABLE_INTERRUPTS(); \ for( ; ; ) \ ; \ } /* ************************************************************************* * 10. 可选API函数使能 * ************************************************************************/ #define INCLUDE_vTaskPrioritySet 1 /* 启用 设置任务优先级 API */ #define INCLUDE_uxTaskPriorityGet 1 /* 启用 获取任务优先级 API */ #define INCLUDE_vTaskDelete 1 /* 启用 删除任务 API */ #define INCLUDE_vTaskSuspend 1 /* 启用 挂起任务 API */ #define INCLUDE_xResumeFromISR 1 /* 启用 中断中恢复任务 API */ #define INCLUDE_vTaskDelayUntil 1 /* 启用 绝对延时 API */ #define INCLUDE_vTaskDelay 1 /* 启用 相对延时 API */ #define INCLUDE_xTaskGetSchedulerState 0 /* 关闭 获取调度器状态 API */ #define INCLUDE_xTaskGetCurrentTaskHandle 0 /* 关闭 获取当前任务句柄 API */ #endif /* FREERTOS_CONFIG_H */R_ARM_THM_JUMP11 编译报错这里报错的意思是汇编里的跳转指令能跳的最大距离只有 ±1KB但要跳的目标函数vPortSVCHandler_C在 0xA24 这个位置超出了芯片允许的跳转范围硬件做不到直接报错HC32L021 Cortex-M0 内核只支持最简指令集Thumb-1普通跳转指令 b 只能跳 ±1024 字节±1KB还不支持长跳转指令 b.w。解决方法是把函数地址放到寄存器里再用 bx 跳转想跳多远就跳多远。void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ { __asm volatile ( .syntax unified \n .extern vPortSVCHandler_C \n \n movs r0, #4 \n mov r1, lr \n tst r0, r1 \n beq stacking_used_msp \n \n stacking_used_psp: \n mrs r0, psp \n ldr r3, vPortSVCHandler_C \n bx r3 \n \n stacking_used_msp: \n mrs r0, msp \n ldr r3, vPortSVCHandler_C \n bx r3 \n \n .align 4 \n ); }测试下void hello_Task(void *pvParameters) { for(;;) { printf(hello task\r\n); vTaskDelay(1000 / portTICK_PERIOD_MS); } } void led_Task(void *pvParameters) { for(;;) { printf(led task\r\n); vTaskDelay(1000 / portTICK_PERIOD_MS); } } int32_t main(void) { SysClockConfig(); STK_LedConfig(); GpioConfig(); SpiConfig(); SPI_Enable(SPI); UartGpioConfig(); LpuartConfig(); xTaskCreate(hello_Task, hello_Task, configMINIMAL_STACK_SIZE, NULL, 1, NULL); xTaskCreate(led_Task, hello_Task, configMINIMAL_STACK_SIZE, NULL, 1, NULL); vTaskStartScheduler(); while (1) { DDL_Delay1ms(500); } }