本教程以MDK的集成开发环境作为演示
教程配套资料(百度网盘):
链接:https://pan.baidu.com/s/1GgI2DKSq2Ucp5Kh77RUqkQ
提取码:u309
(gitee仓库):
STM32F1_LiteOS移植: STM32F1C8T6成功移植LiteOS资料和移植好的工程文件
因为最近有个鸿蒙开源大赛需要使用到鸿蒙开源的操作系统,所以最近需要移植一个LiteOS实时操作系统的工程,本来想移植LiteOS到ESP32的,但是由于esp-idf的框架与FreeRTOS深度绑定(就是什么操作基本上都有FreeRTOS的操作),实在是太难移植了,所以最终还是选择了资源和教程都比较多的STM32来移植,我选择的是STM32F103C8T6作为演示,当然同样也适合STM32F1全系列的芯片的,下面开始演示教程:
在下载资料中为大家准备了移植需要的文件(Middlewares&&OS_CONFIG)和两个已经移植好可以正常使用的工程(LiteOS_stm32f103c8t6(firmware)、LiteOS_stm32f103c8t6(MX))和一个模版工程(STM32工程模板(firmware))、一个LiteOS创建任务 开启调度的例子(使用HAL库驱动的),其中fremware是固件库(标准库)版本的,MX是HAL库(STM32CubeMX)版本的,如果不想移植可以直接使用已经移植好的工程。
首先演示固件库移植演示( 参考文章:http://t.csdnimg.cn/zT3ER)
首先打开资料中准备的固件库版本的模版工程,打开文件管理
首先添加“Middlewares/LiteOS/kemel”、“Middlewares/LiteOS/arch”这两个文件夹(文件夹名字随意,只要添加对的文件,名字是无所谓的,最好是规范的),在“Middlewares/LiteOS/arch”这个文件夹下面添加以下文件:(下面是文件所在的路径)
Middlewares\LiteOS\arch\arm\arm-m\cortex-m3\keil\los_dispatch_keil.S
Middlewares\LiteOS\arch\arm\arm-m\src\los_hw.c
Middlewares\LiteOS\arch\arm\arm-m\src\los_hw_tick.c
Middlewares\LiteOS\arch\arm\arm-m\src\los_hwi.c
在“Middlewares/LiteOS/kemel”这个文件夹下添加以下文件:(下面是文件所在的路径)
-
Middlewares\LiteOS\kernel\los_init.c
Middlewares\LiteOS\kernel\base\core 下面全部 .c 文件
Middlewares\LiteOS\kernel\base\ipc 下面全部 .c 文件
Middlewares\LiteOS\kernel\base\mem\bestfit_little 下面全部 .c 文件
Middlewares\LiteOS\kernel\base\mem\common 下面全部 .c 文件
Middlewares\LiteOS\kernel\base\mem\membox 下面全部 .c 文件
Middlewares\LiteOS\kernel\base\misc 下面全部 .c 文件
Middlewares\LiteOS\kernel\base\om 下面全部 .c 文件
Middlewares\LiteOS\kernel\extended\tickless 下面全部 .c 文件
-
添加完文件后,还需要添加文件头路径,打开魔术棒,转到C/C++选项卡
添加以下文件路径:
做完以上操作基本上就相当于移植了LiteOS,但是因为LiteOS需要接管系统滴答(tick)和系统中断从而实现系统调度,而标准库中也有对系统滴答的定义,所以会出现冲突,因此我们还需要将原来标准库的tick和中断注释掉,详细操作:
打开stm32f10x_it.c文件,找到“SysTick_Handler”和“PendSV_Handler”这两个函数,将这两个函数注释掉。说明一下SysTick_Handler函数是系统滴答计时器处理函数,PendSV_Handler函数是一个特殊的系统级中断处理函数,因为裸机开发不需要使用到系统调度,所以原来的标准库中两个函数虽然定义了,但是没有执行任何操作。
做完以上理论操作后,还需要做一下细节的处理,我就遇到以下错误:
.\OS_CONFIG\target_config.h(43): error: #5: cannot open source input file "stm32f1xx.h": No such file or directory
#include "stm32f1xx.h"
这个很简单,就是将stm32f1xx.h改成stm32f10x.h,可能是版本不同的原因,所以文件名字会有细微的差距,我的是stm32f10x.h,你们可能是不同的名字报错,也可能不报错,取决于自己的工程。
由于我们的CMSIS版本已经不适合做LiteOS移植,移植后会出现兼容问题报错
Error: Undefined symbol_ _get_IPSR(找不到符号)
解决方式:把HUAWEI LITEOS\arch\arm\common\cmsis下的所有文件复制到我们在桌面建的文件夹中的Start文件夹中,粘贴时选择替换所有目标,无法替换时,请先保存退出MDK工程再执行替换操作。
做完以上操作你就已经成功将LiteOS-m的操作系统移植到STM32F103C8T6上了,接下来是上机实验,验证是否真的移植成功了。
直接将mian.c文件的全部内容替换成一下代码,因为比较懒,就没有封装文件了,直接写在main.c文件中了:
#include "stm32f10x.h" // Device header
#include "los_typedef.h"
#include "los_base.h"
#include "los_task.h"
static UINT32 TaskLed1_ID;
UINT32 TaskLed1(VOID)
{
while(1)
{
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
LOS_TaskDelay(1000);
GPIO_SetBits(GPIOC, GPIO_Pin_13);
LOS_TaskDelay(1000);
}
}
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC, GPIO_Pin_13);
UINT32 uwRet;
TSK_INIT_PARAM_S stInitParam;
if (LOS_KernelInit() != LOS_OK) //系统内核初始化
{
return LOS_NOK;
}
stInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskLed1; //要创建任务进入的函数
stInitParam.usTaskPrio = 4; //要创建任务的优先级
stInitParam.pcName = "TaskLed1"; //要创建任务的名字
stInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//要创建任务的堆栈大小
uwRet = LOS_TaskCreate(&TaskLed1_ID, &stInitParam); //创建LED1任务
if (uwRet != LOS_OK)
{
return LOS_NOK;
}
LOS_Start();
return LOS_OK;
while (1)
{
}
}
对代码说明一下,首先先初始化一下GPIO,将GPIO设置成输出模式,接着初始化LiteOS内核,创建一个任务函数,设置任务优先级和名字、堆栈大小,根据以上创建任务句柄和任务ID,开启任务调度。我写的是PC13的LED不断闪烁的任务,编译烧录完成后,如果板子上的LED不断闪缩就说明真的移植成功了。
接着是HAL库的移植演示(参考文章:stm32f103C8移植华为LiteOS - 哔哩哔哩)
其实过程和标准库差不多,首先使用STM32CubeMX创建MDK工程,具体创建过程就不演示了,不会的可以自己上网搜索欧,可以参考这篇文章:http://t.csdnimg.cn/LghQB
同上面标准库所说的LiteOS需要接管系统滴答和系统中断一个道理,华为OS系统本身使用了两个中断,如果在裸机中在设置这两个中断就会报错,因此需要去掉。
创建完成MDK工程后,
打开文件管理
首先添加“Middlewares/LiteOS/kemel”、“Middlewares/LiteOS/arch”这两个文件夹(文件夹名字随意,只要添加对的文件,名字是无所谓的,最好是规范的),在“Middlewares/LiteOS/arch”这个文件夹下面添加以下文件:(下面是文件所在的路径)
Middlewares\LiteOS\arch\arm\arm-m\cortex-m3\keil\los_dispatch_keil.S
Middlewares\LiteOS\arch\arm\arm-m\src\los_hw.c
Middlewares\LiteOS\arch\arm\arm-m\src\los_hw_tick.c
Middlewares\LiteOS\arch\arm\arm-m\src\los_hwi.c
在“Middlewares/LiteOS/kemel”这个文件夹下添加以下文件:(下面是文件所在的路径)
-
Middlewares\LiteOS\kernel\los_init.c
Middlewares\LiteOS\kernel\base\core 下面全部 .c 文件
Middlewares\LiteOS\kernel\base\ipc 下面全部 .c 文件
Middlewares\LiteOS\kernel\base\mem\bestfit_little 下面全部 .c 文件
Middlewares\LiteOS\kernel\base\mem\common 下面全部 .c 文件
Middlewares\LiteOS\kernel\base\mem\membox 下面全部 .c 文件
Middlewares\LiteOS\kernel\base\misc 下面全部 .c 文件
Middlewares\LiteOS\kernel\base\om 下面全部 .c 文件
Middlewares\LiteOS\kernel\extended\tickless 下面全部 .c 文件
-
添加完文件后,还需要添加文件头路径,打开魔术棒,转到C/C++选项卡
添加以下文件路径:
添加完成后,你就移植成功了,接下来是上机实验,验证是否真的移植成功了。
打开我准备的Task文件夹,里面有两个文件,都添加到MDK工程中,然后在主函数中分别添加
#include "Task.h" //添加到main.c的头中
TaskMain(); //添加到mian函数中
然后编译,没错误就烧录,如果看到PC13的LED不断闪烁就说明移植成功了。
免责声明:如有不对,以你为主。