📄 manual.txt
字号:
Small RTOS(51) 1.10v 使用手册
概述:
Small RTOS是一个源代码公开的多任务实时操作系统,Small RTOS 51
是其在8051系列处理器上的移植(使用keil c51)。Small RTOS可以简化那
些复杂而且时间要求严格的工程的软件设计工作.本手册主要讲述Small RTOS
的使用,本说明了在8051系列处理器上使用应该注意的问题。同时讲述了
Small RTOS的移植。
本手册仅针对Small RTOS(51) 1.10版本
Small RTOS的特点:
(1)公开源代码
只要遵循许可协议,任何人可以免费获得源代码。
(2)可移植
作者尽量使用把与CPU相关部分压缩到最小,与CPU无关部分用ansi c编
写。
(3)可固化
Small RTOS为嵌入系统设计,如果您有固化手段,它可以嵌入到您的产
品中成为产品的一部分。
(4)占先式
Small RTOS可以管理16个任务,每个任务优先级不同。
(5)中断管理
中断可以使正在执行的任务挂起。如果优先级更高的任务被中断唤醒,则
高优先级的任务在中断嵌套全部退出后立即执行。中断嵌套层数可达255
层。如果需要,可以禁止中断嵌套管理。
(6)RAM需求小
Small RTOS为小RAM系统设计,应而RAM需求小,相应的,系统服务也少。
Small RTOS的使用:
(1)系统配置:
os_cfg.h中定义了一些常量可以配置系统,具体定义如下:
#define OS_MAX_TASKS 4 /* 最大任务数1~16 */
#define OS_TICKS_PER_SEC 10 /* 设置1秒系统系统节拍数 */
#define EN_USER_TICK_TIMER 0 /* 禁止(0)或允许(1)系统定时中断调用用户函数UserTickTimer() */
#define EN_OS_INT_ENTER 1 /* 禁止(0)或允许(1)中断嵌套管理 */
#define EN_TIMER_SHARING 1 /* 禁止(0)或允许(1)定时器中断调用OSTimeTick() */
#define TICK_TIMER_SHARING 1 /* 定义进入多少次硬件中断为一次系统定时器软中断 */
#define EN_OS_Q 0 /* 禁止(0)或允许(1)消息队列 */
#define EN_OS_Q_CHK 0 /* 禁止(0)或允许(1)校验消息队列指针 */
#define OS_Q_MEM_SEL xdata /* 消息队列存储空间选择,keil c51有用,必须为idata、xdata */
/* 不是keil c51时它必须为空格 */
#define EN_OS_Q_PENT 1 /* 禁止(0)或允许(1)等待队列中的消息 */
#define EN_OS_Q_ACCEPT 0 /* 禁止(0)或允许(1)无等待的从队列中取得消息 */
#define EN_OS_Q_POST 0 /* 禁止(0)或允许(1)FIFO方式相对列发送消息 */
#define EN_OS_Q_POST_FRONT 1 /* 禁止(0)或允许(1)LIFO方式相对列发送消息 */
#define EN_OS_Q_INT_POST 0 /* 禁止(0)或允许(1)中断中FIFO方式相对列发送消息 */
#define EN_OS_Q_INT_POST_FRONT 1 /* 禁止(0)或允许(1)中断中LIFO方式相对列发送消息 */
#define EN_OS_Q_NMsgs 1 /* 禁止(0)或允许(1)取得队列中消息数 */
#define EN_OS_Q_SIZE 0 /* 禁止(0)或允许(1)取得队列总容量 */
#define EN_OS_Q_FLUSH 0 /* 禁止(0)或允许(1)清空队列 */
#define EN_OS_SEM 0 /* 禁止(0)或允许(1)信号量 */
#define EN_OS_SEM_CHK 0 /* 禁止(0)或允许(1)校验信号量索引 */
#define OS_SEM_MEM_SEL idata /* 信号量储空间选择,keil c51有用,必须为idata、xdata */
/* 不是keil c51时它必须为空格 */
#define OS_MAX_SEMS 2 /* 最大信号量数目 */
#define EN_OS_SEM_PENT 1 /* 禁止(0)或允许(1)等待信号量 */
#define EN_OS_SEM_ACCEPT 0 /* 禁止(0)或允许(1)无等待请求信号量 */
#define EN_OS_SEM_INT_POST 0 /* 禁止(0)或允许(1)中断中发送信号量 */
#define EN_OS_SEM_POST 1 /* 禁止(0)或允许(1)中发送信号量 */
#define EN_OS_SEM_QUERY 0 /* 禁止(0)或允许(1)查询信号量 */
//#define idata /* 非keil c51时必须加止这一句 */
#if EN_TIMER_SHARING == 0
#define TIME_ISR_TASK_ID SHOW_TASK_ID /* 定义系统定时器软中断触发的任务ID */
#endif
Os_cpu.h中定义了一些常量可以配置一些与cpu相关的部分。
针对Small RTOS 51,具体定义如下:
#define EN_SP2 0 /* 禁止(0)或允许(1)非屏蔽中断 */
#define IDATA_RAM_SIZE 0x100 /* idata大小 */
#define Sp2Space 4 /* 高级中断(软非屏蔽中断)堆栈大小 EN_SP2为0时无效 */
#define OS_TIME_ISR 1 /* 系统定时器使用的中断 */
//
SET_EA MACRO ;打开所有允许中断
SETB EA
ENDM
(2)与编译器无关的数据类型
为了便于移植,Small RTOS定义了6种数据类型,它在Os_cpu.h定义。
针对Small RTOS 51,具体定义如下:
typedef unsigned char uint8; /* 定义可移植的无符号8位整数关键字 */
typedef signed char int8; /* 定义可移植的有符号8位整数关键字 */
typedef unsigned int uint16; /* 定义可移植的无符号16位整数关键字 */
typedef signed int int16; /* 定义可移植的有符号16位整数关键字 */
typedef unsigned long uint32; /* 定义可移植的无符号32位整数关键字 */
typedef signed long int32; /* 定义可移植的有符号32位整数关键字 */
(3)运行Small RTOS
在main函数中调用OSStart()后系统开始运行,OSStart()结束后运行
优先级为0的任务。
注意:在调用OSStart()前不要使能总中断标志,系统会自动使能这个
标志,对于8051系列,这个标志为EA。
(4)建立任务:
Small RTOS使用静态方法建立任务,在config.h中有这样一段代码:
#ifdef IN_OS_CPU_C
extern void TaskA(void);
extern void TaskB(void);
extern void TaskC(void);
void (* const TaskFuction[OS_MAX_TASKS])(void)={TaskA,TaskB,TaskC};
//函数数组TaskFuction[]保存了各个任务初始PC指针,其按任务ID(既优先级次序)顺序保存
#endif
用户只要定义好OS_MAX_TASKS,TaskFuction[],任务将自动运行。其
中TaskA等为任务对应函数。
注意:ID为0的任务为最高优先级任务,系统运行后首先执行它。
(5)删除任务
Small RTOS 1.10版不允许删除任务,因此,每个任务必须为无限循环
结构。
(6)任务睡眠
任务可以调用OSWait()使自己睡眠,其原型如下:
unsigned char OSWait(uint8 typ, uint8 ticks);
功能描述: 系统等待函数,任务调用此函数可以等待一定时间或信号
输入: typ: 等待事件类型,目前可以取以下值,或是其中任意个值的按位或
K_SIG: 等待信号
K_TMO: 等待超时
ticks : 等待超时时的系统节拍数
输出 : NOT_OK : 参数错误
TMO_EVENT : 超时到
SIG_EVENT : 有信号
如果任务等待信号,另一个任务可以调用OSSendSignal()使其进入就
绪状态,其原型如下:
void OSSendSignal(uint8 TaskId);
功能描述: 中断中给指定任务发送信号,既使指定任务就绪
输 入: TaskId : 任务ID
输 出: 无
中断调用OSIntSendSignal()也可以唤醒睡眠任务,其原型如下:
void OSIntSendSignal(uint8 TaskId);
功能描述: 任务中给指定任务发送信号,既使指定任务就绪
输 入: TaskId : 任务ID
输 出: 无
用户调用OSQPend和OSSemPend时也可能使任务睡眠,可参见相应章节。
(7)优先级最低的任务
优先级最低的任务必须一直处于就绪状态,不允许调用OSWait等可能
使自己进入休眠状态的函数。
(8)消息队列和信号量
Small RTOS使用简化的消息队列,实质上出队入队的均为uint8类型
变量,而不是指针。消息队列和信号量的使用请参见示例及Small
RTOS的系统调用。
(9)Small RTOS 51 任务特殊处
由于keil c51由于keil c51默认不支持重入函数,它的重入函数使用
仿真的重入栈而不使用系统栈,而Small RTOS 51没有进行重入栈管
理,因此,用户应该保证各个任务的局部变量不会互相覆盖(方法后
面有介绍),并且不定义重入函数。
(10)中断程序编制
keil c51 例子如下:
#if EN_OS_INT_ENTER >0
#pragma disable /* 除非最高优先级中断或是不需要系统管理的中断,否则,必须加上这一句 */
#endif
void OSTickISR(void) interrupt USER_ISR
{
#if EN_OS_INT_ENTER >0
OS_INT_ENTER(); /* 中断开始处理 */
#endif
/*用户代码在这*/
OSIntExit(); /* 中断结束处理, */
}
在其它CPU中,#pragma disable不是必须的,但是可能需要自己在
OS_INT_ENTER()之前保存任务环境。如果某个中断不需要OS管理,
则可以自由编写。
Small RTOS的系统调用:
(1)OSVersion()
宏,返回Small RTOS版本号*100
(2)OSRunningTaskID()
宏,返回当前正在运行的任务ID
(3)OSWait()
原型:uint8 OSWait(uint8 typ, uint8 ticks);
功能描述: 系统等待函数,任务调用此函数可以等待一定时间或信号
输 入: typ: 等待事件类型,目前可以取以下值,或是其中任意个值的按位或
K_SIG: 等待信号
K_TMO: 等待超时
ticks : 等待超时时的系统嘀嗒数
输 出 : NOT_OK : 参数错误
TMO_EVENT : 超时到
SIG_EVENT : 有信号
全局变量: OSWaitTick
调用模块: OSIntSendSignal
(4)OSSendSignal()
原型:void OSSendSignal(uint8 TaskId)
功能描述: 任务中给指定任务发送信号,既使指定任务就绪
输 入: TaskId : 任务ID
输 出: 无
全局变量: OSTaskRuning
调用模块: OSSched
(5)OSIntSendSignal()
原型:void OSIntSendSignal (uint8 TaskId);
功能描述: 中断中给指定任务发送信号,既使指定任务就绪
输 入: TaskId : 任务ID
输 出: 无
全局变量: OSTaskRuning
调用模块: 无
(6)OSQCreate()
原型:uint8 OSQCreate(uint8 OS_Q_MEM_SEL *Buf, uint8 SizeOfBuf);
功能描述: 初始化消息队列
输 入: Buf:为队列分配的存储空间地址
SizeOfBuf:为队列分配的存储空间大小
输 出: NOT_OK:参数错误
OS_Q_OK:成功
全局变量: 无
调用模块: 无
(7)OSQPend()
原型:uint8 OSQPend(uint8 idata *Ret, uint8 OS_Q_MEM_SEL *Buf, uint8 Tick);
功能描述: 等待消息队列中的消息
输 入: Ret:返回的消息
Buf:指向队列的指针
Tick:等待时间
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -