zoukankan      html  css  js  c++  java
  • 数据字节对齐案例

    1、发现问题

    项目需要使用上位机配置,所以列了一个结构体包含了浮点数和整形和短整型,可以查看下面的数据,

    union
     {
      struct
      {
       float AD[AD_NUM];//当前AD工程量 32 0 R
       u8 DX[DI_NUM];//当前输入 4  32 R
       u8 DY[DO_NUM];//当前输出 2 36  RW
    
       u8 AD_EN[AD_NUM]; //使用工程量 8 38 不适用默认0-32000 RW
       float AD_LLim[AD_NUM]; //AD工程量下限 32 46 RW 
       float AD_HLim[AD_NUM]; //AD工程量上限 32 78 RW
       u16 ADSampNum[AD_NUM]; //AD采样数 16 110 RW
    
       float DISampNum[DI_NUM]; //DI滤波时间 单位 ms 16 126 RW
       u8 DO_StopOut[DO_NUM];//停机输出 2 142 RW
       u8 CorreEN[AD_NUM];//修正启用  默认不启用防止误操作 8 144 RW
       float ZeroCorre[AD_NUM];//AD零点修正值 32 152 RW
       float CoefCorre[AD_NUM];//AD系数修正值 32 184 RW
       u8 ZZZZZ[10];//预留 10 216 RW
       u8 AllCorreEN;//一键零点修正 1 226 RW
       u8 AllDefault;//恢复默认值 1 227 RW
       u8 NAddr;//从站地址 1 228    RW
       union
       {
        struct
        {
         u8 len:1;//数据长度[0] :0- 8位;1-7位
         u8 cek:2;//奇偶校验[1:2] :00-无校验; 01-奇校验O; 11-偶校验E
         u8 stop:1;//停止位[3]:0-1位;1-2位 
         u8 bood:4;//波特率[4-7]:0-9600; 1-19200;2-38400;3-57600; 4-115200
        }stu;
        u8 Da;// 1 229通讯配置:    RW
       }COMx;
       char ModeName[10];//10 230 名字 R
       char ModeVnum[10];//10 240 版本 R
      }stuTD;
      u8 Arr[BM_LEN];
     }uniCFG;

    正常来说数据正常我的240开始应该是我定义的版本数据:v1.0  :

    实际却是这样子,偏移了4位,

    2、查找问题

    既然位置不对,全部赋值检查位置数据哪里开始错误;

    一步步找发现在地址 46和47这边却没有数据,我明明已经全部赋值了,毛病就在这里!但是是什么原因导致的呢?

    检查数据类型和长度

    在单字节类型的后面出错,后面是浮点型4字节,照理来说没错啊;一万个马崩腾而过。。。又来bug了吗。。。

    3.解决问题

    突然想到是两个有问题,上面的单字节的长度加起来只有 14 ,加上2就是16,16才能字节对齐。下面还有一个也是只有2字节的没对齐,补齐的话加起来刚好4个,也就是偏移的4个数据;

    感觉有戏,把下面的2个字节的提上来,修改后的结构体

    union
        {
            struct
            {
                float AD[AD_NUM];//当前AD工程量 32 0-31 R
                u8 DX[DI_NUM];//当前输入 4  32-35 R
                u8 DY[DO_NUM];//当前输出 2 36-37  RW
                u8 DO_StopOut[DO_NUM];//停机输出 2 38-39 RW
                u8 AD_EN[AD_NUM]; //使用工程量 8 40-47 不适用默认0-32000 RW
                float AD_LLim[AD_NUM]; //AD工程量下限 32 48-79 RW 
                float AD_HLim[AD_NUM]; //AD工程量上限 32 80-111 RW
                u16 ADSampNum[AD_NUM]; //AD采样数 16 112-127 RW
    
                float DISampNum[DI_NUM]; //DI滤波时间 单位 ms 16 128-143 RW
                u8 CorreEN[AD_NUM];//修正启用  默认不启用防止误操作 8 144-151 RW
                float ZeroCorre[AD_NUM];//AD零点修正值 32 152-183 RW
                float CoefCorre[AD_NUM];//AD系数修正值 32 184-215 RW
                u8 ZZZZZ[10];//预留 10 216-225 RW
                u8 AllCorreEN;//一键零点修正 1 226 RW
                u8 AllDefault;//恢复默认值 1 227 RW
                u8 NAddr;//从站地址 1 228    RW
                union
                {
                    struct
                    {
                        u8 len:1;//数据长度[0] :0- 8位;1-7位
                        u8 cek:2;//奇偶校验[1:2] :00-无校验; 01-奇校验O; 11-偶校验E
                        u8 stop:1;//停止位[3]:0-1位;1-2位 
                        u8 bood:4;//波特率[4-7]:0-9600; 1-19200;2-38400;3-57600; 4-115200
                    }stu;
                    u8 Da;// 1 229通讯配置:       RW
                }COMx;
                char ModeName[10];//10 230-239 名字 R
                char ModeVnum[10];//10 240-249 版本 R
            }stuTD;
            u8 Arr[BM_LEN];
        }uniCFG;

    重新编译,见证奇迹!!

    完美解决

    后话:其实原来都是理论上说道什么字节对齐什么的,实际中遇到的没有,有时可能这辈子都根本不会遇到,遇到这实际的问题拿出来分享一下,给大家点实际体会,希望对大家有帮助!!

     

  • 相关阅读:
    Kubernetes 1.5 配置dns
    详细图解,一眼就能看懂!卷帘快门(Rolling Shutter)与全局快门(Global Shutter)的区别
    把C#程序(含多个Dll)合并成一个Exe的超简单方法
    TortoiseSVN 合并操作简明教程
    简单说说.Net中的弱引用
    漫谈并发
    可靠UDP设计
    自动内存管理算法 —— 标记和复制法
    Unity防破解 —— 加密Dll与Key保护
    Unity防破解 —— 重新编译mono
  • 原文地址:https://www.cnblogs.com/luckytimor/p/11212485.html
Copyright © 2011-2022 走看看