前言

习惯了实时操作系统的多任务分模块的编写方式后,最近在在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

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