Giter VIP home page Giter VIP logo

agile_modbus's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

agile_modbus's Issues

[bug]在swtich的case中定义变量,导致指针指向该变量的地址被其他变量使用

在swtich的case中定义变量,导致指针指向该变量的地址被其他变量使用

运行环境

  • 硬件:STM32F429IGT6单片机
  • 操作系统:RTT 5.0.0
  • 使用串口V2驱动:使用收发DMA
  • 编译:KEIL AC6编译器
  • 使用MODBUS RTU 从机功能

错误情况

  • AC6编译器使用-O0优化,上位机进行线圈写入True成功。上位机发送成功,上位机发送读取该寄存器写入为True.
  • AC6编译器使用-Oz优化,上位机进行线圈写入True失败。上位机发送成功,上位机发送读取该寄存器写入为False.
    例如对线圈地址0X02写入True,读取回来还是FALSE。

错误原因

  • data 变量在case中定义,在退出该case时,该地址已经被释放,导致该地址被其他变量使用,导致写入失败。
  • slave_info.buf = (uint8_t *)&data;该代码使用挂钩data地址,退出case时,地址已被认为可以使用。
    case AGILE_MODBUS_FC_WRITE_SINGLE_COIL: {
        //! warning: comparison is always false due to limited range of data type [-Wtype-limits]
        #if 0
        if (address > 0xFFFF) {
            exception_code = AGILE_MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
            break;
        }
        #endif

        int data = (req[offset + 3] << 8) + req[offset + 4];
        if (data == 0xFF00 || data == 0x0)
            data = data ? 1 : 0;
        else {
            exception_code = AGILE_MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE;
            break;
        }
        slave_info.buf = (uint8_t *)&data;
        rsp_length = req_length;
        if (ctx->send_bufsz < (int)(rsp_length + ctx->backend->checksum_length)) {
            exception_code = AGILE_MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE;
            break;
        }
        memcpy(rsp, req, req_length);
    } break;

debug查看

slave_info.buf = (uint8_t *)&data;
  • 使用全局变量debug_slave_info 获取slave_info地址
volatile struct agile_modbus_slave_info *debug_slave_info = {0};
debug_slave_info = &slave_info;
  • 代码运行后,slave_info.buf指向地址
    image

  • 该地址内存如下
    image

  • 进入write_registers函数后map数组地址变为和slave_info.buf一致,这时map数组还未被赋值
    image
    不用查看内存都可以看出,目前内容还未修改,首地址为0x01.

  • 后续运行至memset,地址内容被清除
    image

  • 运行map->get再次被修改
    image

以上是-OZ情况,-O0情况如下

slave_info.buf = (uint8_t *)&data;
  • 运行该函数后
    image

  • 进入write_registers函数后,可以看出地址不一致
    image

所以在case中定义的变量使用指针挂钩该变量地址会出现问题

  • 是编译器优化导致的,但是该优化是合理的。case里变量等于是静态变量,且作用域只在case中。

建议

  • data函数改为在函数开头初始化,case里不进行定义。
    已测试在-OZ优化下,线圈读写成功,保持寄存器读写成功。

我看从机代码,有一个问题咨询?

我看了一下从机的代码,一方面对于map_buf数组长度有限制,这个还不是主要问题(因为Modbus协议本身就有定义每次最多只允许操作124个寄存器).
但是不管是读取寄存器还是写入寄存器,你都需要把该字段的所有寄存器全部读取一次,这样的操作是否有冗余,这样的操作是为什么?理论上读取寄存器我们只需要读取对应的寄存器就好了,不需要把整个字段的寄存器都读取出来。写入寄存器的时候也不需要读取寄存器啊!所以这一块没有特别搞懂?是否可以优化。

agile_modbus_rtu_check_integrity校验不通过

按照库中校验函数,高位在后地位在前,agile_modbus_rtu_check_integrity中crc_received的值的算法是颠倒的
`
static int agile_modbus_rtu_check_integrity(agile_modbus_t *ctx, uint8_t *msg, const int msg_length)
{
uint16_t crc_calculated;
uint16_t crc_received;

crc_calculated = agile_modbus_rtu_crc16(msg, msg_length - 2);
crc_received = (msg[msg_length - 2] << 8) | msg[msg_length - 1];/*该处应修改为crc_received = (msg[msg_length - 1] << 8) | msg[msg_length - 2];*/

//mrd_log_printf(MRD_DEBUG,"crc_calculated = %d,crc_received=%d\n",crc_calculated,crc_received);
/* Check CRC of msg */
if (crc_calculated == crc_received)
    return msg_length;

return -1;

}
`

提一个新功能的想法

希望能加一个接口,可以无需主机请求,主动推送对应的数据。
接口只需要传入功能码,起始地址,结束地址即可。

尽快适配一下 RT-Thread

看了一下,目前在 rt-thread 中使用,还需要改不少地方,不知道您什么是否能够适配完?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.