【IoT】小白进阶之移植 LiteOS 到 STM32

简介: 移植Liteos

1、LiteOS 简介

Huawei LiteOS 是华为轻量级物联网操作系统,其体系架构如下图所示:

20190122141804157.png

Huawei LiteOS由Huawei LiteOS kernel、互联互通中间件、开放API以及安全组成:

1)Huawei LiteOS Kernel为Huawei LiteOS基础内核,属于最精简RTOS。

包括任务管理、内存管理、时间管理、通信机制、中断管理、队列管理、事件管理、定时器、异常管理等操作系统基础组件,可以单独运行;

2)Huawei LiteOS互联互通中间件,可覆盖短距(Wifi、 BT等)/广域(4G/NB-IoT)协议,可解决不同协议架构间互联互通、互操作问题;

3)Huawei LiteOS提供面向不同IoT领域的业务Profile,并以开放API的方式提供给第三方开发者;

4)Huawei LiteOS构建完备的设备侧安全、轻量级E2E传输安全能力。

1.1、LiteOS 特性

20190122142206958.png

1.2、移植环境

开发板:

可选STM32F103、 STM32F4、 STM32F7全系列芯片。

仿真器:

J-Link V9 或者ST-Link

软件环境:

主流的ARM cortex M系列微控制器集成开发环境主要有MDK、 IAR;

由于华为开发者社区已经提供IAR版本的Huawei LiteOS源码,集成开发环境为MDK5.21 ,在 MDK5 安装完成后,要让 MDK5 支持 STM32F103 的开发,还要安装 STM32F103的器件支持包: Keil.STM32F1xx_DFP.2.1.0.pack(STM32F1 系列的器件包)。

下载地址: STM32 器件包

2、源码目录结构介绍

LiteOS 下载地址:

LiteOS

新建工程目录:

在电脑上新建一个目录,这里命名为Huawei LiteOS_STM32_DEMO,将STM32的LED灯例程的文件全部拷贝到该目录下,并将Huawei LiteOSKernel源码文件夹Huawei_LiteOS也拷贝到该目录下,删除Listing、 Output两个文件夹,并将Project文件夹目录下面的文件全部删除。

源码中共有 6 个目录,移植需要使用到的代码在下面用红色标记:

/arch/arm/arm-m M核中断、调度、tick相关代码

     /common    arm核公用的cmsis core接口(这个可以在keil直接设置)

/components/cmsis LiteOS提供的cmsis os接口实现

       /connectivity/agent_tiny         agent_tiny端云互通组件
                    /lwm2m              lwm2m协议实现
       /net/lwip_port                   lwip驱动及OS适配代码
           /lwip-2.0.3                  lwip协议实现
      /security/mbedtls/mbedtls_port    MBEDTLS的OS适配代码
                       /mbedtl-2.6.0    MBEDTLS协议实现

/doc 此目录存放的是LiteOS的使用文档和API说明等文档
/examples 供开发者测试LiteOS内核的demo示例,此目录存放的是内核功能测试用的相关用例的代码
/kernel/base/core LiteOS基础内核代码,包括队列、task调度、软timer、时间片计算等功能

        /om                 与错误处理相关的文件
        /include            LiteOS内核内部使用的头文件
        /ipc                LiteOS中task间通讯的相关接口,包括事件、信号量、消息队列、互斥锁等
        /mem                LiteOS中的内核内存管理的相关代码
        /misc               内存对齐功能以及毫秒级休眠sleep功能
   /extended/tickless       低功耗框架代码
   /include                 LiteOS开源内核头文件

/targets 不同内核的板端工程代码(含原厂芯片驱动)
由于这里移植的是stm32f1,系统中需要使用到配置文件,在移植时需要复制以下目录中的三个头文件:

/targets/STM32F103RB_NUCLEO/OS_CONFIG/(los_builddef.h, los_printf.h, target_config.h)

/targets/STM32F103RB_NUCLEO也将作为的例程工程进行移植的参考和学习。

