|
发表于 2012-12-20 16:47:40
|
显示全部楼层
本帖最后由 ifree64 于 2012-12-20 16:49 编辑
花了点时间写了这样一种调度方法,调度思想与这个帖子里的类似。
请大家点评下。- #include <reg51.h>
- #define FCPU 11059200UL
- #define HZ 1000
- /* --------- Begin of Simple OS -----------------*/
- #define MAX_TASKS 4
- #define MAX_TASK_DEP 12
- unsigned char idata os_task_stack[MAX_TASKS+1][MAX_TASK_DEP];
- unsigned char idata os_task_sp[MAX_TASKS+1];
- unsigned char idata os_task_timers[MAX_TASKS+1];
- unsigned char os_task_id;
- void os_sched()
- {
- os_task_sp[os_task_id] = SP;
- for(os_task_id = 0; os_task_id < MAX_TASKS+1; ++os_task_id)
- {
- if(os_task_timers[os_task_id] == 0)
- {
- SP = os_task_sp[os_task_id];
- return;
- }
- }
- }
- void os_task_load(unsigned int fn, unsigned char tid)
- {
- os_task_sp[tid] = os_task_stack[tid] + 1;
- os_task_stack[tid][0] = (unsigned int)fn & 0xff;
- os_task_stack[tid][1] = (unsigned int)fn >> 8;
- }
-
- void os_timer_tick()
- {
- unsigned char i = MAX_TASKS;
- for(; i > 0; --i)
- {
- if(os_task_timers[i-1] && os_task_timers[i-1] != 255){
- --os_task_timers[i-1];
- }
- }
- }
- void os_wait(unsigned char tick)
- {
- os_task_timers[os_task_id] = tick;
- os_sched();
- }
- void os_idle()
- {
- while(1)
- {
- PCON |= 0x01;
- os_sched();
- }
- }
- void os_start(tid)
- {
- os_task_stack[MAX_TASKS][0] = (unsigned int)os_idle & 0xff;
- os_task_stack[MAX_TASKS][1] = (unsigned int)os_idle >> 8;
- os_task_sp[MAX_TASKS] = os_task_stack[MAX_TASKS] + 1;
- os_task_id = tid;
- SP = os_task_sp[tid];
- return; // return to task tid.
- }
- /* --------- End of Simple OS -------------*/
- sbit LED1 = P1^0;
- sbit LED2 = P1^7;
- void timer0_init()
- {
- TMOD = 0x21;
- IE |= 0x82; // 12t
- TL0 = (65536-FCPU/12/HZ);
- TH0 = (65536-FCPU/12/HZ)>>8;
- TR0 = 1;
- }
- void timer_isr(void) interrupt 1 using 1
- {
- TL0 = (65536-FCPU/12/HZ);
- TH0 = (65536-FCPU/12/HZ)>>8;
- os_timer_tick();
- }
- void task1()
- {
- while(1)
- {
- LED1 = !LED1;
- os_wait(100);
- }
- }
- void task2()
- {
- while(1)
- {
- LED2 = !LED2;
- os_wait(250);
- }
- }
- unsigned char code zixingma[] = {
- 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f
- };
- unsigned char code weiduanma[] = {
- 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
- };
- unsigned char buffer[6];
- void task3()
- {
- static unsigned char pos = 0;
- while(1)
- {
- for(pos = 0; pos < 6; pos++)
- {
- P2 = 0xff;
- P0 = ~zixingma[buffer[pos]];
- P2 = weiduanma[pos];
- os_wait(2);
- }
- }
- }
- void task4()
- {
- static unsigned char hour, min, sec, i;
- while(1)
- {
- for(i = 0; i < 10; i++)
- os_wait(100);
- if(++sec >= 60)
- {
- sec = 0;
- if(++min >= 60){
- min = 0;
- if(++hour >= 24)
- hour = 0;
- }
- }
- buffer[0] = sec%10;
- buffer[1] = sec/10;
- buffer[2] = min%10;
- buffer[3] = min/10;
- buffer[4] = hour%10;
- buffer[5] = hour/10;
- }
- }
- void main()
- {
- timer0_init();
- os_task_load(task1, 0);
- os_task_load(task2, 1);
- os_task_load(task3, 2);
- os_task_load(task4, 3);
- os_start(0);
- }
复制代码 简单解释下为什么没有在任务切换时保存寄存器。
C51规定调用函数时,被调用函数可以任意使用寄存器,意味着调用函数时,已经保存了所有需要保存的参数。但由于C51不是在堆栈里分配局部变量和传递参数,所以每一个任务的变量使用了静态变量来避免重入问题。 |
|