UCOS-III

news/2024/11/7 22:31:41/

一、UCOSIII 简介

UCOSIII 是一个可裁剪、可固化、可剥夺的多任务系统,没有任务数目的限制,是 UCOS
的第三代内核,UCOSIII 有以下几个重要的特性:

可剥夺多任务管理UCOSIII 和 UCOSII 一样都属于可剥夺的多任务内核,总是执行当前
就绪的最高优先级任务
同优先级任务的时间片轮转调度:这个是 UCOSIII 和 UCOSII 一个比较大的区别,UCOSIII
允许一个任务优先级被多个任务使用,当这个优先级处于最高就绪态的时候,UCOSIII 就会轮
流调度处于这个优先级的所有任务,让每个任务运行一段由用户指定的时间长度,叫做时间片。
极短的关中断时间UCOSIII 可以采用锁定内核调度的方式而不是关中断的方式来保护临
界段代码,这样就可以将关中断的时间降到最低,使得 UCOSIII 能够非常快速的响应中断请求。
任务数目不受限制:UCOSIII 本身是没有任务数目限制的,但是从实际应用角度考虑,任
务数目会受到 CPU 所使用的存储空间的限制,包括代码空间和数据空间。
优先级数量不受限制:UCOSIII 支持无限多的任务优先级。
内核对象数目不受限制:UCOSIII 允许定义任意数目的内核对象。内核对象指任务、信号
量、互斥信号量、事件标志组、消息队列、定时器和存储快等。
软件定时器:用户可以任意定义“单次”和“周期”型定时器,定时器是一个递减计数器,
递减到零就会执行预先定义好的操作。每个定时器都可以指定所需操作,周期型定时器在递减
到零时会执行指定操作,并自动重置计数器值。
同时等待多个内核对象:UCOSIII 允许一个任务同时等待多个事件。也就是说,一个任务
能够挂起在多个信号量或消息队列上,当其中任何一个等待的事件发生时,等待任务就会被唤
醒。
直接向任务发送信号:UCOSIII 允许中断或任务直接给另一个任务发送信号,避免创建和
使用诸如信号量或事件标志等内核对象作为向其他任务发送信号的中介,该特性有效地提高了
系统性能。
直接向任务发送消息:UCOSIII 允许中断或任务直接给另一个任务发送消息,避免创建和
使用消息队列作为中介。
任务寄存器:每个任务都可以设定若干个“任务寄存器”,任务寄存器和 CPU 硬件寄存器
是不同的,主要用来保存各个任务的错误信息,ID 识别信息,中断关闭时间的测量结果等。
任务级时钟节拍处理:UCOSIII 的时钟节拍是通过一个专门任务完成的,定时中断仅触发
该任务。将延迟处理和超时判断放在任务级代码完成,能极大地减少中断延迟时间。
防止死锁:所有 UCOSIII 的“等待”功能都提供了超时检测机制,有效地避免了死锁。
时间戳:UCOSIII 需要一个 16 位或 32 位的自由运行计数器(时基计数器)来实现时间测
量,在系统运行时,可以通过读取该计数器来测量某一个事件的时间信息。例如,当 ISR 给任
务发送消息时,会自动读取该计数器的数值并将其附加在消息中。当任务读取消息时,可得到
该消息携带的时标,这样,再通过读取当前的时标,并计算两个时标的差值,就可以确定传递
这条消息所花费的确切时间。

二、移植文件

2.1.滴答定时器 Systick

滴答定时器是一个 24 位的倒计数定时器,当计到 0 时,将从 RELOAD 寄存器中自动重装
载定时器初值,只要不把它在 SysTick 控制以及状态寄存器中的使能位清零,就将永久不息。SysTick 的最大使命,就是定期地产生异常请求作为系统的时基。OS 都需要这种“滴答”来推动任务和时间的管理。

