You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何限制Modbus保持寄存器中特定寄存器的写入操作?

解决Modbus Slave部分保持寄存器只读的问题

要在保持寄存器区域(MB_PARAM_HOLDING)实现部分寄存器只读,同时支持主站一次性读取所有寄存器,核心思路是通过写回调函数拦截非法写入请求,具体步骤如下:

  • 第一步:标记只读寄存器范围
    先在代码里定义需要设为只读的寄存器地址范围,比如:

    // 示例:地址10到14的寄存器设为只读(共5个)
    #define READ_ONLY_REG_START 10
    #define READ_ONLY_REG_COUNT 5
    

    如果是离散的单个寄存器,也可以用数组存储只读地址列表,后续在回调里逐个比对。

  • 第二步:修改Modbus写回调函数
    在ESP-IDF示例的mb_slave_cb回调中,针对MB_REG_WRITE和MB_REG_WRITE_MULTIPLE类型的请求,添加权限校验逻辑:

    esp_err_t mb_slave_cb(esp_mb_param_group_t *param_group, const esp_mb_param_info_t *param_info,
                          esp_mb_cmd_type_t cmd_type, void *context)
    {
        esp_err_t err = ESP_OK;
        switch (cmd_type) {
            case MB_REG_WRITE:
            case MB_REG_WRITE_MULTIPLE: {
                uint16_t req_start = param_info->start_offset;
                uint16_t req_count = param_info->param_count;
                uint16_t ro_end = READ_ONLY_REG_START + READ_ONLY_REG_COUNT;
                
                // 检查请求的寄存器范围是否与只读范围重叠
                if (!(req_start + req_count <= READ_ONLY_REG_START || req_start >= ro_end)) {
                    // 存在只读寄存器,返回错误拦截写入
                    err = ESP_ERR_INVALID_ARG;
                    break;
                }
                // 校验通过,执行原有写逻辑
                // (此处保留示例中原有的寄存器值更新代码)
                break;
            }
            case MB_REG_READ:
                // 读操作不做限制,所有寄存器均可正常读取
                // (保留示例中原有的读逻辑代码)
                break;
            default:
                err = ESP_ERR_NOT_SUPPORTED;
                break;
        }
        return err;
    }
    
  • 第三步:错误码映射说明
    返回的ESP_ERR_INVALID_ARG会被ESP-IDF的Modbus栈自动转换为Modbus协议的MB_EX_ILLEGAL_DATA_VALUE异常码,主站收到后会知晓该写入请求无效,等同于这些寄存器是只读属性。

这种方案既保留了所有寄存器在同一保持寄存器区域(支持一次性批量读取),又精准拦截了对特定寄存器的写入操作,完全匹配你的需求。

内容的提问来源于stack exchange,提问作者JimitD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 23:25:20