small rtos 是陈明计先生根据51机器的特点,专门写的少内存专用rtos。源代码公开,支持抢占式切换,总是运行优先级最高的任务。中断嵌套可以255层。下面逐步分析这个专用的rtos。
首先,作者推荐了一种编程技巧,那就是专门写一个点H文件,把需要包含的内容和定义的内容都放在这个头文件里。例如。
/********************************/
/* "以下为系统配置" */
/********************************/
#pragma REGPARMS
#include <reg52.h>
#include <intrins.h>
#include <absacc.h>
#define const code
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
像TRUE和FALSE这样的数值在程序中直接用文字代替。然后作者定义了几个头文件。例如:
/* "操作系统定义" */
#include "OS_CFG.H"
#include "OS_CPU.H"
#include "..\os\OS.H"
#include "..\os\OS_Q.h"
#include "..\os\OS_SEM.h"
这样把操作系统需要的所有的文件都包括在里面了。第三部分就是声明一些函数,自己要写的函数都放在这里。
以上说了作者推荐的写作技巧,和"config.h"的常用内容。
下面分项说说系统定义的这些头文件。
一、OS_CFG.H
? ? ? 从名称可以猜出个大概,OS开头的是系统头文件。cfg是config的缩写。意思就是关于系统的配置头文件。实际就是small RTOS的配置文件。
二、OS_CPU.H
? ? 这个头文件定义了一些与CPU有关的宏和常量。不同的cpu,宏和常量有可能不同,在做系统移植的时候要调整这个文件内容。
以上两条是config.h必须要包含的内容。先说OS_CFG.H
#define OS_MAX_TASKS 3 /* 最大任务数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)查询信号量 */
if EN_TIMER_SHARING == 0
#define TIME_ISR_TASK_ID SHOW_TASK_ID /* 定义系统定时器软中断触发的任务ID */
#endif
#ifdef IN_OS_CPU_C
#if EN_USER_TICK_TIMER > 0
extern void UserTickTimer(void); /* 系统定时中断中调用的用户函数 */
#endif
#endif
这是OS_CFG.H的全部内容。这些内容陈明计先生在注释里写得非常清楚了,就不逐个讲解了。
再说第二个OS_CPU.H
#ifdef __C51__
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位整数关键字 /
#ifndef NULL
#define NULL 0
#endif
为了编程方便和为了跟标准C配套,定义了一些常用的数据类型。用来保证移植性,当然作者是为了适应大部分使用者来写的,每个人可以根据自己实际的的编译器重新定义。
OS_CPU.H中还定义了一些宏,留待第二个内容讲解。