51单片机多线程神器:Tiny-51操作系统_rtx51 tiny api
在编译完成之后,我们电机RTX51TINY.H的头文件里面进入之后,我们会看到如下代码,其中声明了许多调用函数,这些就是Tiny的API接口函数了详细讲解一下这些接口和参数任务创建与删除函数//创建任务,传入的参数为目标任务的ID//删除任务,传入的参数为目标任务的ID阻塞延时函数阻塞当前任务(任务变为等待态)直到指定的时间到来(任务变为就绪态), 继续往下执行,等待的期间该任务释放CPU使用权,
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)
- 找到Tiny源文件
右击keil,打开文件所在位置
返回此文件夹的上一级,找到C51文件夹,点击进去,找到如下文件路径
C51\RtxTiny2\SourceCode
复制配置文件(.a51)和库文件(.lib)到我们的工程下
复制到点灯例程,这里我新建了一个文件夹专门放源文件
在keil内添加文件
- 配置keil
在keil设置里面按下图配置选择RTX-Tiny系统
配置完成后我们在main函数复制以下内容
#include "RTX51TNY.h"
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* 函 数 名 : task\_create
\* 函数功能 : 任务0
\* 输 入 : 无
\* 输 出 : 无
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
void task\_create(void) _task_ 0
{
while(1)
{
;
}
}
编译一下,结果如下,无报错
我们系统的移植就完成了,下面就是根据项目需要对内容的具体修改以及调用API了
四、API介绍
在编译完成之后,我们电机RTX51TINY.H的头文件里面
进入之后,我们会看到如下代码,其中声明了许多调用函数,这些就是Tiny的API接口函数了
详细讲解一下这些接口和参数
- 任务创建与删除函数
unsigned char os\_create\_task (unsigned char task_id);//创建任务,传入的参数为目标任务的ID
unsigned char os\_delete\_task (unsigned char task_id);//删除任务,传入的参数为目标任务的ID
- 阻塞延时函数
阻塞当前任务(任务变为等待态)直到指定的时间到来(任务变为就绪态), 继续往下执行,等待的期间该任务释放CPU使用权,不再参与调度。
unsigned char os\_wait (unsigned char typ,
unsigned char ticks,
unsigned int dummy);
参数
typ:阻塞类型
参数 | 功能 |
---|---|
K_SIG | 等待一个信号 |
K_IVL | 等待时间间隔(滴答数为单位) |
K_TMO | 等待超时时间(滴答数为单位) |
tick:阻塞的心跳时钟数目**(最大255)**
dummy:无用参数
阻塞延时函数的简单版本
unsigned char os\_wait1 (unsigned char typ);//唯一参数只能是K\_SIG,等待信号。
unsigned char os\_wait2 (unsigned char typ,
unsigned char ticks);//(要等待的事件,要等待的滴答数),参数和os\_wait一样,少一个无用参数
阻塞函数的返回值
返回值 | 功能 |
---|---|
RDY_EVENT | 表示任务的就绪标志是被函数置位的 |
SIG_EVENT | 收到一个信号 |
TMO_EVENT | 超时完成,或者时间间隔到 |
NOT_OK | 参数的值无效 |
- 任务信号API
任务信号用于任务间同步,配合阻塞函数使用,当任务在阻塞在等待信号量时,使用send信号量置位对应任务编号的信号量,就可以使其解除等待,运行程序
unsigned char os\_send\_signal (unsigned char task_id);//向其他任务发送信号。如果此任务在等待信号,则会使该任务取消等待准备执行,但不是马上执行,信号储存在任务的信号标志中
unsigned char os\_clear\_signal (unsigned char task_id);//清除对应编号任务的信号标志。
unsigned char isr\_send\_signal (unsigned char task_id);//中断中使用和os\_send\_signal功能相同
- 强制就绪API
使任务强制脱离其他状态,进入就绪态,加入任务调度中
void os\_set\_ready (unsigned char task_id);//函数中调用,传入参数为强制就绪的目标任务编号
void isr\_set\_ready (unsigned char task_id);//中断中使用,和上面功能相同
- 强制切换API
强制停止当前任务,切换到下一个就绪任务
unsigned char os\_switch\_task (void); // 停止当前任务,立即切换到另一个就绪的任务。
- 读取当前运行任务编号API
返回当正在执行的任务编号。
unsigned char os\_running\_task\_id (void);
- 纠正时钟偏差API
用于纠正可能由os_wait引起的等待时间错乱问题,因为由信号事件K_SIG引起的 退出,时间间隔定时器并不调整,通常会调用此函数进行调整。
void os\_reset\_interval (unsigned char ticks);
注意:Tiny的内核在使用过程中与中断息息相关,要确保EA=1,中断处于开启状态,如果有特殊需求,比如任务在通信的时候不想被打断可以短暂的EA=0,但一定要短,并且**在EA=0的时间段内,千万千万千万不要调用内核函数!**不然系统崩溃!!!
五、创建基本任务
- 时钟配置
创建任务之前,我们先打开Conf配置文件,进入配置我们的时间周期,因为任务的切换是以conf内的时间周期为基准了,配置错了系统则会运行异常,具体配置代码在打开配置文件后的33-39行
INT_CLOCK是系统的心跳时钟,每个心跳时钟到达后会进行一次中断,在中断中根据时间片来切换任务,此处使用了EQU汇编相当于#define,后面的数值表示的是心跳时钟是机器周期多少倍。因为我使用的是12M晶振,机器周期为1us,所以我如果要设置心跳时钟为1ms,则需要把这个数字设置为1000(这个数的最大值为65536)
; Define Hardware-Timer tick time in 8051 machine cycles.
INT_CLOCK EQU 1000 ; default is 10000 cycles
这样心跳时间就设置完毕了,下面到设置时间片的长度-TIMESHARING,表示给每个任务设置的运行时间上限,到达时则必须要切换任务,切换到其他就绪的任务(不在延时状态的任务),这里我使用默认值,不改变他,一般程序基本会在1ms内完成程序,然后进入延时状态,脱离调度,切换其他任务
- 任务形式
有了上面的时间周期配置后,下面我们就开始创建任务,tiny没有复杂的启动步骤,其创建任务方式非常简单,创建一个函数后,在其名称旁边加上任务编号说明就可以,形式如下
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* 函 数 名 : task\_create
\* 函数功能 : 任务0
\* 输 入 : 无
\* 输 出 : 无
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
void task\_create(void) _task_ 0
{
while(1)
{
;
}
}
每个创建的任务都有必须有一个死循环,防止cpu彻底跳出任务体,引起系统崩溃,工程开始时首先创建一个任务0,不需要调用创建api,系统直接从0开始运行,在任务0里面我们一般放硬件初始化以及以及调用其他任务的创建声明,在最后调用删除API删除任务0,释放任务0资源,创建和删除API如下,传入参数
此处我们创建两个任务1和2,在任务0中对他们进行创建,同时设置两个led端口led0和led1(定义如下),在任务1和任务2中设置不同的延时周期取反,代码如下:
#include "RTX51TNY.h"
#include "reg52.h"
sbit led0=P1^0;
sbit led1=P2^0;
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* 函 数 名 : task\_create
\* 函数功能 : 任务0
\* 输 入 : 无
\* 输 出 : 无
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
void task\_create(void) _task_ 0
{
os\_create\_task(1);
os\_create\_task(2);
os\_delete\_task(0);
while(1)
{
;
}
}
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* 函 数 名 : task\_1
\* 函数功能 : 任务1
\* 输 入 : 无
\* 输 出 : 无
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
void task\_1(void) _task_ 1
{
while(1)
{
led0=!led0;
os\_wait2(K_IVL,50);
}
}
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* 函 数 名 : task\_2
\* 函数功能 : 任务2
\* 输 入 : 无
\* 输 出 : 无
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
void task\_2(void) _task_ 2
{
while(1)
{
led1=!led1;
os\_wait2(K_IVL,150);
}
}
代码编译一下,没有报错
此处我们keil仿真观察一下波形
首先点击debug设置仿真模式
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)
y,size_16,color_FFFFFF,t_70)
[外链图片转存中…(img-NAJYZfch-1715835343636)]
[外链图片转存中…(img-9G1jnWIw-1715835343637)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)