3、建立工程

工程可分为三个文件夹 Libraries、Project 和 User。

Libraries 存放的是 stm32 的标准库文件,包括源文件和头文件。

Project存放的是工程相关的文件;

User文件夹下包括了main.c,自己写的bsp,以及移植系统需要用到的源码文件。

若使用到stm32的库函数,则需要添加"stm32f10x_conf.h"这一头文件,并在工程中定义宏“USE_STDPERIPH_DRIVER”和"STM32F10X_HD"。

4、修改启动文件和 .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

}
}
5、配置参数和任务

在 los_config.h 中修改相应参数:

常用参数如下,这里示例采用的是STM32F103芯片,因此将OS_SYS_CLOCK设为系统主频72Mhz。

DEFINE OS_SYS_CLOCK 72000000

DEFINE LOSCFG_BASE_CORE_TSK_LIMIT 15

DEFINE OS_SYS_MEM_SIZE 0X00008000

DEFINE LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE SIZE(0X2D0)

DEFINE LOSCFG_BASE_CORE_SWTMR_LIMIT 16

内核代码移植完毕后,main()函数就可以跑起来了。贴出用来测试的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;
}

}

卫朋

人人都是产品经理受邀专栏作家,CSDN 嵌入式领域新星创作者、资深技术博主。2020 年 8 月开始写产品相关内容,截至目前,人人都是产品经理单渠道阅读 56 万+,鸟哥笔记单渠道阅读200 万+,CSDN 单渠道阅读 210 万+,51CTO单渠道阅读 180 万+。

卫朋入围2021/2022年人人都是产品经理平台年度作者,光环国际学习社区首批原创者、知识合作伙伴,商业新知 2021 年度产品十佳创作者,腾讯调研云2022年达人榜第三名。

文章被人人都是产品经理、CSDN、华为云、运营派、产品壹佰、鸟哥笔记、光环国际、商业新知、腾讯调研云等头部垂直类媒体转载。文章见仁见智,各位看官可策略性选择对于自己有用的部分。

相关文章
|
缓存 Java C语言
嵌入式 LVGL移植到STM32F4
嵌入式 LVGL移植到STM32F4
|
14天前
|
存储
【TFT彩屏移植】STM32F4移植1.8寸TFT彩屏简明教程(二)
【TFT彩屏移植】STM32F4移植1.8寸TFT彩屏简明教程(二)
|
14天前
|
存储 芯片
【TFT彩屏移植】STM32F4移植1.8寸TFT彩屏简明教程(一)
【TFT彩屏移植】STM32F4移植1.8寸TFT彩屏简明教程(一·)
|
6月前
|
消息中间件 Web App开发 API
FreeRTOS介绍 和 将FreeRTOS移植到STM32F103C8T6
FreeRTOS介绍 和 将FreeRTOS移植到STM32F103C8T6
FreeRTOS介绍 和 将FreeRTOS移植到STM32F103C8T6
|
3月前
|
传感器
手把手在STM32F103C8T6上构建可扩展可移植的DHT11驱动
【8月更文挑战第29天】本文详细介绍在STM32F103C8T6上构建可扩展且可移植的DHT11温湿度传感器驱动的步骤,包括硬件与软件准备、硬件连接、驱动代码编写及测试。通过这些步骤,可根据实际项目需求优化和扩展代码。
|
4月前
|
数据安全/隐私保护
STM32CubeMX U8g2移植
STM32CubeMX U8g2移植
79 12
|
6月前
|
C语言
【STM32 CubeMX】移植u8g2(一次成功)
【STM32 CubeMX】移植u8g2(一次成功)
564 0
STM32CubeIDE移植ARM DSP库
STM32CubeIDE移植ARM DSP库
|
API 芯片
嵌入式 STM32 实现STemwin移植+修改其配置文件,驱动LCD显示文本 (含源码,建议收藏)
嵌入式 STM32 实现STemwin移植+修改其配置文件,驱动LCD显示文本 (含源码,建议收藏)