基于CUBEMX H750 移植 RTX5 使用AC6编译器
本文参考了安富莱论坛的相关教程: 【安富莱】RTX5内核教程,采用CMSIS-RTOS V2封装层,已经更新发布至第6章 (2020-09-21)
硬件: STM32H750VB开发板
软件配置:
一.创建CUBEMX工程。 1.时基使用TIM6  2.启用高速外部晶振  设置Debug为SW  并配置好时钟  3.关闭NVIC的代码生成,这三个中断函数在 RTX5 里有定义。 
4.配置 2个 LED 灯用于测试。  5.工程配置  注意修改IDE,和堆栈大小。  6.生成代码,并打开工程。  二.添加RTX5组件。 1.修改工程配置。启用MicroLIB,并使用AC6编译器,点击编译,确保没有警告及错误。  
2.开始添加 RTX5 组件,点击此处。  3.勾选 RTX5 组件,选择使用源码方式加入,点击resolve,自动完成配置,最后点击OK。  4.完成后会弹出下面的窗口,提示要使用cubemx-api生成一次配置文件。  5.在新打开的CUBEMX中,不做任何配置直接点击生成代码,然后关闭它。   6.回到KEIL,提示文件被修改,点击 “是” 更新文件。  7.此时,工程文件如下图所示。  8.屏蔽不需要的工程文件,使其兼容 CUBEMX 工程模板,具体操作如下: 8.1 右键选择需要屏蔽编译的文件:如 stm32h7xx_hal.c ,选择 Option for Component Class “Device”,取消 Include in target build 前的勾选,点击OK  8.2 按下图依次将 Device 中的文件屏蔽,保留 stm32h7xx_hal_msp.c 文件:  8.3 按下图依次将 STM32CubeMX:Common Sources 中的文件屏蔽,stm32h7xx_it.h不用管它: 
9.打开 “Device” 下的 stm32h7xx_hal_msp.c 文件,在文件首尾位添加条件编译,此文件与cubemx生成的文件冲突。如果只是屏蔽掉的话,每次使用cubemx重新生成代码都会使其恢复编译状态,所以使用条件编译来屏蔽掉它。  
10.完成以上操作后,点击编译。  11.至此RTX5移植工作完成。
三.功能测试 1.添加测试代码 OS_Start.c 和 OS_Start.h OS_Start.c 内容如下:
#include "OS_start.h"
#include "stdio.h"
#include "cmsis_os2.h"
static void AppTaskCreate (void);
void AppTaskUserIF(void *argument);
void AppTaskLEDG(void *argument);
void AppTaskLEDR(void *argument);
void AppTaskMsgPro(void *argument);
void AppTaskStart(void *argument);
const osThreadAttr_t ThreadStart_Attr =
{
.name = "osRtxStartThread",
.attr_bits = osThreadDetached,
.priority = osPriorityHigh4,
.stack_size = 2048,
};
const osThreadAttr_t ThreadMsgPro_Attr =
{
.name = "osRtxMsgProThread",
.attr_bits = osThreadDetached,
.priority = osPriorityHigh3,
.stack_size = 1024,
};
const osThreadAttr_t ThreadLEDG_Attr =
{
.name = "osRtxLEDGThread",
.attr_bits = osThreadDetached,
.priority = osPriorityHigh2,
.stack_size = 512,
};
const osThreadAttr_t ThreadLEDR_Attr =
{
.name = "osRtxLEDRThread",
.attr_bits = osThreadDetached,
.priority = osPriorityHigh2,
.stack_size = 512,
};
const osThreadAttr_t ThreadUserIF_Attr =
{
.name = "osRtxThreadUserIF",
.attr_bits = osThreadDetached,
.priority = osPriorityHigh1,
.stack_size = 1024,
};
osThreadId_t ThreadIdTaskUserIF = NULL;
osThreadId_t ThreadIdTaskMsgPro = NULL;
osThreadId_t ThreadIdTaskLEDG = NULL;
osThreadId_t ThreadIdTaskLEDR = NULL;
osThreadId_t ThreadIdStart = NULL;
void Task_start(void)
{
osKernelInitialize();
ThreadIdStart = osThreadNew(AppTaskStart, NULL, &ThreadStart_Attr);
osKernelStart();
}
void AppTaskMsgPro(void *argument)
{
while(1)
{
osDelay(10);
}
}
void AppTaskUserIF(void *argument)
{
while(1)
{
osDelay(200);
}
}
void AppTaskLEDG(void *argument)
{
const uint16_t usFrequency = 200;
uint32_t tick;
tick = osKernelGetTickCount();
while(1)
{
tick += usFrequency;
osDelayUntil(tick);
HAL_GPIO_TogglePin(LEDG_GPIO_Port,LEDG_Pin);
}
}
void AppTaskLEDR(void *argument)
{
const uint16_t usFrequency = 250;
uint32_t tick;
tick = osKernelGetTickCount();
while(1)
{
tick += usFrequency;
osDelayUntil(tick);
HAL_GPIO_TogglePin(LEDR_GPIO_Port,LEDR_Pin);
}
}
void AppTaskStart(void *argument)
{
const uint16_t usFrequency = 1;
uint32_t tick;
HAL_ResumeTick();
AppTaskCreate();
tick = osKernelGetTickCount();
while(1)
{
tick += usFrequency;
osDelayUntil(tick);
}
}
static void AppTaskCreate (void)
{
ThreadIdTaskMsgPro = osThreadNew(AppTaskMsgPro, NULL, &ThreadMsgPro_Attr);
ThreadIdTaskLEDG = osThreadNew(AppTaskLEDG, NULL, &ThreadLEDG_Attr);
ThreadIdTaskLEDR = osThreadNew(AppTaskLEDR, NULL, &ThreadLEDR_Attr);
ThreadIdTaskUserIF = osThreadNew(AppTaskUserIF, NULL, &ThreadUserIF_Attr);
}
OS_Start.h内容如下:
#ifndef _OS_START_H_
#define _OS_START_H_
#include "main.h"
extern void Task_start(void);
#endif
2.在 main.c 对应位置添加如下代码:
#include "OS_start.h"
Task_start();
编译并下载。
运行效果,LEDG和LEDR以不同频率闪烁。 
四.已知存在的问题: 1.编译信息会多出一条提示:
Note: source file ‘D:\H750_RTX5_AC6\MDK-ARM\RTE\Device\STM32H750VBTx\STCubeGenerated\Src\stm32h7xx_hal_msp.c’ - object file renamed from ‘H750_RTX5_AC6\stm32h7xx_hal_msp.o’ to ‘H750_RTX5_AC6\stm32h7xx_hal_msp_1.o’.
原因:这是因为工程中同时存在 两个 stm32h7xx_hal_msp.c 文件。
2.使用 cubemx 重新生成时会出现下面的提示,  原因:加入了 RTX5 的工程文件多了关于RTX5的描述文件,cubemx生成的工程文件少了这些描述文件所以报错了,不用担心,再次使用 cubemx 生成一次就可以打开了。
五.后续 等过几天有时间,打算移植RL-USB 到 cubemx 里,这样使用起来就方便了。
|