RXT51-Tiny学习
前言
习惯了实时操作系统的多任务分模块的编写方式后,最近在在51板上写点东西,其它主流的实时系统不是太大,就是没有太多适配,看到Keil里,有为51适配的RXT51,就学习学习。
本文也参考了RTX51-Tiny 使用手册文档,只把关键常用部分介绍,更多细节可以自行查看手册。
基本介绍
RXT51-Tiny
| 产品参数 | 限制值 |
|---|---|
| 最大可定义的任务数 | 16 |
| 最大激活的任务数 | 16 |
| 需要的 CODE 空间 | 900 字节(最大) |
| 需要的 DATA 空间 | 7 字节 |
| 需要的 STACK 空间 | 3 字节/任务 |
| 需要的 XDATA 空间 | 0 字节 |
| 需要的定时器 | 定时器 0 |
| 系统时钟的机器周期数 | 1,000-65,535 |
| 中断响应时间 | 20 机器周期 (最大) |
| 上下文切换时间 | 100-700机器周期 |
事件选择器
| 事件选择 | 功能描述 |
|---|---|
| K_IVL | 等待时间间隔事件 |
| K_SIG | 等待信号事件 |
| K_TMO | 等待超时事件 |
os_wait的返回值
| 函数返回值 | 描述 |
|---|---|
| RDY_EVENT | 任务的就绪标志被设置 |
| SIG_EVENT | 收到一个信号事件 |
| TMO_EVENT | 超时事件或者时间间隔事件设定的内核时钟滴答数已经耗尽 |
通常都是在os_wait中选择事件等待,部分事件之间组合
- K_SIG | K_TMO:内核函数 os_wait 延迟当前任务的执行,一直到收到信号或者设 定的超时时间已经耗尽。
- K_SIG | K_IVL:内核函数 os_wait 延迟当前任务的执行,一直到收到信号或者设定 的间隔时间已经耗尽。
- 注意:事件选择器不能将 K_IVL 和 K_TMO 这两个事件组合在一起。
Keil5中使用
在keil5中,可以通过选项来快速配置使用RTX-51-Tiny

还有Conf_tny.A51,也是要添加进来。通常在keil5的安装目录下,Keil5 C51\C51\RtxTiny2\SourceCode,例如我的就在D:\my\Keil5 C51\C51\RtxTiny2\SourceCode,如果没有添加进来,但是按上图选择了,也是会默认链接的,但是不利于个性化修改。
功能内容
基本介绍
在RTX51 Tiny中,不需要main函数,其总是从任务0开始执行,可以在任务0中产生所有其他任务后,在将自己删除。借助Keil C51引进的关键字(_task_)用来标识任务。
void task1() _task_ 1
{
// ...
}
void task2() _task_ 2
{
// ...
}
void task3() _task_ 3
{
// ...
}
void task_init(void) _task_ 0
{
os_create_task(1); // 创建任务1
os_create_task(2); // 创建任务2
os_create_task(3); // 创建任务3
os_delete_task(0); // 删除任务0
}
基本案例
#include <STC89C5xRC.H>
#include <RTX51TNY.h>
// 封装os的延时函数--10MS为单位
void os_delay(unsigned char ms10)
{
os_wait(K_TMO,ms10,0);
}
// 任务3--控制LED
void task3_ConLed(void) _task_ 3
{
while(1)
{
if(os_wait(K_SIG,50,0) == SIG_EVENT)
{
P27 = (P27 == 0 ? 1 : 0);
}
os_delay(1);
}
}
// 任务2--按键检测
void task2_Key(void) _task_ 2
{
while(1)
{
if(P31 == 0)
{
os_delay(1);
if(P31 == 0)
{
// 确认按下,发送信号
os_send_signal(3);
// 等待回1
while(P31 == 0);
}
}
os_delay(1);
}
}
// 任务1--运行LED
void task1_RunLed(void) _task_ 1
{
while(1)
{
// 翻转
P20 = (P20 == 0 ? 1 : 0);
// 暂停当前任务500毫秒
os_delay(100);
}
}
// 任务0--初始化
void task0_Init() _task_ 0
{
os_create_task(1);
os_create_task(2);
os_create_task(3);
os_delete_task(0);
}
库函数
- 如果函数是以 os_开头的,那么可以在任务中调用,但是不能在中断函数中调用;
- _如果函数是以 isr_开始的,那么可以在中断函数里调用,但是不能在任务中调用;
char isr_send_signal(unsigned char task_id); /* 发送信号给一个任务 */
char isr_set_ready(unsigned char task_id); /* 任务进入就绪状态 */
char os_clear_signal(unsigned char task_id); /* 清除指定任务的信号标志
*/
char os_create_task(unsigned char task_id); /* 指定的任务被启动 */
char os_delete_task(unsigned char task_id); /* 指定的任务被删除 */
void os_reset_interval(unsigned char ticks); /* 内核时钟数 */
char os_running_task_id(void); /* 返回当前正在运行的任务的 ID 号是多少 */
char os_send_signal(unsigned char task_id); /* 给指定任务发送信号 */
char os_set_ready(unsigned char task_id); /* 给指定任务设定就绪标志 */
char os_switch_task(void); /* 让任务暂停,转而运行其它任务 */
char os_wait (
unsigned char event_sel, /* 选择要等待的事件 */
unsigned char ticks, /* 需要等待的内核时钟周期数 */
unsigned int dummy); /* 没有使用的参数 */
char os_wait1(unsigned char event_sel); /* 指定等待的事件 */
char os_wait2 (
unsigned char event_sel, /* 选择要等待的事件 */
unsigned char ticks); /* 需要等待的内核时钟周期数 */
关于os_wait的延时,是按机器周期来到,并没有进一步封装成ms级,所以要自己计算转化成现实的时间函数,RTX51Tiny默认的时钟中断是10000个机器周期,因此对于一个运行在12MHz时钟标准8051而言,内核的时钟就是100Hz(周期0.01秒),计算公式就是:12MHz/12/10000。这个值可以通过配置文件CONF_TNY.A51来更改
所以在默认情况下1个时钟周期就是10ms。
手册文件链接:
链接:https://pan.baidu.com/s/1RZsIXtmHzJMgWNLCVB-Kkw 提取码:8bcj
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)