• 关于裸机多任务


    // 任务结构
    typedef struct _TASK_COMPONENTS
    {
        uint8 Run;        // 程序运行标记:0-不运行,1运行
        uint8 Timer;       // 计时器
        uint8 ItvTime;      // 任务运行间隔时间
        void (*TaskHook)(void);  // 要运行的任务函数
    } TASK_COMPONENTS;        // 任务定义
     
     
    //定时器中断函数
    void TaskRemarks(void)
    {
        uint8 i;
        for (i=0; i<TASKS_MAX; i++)          // 逐个任务时间处理
        {
             if (TaskComps[i].Timer)          // 时间不为0
            {
                TaskComps[i].Timer--;         // 减去一个节拍
                if (TaskComps[i].Timer == 0)       // 时间减完了
                {
                     TaskComps[i].Timer = TaskComps[i].ItvTime;       // 恢复计时器值,从新下一次
                     TaskComps[i].Run = 1;           // 任务可以运行
                }
            }
       }
    }
     
    /**************************************************************************************
    * FunctionName   : TaskProcess()
    * Description    : 任务处理
    * EntryParameter : None
    * ReturnValue    : None
    **************************************************************************************/
    void TaskProcess(void)
    {
        uint8 i;
        for (i=0; i<TASKS_MAX; i++)           // 逐个任务时间处理
        {
             if (TaskComps[i].Run)           // 时间不为0
            {
                 TaskComps[i].TaskHook();         // 运行任务
                 TaskComps[i].Run = 0;          // 标志清0
            }
        }  
    }
     
     
     
    static TASK_COMPONENTS TaskComps[] =
    {
        {0, 60, 60, TaskDisplayClock},            // 显示时钟
        {0, 20, 20, TaskKeySan},               // 按键扫描
        {0, 30, 30, TaskDispStatus},            // 显示工作状态
         // 这里添加你的任务。。。。
    };
     
     
    这个就要靠你自己编码了 ,既然在滴答中断中做任务调度,那么只需在延时的滴答时间内不去做该任务的调度即可,这样不就是实现了延时挂起任务了吗 做一个实现延时并且挂起任务的函数api
     
     
     
    刚才找到了那个案例,看了下还真是大循环……并不适合我现在做的这个多任务并行产品上,会考虑用OS去解决这个问题……
    不过就是心理有疑问:不用OS能不能很好的解决这些问题呢?又不用额外开个定时器呢?
    之前裸跑做复杂应用的时候难道都是像mini的综合历程一样很费劲的写菜单数据结构再来个大循环?要真是这样上OS确实是上上之策
    总想把不懂得东西搞清楚……有时候太爱钻牛角尖,自己跟自己过不去
     
     
    都说ucos商业要钱,freertos不要钱……那么ucos怎么知道我在产品上用没用他的系统呢?
     
     
     
    “小的延时通过死等实现,对于大于最小时间片(1ms)的延时,是不是在delay的地方重新对TaskComps.Timer进行赋值呢?”

    这个问题是你提出来的吧?别的不说,先考虑IIC时序,有部分延时是超过1ms的,那请问你怎么解决这个时序的延时?想不通的话看看我上面的截图吧,我的测试代码是最小延时节拍是1ms,只要你的IIC延时大于1ms,可以直接像操作系统那样子调用PROCESS_DELAY来实现
     
     
    楼主,你贴的代码,是属于时间触发的嵌入式系统构架!
    然而,楼主你的理解本质上是错的!
    原因:TaskProcess这个函数就不应该在中断里运行,而是应该在主循环运行!
    结构是:IRQ:TaskRemarks
                  Main Loop:TaskProcess
    这是典型的前台负责系统滴答,后台负责任务轮询调度!
    然后:在设计任务的时候,设计任务时单次运行时间应该越短越好!
    除时序延时外的延时都尽量去除而采用状态转移(状态机)来处理!
    假如要发送一个hello
    如果while(print(hello))这种形式是最笨的设计方法!
    用switch ---h---e---l---l---o把hello分成5次发送,发送不要死等标记,发送成功退出,不发送成功照样退出!
    设计的时候考虑消费者生产者原则!认清辅助和主线任务,必要的时候要做取舍(偏心)!
     
     

    出问题那是设计者笨!
    任务的运行期间出现中断是必然的事情,这个时候就需要你来保护了(原子保护)
    这个正点原子保护在你们用的OS中有个名词,叫临界区!
     
     
     
  • 相关阅读:
    理解Linux 的CPU Load和CPU利用率
    Linux进程和信号超详细分析
    Linux 磁盘配额
    linux磁盘阵列raid详解
    Linux LVM管理
    Linux fstab文件详解
    Linux 磁盘管理
    sourceTree的使用
    Logstash 参考指南(Kafka输入插件)
    ELK的一次吞吐量优化
  • 原文地址:https://www.cnblogs.com/chulin/p/8998013.html
Copyright © 2020-2023  润新知