Huawei_LiteOS——STM32F1移植(野火开发板)

举报
i小龙 发表于 2018/11/29 13:22:15 2018/11/29
【摘要】 介绍了一种Huawei_LiteOS移植到STM32F103的一种方法。

硬件环境:秉火STM32F1

软件环境:Keil 5

Huawei_LiteOS Version:2018.11.21

源代码下载地址:

github:https://github.com/LiteOS/LiteOS

移植代码分享(包含源码):

rar:https://download.csdn.net/download/sinat_27066063/10809185


1.  源码文件及目录介绍

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

11.png

/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也将作为的例程工程进行移植的参考和学习。


2.  建立工程

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

  • Libraries存放的是stm32的库文件,包括源文件和头文件;

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

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

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

12.png

13.png

main.c文件中的main()函数暂时先不做任何工作。最后在工程中添加所有使用到的头文件的目录。

14.png


工程选项中勾选C99mode,否则有些语法编译时无法通过。

15.png


target_config.h文件的头文件中,将#include "stm32f1xx.h"更改为#include "stm32f10x.h"。

16.png

在完成上面的工作后,编译会生成两个错误:

17.png

值得一提的是,对例程工程进行编译,发现例程中的工程编译后是0警告,而自己移植后的工程编译出现了8个警告,明明是相同的文件,怎么会这样呢?参考:keil中忽略特定警告的方法,例程工程将警告全部忽略掉了。


3.  修改启动文件和.sct文件

移植中的启动文件和sct文件对比源码的例程工程并没有进行大幅度的修改简化,保证程序运行的稳定性。但是这两个文件相比较于裸机工程修改的幅度还是很大的,sct文件添加了若干个加载域进行分散加载,启动文件也进行了大规模的修改,以后有机会进行深入的分析,在本文中则不进行讨论,因为涉及到的知识范围太大了。本文侧重于移植的有效性。

(之前我也尝试过不使用例程工程给的这两个文件,自己来编写,能力有限,实在是办不到,浪费了很多时间,太打击了)

在例程工程中的启动文件中,与裸机的启动文件不同,使用符号"Image$$ARM_LIB_STACKHEAP$$Base",合并的堆栈/堆区的方法,对堆栈进行划分,并定义了了LOS_HEAP_ADDR_END和LOS_HEAP_ADDR_START两个地址变量。而原来的启动文件是将堆栈分开进行设置的。另外,例程工程中的启动文件将中断向量表省略,改成了"boot向量表",缩减了很多,只存有栈指针和Reset_Handler,而将其他的中断向量成员的定义工作完成在"los_hwi.c"文件中,因此sct也随之变动。本人觉得这里相比于ucos实在是麻烦的多,不知道为什么要这么修改。


启动文件的代码如下:

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.  完善main()函数

内核代码移植完毕后,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;
    }
}

实验结果可以看到灯blingbling的闪,闪~闪~闪~

至此,移植工作及测试全部结束。



【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。