硬汉嵌入式论坛

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

建议增加一个 "开源github"板块

  [复制链接]

22

主题

198

回帖

264

积分

高级会员

H7 TOOL 大法好!

积分
264
发表于 2026-1-8 12:55:45 | 显示全部楼层 |阅读模式
大家在开发产品 或者 学习过程中, 有时候 会接触一些开源项目, 比如 modbus , Flash存储等, 经过我们产品验证的 才是真真实实的好用的开源项目, 增加这个板块, 后续可以方便大家 相互借鉴探讨, 时代变了, 我自己反正是不怎么 愿意 "手搓"造轮子了, 我先推荐两个开源项目:
1. modbus 我推荐:stbanana/modbusX: modbus protocol support    , 可以给单片机的每个串口 / 或者USB 端口 分配modbus 角色(主机or从机),用一个 寄存器映射表来管理,彼此之间都不干扰,非常好用;

2. flash存储 我推荐:FlashDB armink/FlashDB: An ultra-lightweight database that supports key-value and time series data | 一款支持 KV 数据和时序数据的超轻量级数据库  这位大神 还有好多 好用的库
回复

使用道具 举报

22

主题

198

回帖

264

积分

高级会员

H7 TOOL 大法好!

积分
264
 楼主| 发表于 2026-1-8 13:01:33 | 显示全部楼层
本帖最后由 312456990 于 2026-1-8 13:02 编辑


用开源项目来实现产品开发 或者 学习有以下好处:
1. 自己写的 函数封装未必好移植,连自己原作者都不好移植到其他项目中的代码, 维护性很差, 反之用开源代码, 移植的思路是一样的, 以后在其他单片机中 拿来就可以用, 只要第一次投入学习成本, 后面基本上都是 很快就移植;
2. 学习大佬的代码 如饮美酒, 设计哲学 非常独到, 增长自己的能力与见识, 这才是站在巨人的肩膀上
3. 好维护, 我说真的, 给同事交接的代码, 容易阅读 容易维护 是职业最起码的操守, 我以前遇到一个同事, 临走时, 把所有注释全部删除, 然后跑路, 我觉得人活一辈子, 不要走到一个地方, 就被一个地方所厌恶, "爱人者,爱返 , 福往者,福来"  不要让自己活成故事里面的 反面角色
回复

使用道具 举报

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
121120
QQ
发表于 2026-1-8 13:09:32 | 显示全部楼层
谢谢建议,开源github根据功能划分,我基本都分享到各个板块了。
回复

使用道具 举报

27

主题

285

回帖

366

积分

高级会员

积分
366
QQ
发表于 2026-1-8 13:57:33 | 显示全部楼层
回复

使用道具 举报

7

主题

47

回帖

68

积分

初级会员

积分
68
发表于 2026-1-8 16:47:15 | 显示全部楼层
yono 发表于 2026-1-8 13:57
那还不快点给我其他库点星!我也要当网红

stbanana/ReturnCodesC: A series of common C/C++ function r ...

大佬牛逼的,modbusX仔细看了一下实现逻辑,这种查表和事件回调的方式确实适合Modbus设备开发,尤其是从机。
我有几点不成熟的建议:
1、由于查表是基于地址的,导致线圈,离散输入量,保持寄存器和输入寄存器都需要拥有唯一的地址,不能出现地址重复的情况。虽然实际应用过程中也很少出现这种情况。或许定义表时可以增加一个属性”寄存器类型“,但是这样即使可以有重复地址又破坏了二分法查表的意义。

2、虽然大佬在Readme文档末尾说明对线圈和离散输入量支持不是很好,我反而觉得这种很好,现在芯片也不差那7个bit的资源。

3、最后超时机制,不知大佬是否实现了Modbus中根据波特率不同的35us超时机制。不过这也不重要。提这点是因为我发现很多不知名厂家的Modbus接口的传感器数据发送,一帧完整的数据,中间会间隔一点时间被隔成两帧了。可能是有发送过程被中断了。然后往往我主机都是采用的UART+DMA+IDLE方式(减少中断次数)去接收数据帧的。导致都是一些错误的帧。如果使用大佬的主机会不存在这个问题。

倒不是对大佬的心血指指点点,只是觉得一楼大佬说的很对,不想重复造轮子,奈何自己的水平有限,写不出大佬这么牛逼的组件。所以我的项目基本上是百家衣一样,easylogger,SFUD,Lettershell,FlashDB,MultiButton,LVGL,Cjson等等。

