当前位置:首页 > > 嵌入式云IOT技术圈
[导读]Micrium Software提供了RTOS解决方案系列,俗称ucos全家桶,其中最为出名的就是ucOS-II 和ucOS-III,于2016年成为Silicon Labs的一部分。

一、uc/OS全家桶

1. Micrium Software

Micrium Software提供了 RTOS 解决方案系列,俗称ucos全家桶,其中最为出名的就是 ucOS-II 和ucOS-III,于 2016 年成为 Silicon Labs 的一部分。

2. μc/OS RTOS & stacks

ucos整条产品线非常丰富,常用的组件都有,官方叫做 μc/OS RTOS & stacks,民间叫做ucos全家桶。

作为一个上过火星的老牌RTOS,找机会体验一下还是很爽的,ucos全家桶中提供了非常丰富的内容。

目前ucos全家桶中的产品大多数已经在github开源,遵循 Apache-2.0 开源许可,开源地址在:

https://github.com/SiliconLabs

3. ucos内核选择

玩全家桶之前,肯定要先把RTOS内核玩起来,关于选择ucos-II还是ucos-III是个老生长谈的问题,上图解决:

4. uc/OS-III源码下载

uc/OS-III系统分为了三个开源仓库,要分别拉取。

① uC-OS3:

git clone https://github.com/SiliconLabs/uC-OS3.git

② uC-CPU:

git clone https://github.com/SiliconLabs/uC-CPU.git

③ uC-LIB:

git clone https://github.com/SiliconLabs/uC-LIB.git

二、移植前的准备

本文中使用的开发板为小熊派IoT开发板,主控为STM32L431RCT6:

本文使用的开发工具是MDK 5.30版本,编译器版本为ARMCC5。

移植之前使用STM32CubeMX生成一份裸机工程,保证可以使用printf在串口正常打印。

三、移植uc/OS-III

1. 复制ucos内核文件到工程中

这里我全都复制过来,后续可以将未添加到MDK中的文件删除。

在工程下新建 ucOS-III 文件夹,存放ucOS-III相关文件。

① 复制ucos内核文件夹过来:

② 复制uC-CPU和uC-LIB两个文件夹过来:

2.添加文件到MDK工程

① 添加 ucos-iii/ports 分组,添加 Ports\ARM-Cortex-M\ARMv7-M 目录下的os_cpu_c.c文件,以及该目录下ARM目录下的os_cpu_a.asm文件和 os_cpu_c.c文件:② 添加 ucos-iii/source分组,添加Source文件夹下的所有c文件(除去__dbg_uCOS-III.c):③ 添加uC-LIB分组,添加uC-LIB文件夹下的4个c文件:④ 添加uC-CPU分组,添加uC-CPU下的相关文件,如图:⑤ 添加 ucos-iii/config 分组,添加配置文件,如下:

  • lib_cfg.h:uC-LIB\Cfg\Template
  • os_cfg.h:Cfg\Template
  • cpu_cfg.h:uC-CPU\Cfg\Template

3. 添加头文件路径到工程中

4. 修改配置文件

① 修改 cpu_cfg.h,配置本工程所使用内核中CPU的NVIC优先级位数:

② 修改 os_cfg.h,关闭系统中 APP HOOKS 功能:

5. 处理中断

RTOS中内核得以运行需要两个中断:

  • 在pendSV异常处理中进行任务切换
  • 在systick异常处理中进行内核时钟处理

首先包含进来ucos的头文件,修改 stm32l4xx_it.c 文件,在头文件添加:

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "os.h"
/* USER CODE END Includes */

① 处理pendSV异常,如下:

/**
  * @brief This function handles Pendable request for system service.
  */

void PendSV_Handler(void)
{
  /* USER CODE BEGIN PendSV_IRQn 0 */
   OS_CPU_PendSVHandler();

  /* USER CODE END PendSV_IRQn 0 */
  /* USER CODE BEGIN PendSV_IRQn 1 */

  /* USER CODE END PendSV_IRQn 1 */
}

