打印

有兴趣一起讨论下一个不成熟的编程思路!

[复制链接]
楼主: wuhenyouyu
手机看帖
扫描二维码
随时随地手机跟帖
21
wuhenyouyu|  楼主 | 2016-4-11 17:36 | 只看该作者 回帖奖励 |倒序浏览
Simon21ic 发表于 2016-4-1 15:20
其实都一样,很多抢占式的RTOS也无非就是上下文切换
都只是实现方式不同而已,不过实现方式还是比较多样化 ...

void osal_start_system( void )
{
#if !defined ( ZBIT )
  for(;;) // Forever Loop

#endif
  {
    uint8 idx = 0;

    Hal_ProcessPoll(); // This replaces MT_SerialPoll() and osal_check_timer().


    do {
      if (tasksEvents[idx]) // 最高优先级任务被找到

      {
        break;
      }
    } while (++idx < tasksCnt); //其中tasksCnt为tasksArr数组中元素的个数

//得到了待处理的具有最高优先级的任务的索引号 idx

    if (idx < tasksCnt)
    {
      uint16 events;
      halIntState_t intState;
  // 进入/退出临界区,来提取出需要处理的任务中的事件,其实这和μC/OS-II操作系统中进入临界区很相似,μC/OS-II中使用OS_ENTER_CRITICAL();OS_EXIT_CRITICAL();

      HAL_ENTER_CRITICAL_SECTION(intState);
      events = tasksEvents[idx];
      tasksEvents[idx] = 0; // Clear the Events for this task.

      HAL_EXIT_CRITICAL_SECTION(intState);//通过指针调用来执行对应的任务处理函数


      events = (tasksArr[idx])( idx, events );
    //进入/退出临界区,保存尚未处理的事件

          HAL_ENTER_CRITICAL_SECTION(intState);
      tasksEvents[idx] |= events; // Add back unprocessed events to the current task.

          HAL_EXIT_CRITICAL_SECTION(intState);
      } //本次事件处理结束,

#if defined( POWER_SAVING )
    else // 所有的任务事件都被查询结束后,没有任何事件被激活

    {
      osal_pwrmgr_powerconserve(); // 系统进入休眠状态。

    }
#endif
    }
}

使用特权

评论回复
22
wuhenyouyu|  楼主 | 2016-4-12 19:29 | 只看该作者
yyy71cj 发表于 2016-4-12 19:24
看起来很高深!

这个是z-stack的调度机制,和Simon21ic所说的调度原理一样。我感觉Simon21ic的架构,应该和Contiki架构一样。

使用特权

评论回复
23
Simon21ic| | 2016-4-13 18:23 | 只看该作者
wuhenyouyu 发表于 2016-4-12 19:29
这个是z-stack的调度机制,和Simon21ic所说的调度原理一样。我感觉Simon21ic的架构,应该和Contiki架构一 ...

设计的时候参考了uip的PT线程,和contiki有一些区别,不够构架上有些类似的

使用特权

评论回复
24
Simon21ic| | 2016-4-13 18:26 | 只看该作者
yyy71cj 发表于 2016-4-12 19:24
看起来很高深!

这个代码很简单的吧,也是一种事件驱动

使用特权

