硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2171|回复: 37
收起左侧

modbus 开源库完成辣

  [复制链接]

22

主题

182

回帖

248

积分

高级会员

积分
248
QQ
发表于 2024-12-16 13:35:39 | 显示全部楼层 |阅读模式
断断续续做了小半年,终于各个方面自己都比较满意了。


非常简单易用,文档完整的 modbus RTU/TCP 的支持。

源码地址
stbanana/modbusX: modbus protocol support
文档地址
土星环的图书馆—modbusx

找了个机会在实际项目上测试了,最后做了资源占用报告。欢迎大家试用找 bug。

评分

参与人数 7金币 +138 收起 理由
YFS + 18
05021420 + 20
songsong + 20 很给力!
lililili + 20 很给力!
会飞的猪_2020 + 20 很给力!
skyshine + 20 很给力!
WALL_E + 20 很给力!

查看全部评分

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115434
QQ
发表于 2024-12-16 15:08:04 | 显示全部楼层
你这个网站竟然还备案成功了,相当可以啊

另外我有个问题想请教下,有没有办法doc文件方便转换成网页文件的,这样不用在编辑帖子了,可以直接挂到服务器上就行。
回复

使用道具 举报

22

主题

182

回帖

248

积分

高级会员

积分
248
QQ
 楼主| 发表于 2024-12-16 16:03:49 | 显示全部楼层
eric2013 发表于 2024-12-16 15:08
你这个网站竟然还备案成功了,相当可以啊

另外我有个问题想请教下,有没有办法doc文件方便转换成网 ...

doc 文件太复杂了,word 原生是可以转换成 htm 等网页文件的,但是比较拉跨。

我看到的文档网站或者现代化的论坛都是 markdown 的支持,因为 md 本来就是非常简单的标记语言,依据不同的解析方式渲染成符合网站气质的网页很合理。

虽然也不是这方面的工程师,但是我觉得,doc 想比较好的转网页是不现实的,doc 本身就是比网页更复杂的文本,包含更多信息。抽离哪些信息、保留哪些信息、如何转换存储、怎么索引图片(基于域名or图床基址?)、如何渲染,一大堆的问题,能从头做这件事的都选 markdown 方案了。

由俭入奢易,由奢入俭难。
回复

使用道具 举报

1

主题

47

回帖

50

积分

初级会员

积分
50
发表于 2024-12-16 17:27:01 | 显示全部楼层
真不错,问一下,代码中格式化的注释是用什么工具了吗
回复

使用道具 举报

22

主题

182

回帖

248

积分

高级会员

积分
248
QQ
 楼主| 发表于 2024-12-16 17:44:34 | 显示全部楼层
lililili 发表于 2024-12-16 17:27
真不错,问一下,代码中格式化的注释是用什么工具了吗

函数的头注释是 vscode 的 c/c++ 原生功能。

其他格式化都是 clang-format ,结合 vscode 每次保存时自动格式化。

vs code 技巧:使用clang-format来格式化代码 - 不回本不改名 - 博客园
使用clang-format格式化代码 - 开发环境 - 硬汉嵌入式论坛 - Powered by Discuz!

本质上都是打指令,需要 clang-format 的可执行文件在环境变量能找到,风格化文件用我库里那个 .clang-format 就挺好,是精调过的。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115434
QQ
发表于 2024-12-17 09:24:52 | 显示全部楼层
yono 发表于 2024-12-16 16:03
doc 文件太复杂了,word 原生是可以转换成 htm 等网页文件的,但是比较拉跨。

我看到的文档网站或者现 ...

微软前段时间弄了个doc转markdown插件,效果一般,我打算doc转markdonw,再转htm

再单独做一份markdown编辑的文档,太麻烦了,文档太多。
回复

使用道具 举报

0

主题

7

回帖

7

积分

新手上路

积分
7
发表于 2024-12-17 13:45:46 | 显示全部楼层
好东西,打算用起来试试,不过你的主从机的线圈和离散输入读写大概有多久完成啊?
回复

使用道具 举报

22

主题

182

回帖

248

积分

高级会员

积分
248
QQ
 楼主| 发表于 2024-12-17 14:19:26 | 显示全部楼层
dmzy007 发表于 2024-12-17 13:45
好东西,打算用起来试试,不过你的主从机的线圈和离散输入读写大概有多久完成啊?

线圈和离散输入比较难映射,因为 bit 位没有独立的 ram 地址,需要多指定一下是第几位,这个地方我还没有想好怎么处理。

