基于STM32使用HAL库手把手移植华为LiteOS系统并使用CMSIS接口API
目录
- 基于STM32使用HAL库手把手移植华为LiteOS系统并使用CMSIS接口API
- (一)说明
- (二)裸机工程创建
- (三)移植LiteOS
- (四)系统运行测试
- 1、原始LiteOS-API测试
- 2、CMSIS-API测试
(一)说明
本章节实验工程源码下载:https://github.com/wowyyy/HAL_STM32_LiteOS_Demo
华为LiteOS内核源码下载地址:https://github.com/LiteOS/LiteOS,选择develop分支下载。
(二)裸机工程创建
使用STM32CubeMX创建裸机工程:
这里我是用的芯片是STM32F103RBT6,时钟主频为72MHz,配置时钟树:
配置调试串口1:
配置两个LED灯:
由于LiteOS使用系统嘀嗒定时器当作心跳,HAL库也使用了这个定时器,所以我们将HAL库的定时器改为其他,这里我该为了定时器4:
配置中断,这里我选择了组4,也就是全部为抢占优先级:
取消掉以下两个中断服务函数的生成,因为ListOS已经实现了这两个函数:
最后输出工程即可!
(三)移植LiteOS
下载解压LiteOS,文件目录如下:
文件目录说明:
- arch:这个文件夹与平台有关,我们这里的平台是ARM
- components:这是一些组件,例如fatfs文件系统、mqtt协议栈等
- kernel:内核文件
- osdepends:CMSIS的API接口,如果系统需要使用CMSIS接口,那么需要移植这里面的文件
- targets:各个不同平台的示例工程
我们需要的文件有:
-
LiteOS-develop\arch\arm\arm-m\cortex-m3\keil\los_dispatch_keil.S
(注:因为我使用的是STM32F1系列是M3内核所以选择cortex-m3文件夹下的,如果是F4系列那么就是M4内核应该选择cortex-m4文件夹下的文件) -
LiteOS-develop\arch\arm\arm-m\src
目录下全部源文件 -
LiteOS-develop\kernel\base\core
目录下全部源文件 -
LiteOS-develop\kernel\base\ipc
目录下全部源文件 -
LiteOS-develop\kernel\base\mem\bestfit_little
目录下全部源文件 -
LiteOS-develop\kernel\base\mem\common
目录下全部源文件 -
LiteOS-develop\kernel\base\mem\membox
目录下全部源文件 -
LiteOS-develop\kernel\base\misc
目录下全部源文件 -
LiteOS-develop\kernel\base\om
目录下全部源文件 -
LiteOS\kernel\extended\tickless
目录下全部源文件 -
LiteOS\kernel\los_init.c
- 拷贝示例工程下的
OS_CONFIG
目录下的头文件 (此目录是在示例工程LiteOS-develop\targets\STM32F103VET6_NB_GCC\OS_CONFIG
中)
在Keil中添加源码,如下图所示:
添加头文件包含,如下图所示:
- 修改
OS_CONFIG/target_config.h
文件,找到BOARD_SRAM_SIZE_KB
宏,此宏定义了SRAM(内存)的大小,STM32F103RB是20K,所以此处改为20。 - 修改宏
LOSCFG_PLATFORM_HWI
为NO。此宏控制着系统中断的管理方式,为NO表示系统中断不被系统管理,为YES表示系统接管中断。STM32的中断管理已经很好了不需要系统接管。
(四)系统运行测试
1、原始LiteOS-API测试
这里创建了三个任务:
- led1灯间隔1s反转电平
- led2灯间隔300ms反转电平
- print每隔2s串口打印任务
int fputc(int ch, FILE* fp)
{
while(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TXE) != SET);
huart1.Instance->DR = ch & 0XFF;
return ch;
}
void* led1_task(UINT32 arg)
{
for(;;)
{
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
LOS_TaskDelay(1000);
}
}
void* led2_task(UINT32 arg)
{
for(;;)
{
HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
LOS_TaskDelay(300);
}
}
void* print_task(UINT32 arg)
{
for(;;)
{
PRINTK("Hello LiteOS !\r\n");
LOS_TaskDelay(2000);
}
}
UINT32 led1_task_handle;
UINT32 led2_task_handle;
UINT32 print_task_handle;
int main(void)
{
TSK_INIT_PARAM_S task_param;
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
LOS_KernelInit();
task_param.pcName = "led1_task";
task_param.pfnTaskEntry = led1_task;
task_param.uwStackSize = 512;
task_param.usTaskPrio = 4;
if(LOS_TaskCreate(&led1_task_handle, &task_param) != LOS_OK)
{
PRINT_ERR("create led1 task failed!\r\n");
}
task_param.pcName = "led2_task";
task_param.pfnTaskEntry = led2_task;
task_param.uwStackSize = 512;
task_param.usTaskPrio = 4;
if(LOS_TaskCreate(&led2_task_handle, &task_param) != LOS_OK)
{
PRINT_ERR("create led2 task failed!\r\n");
}
task_param.pcName = "print_task";
task_param.pfnTaskEntry = print_task;
task_param.uwStackSize = 512;
task_param.usTaskPrio = 4;
if(LOS_TaskCreate(&print_task_handle, &task_param) != LOS_OK)
{
PRINT_ERR("create print task failed!\r\n");
}
LOS_Start();
for(;;)
{
}
}
2、CMSIS-API测试
由于使用CMSIS接口,那么只需要包含头文件#include "cmsis_os.h"
即可:
示例代码:
osThreadId_t LED0TaskHandle;
const osThreadAttr_t LED0Task_attributes = {
.name = "led0task",
.priority = (osPriority_t) osPriorityNormal,
.stack_size = 128 * 4
};
void LED0TaskEntry(void* arg);
osThreadId_t LED1TaskHandle;
const osThreadAttr_t LED1Task_attributes = {
.name = "led1task",
.priority = (osPriority_t) osPriorityNormal,
.stack_size = 128 * 4
};
void LED1TaskEntry(void* arg);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
// 初始化内核
osKernelInitialize();
// 创建LED0任务
LED0TaskHandle = osThreadNew(LED0TaskEntry, NULL, &LED0Task_attributes);
// 创建LED1任务
LED1TaskHandle = osThreadNew(LED1TaskEntry, NULL, &LED1Task_attributes);
// 启动内核调度
osKernelStart();
while (1)
{
}
}
void LED0TaskEntry(void* arg)
{
for(;;)
{
HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);
osDelay(300);
}
}
void LED1TaskEntry(void* arg)
{
for(;;)
{
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
osDelay(1000);
}
}
ends…