评论回复
25
Simon21ic| | 2016-4-14 00:07 | 只看该作者
本帖最后由 Simon21ic 于 2016-4-14 00:22 编辑
wuhenyouyu 发表于 2016-4-11 17:36
void osal_start_system( void )
{
#if !defined ( ZBIT )

你可以对比几种不同的构架的使用环境和优缺点,然后按照你自己的想法,把系统完善起来,这种构架不是一下子开发好的,需要维护一段时间才能稳定的。

使用特权

评论回复
26
wuhenyouyu|  楼主 | 2016-4-14 07:03 | 只看该作者
Simon21ic 发表于 2016-4-14 00:07
你可以对比几种不同的构架的使用环境和优缺点,然后按照你自己的想法,把系统完善起来,这种构架不是一下 ...

嗯,谢谢!目前在看…我现在感觉每种架构都是自己的优缺点,在某个行业是实用的!

使用特权

评论回复
27
batsong| | 2016-4-17 23:02 | 只看该作者
其实,找一个操作系统的代码,屏蔽了抢占调度的功能,就是你要的东西

使用特权

评论回复
28
whtwhtw| | 2016-4-18 09:08 | 只看该作者
本帖最后由 whtwhtw 于 2016-4-18 09:14 编辑

可以用网友公开的小小调度器实现,真的很小,很简单,很好用,我已经在项目中应用(键盘+LCD带切屏+pwm+ADC+其他功能)。以下内容为转载。
有如下特点:

1)  超级可以移植性,与CPU无关,几乎任何支持C语言编程的CPU都可以用!(本文仅仅以51单片机为例而已,但实际上可以任意移植)
2)  小之又小, 原理很简单,一看就懂。
3)  省之又省, 可以说对RAM和ROM省到极致。
4)  取protothread之精华,将定时器与状态机和伪线程语法融合到一个框架,任务函数可以有两种写法。
5)  基于定时器触发,调度效率高,最大化减少无效的代码运行时间。
***********************************************************/  
#include <stc89c51.h>
#include <stdio.h>

/*****************小小调度器部分开始********************************************/
#define  _SS   static char lc=0; switch(lc){   case 0: lc=0;
#define  _EE   }; lc=0;
#define  WaitX(a,b)  settimer(&lc,__LINE__,a,b); return ; case __LINE__:
struct TASK {
  char td;
  void (*fp)();
};
#define MAXTASKS 5
struct TASK tasks[MAXTASKS];

//设置定时器
void settimer(char *lc,char  line,char  tmrid,int d){
  *lc=line;
  tasks[tmrid].td=d;
}
//逻辑定时器处理,在定时器中断里调用
void dectimers() {
unsigned char i;   
for (i=0;i<MAXTASKS;i++){
   if (tasks.td>0)  tasks.td--;  
}
}
//任务调度函数,在main里面运行
void runtasks() {
   unsigned char i;   
   for(i=0;i<MAXTASKS;i++)        
   {   
     if (tasks.fp!=0){   
           if (tasks.td==0){
             tasks.td=-1;  
             tasks.fp();
                }  
         }         
        }
}
/****************小小调度器部分结束*******************************************************/


sbit KEY = P3^2;
unsigned char code numtab[16]={0x24,0x6F,0xE0,0x62,0x2B,0x32,0x30,0x67,0x20,0x22,0x21,0x38,0xB4,0x68,0xB0,0xB1};


sfr IAP_CONTR = 0xC7;
sfr WDT_CONTR = 0xC1;

//清除看门狗
void clr_wdt()
{
  WDT_CONTR =0x3C;
}

//初始化定时器
void InitT0()
{
        TMOD = 0x21;
        IE |= 0x82;  // 12t
        TL0=0Xff;
        TH0=0Xb7;
        TR0 = 1;
}
//定时器中断
void INTT0(void) interrupt 1 using 1
{
        TL0=0Xff;    //10ms 重装
        TH0=0Xb7;
        dectimers();
}

sbit LED1= P2^4;  

//任务一,状态机写法
void ontimer0(){
  LED1=!LED1;  // LED1引脚接在发光管负极,LED1=0 为亮,LED1=1为灭。

  //重装定时器
  if (LED1) tasks[0].td=45;  //450mS 灭
  else tasks[0].td=5;  //50ms  亮
}

//任务二,状态机写法
char keycount=0;
void task1(){
if(KEY==0) {
   keycount++;
   if (keycount>20) IAP_CONTR = 0x60;  //持续按下键1秒,将重启并进入固件升级
}
else{
    keycount=0;
}
//重装定时器
tasks[1].td=5;
}


//任务三,伪线程写法
void  task2()
{
static char i;
_SS

while(1){

for(i=0;i<=9;i++){   //从0--9快速显示,间隔200mS
   WaitX(2,20);         //    等待200mS,实际是设置定时器2为200mS
   P1=numtab;
}
for(i=0;i<=9;i++){ //从0--9慢速显示,间隔500mS
   WaitX(2,50);       //    等待500mS,实际是设置定时器2为500mS
   P1=numtab;
}
}

_EE
}