如果要做,就在写处理的 switch 后面加就好了,需要的时钟周期上都是一样的。但是这样比较丑,而且我自己暂时没有bit的需求。

我这个核心的思路就是建立 modbus 和程序地址的映射关系,线圈对应 bit 位域,uint8、uint16、uint32的不同 bit ,相对地址的移位处理都不一样,强行加 switch 需要 32 个case,还没想好怎么做。
回复

使用道具 举报

0

主题

7

回帖

7

积分

新手上路

积分
7
发表于 2024-12-17 18:49:52 | 显示全部楼层
您好,我下午尝试跑了一下RTU_Mmain,在Win上算是跑通了。但是用到板子上有两个问题想请教下:
1、MBxSend和MBxGetc都是函数指针,如果使用stm32的标准库的话,MBxSend可以自己编写自定义的串口发送函数,但是串口接收有自带的USART1_IRQHandler,MBxGetc我应该怎么给它赋值呢?
2、如果是485通讯的话,485的收发使能切换放哪里呢?按照一般主机发送完数据后,应置为接收,那就应该放在MBxSend里面嘛?

还请楼主不吝赐教
回复

使用道具 举报

22

主题

182

回帖

248

积分

高级会员

积分
248
QQ
 楼主| 发表于 2024-12-18 09:08:17 | 显示全部楼层
dmzy007 发表于 2024-12-17 18:49
您好,我下午尝试跑了一下RTU_Mmain,在Win上算是跑通了。但是用到板子上有两个问题想请教下:
1、MBxSend ...

首先软件协议抽象层,和物理外设层应该解耦,是这个库的理念之一。

1、我认为是你的串口驱动没有设计到位,无论发送或者接收都应该是自定义包装过的驱动,有 buffer 缓冲。那么这个串口外设的驱动就通用了,可以将数据流向不同的协议库进行处理,在不同的产品定义里都可以使用。对于所有其他的软件部分来说,根本不想知道你的串口是485还是232还是别的什么,只知道他是一个数据的来源和出路。
例如自己包装一个发送 API ,填入发送 buffer ,每毫秒检查发送 buffer 是否非空 && 发送通道是否开启,这个时候开启发送通道、发送通道从 buffer 取数据发出,如果有 485 ,拉电平也在这里。
接收中断,有数据,立即填进接收 buffer ,接收API设计成从接收 buffer 里取。

2、485 通信是一个比较麻烦的事情,
例如以下是每毫秒需要轮询的代码,其中0相当于 空闲态 ,1相当于 结束态, 2相当于 发送态。
空闲轮询有机会进2态,会在下一个周期开启发送通道。
发送完毕中断,立即进1态,会在下一个周期检查485切换。
这里主要是不能拉高 485 芯片后立即发送数据,接收也是同理,但主要是发送需要注意。要建立一个合理的同步机制,把发送分成两步来做。

[C] 纯文本查看 复制代码
        switch(pd->SendFlag)
        {
        case 0:
            if(IsUARTTxBufferEmpty(pd) == RETURN_ERR_INDEFINITE) // 为非空
            {
    pd->SendFlag = 2;
    if(pd->SendBefor != NULL) // 检查发送前回调函数
        pd->SendBefor( );
            }
            break;
        case 1:
            pd->SendFlag = 0;
            if(pd->SendOver != NULL) // 检查发送结束回调函数
    pd->SendOver( );
            break;
        case 2:
            UartInterruptTxEnable(pd); // 启动发送通道
            break;

        default:
            break;
        }


注:如果是非常定制化非常缺资源,这些东西都是虚的,就得自己一点一点抠细节写成软硬件各层全耦合。但是正常做我觉得这是合理的思路。
回复

使用道具 举报

22

主题

182

回帖

248

积分

高级会员

积分
248
QQ
 楼主| 发表于 2024-12-18 09:18:32 | 显示全部楼层
dmzy007 发表于 2024-12-17 18:49
您好,我下午尝试跑了一下RTU_Mmain,在Win上算是跑通了。但是用到板子上有两个问题想请教下:
1、MBxSend ...


源码不能放出来,我的串口驱动,包装成对其他软件部分只有这些接口。无论485、232、用中断手动、用DMA,在这里都有实现,同时开了5个串口,都是不同的功能。
你可以参考一下库对于主从机对象的定义,其中有一些配置位,你也可以这样干,然后初始化时进行配置,在统一的串口对外API里进行处理。相信能写出稳健通用的串口驱动。

