这一次咱们来移植大名鼎鼎的ThreadX RTOS,目前微软已经把它转到eclipse组织下了,笔者比较喜欢这个os的代码风格。为跑起ThreadX RTOS,至少需要timer中断中断,然后弄个uart驱动输出。我们最好利用原厂的一些驱动代码,英飞凌是由工具生成的驱动代码,但由于你懂的原因,英飞凌那个工具我用起来不太方便,怎么办?上一篇评测文章其实已经有些风声:我是把RT-Thread英飞凌的bsp抠出来替代的,RT-Thread大部分外设都配置好了,所以它带的bsp和自己用英飞凌的工具自动生成的bsp代码应该差不多。

RT-Thread的 英飞凌的bsp 有些代码是做成package的,所以我们scons --menuconfig一次然后更新包:
  1. cd rt-thread/bsp/Infineon/psoc6-evaluationkit-062S2
  2. scons --menuconfig
  3. pkgs --update


现在可以复制rt-thread/bsp/Infineon/psoc6-evaluationkit-062S2目录备用
  1. cp -a rt-thread/bsp/Infineon/psoc6-evaluationkit-062S2 ~/psoc6


因ThreadX RTOS原生使用cmake管理,所以笔者也以cmake组织工程编译。为写CMakeLists.txt,需要对刚刚拷贝出来的psoc6文件仔细分析哪些是bsp驱动、哪些是RT-Thread的HAL,哪些是RT-Thread的app。经过分析后发现,
1.真正有用的目录就是libs和packages两个目录,可以其它目录都删除了
2.libs和packages目录下的目录/文件并没有全部用上,需要分析SConscript后把结果写入CMakeLists.txt编译规则,具体可以参考笔者后附的完整CMakeLists.txt文件
  1. set(CMAKE_SYSTEM_NAME Generic)
  2. set(CMAKE_SYSTEM_VERSION 1)
  3. set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
  4. cmake_minimum_required(VERSION 3.20)

  5. set(CMAKE_C_COMPILER arm-none-eabi-gcc)
  6. set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
  7. set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
  8. set(CMAKE_AR arm-none-eabi-ar)
  9. set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
  10. set(CMAKE_OBJDUMP arm-none-eabi-objdump)
  11. set(SIZE arm-none-eabi-size)

  12. set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
  13. set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
  14. set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
  15. set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

  16. add_compile_options(-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16)
  17. add_compile_options(-ffunction-sections -fdata-sections -fno-builtin -fno-common -Wall -Wshadow -Wdouble-promotion -Wno-unused-parameter)

  18. add_compile_options(-O3)

  19. project(cy8c624alqi C ASM)
  20. set(CMAKE_CXX_STANDARD 11)
  21. set(CMAKE_C_STANDARD 99)

  22. include_directories(libs/TARGET_RTT-062S2/config/GeneratedSource
  23.                     libs/TARGET_RTT-062S2
  24.                     packages/Infineon_cmsis-latest/Core/Include
  25.                     packages/Infineon_retarget-io-latest
  26.                     packages/Infineon_core-lib-latest/include
  27.                     packages/Infineon_capsense-latest
  28.                     packages/Infineon_mtb-hal-cat1-latest/include
  29.                     packages/Infineon_mtb-hal-cat1-latest/include_pvt
  30.                     packages/Infineon_mtb-hal-cat1-latest/COMPONENT_CAT1A/include
  31.                     packages/Infineon_mtb-hal-cat1-latest/COMPONENT_CAT1A/include/pin_packages
  32.                     packages/Infineon_mtb-hal-cat1-latest/COMPONENT_CAT1A/include/triggers
  33.                     packages/Infineon_mtb-pdl-cat1-latest/drivers/include
  34.                     packages/Infineon_mtb-pdl-cat1-latest/devices/COMPONENT_CAT1A/include
  35.                     packages/Infineon_mtb-pdl-cat1-latest/devices/COMPONENT_CAT1A/include/ip)

  36. add_definitions(-DCY_RETARGET_IO_NO_FLOAT -DCY8C624ALQI_S2D42 -DCORE_NAME_CM0P_0 -DCORE_NAME_CM4_0 -DCY_USING_PREBUILT_CM0P_IMAGE -DCY_USING_HAL -DCOMPONENT_CAT1A -DCOMPONENT_CAT1)

  37. file(GLOB_RECURSE SOURCES
  38.                 "applications/threadx/*.c"
  39.                 "packages/Infineon_cat1cm0p-latest/COMPONENT_CAT1A/COMPONENT_CM0P_SLEEP/*.c"
  40.                 "packages/Infineon_retarget-io-latest/cy_retarget_io.c"
  41.                 "packages/Infineon_mtb-pdl-cat1-latest/devices/COMPONENT_CAT1A/source/cy_device.c"
  42.                 "packages/Infineon_mtb-pdl-cat1-latest/drivers/source/*.c"
  43.                 "packages/Infineon_mtb-pdl-cat1-latest/drivers/source/TOOLCHAIN_GCC_ARM/cy_syslib_ext.S"
  44.                 "packages/Infineon_mtb-hal-cat1-latest/source/*.c"
  45.                 "packages/Infineon_mtb-hal-cat1-latest/COMPONENT_CAT1A/source/triggers/cyhal_triggers_psoc6_02.c"
  46.                 "packages/Infineon_mtb-hal-cat1-latest/COMPONENT_CAT1A/source/pin_packages/cyhal_psoc6_02_68_qfn.c"
  47.                 "libs/TARGET_RTT-062S2/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/startup_psoc6_02_cm4.S"
  48.                 "libs/TARGET_RTT-062S2/COMPONENT_CM4/system_psoc6_cm4.c"
  49.                 "libs/TARGET_RTT-062S2/config/GeneratedSource/*.c"
  50.                 "libs/TARGET_RTT-062S2/cybsp.c"
  51.                 )

  52. set(THREADX_SRC_DIR ${CMAKE_SOURCE_DIR}/../../kernel/threadx/)
  53. set(THREADX_ARCH "cortex_m4")
  54. set(THREADX_TOOLCHAIN "gnu")
  55. add_subdirectory(${THREADX_SRC_DIR}/threadx threadx)

  56. set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/board/linker_scripts/link.ld)
  57. add_link_options(
  58.                 -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16
  59.                 -Wl,--gc-sections,--print-memory-usage,-Map,${PROJECT_NAME}.map
  60.                 --specs=nano.specs
  61.                 --specs=nosys.specs)
  62. add_link_options(-T ${LINKER_SCRIPT})

  63. add_executable(${PROJECT_NAME}.elf ${SOURCES} ${LINKER_SCRIPT})

  64. target_link_libraries(${PROJECT_NAME}.elf azrtos::threadx)

  65. set(HEX_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex)
  66. set(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)
  67. set(LST_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.lst)
  68. add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
  69.         COMMAND ${CMAKE_OBJCOPY} -Oihex [        DISCUZ_CODE_140        ]lt;TARGET_FILE:${PROJECT_NAME}.elf> ${HEX_FILE}
  70.         COMMAND ${CMAKE_OBJCOPY} -Obinary [        DISCUZ_CODE_140        ]lt;TARGET_FILE:${PROJECT_NAME}.elf> ${BIN_FILE}
  71.         COMMAND ${CMAKE_OBJDUMP} --all-headers --demangle --disassemble [        DISCUZ_CODE_140        ]lt;TARGET_FILE:${PROJECT_NAME}.elf> > ${LST_FILE}
  72.         COMMAND ${SIZE} --format=berkeley [        DISCUZ_CODE_140        ]lt;TARGET_FILE:${PROJECT_NAME}.elf>
  73. )

