笔者近一年来MCU上的OS玩遍了FreeRTOS、ThreadX、Nuttx、RT-Thread、zephyr和NOMMU linux,兜兜转转现在又回到用FreeRTOS上来了。FreeRTOS移植挺简单的,本身雅特力官方的Firmware Libraray中就有FreeRTOS的适配代码,其位置在
- middlewares/freertos和utilities/at32f435_437_freertos_demo
但一来,官方适配的版本比较老还是V10.4.3版本,二来笔者想再练练手,所以咱们从零开始适配吧。
下载最新的FreeRTOS源码
删除middlewares/freertos/下的内容,用从www.freertos.org上下载最新release的版本替代,也可以clone github仓库,不过如果不关心源码变动历史,下载release版本挺好的。
FreeRTOS配置与测试用例
雅特力官方的测试用例是兼容最新版本的FreeRTOS的,也比较简单,创建了LED2和LED3两个task,这两task不干别的就是点灯,但用来观察FreeRTOS移植是否成功基本够了。所以这一步跑个测试用例就先用雅特力官方的版本,等后面移植shell时会全部切换成自己的代码。
所有FreeRTOS配置选项都放在一个名为FreeRTOSConfig.h文件里:
- utilities/at32f435_437_freertos_demo/inc/FreeRTOSConfig.h
这个文件我做了两处小改动:一使能了tickless;二改大了heap大小 - #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 508 * 1024 ) )
- #define configUSE_TICKLESS_IDLE 1
tickless改动解释 顾名思义,tickless就是时钟心跳中断不再是固定的100次/s或1000次/s,而是按需要触发时钟中断,>可以降低功耗。FreeRTOS的CM4F的port就有使用systick的tickless支持,当然因为arm cortex m系systick只有24bit,所以对于288MHZ的cm4来说大概58ms左右就溢出了,这时候tickless不得不退出重新program systick,不过这相比原来使能tickless前1ms就来一次systcik中断好得多,如果想再进一步降低功耗,就不能使用FreeRTOS的CM4F port的默认tickless实现,而需要利用mcu的其它low power timer来实现tickless,不过功耗不是这次测评重点,所有笔者就使用CM4 port的默认tickless实现了。
增大heap解释 增大heap大小就是想尽可能多的把sram空间给FreeRTOS的heap,充分利用大sram,笔者一直喜欢大sram,而且上一篇测评文章费了好大功夫用openocd修改了EOPB0选项使能了大sram,不用真浪费阿。当然所有sram不能全给HEAP,本身代码的数据段等有些sram占用,还需要给MSP栈留下足够空间,此栈主要供系统初始化和中断程序使用。
CMakeLists.txt文件 最后一步修改CMakeLists.txt文件,编译freertos源码以及测试用例,笔者的完整CMakeLists内容如下: - set(CMAKE_SYSTEM_NAME Generic)
- set(CMAKE_SYSTEM_VERSION 1)
- set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
- cmake_minimum_required(VERSION 3.20)
- set(CMAKE_C_COMPILER arm-none-eabi-gcc)
- set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
- set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
- set(CMAKE_AR arm-none-eabi-ar)
- set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
- set(CMAKE_OBJDUMP arm-none-eabi-objdump)
- set(SIZE arm-none-eabi-size)
- set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
- set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
- set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
- set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
- add_compile_options(-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16)
- add_compile_options(-ffunction-sections -fdata-sections -fno-builtin -fno-common -Wall -Wshadow -Wdouble-promotion -Werror -Wno-unused-parameter)
- add_compile_options(-O3)
- project(at32f437 C ASM)
- set(CMAKE_CXX_STANDARD 11)
- set(CMAKE_C_STANDARD 99)
- include_directories(libraries/cmsis/cm4/core_support
- libraries/cmsis/cm4/device_support
- libraries/cmsis/dsp/include
- libraries/drivers/inc
- project/at32f435_437_board
- middlewares/freertos/source/include
- middlewares/freertos/source/portable/GCC/ARM_CM4F
- utilities/at32f435_437_freertos_shell/inc)
- add_definitions(-DAT32F437ZMT7 -DAT_START_F437_V1)
- file(GLOB_RECURSE SOURCES
- "project/at32f435_437_board/at32f435_437_board.c"
- "middlewares/freertos/source/croutine.c"
- "middlewares/freertos/source/stream_buffer.c"
- "middlewares/freertos/source/timers.c"
- "middlewares/freertos/source/event_groups.c"
- "middlewares/freertos/source/list.c"
- "middlewares/freertos/source/queue.c"
- "middlewares/freertos/source/tasks.c"
- "middlewares/freertos/source/portable/memmang/heap_4.c"
- "middlewares/freertos/source/portable/GCC/ARM_CM4F/port.c"
- "utilities/at32f435_437_freertos_demo/*.c"
- "libraries/drivers/src/*.c"
- "libraries/cmsis/cm4/device_support/system_at32f435_437.c"
- "libraries/cmsis/cm4/device_support/startup/gcc/startup_at32f435_437.s"
- )
- set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F437xM_FLASH.ld)
- add_link_options(
- -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16
- -Wl,--gc-sections,--print-memory-usage,-Map,${PROJECT_NAME}.map
- --specs=nano.specs
- --specs=nosys.specs)
- add_link_options(-T ${LINKER_SCRIPT})
- add_executable(${PROJECT_NAME}.elf ${SOURCES} ${LINKER_SCRIPT})
- # target_link_libraries(${PROJECT_NAME}.elf printfloat)
- set(HEX_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex)
- set(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)
- set(LST_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.lst)
- add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
- COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}.elf> ${HEX_FILE}
- COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${PROJECT_NAME}.elf> ${BIN_FILE}
- COMMAND ${CMAKE_OBJDUMP} --all-headers --demangle --disassemble $<TARGET_FILE:${PROJECT_NAME}.elf> > ${LST_FILE}
- COMMAND ${SIZE} --format=berkeley $<TARGET_FILE:${PROJECT_NAME}.elf>
- )
编译&烧录
- rm -rf build
- cmake -B build
- cmake --build build -j8
|