[C] 纯文本查看 复制代码
/*      配置API     */
/* 配置Uart功能 */
extern void UartStdioInit(void);
/* 单独配置某个UART的波特率 */
extern uint32_t UartBaudRateSet(_UART_STDIO_HANDLE *pd, uint32_t Baud);

/*      功能API     */
/* 发送一些字节 */
extern uint32_t UartWrite(_UART_STDIO_HANDLE *pd, const uint8_t *pcBuf, uint32_t ui32Len);
/* 发送一个字节(尽量不要使用单字节发送,性能较差,为了兼容一些旧API处理而创建) */
extern uint32_t UartWritec(_UART_STDIO_HANDLE *pd, uint8_t data);
/* 取一个接收到的字节 */
extern uint32_t UartGetc(_UART_STDIO_HANDLE *pd, uint8_t *data_rx);

/*      查询API     */
/* 检查接收buffer是否为空 */
extern uint32_t IsUARTRxBufferEmpty(_UART_STDIO_HANDLE *pd);

/*      周期调用API(适用于DMA发送以及485支持)     */
extern uint32_t UartBufferCheck(_UART_STDIO_HANDLE *pd);

回复

使用道具 举报

0

主题

7

回帖

7

积分

新手上路

积分
7
发表于 2024-12-18 10:22:02 | 显示全部楼层
了解了,非常感谢您的回答。然后我还想问下MBx_Ticks函数参数值设置问题,我尝试过设置的比较小的话,数据会收不到;设置的比较大的话,程序就容易卡住。我想问下这个有参考值可以借鉴嘛,还是根据自己的使用情况硬调?
回复

使用道具 举报

22

主题

182

回帖

248

积分

高级会员

积分
248
QQ
 楼主| 发表于 2024-12-18 11:24:46 | 显示全部楼层
dmzy007 发表于 2024-12-18 10:22
了解了,非常感谢您的回答。然后我还想问下MBx_Ticks函数参数值设置问题,我尝试过设置的比较小的话,数据 ...

MBx_Ticks传参以实际调用的轮询周期为准,
我通常是1000或者500,1毫秒或0.5毫秒调用,RTOS任务或者纯定时器任务都可以。你描述的情况应该是外设驱动做的有问题。
另外可以参考 MBxErrTraceGet 函数的使用,可以辅助错误的排查。
回复

使用道具 举报

0

主题

7

回帖

7

积分

新手上路

积分
7
发表于 2024-12-20 18:31:55 | 显示全部楼层
您好,目前我已经移植到板子上了,但是现在经常报MBX_API_RETURN_BUFFER_FULL的错误,想请老哥帮忙给排查下是什么问题。
主要测试代码如附件所示。我起用了SysTick时钟,1ms中断一次,sysTick在里面进行累加计数,所以我发送四条命令的间隔时间是100ms。MBX_MASTER_REQUEST_QUEUE_MAX我设置的是255。
现在的现象就是代码跑一会就一直报MBX_API_RETURN_BUFFER_FULL错误,还想请老哥帮忙给指点指点,先在此谢过了。

添加从机代码.png
发送代码.png
回复

使用道具 举报

22

主题

182

回帖

248

积分

高级会员

积分
248
QQ
 楼主| 发表于 2024-12-20 19:58:33 | 显示全部楼层
dmzy007 发表于 2024-12-20 18:31
您好,目前我已经移植到板子上了,但是现在经常报MBX_API_RETURN_BUFFER_FULL的错误,想请老哥帮忙给排查下 ...

MBx_Ticks 传参是 25?
MBx_Ticks 是一个常周期调用的函数,传参是 调用本函数的周期值us ,微秒,文档里有写。如果对不上的话,3.5字符间隔会严重失真。
你这个看起来是很久很久才触发一次状态机的流转,所以发送通道完全没有跑满。导致buffer挤压了。

另外还有一个建议
MCU 的编程尽量不要用 malloc 函数,对于这个库,完全可以用一个全局数组作为 buffer 空间。
回复

使用道具 举报

0

主题

7

回帖

7

积分

新手上路

积分
7
发表于 2024-12-20 20:34:26 | 显示全部楼层
yono 发表于 2024-12-20 19:58
MBx_Ticks 传参是 25?
MBx_Ticks 是一个常周期调用的函数,传参是 调用本函数的周期值us ,微秒,文档 ...

你可以看我的代码,基本1ms来调用一次MBx_Ticks,之前传参填过1000,发现还是经常出现MBX_API_RETURN_BUFFER_FULL,所以我才后面尝试改成别的参数
回复