创建applications/threadx目录,目录中有main.c和sample_threadx.c。其中sample_threadx.c内容来自ThreadX的测试用例,main.c内容如下:
  1. #include "cyhal.h"
  2. #include "cybsp.h"
  3. #include "cy_retarget_io.h"

  4. #define TICK_PER_SECOND 100

  5. extern void tx_main(void);
  6. extern void _tx_timer_interrupt(void);

  7. static void handle_error(void)
  8. {
  9.      /* Disable all interrupts. */
  10.     __disable_irq();

  11.     CY_ASSERT(0);
  12. }

  13. int main(void)
  14. {
  15.         cy_rslt_t result;

  16.         /* Initialize the device and board peripherals */
  17.         result = cybsp_init();
  18.         if (result != CY_RSLT_SUCCESS)
  19.                 handle_error();

  20.         /* Initialize retarget-io to use the debug UART port */
  21.         result = cy_retarget_io_init_fc(CYBSP_DEBUG_UART_TX,
  22.                                         CYBSP_DEBUG_UART_RX,
  23.                                         NC,
  24.                                         NC,
  25.                                         CY_RETARGET_IO_BAUDRATE);
  26.         if (result != CY_RSLT_SUCCESS)
  27.                 handle_error();

  28.         tx_main();
  29. }

  30. static void SysTick_Handler_CB(void)
  31. {
  32. #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
  33.         _tx_execution_isr_enter();
  34. #endif
  35.         _tx_timer_interrupt();
  36. #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
  37.         _tx_execution_isr_exit();
  38. #endif
  39. }

  40. void _tx_initialize_low_level(void)
  41. {
  42.         __disable_irq();

  43.         /* TODO Enable the cycle count register */

  44.         /* not used */
  45.         //_tx_initialize_unused_memory = __RAM_segment_used_end__;
  46.         //_tx_thread_system_stack_ptr = _estack;

  47.         SysTick_Config(SystemCoreClock / TICK_PER_SECOND);
  48.         (void)Cy_SysInt_SetVector(SysTick_IRQn, SysTick_Handler_CB);

  49.         NVIC_SetPriority(SVCall_IRQn, 0xff);
  50.         NVIC_SetPriority(PendSV_IRQn, 0xff);
  51.         NVIC_SetPriority(SysTick_IRQn, 4);
  52. }

编译:
  1. cmake -B build
  2. cmake --build build

烧录:
  1. openocd -f interface/kitprog3.cfg -f target/psoc6_2m.cfg -c "program build/cy8c624alqi.bin verify reset exit 0x10000000"

运行视频: