1、LiteOS 简介
华为的 LiteOS 以轻量级(内核小于10k)、低功耗(1节5号电池最多可以工作5年),快速启动,互联互通,安全等关键能力,为开发者提供 "一站式" 完整软件平台,有效降低开发门槛、缩短开发周期。
华为提出 1+2+1战略,即一个物联网操作系统,两种接入方式,一个平台,从而实现其使能万物智能的目标。
示意图如下:
操作系统特点及框架如下图所示:
2、建立工程
源码下载:github.com/liteos/liteos
工程可分为三个文件夹 Libraries,Project 和 User。
Libraries存放的是stm32的标准库文件,包括源文件和头文件,下载方式参考:如何从ST官网下载STM32标准库;
Project存放的是工程相关的文件;
User文件夹下包括了main.c,自己写的bsp,以及移植系统需要用到的源码文件。
若使用到stm32的库函数,则需要添加"stm32f10x_conf.h"这一头文件,并在工程中定义宏“USE_STDPERIPH_DRIVER”和"STM32F10X_HD"。
工程选项中勾选C99mode,否则有些语法编译时无法通过。
target_config.h文件的头文件中,将#include "stm32f1xx.h"更改为#include "stm32f10x.h"。
3、修改启动文件和 .sct 文件
移植中的启动文件和.sct文件对比源码的例程工程并没有进行大幅度的修改简化,保证程序运行的稳定性。
但是这两个文件相比较于裸机工程修改的幅度还是很大的,.sct文件添加了若干个加载域进行分散加载,启动文件也进行了大规模的修改。
在例程工程中的启动文件中,与裸机的启动文件不同,使用符号"Image$ $ARM_LIB_STACKHEAP$ $Base",合并的堆栈/堆区的方法,对堆栈进行划分,从而产生了LOS_HEAP_ADDR_END和LOS_HEAP_ADDR_START两个地址变量。
而原来的启动文件是将堆栈分开进行设置的。
另外,例程工程中的启动文件将中断向量表省略,改成了"boot向量表",缩减了很多,只存有堆栈和Reset_Handler,而将其他的中断向量成员的定义工作完成在"los_hwi.c"文件中,因此.sct也随之变动。
启动文件的代码如下:
Heap_Size EQU 0x00000400
AREA LOS_HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
AREA LOS_HEAP_INFO, DATA, READONLY, ALIGN=2
IMPORT |Image$$ARM_LIB_STACKHEAP$$ZI$$Base|
EXPORT __LOS_HEAP_ADDR_START__
EXPORT __LOS_HEAP_ADDR_END__
__LOS_HEAP_ADDR_START__
DCD __heap_base
__LOS_HEAP_ADDR_END__
DCD |Image$$ARM_LIB_STACKHEAP$$ZI$$Base| - 1
PRESERVE8
THUMB
AREA RESET, CODE, READONLY
IMPORT ||Image$$ARM_LIB_STACKHEAP$$ZI$$Limit||
IMPORT osPendSV
EXPORT _BootVectors
EXPORT Reset_Handler
_BootVectors DCD ||Image$$ARM_LIB_STACKHEAP$$ZI$$Limit|| ; Top of Stack
DCD Reset_Handler ; Reset Handler
; Reset handler
Reset_Handler
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ALIGN
END
.sct 文件对应启动文件的改变主要增加了两个加载域:VECTOR 和 ARM_LIB_STACKHEAP
.sct 文件代码如下:
LR_IROM1 0x08000000 0x00080000 { ; load region size_region
ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
* (LOS_HEAP_INFO)
}
VECTOR 0x20000000 0x400 { ; Vector
* (.data.vector)
}
RW_IRAM1 0x20000400 0x0000F800 { ; RW data
* (.data, .bss)
* (LOS_HEAP)
}
ARM_LIB_STACKHEAP 0x2000FC00 EMPTY 0x400 { ;LiteOS MSP
}
}
4、测试
内核代码移植完毕后,main()函数就可以跑起来了。
int main(void)
{
UINT32 uwRet = LOS_OK;
LED_Init(); //硬件驱动初始化
uwRet = LOS_KernelInit(); //OS内核初始化
if (uwRet != LOS_OK)
{
return LOS_NOK;
}
uwRet = create_task1(); //创建任务
if (uwRet != LOS_OK)
{
return LOS_NOK;
}
LOS_Start(); //启动OS
}
其中,create_task1()如下所示,主要是填满TSK_INIT_PARAM_S类型结构体,调用LOS_TaskCreate函数进行创建:
UINT32 create_task1(void)
{
UINT32 uwRet = LOS_OK;
TSK_INIT_PARAM_S task_init_param;
task_init_param.usTaskPrio = 1;//任务优先级
task_init_param.pcName = "task1";//任务名
task_init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)task1;//指定任务入口函数
task_init_param.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//设置任务堆栈大小
uwRet = LOS_TaskCreate(&g_TestTskHandle,&task_init_param);//调用任务创建函数
if(uwRet !=LOS_OK)
{
return uwRet;
}
return uwRet;
}
task1主要做的工作是指示灯的状态切换:
VOID task1(void)
{
UINT32 uwRet = LOS_OK;
while(1)
{
macLED1_TOGGLE();
uwRet = LOS_TaskDelay(1000);//操作系统延时
if(uwRet !=LOS_OK)
return;
}
}
refer:
https://blog.csdn.net/franklfeng/article/details/64437907
https://blog.csdn.net/sinat_27066063/article/details/84320579