找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5051|回复: 11
打印 上一主题 下一主题
收起左侧

我的ModBus主机-调度篇

  [复制链接]
跳转到指定楼层
楼主
ID:446156 发表于 2021-11-15 13:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
开始本篇之前我想先谈一下为什么要把一个ModBus主机分成4篇来写,一是代码的分层理念,随着工作时间的增长以及工作的深入你会发现分层是那么的至关重要不仅仅是代码的可读性更重要的是更方便的维护。初期写代码一个文件中甚至一个函数中既有功能代码又有底层代码,当增删功能或者平台移植的时候都不知道去哪里哭,分层也许在初期会增加代码量显得很麻烦但是当你的架构建立起来之后会变得十分方便,解决问题得心应手。操作系统帮你做好了底层的分层和软件层面的任务调度,但是应用层面依然需要个人来做好。分层理念需要时时有处处有。二是ModBus的一对多特性,当一个主机任务读取某个从机的数据并等待从机应答时,必须保证别的主机任务不要来动ModBus总线,如果有个不长眼的主机任务过来咔咔操作了总线那么之前等待从机应答的任务就崩溃了。可能有人说了等待应答的时候我直接while死等不就行了,直接断了别的主机任务的念想,当然这样是可以解决问题的不过要是某个从机不在线就会导致整个系统卡死一段时间,要是你用了操作系统还好如果是裸机那就非常影响用户体验并且会使其他任务比如刷屏按键出现一些莫名其妙的问题,我们都知道人的新陈代谢越快身体越强壮,同样任务轮询越快系统也越强壮。无论你使用操作系统还是裸机都要避免使用阻塞式的写法。所以我们才大费周章分4层来解决一个ModBus主机问题。本篇调度篇内容很少但是整个ModBus主机系统的重中之重。
我们先来看代码。
  1. #ifndef __RS485_H
  2. #define __RS485_H

  3. #include "Header.h"
  4. #include "THP.h"
  5. #include "EPC.h"
  6. #include "Delay.h"

  7. extern uint16_t RS485BusSilentTime1;

  8. void RS485Device1Init(void);
  9. void RS485Device1Handle(void);

  10. #endif
复制代码
  1. #include "RS485Device.h"

  2. uint16_t RS485BusSilentTime1;

  3. void RS485Device1Init(void)
  4. {
  5.         THPInit();
  6.         EPCInit();
  7. }

  8. static uint8_t TaskHandle(uint8_t En, uint8_t (*Task)(void*), void *Dev, uint8_t *BusTake, uint8_t TaskID, uint16_t *DelayTime)
  9. {
  10.         if((En!=0) && ((*BusTake==0)||(*BusTake==TaskID)))
  11.         {
  12.                 if(Task(Dev) != 0)
  13.                 {
  14.                         /*释放总线*/
  15.                         *BusTake = 0;
  16.                         Set_Delay_Time(10,DelayTime);
  17.                 }
  18.                 else
  19.                 {
  20.                         /*占用总线*/
  21.                         *BusTake = TaskID;
  22.                         return 1;
  23.                 }
  24.         }
  25.         return 0;
  26. }
  27. void RS485Device1Handle(void)
  28. {
  29.         static uint8_t BusTake=0;
  30.        
  31.         if(CheckDelay(&RS485BusSilentTime1) == 0)
  32.         {
  33.                 if(TaskHandle(EPC1.S_P_En,SetPreVal,&EPC1,&BusTake,1,&RS485BusSilentTime1) != 0)
  34.                 {
  35.                         return;
  36.                 }
  37.                 if(TaskHandle(THP1.Enable,ReadTHP,&THP1,&BusTake,2,&RS485BusSilentTime1) != 0)
  38.                 {
  39.                         return;
  40.                 }
  41.                 if(TaskHandle(EPC1.R_En,ReadEPC,&EPC1,&BusTake,3,&RS485BusSilentTime1) != 0)
  42.                 {
  43.                         return;
  44.                 }
  45.         }
  46. }
复制代码
通过代码可以看到该层引用了任务篇创建的"THP.h"和"EPC.h",在这里我们要对三个主机任务进行调度。
首先来看函数“static uint8_t TaskHandle(uint8_t En, uint8_t (Task)(void), void *Dev, uint8_t *BusTake, uint8_t TaskID, uint16_t *DelayTime)”;
该函数参数比较多,分别为任务使能信号(uint8_t En)、任务主体(uint8_t (Task)(void))、设备名称(void *Dev)、是谁在使用总线(uint8_t *BusTake)、任务编号(uint8_t TaskID)、总线静默时间控制(uint16_t *DelayTime);
该函数逻辑很简单,就是判断任务使能信号是否置位了并查看总线被哪个任务占用,若总线空闲或者被自己占用就去占用总线去执行任务主体函数,若任务主体函数返回0说明正在等待从机应答接着占用总线并返回1告知调度器我还没用完,否则说明任务完成了释放总线并给总线插入10ms的静默时间然后返回0告诉调度器我完事了让别人来吧。
函数“void RS485Device1Handle(void)”就是最终的调度器它在main函数的while循环中被执行,它首先实现10ms的总线静默然后挨个询问主机任务的当前状态并满足他们的需求。
至此,我的ModBus主机就完结了。



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏13 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:939553 发表于 2021-11-20 09:49 | 只看该作者
谢谢分享,能否提供一些关于分层的思想的文章,学习。
回复

使用道具 举报

板凳
ID:1005484 发表于 2022-2-16 21:05 | 只看该作者

谢谢分享,能否提供一些关于分层的思想的文章,学习。
回复

使用道具 举报

地板
ID:97078 发表于 2022-3-9 08:33 | 只看该作者
mark,标记学习下
回复

使用道具 举报

5#
ID:1012071 发表于 2022-3-21 22:25 | 只看该作者
mark,标记学习下
回复

使用道具 举报

6#
ID:195496 发表于 2022-5-7 14:38 | 只看该作者
上的操作系统?
回复

使用道具 举报

7#
ID:434978 发表于 2022-5-20 12:10 | 只看该作者
谢谢分享,能否提供一些关于分层的思想的文章,学习
回复

使用道具 举报

8#
ID:1056996 发表于 2022-12-11 15:36 | 只看该作者
mark,标记学习下
回复

使用道具 举报

9#
ID:821429 发表于 2023-4-16 09:43 | 只看该作者
,标记学习一下,感谢分享
回复

使用道具 举报

10#
ID:27536 发表于 2023-5-12 16:42 | 只看该作者

mark,标记学习下
回复

使用道具 举报

11#
ID:1045571 发表于 2023-8-6 14:58 | 只看该作者
moubus在工作中我遇到了,也看了大概的基本原理,但程序写不出来,借鉴一下楼主的
回复

使用道具 举报

12#
ID:939553 发表于 2023-8-15 14:34 来自手机 | 只看该作者
思路清晰,程序扎实
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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