//初始化延迟函数
//当使用 ucos 的时候,此函数会初始化 ucos 的时钟节拍
//SYSTICK 的时钟固定为 HCLK 时钟的 1/8
//SYSCLK:系统时钟
void delay_init(u8 SYSCLK)
{
#if SYSTEM_SUPPORT_UCOS//如果需要支持 OS.u32 reload;
#endifSysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//选择外部时钟 HCLK/8fac_us=SYSCLK/8;//为系统时钟的 1/8
#if SYSTEM_SUPPORT_UCOS//如果需要支持 OS.reload=SYSCLK/8;//每秒钟的计数次数 单位为 Kreload*=1000000/delay_tickspersec;//根据 OS_TICKS_PER_SEC 设定溢出时间//reload 为 24 位寄存器,最大值:16777216,在//72M 下,约合 1.86s 左右fac_ms=1000/delay_tickspersec;//代表 ucos 可以延时的最少单位SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;//开启 SYSTICK 中断SysTick->LOAD=reload;//每 1/OS_TICKS_PER_SEC 秒中断一次SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启 SYSTICK
#elsefac_ms=(u16)fac_us*1000;//非 ucos 下,代表每个 ms 需要的 systick 时钟数
#endif

SysTick 的中断服务函数 SysTick_Handler()

//systick 中断服务函数,使用 ucos 时用到
void SysTick_Handler(void)
{if(delay_osrunning==1)//OS 开始跑了,才执行正常的调度处理{OSIntEnter();//进入中断OSTimeTick();//调用 ucos 的时钟服务程序OSIntExit();//触发任务切换软中断}
}

2.2os_cpu_a.asm 文件详解(暂且跳过,粗略看了一下)

IMPORT OSRunning
IMPORT OSPrioCur
IMPORT OSPrioHighRdy
IMPORT OSTCBCur
IMPORT OSTCBHighRdy
IMPORT OSIntNesting
IMPORT OSIntExit
IMPORT OSTaskSwHookEXPORT OSStartHighRdy
EXPORT OSCtxSw
EXPORT OSIntCtxSw
EXPORT OS_CPU_SR_Save
EXPORT OS_CPU_SR_Restore
EXPORT PendSV_Handler

2.3os_cpu.h 文件详解

typedef unsigned char BOOLEAN;
typedef unsigned char INT8U;        //无符号 8 位数
typedef signed char INT8S;          //有符号 8 位数
typedef unsigned short INT16U;      //无符号 16 位数
typedef signed short INT16S;        //有符号 16 位数
typedef unsigned int INT32U;        //无符号 32 位数
typedef signed int INT32S;          //有符号 32 位数
typedef float FP32;                 //单精度浮点数
typedef double FP64;                //双精度浮点数//STM32 是 32 位位宽的,这里 OS_STK 和 OS_CPU_SR 都应该为 32 位数据类型
typedef unsigned int OS_STK;        //OS_STK 为 32 位数据,也就是 4 字节
typedef unsigned int OS_CPU_SR;     //默认的 CPU 状态寄存器大小 32 位

//定义栈的增长方向.
//CM3 中,栈是由高地址向低地址增长的,所以 OS_STK_GROWTH 设置为 1
#define OS_STK_GROWTH 1 //堆栈增长方向
//任务切换宏,由汇编实现.
#define OS_TASK_SW() OSCtxSw()
//OS_CRITICAL_METHOD = 1 :直接使用处理器的开关中断指令来实现宏
//OS_CRITICAL_METHOD = 2 :利用堆栈保存和恢复 CPU 的状态
//OS_CRITICAL_METHOD = 3 :利用编译器扩展功能获得程序状态字,保存在局部变量 cpu_sr
#define OS_CRITICAL_METHOD 3
//进入临界段的方法#if OS_CRITICAL_METHOD == 3#define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();}#define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);}
#endif

2.4os_cpu_c.c 文件详解 

OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt)
{OS_STK *stk;(void)opt; //opt 未使用stk = ptos;// Load stack pointer*(stk) = (INT32U)0x01000000L;//xPSP*(--stk) = (INT32U)task;//PC*(--stk) = (INT32U)OS_TaskReturn; //R14*(--stk) =(INT32U)0x12121212L; //R12*(--stk) = (INT32U)0x03030303L;//R3*(--stk) = (INT32U)0x02020202L;//R2*(--stk) = (INT32U)0x01010101L;//R1*(--stk) = (INT32U)p_arg;//R0*(--stk) = (INT32U)0x11111111L; //R11*(--stk) = (INT32U)0x10101010L;//R10*(--stk) = (INT32U)0x09090909L; //R9*(--stk) = (INT32U)0x08080808L; //R8*(--stk) = (INT32U)0x07070707L; //R7*(--stk) = (INT32U)0x06060606L; //R6*(--stk) = (INT32U)0x05050505L; //R5*(--stk) = (INT32U)0x04040404L; //R4return (stk);
}