② 处理Systick异常,如下:

/**
  * @brief This function handles System tick timer.
  */

void SysTick_Handler(void)
{
 /* USER CODE BEGIN SysTick_IRQn 0 */
 
 /* USER CODE END SysTick_IRQn 0 */
 HAL_IncTick();
 /* USER CODE BEGIN SysTick_IRQn 1 */
 OS_CPU_SysTickHandler();
 
 /* USER CODE END SysTick_IRQn 1 */
}

至此,移植完成。

四、测试系统调度和延时

在main.c中按照如下过程编写测试代码。

① 引入ucos头文件:

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include 
#include "os.h"
/* USER CODE END Includes */

② 定义任务栈、任务控制块、任务入口函数:

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
static  OS_TCB   Task1TCB;
static  CPU_STK  Task1Stk[512];

static void Task1_entry(void *p_arg)
{
 OS_ERR  err;
    
 (void)p_arg;
    
 while(1)
 {
        printf("task1 is running...\r\n");
     OSTimeDly(1000, OS_OPT_TIME_DLY, &err);  
 }   
}


static  OS_TCB   Task2TCB;
static  CPU_STK  Task2Stk[512];

static void Task2_entry(void *p_arg)
{
 OS_ERR  err;
    
 (void)p_arg;
    
 while(1)
 {
        printf("task2 is running...\r\n");
     OSTimeDly(1000, OS_OPT_TIME_DLY, &err);  
 }   
}


/* USER CODE END PV */

③ 在main函数中定义错误值变量:

  /* USER CODE BEGIN 1 */
    OS_ERR  err;
  /* USER CODE END 1 */

④ 在main函数中初始化内核、创建两个任务、启动内核:

/* USER CODE BEGIN 2 */
printf("uc/OS-III Port On BearPi Board By Mculover666\r\n");

/* 初始化 uc/OS 内核 */
OSInit(&err); 

/* 创建task1 */
OSTaskCreate((OS_TCB       *)&Task1TCB,         //任务控制块指针           
             (CPU_CHAR     *)"Task 1",          //任务名称
             (OS_TASK_PTR   )Task1_entry,       //任务入口函数
             (void         *)NULL,              //任务入口函数的参数
             (OS_PRIO       )2,                 //任务优先级
             (CPU_STK      *)&Task1Stk[0],      //任务栈地址
             (CPU_STK_SIZE  )512 / 10,          //任务栈监测区大小
             (CPU_STK_SIZE  )512,               //任务栈大小
             (OS_MSG_QTY    )0,                 //任务支持接受的最大消息数
             (OS_TICK       )0,                 //时间片 */
             (void         *)0,                 //堆栈空间大小  
             (OS_OPT        )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
 /*
 OS_OPT_TASK_STK_CHK      使能检测任务栈,统计任务栈已用的和未用的
 OS_OPT_TASK_STK_CLR      在创建任务时,清零任务栈
 */
  
             (OS_ERR       *)&err);

/* 创建task2 */
OSTaskCreate((OS_TCB       *)&Task2TCB,   
             (CPU_CHAR     *)"Task 2",
             (OS_TASK_PTR   )Task2_entry,
             (void         *)0,
             (OS_PRIO       )3,
             (CPU_STK      *)&Task2Stk[0],
             (CPU_STK_SIZE  )512 / 10,
             (CPU_STK_SIZE  )512,
             (OS_MSG_QTY    )0,
             (OS_TICK       )0,
             (void         *)0,
             (OS_OPT        )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
             (OS_ERR       *)&err);

/* 启动内核 */
OSStart(&err);

(void)&err;

/* USER CODE END 2 */

⑤ 编译,下载,在串口助手中查看输出:接下来就可以愉快的去玩uc/OS-III内核啦~还可以玩玩全家桶,go go go!

接收更多精彩文章及资源推送,欢迎订阅我的微信公众号:『mculover666』。

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