void main()
{
        unsigned char         KeyNum;
        P3M0 = 0x00;
        P3M1 =0x00;
        //WDT_CONTR= 0x00;   //关闭看门狗
        P1 = 0xff;         //关显示

          clr_wdt();

        InitT0();

        KEY =1;                                //按键IO口
        KeyNum=0;                        //按下次数

    //装载任务:
        tasks[0].fp=ontimer0;
        tasks[1].fp=task1;
        tasks[2].fp=task2;

    //循环调度
        while(1){
         runtasks();
         clr_wdt();
        }
}


注意事项:此调度器不能使用switch.....case....语句,可用if代替!

使用特权

评论回复
29
Simon21ic| | 2016-4-18 12:50 | 只看该作者
whtwhtw 发表于 2016-4-18 09:08
可以用网友公开的小小调度器实现,真的很小,很简单,很好用,我已经在项目中应用(键盘+LCD带切屏+pwm+ADC ...

这个是最简单的基于PT的构架,不过并没有看到低功耗的支持,这个其实调度算法还是RR,也就是轮询

使用特权

评论回复
30
coslight| | 2016-4-19 13:57 | 只看该作者
这种设计方法如果考虑实时性的话,感觉问题比较严重啊

使用特权

评论回复
31
icecut| | 2016-4-19 15:03 | 只看该作者
现在 os 不就是这么搞的么.你还要重复造轮子?

使用特权

评论回复
32
Simon21ic| | 2016-4-20 00:04 | 只看该作者
icecut 发表于 2016-4-19 15:03
现在 os 不就是这么搞的么.你还要重复造轮子?

OS本身也在发展,而且,针对不同应用,并不是一个OS就是最适合的
比如,前面有人举例的zigbee协议栈,就和OS里的任务切换机制不同
其他的可以举例的就很多了,裸编程讲究的,不就是这些吗?

使用特权

评论回复
33
幸福至上| | 2016-4-21 23:20 | 只看该作者
wuhenyouyu 发表于 2016-4-12 19:29
这个是z-stack的调度机制,和Simon21ic所说的调度原理一样。我感觉Simon21ic的架构,应该和Contiki架构一 ...

正解,看到就很眼熟,是Zstack的OSAL层机制。

使用特权

评论回复
34
前功尽弃| | 2016-4-22 08:48 | 只看该作者
感觉这个就跟UCOS一样

使用特权

评论回复
35
Simon21ic| | 2016-4-22 15:58 | 只看该作者
前功尽弃 发表于 2016-4-22 08:48
感觉这个就跟UCOS一样

不一样吧

使用特权

评论回复
36
wuhenyouyu|  楼主 | 2016-4-23 08:27 | 只看该作者
前功尽弃 发表于 2016-4-22 08:48
感觉这个就跟UCOS一样

不一样,这个只是个简单的调度器!UCOS是个强大的调度内核+各种系统服务!

使用特权

评论回复
37
wuhenyouyu|  楼主 | 2016-4-23 08:28 | 只看该作者
yyy71cj 发表于 2016-4-22 08:01
吃饭讨论米,也是很重要的话题
继续,继续……

余工,OOPC我还没理解,还得多看看您的书!

使用特权

评论回复
38
wuhenyouyu|  楼主 | 2016-4-23 08:30 | 只看该作者
discussant 发表于 2016-3-25 22:42
一些堆栈很少的单片机,例如PIC,可以移植操作系统,或能进行任务调度吗? ...

这个不是操作系统。只是个调度器,切没有任务栈的概念!

使用特权

评论回复
39
前功尽弃| | 2016-4-23 13:32 | 只看该作者
wuhenyouyu 发表于 2016-4-23 08:27
不一样,这个只是个简单的调度器!UCOS是个强大的调度内核+各种系统服务! ...

好吧,不能说一样,只能将这个调度跟ucos类似

使用特权

评论回复
40
bayuan0414| | 2016-4-23 23:00 | 只看该作者
楼主可以了解下qp,一种事件驱动的编程框架,基于层次式状态机HSM的框架。

使用特权

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

本版积分规则