总结

简单的系统移植下载验证


http://www.ppmy.cn/news/147237.html

相关文章

手机通讯原理的工作原理

一、手机的工作原理: 一般来说,我们普通用户只要学会如何使用好手机就可以了,对于其具体的工作原理不必仔细深究;然而在使用手机的过程中,由于各种因素的影响,手机不可避免地要出现故障&#xff0c…

UCOSII

文章目录 UCOSII提出者是什么开发及特性 UCOSII结构UCOSII并发 泉水 UCOSII 提出者 UCOSII的前身是UCOS,最早出自于1992 年美国嵌入式系统专家Jean J.Labrosse 在《嵌入式系统编程》杂志的5月和6月刊上刊登的文章连载,并把UCOS 的源码发布在该杂志的 …

剑指 Offer 17. 打印从1到最大的n位数解题思路

文章目录 题目解题思路 题目 输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。 示例 1: 输入: n 1 输出: [1,2,3,4,5,6,7,8,9] 说明: 用返回一个整数列表来代替打印 n 为正…

如何将Linux命令默认的提示结果不显示或者不输出?以及在脚本中如何替代Ctrl + C等关闭命令的终端窗口?

一、问题描述: 当我们想要获取命令的输出结果时,有时候命令会带出一些默认的提示信息输出到屏幕上,如何过滤掉这个提示信息呢? 例如,telnet命令退出时会默认提示“Connection closed by foreign host.” 例如&#x…

网络原理入门知识小结

文章目录 1 模型介绍2 各层功能3 PDU4 以太网和无线网的差异5 IP地址5.1 IP地址中的特殊地址 6 OSI模型中各层涉及协议7 ARP和RARP 1 模型介绍 OSI七层模型,从下至上分别为物理层,数据链路层,网络层,传输层,会话层&am…

获TÜV莱茵认可,美的冰箱在节能和静音方面已达全球领先水平

近日,美的冰箱(型号:HD-500RWEN(A))获得德国莱茵TV大中华区(以下简称“TV莱茵”)Quality-mark能效Class A等级验证和噪音Class A等级验证认证证书。此次TV莱茵从新欧标能效及噪音两个维度对美的冰箱进行专业…

新电途与华为AITO达成充电合作;SGW和摩托罗拉完成家庭音频产品许可交易 | 美通企业日报...

美通社要闻摘要: 喜来登酒店及度假村继续在华东地区拓展。新电途与华为AITO达成充电合作。"安进生物技术体验项目"中国站正式启动。博世灵活7系吸尘器全新上市。SGW和摩托罗拉完成家庭音频产品许可交易。美的工业技术旗下GMCC美芝、Welling威灵亮相泰国暖…

diy 扫地机器人 滚刷_暴力拆解师 篇十九:跟着拍了57分钟完整记录清扫轨迹 小瓦扫地机器人规划版...

暴力拆解师 篇十九:跟着拍了57分钟完整记录清扫轨迹 小瓦扫地机器人规划版 2018-05-16 19:55:39 25点赞 53收藏 41评论 小编注:想获得更多专属福利吗?金币加成、尊享众测、专属勋章、达人福利任务你想要吗?如果想要,赶…