其他分享
首页 > 其他分享> > uC/Modbus 用户手册——第七节 RTOS接口

uC/Modbus 用户手册——第七节 RTOS接口

作者:互联网

目录

7.00 RTOS接口

7.01 RTOS接口, MB_OS_Init()

7.02 RTOS接口,MB_OS_Exit()

7.03 RTOS接口,MB_OS_RxSignal()

7.04 RTOS接口,MB_OS_RxWait()

7.05 RTOS接口,配置


7.00 RTOS接口

uC/Modbus-S可能会用到RTOS接口,uC/Modbus-M是假设RTOS存在的,但是不会假设一个特定的RTOS。事实上,uC/Modbus是设计成可以工作在商业RTOS之上的,只需要提供简单的RTOS接口层即可。

uC/Modbus提供了uC/Modbus RTOS接口层,因此,如果您的产品中使用了uC/OS-II或uC/OS-III,您也可以uC/Modbus,也可以将该接口层作为您自己的RTOS参考。

图7-1展示了接收模型的流程图。

图7-1,uC/Modbus Rx任务模型

F7-1(1)

uC/Modbus使用一个简单的任务从每个通道接收数据包。Modbus Rx Task只需要等待每个Modbus通道的数据包即可。假设以uC/OS-II作为RTOS,那么就是通过消息队列来实现该功能。对于uC/OS-III,消息队列是内置在任务中的。当接收到数据后,一个指向接收数据通道的指针被发送至消息队列指示“Modbus Rx Task”是哪一个通道接收到数据包。“Modbus Rx Task”只需要解析数据包并给出响应,响应会被适当的转发。

F7-1(2)

假设来自UART的字节是由中断驱动的。接收到字节被存放到一个接收缓存中,直到数据接收完成。如果通道配置为Modbus ASCII,数据包结尾是一个换行符(即,0x0A)。如果通道配置为Modbus RTU,如果3.5字节周期(参考Modbus RTU规范)内未收到任何数据则表示数据结束。

F7-1(3)

假设是Modbus ASCII,通过调用MB_OS_RxSignal()并指定一个指向已接收数据通道的指针来发出数据包结束信号。

F7-1(4)

如果您的产品需要支持Modbus RTU模式,就需要提供一个定时器来中断CPU以便跟踪数据包的结束。基本上,当通道上接收一个字节的时候,该通道的RTU计数器将根据该通道的波特率重置为一个值(见表7-1)。

表7-1,基于通道波特率的RTU超时。

波特率

RTU超时(3.5字节时间)

RTU超时(计数频率1KHz)

9600

3646uS

5

19200

1823uS

3

38400

911uS

2

76800

456uS

2

115200

204uS

2

256000

137uS

2

例如,如果一个通道配置为19200的波特率,在1800us中未接收到任何字节视为数据包结束(RTU模式)。如果RTU计时器被设置为每毫秒中断一次,那么大约需要两次这样的中断,然后才能断定收到了一个数据包。我们决定假设一个数据包至少是在接收5.0字节的时间之后接收完成,而不是3.5字节的时间后。此外,由于计时器相对接收字节的异步特性,我们决定计算至少两个RTU中断,以得出收到数据包的结论。

如果增加RTU计时器中断率,对于超时可以有更好的粒度。但是,这也增加了您放置在CPU上的开销。

F7-1(5)

当RTU定时器中断发生,每个RTU模式通道的超时计数器开始向下计数。当计数器为0时,向“Modbus Rx Task”发送一个信号。告诉“Modbus Rx Task”哪一个通道收到了数据需要处理。信号也可以调用MB_OS_RxSignal()执行。

为了提供上述的RTOS功能,您需要在MB_OS.c文件中定义3个函数:

MB_OS_Init()

MB_OS_Exit()

MB_OS_RxSignal()

MB_OS_RxWait()

​​​​​​​7.01 RTOS接口, MB_OS_Init()

该函数由uC/Modbus调用,初始化所用RTOS的RTOS接口。通常要创建“Modbus Rx Task”任务,并设置在接收到数据包或通道RTU超时时通知该任务所需的机制。

原型

void MB_OS_Init(void);

参数

返回值

注意事项/警告

调用方

mb.c中的MB_Init()

示例

​​​​​​​7.02 RTOS接口,MB_OS_Exit()

该函数由MB_Exit()调用,正常的终止Modbus任务。在uC/OS-II中,只需要删除“Modbus Rx Task”和消息队列就可以。在uC/OS-III中,删除“Modbus Rx Task”即可,消息队列是内置在任务中的。

原型

void MB_OS_Exit(void);

参数

返回值

注意事项/警告

调用方

mb.c中的MB_Exit()

示例

7.03 ​​​​​​​RTOS接口,MB_OS_RxSignal()

该函数发出接收到完成数据包的信号。可以被超时时间内未接到任何字符的通道的RTU定时器中断调用,或者被接收到换行符(0x0A)的Modbus ASCII通道调用。

原型

void MB_OS_RxSignal(MODBUS_CH *pch);

参数

pch

指定一个指向与接收到的数据包相关联的Modbus通道道数据结构的指针。

返回值

注意事项/警告

调用方

mb.c文件中的MB_RTU_TmrUpdate() 或 MB_ASCII_RxByte()。

示例

​​​​​​​7.04 RTOS接口,MB_OS_RxWait()

该函数等待从机的应答。MB_OS_RxWait()在Modbus主机任务向从机发送命令后等待从机应答的时候被调用。如果在配置通道时指定的超时时间内未收到应答,函数将返回给调用方并通知其超时。

原型

void MB_OS_RxWait(MODBUS_CH *pch, CPU_INT16U *perr);

参数

pch

指定一个指向与接收到的数据包相关联的Modbus通道道数据结构的指针。

perr

指向错误代码的指针,指示调用结果,可以是如下错误:

MODBUS_ERR_NONE:调用成功

MODBUS_ERR_TIMED_OUT:指定超时时间内未收到应答

MODBUS_ERR_NOT_MASTER:在非主机通道中调用了该函数

MODBUS_ERR_INVALID:发送无效的错误。详细信息请参考MB_OS.C

注意事项/警告

调用方

MBM_CORE.C文件中的MBM_FC??_???()

示例

​​​​​​​7.05 RTOS接口,配置

如果使用uC/OS-II,需要配置以下#define常量:

OS_Q_EN

大小需要与Modbus通道一样

OS_SEM_EN

如果使用Modbus主机,需要使能信号量服务

MB_OS_CFG_RX_TASK_ID

MB_OS_CFG_RX_TASK_PRIO

MB_OS_CFG_RX_TASK_STK_SIZE

如果使用uC/OS-III,需要配置以下#define常量:

OS_CFG_Q_EN

消息队列的大小被设置为mb_os.c中通道的大小(即,MODBUS_CFG_MAX_CH)

OS_CFG_SEM_EN

如果使用Modbus主机,需要使能信号量服务

MB_OS_CFG_RX_TASK_PRIO

MB_OS_CFG_RX_TASK_STK_SIZE

这些常量需要在您的应用中声明。

标签:MB,数据包,RTOS,Modbus,用户手册,OS,uC
来源: https://blog.csdn.net/mengxiaoguang/article/details/120612993