打印
[51单片机]

请教多任务系统的运行流程

[复制链接]
1135|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wdliming|  楼主 | 2018-8-8 15:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
网上有一个C51的多任务系统,但是对其代码的运行流程不太清楚,请各位网友大神们帮忙解释下。谢谢
/*
使用keil4  ,代码Code Optimization:0   运行OK

可运行8个任务

Program Size:
data=21.0 xdata=0 code=401  (包括2个示例变量,未优化)

任务从中断处切换,在定时时间到后从定时中断中切换回来。

待改进地方

1.手动优化汇编程序

2. 重入问题

3.参数进函数和定时中断的保护问题

*/

#include <regx52.H>
#include <INTRINS.H>

typedef unsigned char u8;
typedef unsigned int u16;

sbit LED1 = P2 ^ 0;
sbit LED2 = P2 ^ 1;

#define TIMER_RELOAD()  {TL0=0xf0;TH0=0xd8;}//使能T/C          初始10ms


#define MAX_TASKS 2 //任务槽最大个数.
u8 idata task_stack[MAX_TASKS][2];//任务堆栈.  PC指针为16位,需2个字节task_stack[][0]L  task_stack[][1]H。
u8 idata task_time[MAX_TASKS]; //定时时间
u8 task_id=0; //当前活动任务号
u8 a=0;
u8 b=0;

void rtos_wait(u8 time)
{
    static u8 i;
        //保存当前任务时间
    task_time[task_id]=time;
        //保存当前断点 并把SP=SP-2,任务切换到下一任务;
    task_stack[task_id][1] =*((u8 data* )(SP));
    SP--;
    task_stack[task_id][0] =*((u8 data*)(SP));
    SP--;

    /* //任务号
    if(++task_id == MAX_TASKS)
    task_id = 0;
     */
                 
        //任务号设为最大,越过最大则回到0
    for(i=0; i<MAX_TASKS; i++)
    {
        if(task_time[i]==0)//根据定时时间判断
        {
            task_id=i;
            break;
        }
    }
        // if(i==MAX_TASKS) //任务满 超出则回到0
        // {
        // task_id=0;
        // }

}

void task_test()
{
    while(1)
    {
        a++;
                LED2 = ~LED2;
        rtos_wait(100); //执行完后,记录下一步地址,返回
        a++;
    }
}
void task_test2()
{
    while(1)
    {
        b++;
                LED1 = ~LED1;
        rtos_wait(50); //执行完后,记录下一步地址,返回
        b++;
    }
}
void Timer0Init() //@18.432MHz
{
        TMOD &= 0xF0;                //设置定时器模式
    TMOD |= 0x01;                //设置定时器模式   16bit timer
    TL0 = 0xF0;                        //设置定时初值
    TH0 = 0xD8;                        //设置定时初值 10ms
    TF0 = 0;                        //清除TF0标志
    TR0 = 1;                        //定时器0开始计时

    ET0 = 1;                        //允许定时器0中断
    EA = 1;                                 //开启总中断
}
void main()
{
    Timer0Init();
    task_test();
    task_test2();
    while(1);
}
void task_sw() //任务时间是否到,任务时间到 实时切换回
{
        //从把定时时间减1 ,找看哪个任务到,任务时间到,则实时切换回
    static u8 i;
    for(i=0; i<MAX_TASKS; i++)
    {
        if(task_time[i])
        {
            task_time[i]--;
            if(task_time[i]==0)//多个定时时间同时到,任务越靠后,越优先执行。
            {
                task_id=i; //当前任务号
                                //保存的PC指针调出来
                SP++;
                (*((u8 data*)(SP)))=task_stack[i][0];
                SP++;
                (*((u8 data*)(SP)))=task_stack[i][1] ;
            }
        }
    }
}
void tm0_isr() interrupt 1 //using 1
{
    //定时时间重载
    TIMER_RELOAD();

           //every 10ms to scan
    task_sw(); //任务时间是否到,任务时间到 实时切换回
}
任务加载后,是怎么做到任务切换的,main函数中的while(1);不会一直占用cpu吗??

相关帖子

沙发
mcu5i51| | 2018-8-8 15:45 | 只看该作者
大概看了一下,应是协作式的,任务中主动放权;
main中的死循环是一直用CPU,不过还有定时中断;
在任务中调用rtos_wait(50);时保存这个位置和中间数据,对参数中的时间倒计时,为0时恢复数据,运行rtos_wait(50);之后的指令;
相比常见的OS没有任务创建删除之类的,简单,用于有固定任务的情况

使用特权

评论回复
板凳
wdliming|  楼主 | 2018-8-8 16:05 | 只看该作者
mcu5i51 发表于 2018-8-8 15:45
大概看了一下,应是协作式的,任务中主动放权;
main中的死循环是一直用CPU,不过还有定时中断;
在任务中 ...

我想请问,他是怎么切换回去的,中断中能切换回去吗??

使用特权

评论回复
地板
wdliming|  楼主 | 2018-8-8 16:06 | 只看该作者
mcu5i51 发表于 2018-8-8 15:45
大概看了一下,应是协作式的,任务中主动放权;
main中的死循环是一直用CPU,不过还有定时中断;
在任务中 ...

//任务号设为最大,越过最大则回到0
    for(i=0; i<MAX_TASKS; i++)
    {
        if(task_time==0)//根据定时时间判断
        {
            task_id=i;
            break;
        }
    }

这段代码是用于切换的吗?

使用特权

评论回复
5
mcu5i51| | 2018-8-8 16:13 | 只看该作者
wdliming 发表于 2018-8-8 16:06
//任务号设为最大,越过最大则回到0
    for(i=0; i

这是加入任务的

使用特权

评论回复
6
wdliming|  楼主 | 2018-8-8 16:20 | 只看该作者
mcu5i51 发表于 2018-8-8 16:13
这是加入任务的

定时时间不到,就保持原来的任务运行是吗?

使用特权

评论回复
7
mcu5i51| | 2018-8-8 16:23 | 只看该作者
你调试一下,可以比较清晰的理解;我只是大概看下,错处海涵。

使用特权

评论回复
评论
wdliming 2018-8-8 17:53 回复TA
谢谢!! 
8
wdliming|  楼主 | 2018-8-8 16:43 | 只看该作者
mcu5i51 发表于 2018-8-8 16:23
你调试一下,可以比较清晰的理解;我只是大概看下,错处海涵。

好的,我把等待时间缩小调试下。。

使用特权

评论回复
9
ayb_ice| | 2018-8-8 16:44 | 只看该作者
只保存了任务的断点,意义不大吧

使用特权

评论回复
10
wdliming|  楼主 | 2018-8-8 16:45 | 只看该作者
ayb_ice 发表于 2018-8-8 16:44
只保存了任务的断点,意义不大吧

是网上找来的一个代码,在学习中。。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:我的未来不是梦

76

主题

913

帖子

4

粉丝