文章目录
前言
在stm32h743上移植华为liteos-m,执行一个任务:LED灯闪烁
一、移植前准备工作
1. CubeMX配置工程模板
可以使用任意一个工程,只要keil编译没有错误的完整的project文件就可以。
2. LiteOS-m源代码
华为LiteOS-M是华为面向物联网(IoT)领域开发的一个基于实时内核的轻量级操作系统,它是华为物联网操作系统Huawei LiteOS的重要组成部分,也是鸿蒙体系的核心内核之一。LiteOS-M具有小体积、低功耗、高性能的特点,专为满足物联网设备对资源限制和高效运行的需求而设计。
2.1 主要特点
轻量级:LiteOS-M的代码结构简洁,体积小巧,能够节省宝贵的物联网设备资源。
实时性:作为实时操作系统(RTOS),LiteOS-M提供了高效的任务调度和实时响应能力,确保设备能够快速处理各种事件。
低功耗:支持tickless机制,减少不必要的系统时钟中断,从而降低功耗,延长设备续航时间。
可扩展性:提供了丰富的内核组件和接口,支持用户根据需求进行裁剪和扩展,以满足不同物联网设备的需求。
安全性:集成了多种安全机制,如LwM2M、CoAP、mbedtls、LwIP等IoT互联协议栈,以及AgentTiny模块,为设备与云平台的连接提供安全保障。
内核功能
LiteOS-M的内核功能强大,主要包括以下几个方面:
任务管理:支持任务的创建、删除、挂起、恢复、延时等操作,提供多任务并发执行的能力。
内存管理:提供多种内存分配方式,如静态内存池、动态内存分配等,以满足不同场景下的内存使用需求。
时间管理:提供高精度的时间管理功能,包括系统时钟、定时器、时间片等,确保任务能够按时执行。
通信机制:支持多种通信方式,如信号量、消息队列、互斥锁等,方便任务之间的同步和通信。
中断管理:提供灵活的中断管理功能,支持中断的嵌套和优先级调整,确保设备能够及时响应外部事件。
2.2 架构与适配
LiteOS-M的架构分为硬件相关层和硬件无关层,其中Kernel Arch模块属于硬件相关层,提供了统一的硬件抽象层(HAL)接口,增强了硬件的适配性。LiteOS-M已经支持多种主流的CPU体系架构,如ARM Cortex-M系列(M3、M4、M7、M33等)和RISC-V等,用户可以根据具体的硬件平台选择相应的架构进行适配。
2.3 应用场景
LiteOS-M广泛应用于各类物联网设备中,如智能家居、智慧城市、工业控制、可穿戴设备等。通过LiteOS-M的引入,这些设备能够实现更高效、更可靠、更安全的运行,为用户提供更好的使用体验。
华为LiteOS-M是一款专为物联网设备设计的轻量级实时操作系统,具有体积小、功耗低、性能高、可扩展性强等特点,是物联网设备开发的重要工具之一。
3. STM32H743
STM32H743是意法半导体(STMicroelectronics)推出的一款高性能微控制器,它基于ARM Cortex-M7内核,具有出色的处理能力和丰富的外设接口,广泛应用于工业自动化、智能电网、医疗设备等领域。以下是对STM32H743的详细介绍:
3.1 核心性能
内核:STM32H743采用ARM Cortex-M7内核,这是一种高性能的微控制器内核,具有6级流水线、浮点运算单元和高效的指令集,能够实现更高的处理能力和更低的功耗。
主频:STM32H743的最高时钟频率可达400MHz(也有资料提到STM32H743/753系列可达480MHz,但具体到STM32H743型号,一般以其官方数据为准,即400MHz)。在高频率下,它能够提供出色的处理速度,满足复杂应用的需求。
3.2 存储器配置
闪存(Flash):STM32H743集成了大容量闪存存储器,容量通常在512KB至2MB之间,可以存放大量的应用程序和固件,满足不同存储需求。
静态随机存取存储器(SRAM):它还配备了大容量的SRAM存储器,容量通常在128KB至1MB之间,可用于存储变量、堆栈和数据缓冲区,确保数据的高速访问和处理。
3.3 外设接口
STM32H743支持多种外设接口,以满足不同应用的需求:
通用输入/输出(GPIO):用于连接外部设备和传感器。
串行通信接口:包括通用串行接口(USART)、串行外设接口(SPI)、I2C等,用于与其他设备进行通信。
定时器和计数器:用于生成精确的定时信号和进行时间测量。
模数转换器(ADC)和数模转换器(DAC):用于模拟信号的采集和输出。
以太网接口:用于实现网络通信。
USB接口:用于与计算机和外部设备进行数据交换。
此外,STM32H743还支持其他多种外设,如摄像头接口、快速JPEG编码和解码器等,进一步扩展了其应用范围。
3.4 功耗与安全性
功耗管理:STM32H743支持多电源域架构,可实现低功耗模式,优化功率效率。在运行模式下,其典型功耗较低;在待机模式下,功耗更低,适合对功耗有严格要求的应用场景。
安全性:STM32H743包含安全加密特性,如加密/哈希硬件加速、支持安全固件安装(SFI)等,保护用户的软件IP和数据安全。
3.5 应用示例与开发支持
STM32H743广泛应用于各种领域,如工业自动化控制、智能电网设备、医疗设备、汽车电子系统等。为了支持开发者更好地使用STM32H743,意法半导体提供了丰富的开发工具和资源,包括开发板、软件库、示例代码等。此外,还有大量的第三方开发社区和论坛提供技术支持和解决方案分享。
STM32H743是一款功能强大、性能卓越的高性能微控制器,其丰富的外设接口和出色的处理能力使其成为众多领域的理想选择。
二、Keil工程文件
- 自行百xxx按照流程配置CubeMX,生成工程文件,编译文件没有任何毛病。
- 找一个template工程文件,编译工程没有毛病的就可以。
三、LiteOS-m源代码
获取Liteos源代码,可以使用如下仓库:
lios-m-dev-deserted
里面是这样的:
自己down下来。
四、移植工作
4.1 Liteos文件夹
首先新建一个Liteos文件:
里面新建四个文件夹
这几个文件夹的作用如下:
arch:编译器启动文件
cmsis:存放 CMSIS-RTOS 接口文件
kernel:存放 LiteOS 内核源码
OS_Config:存放内核配置文件,用于配置和裁剪内核
4.2 arch
复制arch文件夹,只保留里面arm文件夹
arm-m下面是不同arm架构的文件
4.3 cmsis
把components/cmsis里面的文件复制到Liteos/cmsis里面
4.4 kernel
把源码中kernel的文件全部复制到Liteos/kernel中
4.5 OS_CONFIG
找到源码中的targets,里面有Liteos适配的不同开发板,可以看出里面主要用到的就是OS_CONFIG,找到targets/Standard_STM32F746ZG_NUCLEO/OS_CONFIG,复制里面的三个文件到Liteos/OS_CONFIG里面。
los_builddef.h 用于设置构建的定义;
los_printf.h 用于设置串口打印配置;
target_config.h 可以用于裁剪系统内核
简单的把三个文件和其他的架构的对比了一下,最主要的区别就是target_config.h ,它里面会根据不同的芯片区进行开关部分宏,来使能某些功能。里面可以配置接管中断和非接管中断。
至此,所需要的文件全部移到对应的文件夹中,接下来进行调试工程。
五、调试工程
- 在工程管理中新建四个文件夹
- 在arch中添加这四个文件
其中los_dispatch_keil.S文件在
另外三个文件在
- 在cmsis中添加这个文件
该文件在
- 在kernel中添加这些文件
就是把kernel下的所有.c文件都加入到文件夹里面
注意此处事假这三个文件夹里面的文件
5. 在config中加入
为了方便改配置。
- 修改target_config.h中的包含头文件
- 把这俩屏蔽掉
编译no error,no warning!!!!!!!!!!!!
六、新建任务,点灯
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
/* LiteOS 头文件 */
#include "los_sys.h"
#include "los_task.ph"
/* 定义任务句柄 */
uint32_t Test1_Task_Handle;
uint32_t Test2_Task_Handle;
/* 函数声明 */
static uint32_t AppTaskCreate(void);
static uint32_t Creat_Test1_Task(void);
static uint32_t Creat_Test2_Task(void);
static void Test1_Task(void);
static void Test2_Task(void);
int main(void)
{
Cache_Enable(); //打开L1-Cache
HAL_Init(); //初始化HAL库
Stm32_Clock_Init(160,5,2,4); //设置时钟,400Mhz
delay_init(400); //延时初始化
uart_init(115200); //串口初始化
LED_Init(); //初始化LED
uint32_t uwRet = LOS_OK; //定义一个任务创建的返回值,默认为创建成功
/* LiteOS 内核初始化 */
uwRet = LOS_KernelInit();
if (uwRet != LOS_OK)
{
return LOS_NOK;
}
uwRet = AppTaskCreate();
if (uwRet != LOS_OK)
{
return LOS_NOK;
}
/* 开启LiteOS任务调度 */
LOS_Start();
while(1)
{
;
}
}
/*******************************************************************
* @ 函数名 : AppTaskCreate
* @ 功能说明: 任务创建,为了方便管理,所有的任务创建函数都可以放在这个函数里面
* @ 参数 : 无
* @ 返回值 : 无
*************************************************************/
static uint32_t AppTaskCreate(void)
{
/* 定义一个返回类型变量,初始化为LOS_OK */
uint32_t uwRet = LOS_OK;
uint32_t uwRet2 = LOS_OK;
uwRet = Creat_Test1_Task();
uwRet2 = Creat_Test2_Task();
if ((uwRet != LOS_OK) && (uwRet2 != LOS_OK))
{
// printf("Test1_Task任务创建失败!失败代码0x%X\n",uwRet);
return uwRet;
}
return LOS_OK;
}
/******************************************************************
* @ 函数名 : Creat_Test1_Task
* @ 功能说明: 创建Test1_Task任务
* @ 参数 :
* @ 返回值 : 无
******************************************************************/
static uint32_t Creat_Test1_Task()
{
//定义一个创建任务的返回类型,初始化为创建成功的返回值
uint32_t uwRet = LOS_OK;
//定义一个用于创建任务的参数结构体
TSK_INIT_PARAM_S task_init_param;
task_init_param.usTaskPrio = 3; /* 任务优先级,数值越小,优先级越高 */
task_init_param.pcName = "Test1_Task";/* 任务名 */
task_init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)Test1_Task;/* 任务函数入口 */
task_init_param.uwStackSize = 1024; /* 堆栈大小 */
uwRet = LOS_TaskCreate(&Test1_Task_Handle, &task_init_param);/* 创建任务 */
return uwRet;
}
/******************************************************************
* @ 函数名 : Test1_Task
* @ 功能说明: Test1_Task任务实现
* @ 参数 : NULL
* @ 返回值 : NULL
*****************************************************************/
static void Test1_Task(void)
{
/* 任务都是一个无限循环,不能返回 */
while(1)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET); //PB1置0
LOS_TaskDelay(1000);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET); //PB1置1
LOS_TaskDelay(1000);
}
}
/******************************************************************
* @ 函数名 : Creat_Test1_Task
* @ 功能说明: 创建Test1_Task任务
* @ 参数 :
* @ 返回值 : 无
******************************************************************/
static uint32_t Creat_Test2_Task()
{
//定义一个创建任务的返回类型,初始化为创建成功的返回值
uint32_t uwRet2 = LOS_OK;
//定义一个用于创建任务的参数结构体
TSK_INIT_PARAM_S task_init_param;
task_init_param.usTaskPrio = 1; /* 任务优先级,数值越小,优先级越高 */
task_init_param.pcName = "Test2_Task";/* 任务名 */
task_init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)Test2_Task;/* 任务函数入口 */
task_init_param.uwStackSize = 1024; /* 堆栈大小 */
uwRet2 = LOS_TaskCreate(&Test2_Task_Handle, &task_init_param);/* 创建任务 */
return uwRet2;
}
/******************************************************************
* @ 函数名 : Test2_Task
* @ 功能说明: Test2_Task任务实现
* @ 参数 : NULL
* @ 返回值 : NULL
*****************************************************************/
static void Test2_Task(void)
{
/* 任务都是一个无限循环,不能返回 */
while(1)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET); //PB0置0
LOS_TaskDelay(200);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET); //PB0置1
LOS_TaskDelay(200);
}
}
总结
一定一定要小心谨慎,不能够忘记加入需要的文件,仔细一个个的加入进去,不然会出现成堆的错误