最后希望开源项目可以越来越好。实是敬佩,star奉上。
回复

使用道具 举报

27

主题

285

回帖

366

积分

高级会员

积分
366
QQ
发表于 2026-1-8 17:09:50 | 显示全部楼层
lyj41801 发表于 2026-1-8 16:47
大佬牛逼的,modbusX仔细看了一下实现逻辑,这种查表和事件回调的方式确实适合Modbus设备开发,尤其是从 ...

阿巴阿巴,咕咕嘎嘎


1.不同类型寄存器使用相同地址这个问题有人邮件问过我,刚刚把沟通过程同步到 issues 了。如何使用相同地址的寄存器 · Issue #21 · stbanana/modbusX

2.emm,不支持单bit确实是一个缺陷,其实已经有了框架和构思了,只是一直没有实施,比如是一个32位数据中的某个bit,表条目定义属性时使用 MBX_REG_TYPE_BIT_U32_BASE+n 就好,+0代表第0位,+3代表第3位。switch时会进default:分支提取出这个地址代表多少位变量,是第几位bit,这样就可以正确解析了。

3.实现了 T15 和 T35,这是必须的,要不然波特率过低时无法正确连帧,但是并不精确,因为没有硬件定时器,完全靠tick函数的调用周期计时,粒度上会差一点,但是其实应用上没关系,最多多延迟一个tick。
回复

使用道具 举报

4

主题

457

回帖

469

积分

高级会员

积分
469
发表于 2026-1-8 20:32:14 | 显示全部楼层
eric2013 发表于 2026-1-8 13:09
谢谢建议,开源github根据功能划分,我基本都分享到各个板块了。

集中一块比较方便学习没事可以刷刷大佬们的代码
回复

使用道具 举报

7

主题

47

回帖

68

积分

初级会员

积分
68
发表于 2026-1-11 00:04:08 | 显示全部楼层
yono 发表于 2026-1-8 17:09
阿巴阿巴,咕咕嘎嘎

大佬,不晓得是您这边太忙没有继续更新github仓库,还是在其他地方更新。我测试下来发现线圈和离散输入量的支持是有问题,至少我下载发布1.3.0版本是有问题的,查询都是回复FF FF。我把这部分做了修复。
修复如下:
1、读线圈量和离散输入量时回复FF FF的BUG。

2、多线圈量写入时BUG修复。
3、隔离保持寄存器、输入寄存器、线圈和离散输入量,每种变量都单独定义。
上述BUG修复仅支持RTU模式,也只是小量测试。感兴趣的朋友可以把TCP模式也支持第3点。ASCII就算了,大佬嫌弃,我也看不上。

最后,再次感谢大佬提供的开源库。





Modbus.zip

1 MB, 下载次数: 3

回复

使用道具 举报

27

主题

285

回帖

366

积分

高级会员

积分
366
QQ
发表于 2026-1-11 01:58:14 | 显示全部楼层
本帖最后由 yono 于 2026-1-11 02:03 编辑
lyj41801 发表于 2026-1-11 00:04
大佬,不晓得是您这边太忙没有继续更新github仓库,还是在其他地方更新。我测试下来发现线圈和离散输入量 ...


感谢费时费力关注这个破烂库的未完善部分。

你这个做法可行但不符合我的设计理念,我就是固执地使用一个映射表管理,觉得这样在应用项目的后续维护上会更舒适。项目更简洁漂亮。
以下是对线圈和离散的构思,虽然没有在库内实装,所以现在就是没有线圈和离散的支持
如果你明确有离散和线圈的需求,可以邮件或者提 issue ,我会对这个部分进行完成。
屏幕截图 2026-01-11 014701.png

你目前的实现并不完善,对于线圈/离散的读写有特定的补零和拼凑要求,我看到你似乎并没有完成这一点。
屏幕截图 2026-01-11 015118.png

由于以上两点,所以这些变更我不会合进库里,叭好意思。
但是如果只是你自己的工程使用,按你现有的修改继续进行就可以。

我单纯的懒惰,没人提我也没用到,我就懒得实现。

回复

使用道具 举报

7

主题

47

回帖

68

积分

初级会员

积分
68
发表于 2026-1-11 08:50:59 | 显示全部楼层
yono 发表于 2026-1-11 01:58
感谢费时费力关注这个破烂库的未完善部分。