使用道具 举报

0

主题

7

回帖

7

积分

新手上路

积分
7
发表于 2024-12-20 20:35:29 | 显示全部楼层
我个人感觉您这个库很好,也很想用起来,就是目前用的不太顺利,方便加个联系方式给指点指点吗?
回复

使用道具 举报

22

主题

182

回帖

248

积分

高级会员

积分
248
QQ
 楼主| 发表于 2024-12-21 13:46:49 | 显示全部楼层
dmzy007 发表于 2024-12-20 20:35
我个人感觉您这个库很好,也很想用起来,就是目前用的不太顺利,方便加个联系方式给指点指点吗?

yono233@outlook.com

单纯库相关的问题在 github 提 issue 比较好,给后来人一点借鉴,工程相关可以邮件发我看看
回复

使用道具 举报

0

主题

7

回帖

7

积分

新手上路

积分
7
发表于 2024-12-23 14:02:15 | 显示全部楼层
已按照要求发送邮件,并在issue里面写了一些自己的理解,还请斧正。
回复

使用道具 举报

1

主题

47

回帖

50

积分

初级会员

积分
50
发表于 2024-12-25 08:42:34 | 显示全部楼层
yono 发表于 2024-12-17 14:19
线圈和离散输入比较难映射,因为 bit 位没有独立的 ram 地址,需要多指定一下是第几位,这个地方我还没有 ...

bit位的读写方式,可以通过添加一个掩码的数据进行确定到底是哪一位?
回复

使用道具 举报

6

主题

231

回帖

249

积分

高级会员

积分
249
发表于 2024-12-25 10:11:54 | 显示全部楼层
我也推荐不要用malloc 函数,用这个感觉有些害怕,用静态数组,反正也用不了多少。
每个寄存器一个映射稍有麻烦,
我自己的Modbus库,是用的一个结构体,直接读写整体映射,很是方便。
回复

使用道具 举报

22

主题

182

回帖

248

积分

高级会员

积分
248
QQ
 楼主| 发表于 2024-12-25 10:40:39 | 显示全部楼层
fxyc87 发表于 2024-12-25 10:11
我也推荐不要用malloc 函数,用这个感觉有些害怕,用静态数组,反正也用不了多少。
每个寄存器一个映射稍 ...

是,后面修改一下 Example ,因为早期开发时测试都在 windows 上,所以这里更符合 windows C 的写法。

这个库更多还是解决个人工程的痛点,因为我的工程支持很多协议,设置参数部分又有很多已有的函数(把控设置范围以及设置目标),这些协议都调用这一些已有设置函数,各种不同结构体的参数,所以没有找到一个合适的 modbus 实现直接地调动这些资源。

对于比较简单的应用场景,这个库确实没必要。
回复

使用道具 举报

0

主题

6

回帖

6

积分

新手上路

积分
6
发表于 2025-2-15 10:07:00 | 显示全部楼层
我以前寄存器映射都是简单粗暴的不同功能码和不同寄存器地址分组,分别映射,然后读写寄存器的时候查找这个地址有没有映射,有映射的话就直接使用寄存器地址减去这个寄存器组的首寄存器地址拿到映射对应的数组下标,这样就不用查找,速度快很多。比较适合用到寄存器数量多且相对连续的情况,缺点是如果用的寄存器一两个断断续续的话就不方便了。
回复

使用道具 举报

10

主题

678

回帖

708

积分

金牌会员

积分
708
发表于 2025-2-17 13:40:36 | 显示全部楼层
主机,从机都可以用?牛×。。。。
回复

使用道具 举报

12

主题

111

回帖

147

积分

初级会员

积分
147
发表于 2025-2-17 14:27:18 | 显示全部楼层
我也想建个自己的博客写点东西
回复

使用道具 举报

22

主题

182

回帖

248

积分

高级会员

积分
248
QQ
 楼主| 发表于 2025-2-17 15:39:07 | 显示全部楼层
hqgboy 发表于 2025-2-17 13:40
主机,从机都可以用?牛×。。。。

主从支持完全不是难点,毕竟是简单协议。
自认为值得自豪的地方是内存映射表和相关机制。
1.连续读写只查找起点、后续连续查表,这个机制极大提高查表速度。
2.数据碎片机制,接收数据直接作为碎片填充buffer,碎片完整后直接传递buffer地址,这个机制极大提高写入速度。
3.MBX_EXTEN_REG_HANDLE_ENABLE 宏开启后的回调归一处理,这个极大降低复杂项目的维护难度。

