搜索
bottom↓
回复: 7

发一个简单的并行任务运行程序

[复制链接]

出0入0汤圆

发表于 2012-7-23 22:10:39 | 显示全部楼层 |阅读模式
本帖最后由 Tliang 于 2012-7-24 15:07 编辑
  1. #include<avr/io.h>
  2. #include"Task.h"
  3. #include<avr/interrupt.h>

  4. #define Task_Max  5                                //任务数
  5. #define Stack_Top 12                        //任务堆栈空间


  6. typedef struct Task_Value
  7. {
  8.         uint8         p;                                        //任务堆栈指针
  9.         uint16        delay;                                //任务延时
  10.         uint8        State;                                //任务状态
  11. }Task;

  12. static Task Task_Buf[Task_Max];                                //任务空间

  13. static uint8 Task_SP[Task_Max][Stack_Top];        //任务堆栈空间

  14. static uint8 Task_Run_ID;                                        //正在运行任务ID

  15. void AddTask(uint16 TaskName, uint16 TaskDelay, uint8 TaskID)
  16. {
  17.         Task_Buf[TaskID].p = (uint16)Task_SP[TaskID] + 9;
  18.         //AVR单片机SP堆栈方向是由上往下生长的,执行RET的时候SP将加1,所以要比实际地址小1
  19.         Task_SP[TaskID][10] = (uint8)(TaskName >> 8);                //地址高8位
  20.         Task_SP[TaskID][11] = (uint8)(TaskName & 0xff);                //地址低8位
  21.         Task_Buf[TaskID].delay = TaskDelay;
  22.         Task_Buf[TaskID].State = 0;
  23. }

  24. void Task_Delay(uint16 Del)
  25. {
  26.         uint8 Temp = 0;
  27.         Task_Buf[Task_Run_ID].p        = SP;                                        //保存当前堆栈
  28.         Task_Buf[Task_Run_ID].delay = Del;                                //设置延时
  29.         Task_Buf[Task_Run_ID].State -= 1;                                //将状态置0

  30.         for(Temp = 0;Temp < Task_Max - 1;Temp++)
  31.         {
  32.                 if(Task_Buf[Temp].State == 1)                                //如果有任务处于就绪状态,执行.
  33.                 {
  34.                         break;
  35.                 }
  36.         }

  37.         SP = Task_Buf[Temp].p;                                                        //将任务堆栈地址赋给SP堆栈地址
  38.         Task_Run_ID = Temp;                                                                //运行改变ID
  39. }

  40. ISR(TIM0_OVF_vect)
  41. {
  42.         uint8 Index = 0;
  43.         uint8 IDBuf = Task_Run_ID;                                                //保存当前运行任务的ID
  44.         uint8 Task_Run_SP = Task_Buf[Task_Run_ID].p - SP;       
  45.         //任务堆栈指针减去当前堆栈指针得到中断所使用掉的堆栈

  46.         TCNT0 = 0x00;
  47.         Task_Buf[Task_Run_ID].p = SP + Task_Run_SP;
  48.         //当前堆栈指针加上中断所使用掉的堆栈数得到中断前堆栈指针,保存

  49.         for(Index = 0;Index < Task_Max;Index++)
  50.         {
  51.                 if(Task_Buf[Index].p != 0)
  52.                 {
  53.                         if((Task_Buf[Index].delay == 0) && (Task_Buf[Index].State == 0))
  54.                         {
  55.                                 //如果任务延时时间到,将就绪置位
  56.                                 Task_Buf[Index].State = 1;

  57.                                 if(Index < IDBuf)
  58.                                 {
  59.                                         IDBuf = Index;                //如果当前运行任务优先级低于就绪任务则切换
  60.                                 }

  61.                         }
  62.                         else if((Task_Buf[Index].delay != 0) && (Task_Buf[Index].State == 0))
  63.                         {

  64.                                 Task_Buf[Index].delay -= 1;        //时间未到,时间标志减1

  65.                         }
  66.                 }
  67.         }
  68.         //将运行任务指针减去中断所用堆栈数得到中断返回前的堆栈指针,中断返回将加上
  69.         //中断所用掉的堆栈数量,就得到将运行任务的实际堆栈指针
  70.         SP = Task_Buf[IDBuf].p - Task_Run_SP;       
  71.         Task_Run_ID = IDBuf;                //改变当前运行任务ID

  72. }

  73. void Task_Kong(void)
  74. {
  75.         while(1);                                //当没有任务执行的时候就停留在此处,可以加入CPU空闲计算
  76. }

  77. void Time0_Task_Start(void)
  78. {
  79.         AddTask((uint16)Task_Kong, 0, Task_Max - 1);        //添加空任务
  80.         TCCR0A = 0x00;
  81.         TCCR0B = 0x03;
  82.         TCNT0 = 0x00;
  83.         TIMSK0 |= 0x01;
  84.         sei();
  85.         Task_Run_ID = Task_Max - 1;                                                //开始运行运行空任务,可用形参指定运行那个任务
  86.         SP = Task_Buf[Task_Run_ID].p;                                        //任务开始运行
  87. }
复制代码
这段程序在Task_Delay这个函数中Task_Buf[Task_Run_ID].State -= 1不知道为什么不能直接给0。直接给0并未将它清0。所以这里就写减1了。请各位大侠帮忙看看原因。
还有小弟不明白任务间如何通讯。那位大侠能否给小弟我讲解一下消息机制和邮箱队列怎么构成的,多谢了。
这段程序是ATtiny24的程序。在5楼我打包了一个ATmega8的测试程序。有Proteus仿真。

出0入0汤圆

 楼主| 发表于 2012-7-24 10:38:34 | 显示全部楼层
郁闷。。竟无人理

出0入0汤圆

发表于 2012-7-24 10:48:53 | 显示全部楼层
Task_Buf[Index].delay -= 1;
我看到等号前面有个减号,不知道是不是这个原因
带操作系统的逻辑性会有点复杂的。。。还要考虑各种细节,

出0入0汤圆

 楼主| 发表于 2012-7-24 10:56:38 | 显示全部楼层
汗。。。我说错了。。。
这段程序在Task_Delay这个函数中Task_Buf[Task_Run_ID].State -= 1这一句本来是Task_Buf[Task_Run_ID].State = 0不知道为什么直接给0并未将它清0。所以这里就写减1了。

出0入0汤圆

 楼主| 发表于 2012-7-24 14:06:29 | 显示全部楼层
上个测试程序给大家试试。简单易用。可惜没有消息机制

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2012-7-24 15:04:29 | 显示全部楼层
我贴那个程序是ATTINY24上面测试可以的。。。后面打包的是ATmega8的。前面是在ATmega8上测试后来移到ATtiny24上面了,有两个我没细看就把程序贴出来了,汗。。。难怪没人理。各位大概一看就以为不行吧。毕竟ATtiny24没多少人用过吧。。。

出0入0汤圆

发表于 2012-7-24 15:29:12 | 显示全部楼层
这种,应该是用的人比较少。所以就少有人回答了

出0入0汤圆

 楼主| 发表于 2012-7-24 15:34:24 | 显示全部楼层
哦。。。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-5 01:36

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表