你这个做法可行但不符合我的设计理念,我就是固执地使用 ...

高位补0是有的,线圈和离散量输入的处理函数中,ComboBit这个变量,如果是满8bit,就输出一个字节,后面会判断不足8bit时也会往串口弹一个字节。
回复

使用道具 举报

3

主题

12

回帖

21

积分

新手上路

afa

积分
21
发表于 2026-1-14 16:44:00 | 显示全部楼层
有个疑问,为啥寄存器需要使用查表,这样浪费内存和效率;为啥不直接依据数据类型开辟内存,不同的数据类型各创建一个枚举;依据内存首地址和枚举来确定具体的地址?高级一点甚至可以直接用指针来指向对应的内存地址(直接通过结构体指针指向内存,接收收到的数据处理完成后,结构体的成员也对应刷新了,不需要多次copy)
回复

使用道具 举报

117

主题

637

回帖

1003

积分

至尊会员

积分
1003
QQ
发表于 2026-1-14 23:43:08 | 显示全部楼层
liushufa 发表于 2026-1-14 16:44
有个疑问,为啥寄存器需要使用查表,这样浪费内存和效率;为啥不直接依据数据类型开辟内存,不同的数据类型 ...

地址可能不连续吧。
回复

使用道具 举报

27

主题

285

回帖

366

积分

高级会员

积分
366
QQ
发表于 2026-1-15 17:24:37 | 显示全部楼层
liushufa 发表于 2026-1-14 16:44
有个疑问,为啥寄存器需要使用查表,这样浪费内存和效率;为啥不直接依据数据类型开辟内存,不同的数据类型 ...

因为这样很难和其他功能模块结合,整个系统都只能从对应的内存地址获取数据,写入时也很难把控上下限或者做额外响应。

“直接依据数据类型开辟内存”是一个极小资源的实现,适用于极简单系统、极确定功能,这种情况要求缩成本就可以这样做啊,我在这种情况也是定制化开发的,只做最贴合确定应用场景的代码。但是要是客户再提歪七扭八不符合原本产品模型的功能,就完蛋了,基本上不能供应拓展开发。
回复

使用道具 举报

3

主题

12

回帖

21

积分

新手上路

afa

积分
21
发表于 2026-1-16 14:01:40 | 显示全部楼层
yono 发表于 2026-1-15 17:24
因为这样很难和其他功能模块结合,整个系统都只能从对应的内存地址获取数据,写入时也很难把控上下限或者 ...

看取舍:
1、如果想要效率,那在项目初期就要构建好各个功能的地址,通过结构体指向对应的内存,Modbus接收和写入也用同一块内存,实现zero copy;
2、如果想要灵活和适配,是否使用回调(回调使用__weak)会好一点,Modbus一包数据最长256字节,这样Modbus这个模块就可极简化(只需要接收和发送各创建一个256字节的数组),具体的处理在回调中(处理各种杂七杂八的需求),这样Modbus接口封装成一个模块,脱离硬件;
或者大佬您兼容下以上两种,目前实现了第一种(这种碰到奇葩的需求确实不好处理,甚至会浪费很多内存),第二种方案在一个开源项目上看到类似,但没有和硬件解耦
回复

使用道具 举报

27

主题

285

回帖

366

积分

高级会员

积分
366
QQ
发表于 2026-1-16 15:10:23 | 显示全部楼层
liushufa 发表于 2026-1-16 14:01
看取舍:
1、如果想要效率,那在项目初期就要构建好各个功能的地址,通过结构体指向对应的内存,Modbus ...

资源占用测试报告里有写的

从机本来就没消耗多少资源,用宏裁掉主机,一个从机对象只占80字节RAM,查找表const放在ROM里的,内容缓冲区是初始化时绑定进去,只开几十字节buffer做内容缓冲也不是不能用(只要连续请求不超限)。

主机没办法,可靠主机必须把请求原本寄存下来,要不然遇到错误就找不到请求是干啥的了,所以天然要占很大的RAM。

以我的观点这玩意已经很轻量化(RAM来看)了,如果连ROM都要省,那估计是几毛钱的芯片只能自己依据项目需求自己定制手撸。我倒是有一个项目案例用的switch+宏表,主机侧直接不做错误检测和处理,可以做到0RAM占用且ROM占用极低,用在几毛钱的芯片上,但定制化做法就不合适做成库了,
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-2-24 08:33 , Processed in 0.058994 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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