协议解析、不阻塞状态机轮询这些是没有难度的。相比知名的 freemodbus 的信号量阻塞各有优劣,只是我不喜欢阻塞而已。
回复

使用道具 举报

22

主题

182

回帖

248

积分

高级会员

积分
248
QQ
 楼主| 发表于 2025-2-17 15:45:40 | 显示全部楼层
PKB404 发表于 2025-2-17 14:27
我也想建个自己的博客写点东西

如果没那么注重浏览体验,用 github page 就挺好的,不用服务器成本(要能浏览 github 才能比较顺利访问)。我那个 wiki 文档站就搭在 github page 上。
文档站的框架也支持博客,有前端基础也可以做的很好看,比如原作者公司的文档站,我完全不会才比较丑。
https://teedoc.neucrack.com/
回复

使用道具 举报

12

主题

111

回帖

147

积分

初级会员

积分
147
发表于 2025-2-17 17:12:20 | 显示全部楼层
yono 发表于 2025-2-17 15:45
如果没那么注重浏览体验,用 github page 就挺好的,不用服务器成本(要能浏览 github 才能比较顺利访问) ...

我之前用的WordPress搞过个,服务器到期后就没续费了
回复

使用道具 举报

10

主题

678

回帖

708

积分

金牌会员

积分
708
发表于 2025-2-17 17:26:17 | 显示全部楼层
yono 发表于 2025-2-17 15:45
如果没那么注重浏览体验,用 github page 就挺好的,不用服务器成本(要能浏览 github 才能比较顺利访问) ...

GITHUB没梯子,有时候上不去啊。为啥不在GITEE上?
回复

使用道具 举报

22

主题

182

回帖

248

积分

高级会员

积分
248
QQ
 楼主| 发表于 2025-2-17 17:53:19 | 显示全部楼层
hqgboy 发表于 2025-2-17 17:26
GITHUB没梯子,有时候上不去啊。为啥不在GITEE上?

github 老板是微软,完全不差钱,全是福利。
gitee 被zf管制,老板没钱,随时可能删库,zc一变说不定著作权都有争议。完全不是一个级别。
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2025-3-19 19:07:12 | 显示全部楼层
感谢作者进行分享
回复

使用道具 举报

0

主题

33

回帖

33

积分

新手上路

积分
33
发表于 2025-4-16 18:33:39 | 显示全部楼层
先顶一个,我这菜鸟级别的去年也照着别人的写了一个,头发差点掉光了
回复

使用道具 举报

0

主题

4

回帖

4

积分

新手上路

积分
4
发表于 2025-4-17 15:10:22 | 显示全部楼层
eric2013 发表于 2024-12-16 15:08
你这个网站竟然还备案成功了,相当可以啊

另外我有个问题想请教下,有没有办法doc文件方便转换成网 ...

我们公司用 confuluence
回复

使用道具 举报

5

主题

39

回帖

54

积分

初级会员

积分
54
发表于 2025-4-18 09:52:25 | 显示全部楼层
你好,楼主,文档的网页打不开了,请问还有其他地方能够查看嘛
回复

使用道具 举报

22

主题

182

回帖

248

积分

高级会员

积分
248
QQ
 楼主| 发表于 2025-4-18 17:12:23 | 显示全部楼层
咿呀 发表于 2025-4-18 09:52
你好,楼主,文档的网页打不开了,请问还有其他地方能够查看嘛

打得开的,昨天替换了一下DNS服务商,算上重启服务器杂七杂八的,大概有12小时打不开,目前是可以了。
回复

使用道具 举报

22

主题

182

回帖

248

积分

高级会员

积分
248
QQ
 楼主| 发表于 2025-4-18 17:18:03 | 显示全部楼层
网络服务还是有些贵,我工资有限负担不起,尽量找些免费的替一下。
回复

使用道具 举报

5

主题

39

回帖

54

积分

初级会员

积分
54
发表于 7 天前 | 显示全部楼层
yono 发表于 2025-4-18 17:12
打得开的,昨天替换了一下DNS服务商,算上重启服务器杂七杂八的,大概有12小时打不开,目前是可以了。

好的,感谢,确实是的,这笔投入不小
回复

使用道具 举报

39

主题

1503

回帖

1625

积分

至尊会员

积分
1625
发表于 7 天前 | 显示全部楼层
大佬牛逼  有时间体验下
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-4-26 01:45 , Processed in 0.505647 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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