返回> 网站首页 

8051内核多任务切换

yoours2023-02-01 19:31:20 阅读 1210

简介一边听听音乐,一边写写文章。

#include <stdlib.h>

#include "ioCC1110.h"


// 任务函数类型

typedef void (*Fun)();


// 任务槽个数.必须和实际任务数一至

#define MAX_TASKS 2

// 最大栈深.最低不得少于2个,保守值为12

#define MAX_TASK_DEP 12

// 当前活动任务号

unsigned char task_id;


//任务的栈指针

unsigned char __idata task_sp[MAX_TASKS];

// 任务堆栈

unsigned char __idata task_stack[MAX_TASKS][MAX_TASK_DEP];

// 当前活动任务号

unsigned char task_id;


// 从指定的任务开始运行任务调度.调用该宏后,将永不返回.

#define os_start(tid) {task_id = tid,SP = task_sp[tid];}


// 任务切换函数(任务调度器)

void task_switch()

{

    task_sp[task_id] = SP;

    if(++task_id == MAX_TASKS)

task_id = 0;

    SP = task_sp[task_id];

    

    // 本函数返回时,PC取SP指针数据,取两次

}


// 任务装入函数

// 将指定的函数(参数1)装入指定(参数2)的任务槽中.

// 如果该槽中原来就有任务,则原任务丢失,但系统本身不会发生错误.

void task_load(Fun fn, unsigned char tid)

{

// 堆栈通常设在30H~7FH这一段片内RAM中,堆栈区是向地址增大的方向生成的.

// 且由于CPU是8位的,数据入栈时,SP先加1,然后数据再压入SP指向的单元;

// 数据出栈时,先将指向的单元的数据弹出,然后SP再减1。(以字节为单位)


// 含义为:压栈两次

// 未压栈时,SP指向堆栈外面。

// 第一次压栈时指向task_stack[tid][0],第二次压栈时指向task_stack[tid][1]

// 出栈时,PC取堆栈SP数据。

// 先取数据,再减一,取两次

    task_sp[tid] = (unsigned int)(task_stack[tid] + 1)&0xFF;


    // 函数地址为2字节

    task_stack[tid][0] = (unsigned int)fn & 0xff;

    task_stack[tid][1] = (unsigned int)fn  >> 8;

}


void task1()

{

    static unsigned char i;

    while(1)

    {

        i++;

        task_switch();

    }

}


void task2()

{

    static unsigned char j;

    while(1)

    {

        j+=2;

        task_switch();

    }

}


void rtosInit()

{

    // 这里装载了两个任务,因此在定义MAX_TASKS时也必须定义为2

    // 将task1函数装入0号槽

    task_load(task1, 0);

    // 将task2函数装入1号槽

    task_load(task2, 1);

    os_start(0);

}



// 调用

extern void rtosInit();

void main(void)

{

   rtosInit();

}


微信小程序扫码登陆

文章评论

1210人参与,0条评论