數(shù)據(jù)字節(jié)對(duì)齊案例
1、發(fā)現(xiàn)問(wèn)題
項(xiàng)目需要使用上位機(jī)配置,所以列了一個(gè)結(jié)構(gòu)體包含了浮點(diǎn)數(shù)和整形和短整型,可以查看下面的數(shù)據(jù),
union { struct { float AD[AD_NUM];//當(dāng)前AD工程量 32 0 R u8 DX[DI_NUM];//當(dāng)前輸入 4 32 R u8 DY[DO_NUM];//當(dāng)前輸出 2 36 RW u8 AD_EN[AD_NUM]; //使用工程量 8 38 不適用默認(rèn)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采樣數(shù) 16 110 RW float DISampNum[DI_NUM]; //DI濾波時(shí)間 單位 ms 16 126 RW u8 DO_StopOut[DO_NUM];//停機(jī)輸出 2 142 RW u8 CorreEN[AD_NUM];//修正啟用 默認(rèn)不啟用防止誤操作 8 144 RW float ZeroCorre[AD_NUM];//AD零點(diǎn)修正值 32 152 RW float CoefCorre[AD_NUM];//AD系數(shù)修正值 32 184 RW u8 ZZZZZ[10];//預(yù)留 10 216 RW u8 AllCorreEN;//一鍵零點(diǎn)修正 1 226 RW u8 AllDefault;//恢復(fù)默認(rèn)值 1 227 RW u8 NAddr;//從站地址 1 228 RW union { struct { u8 len:1;//數(shù)據(jù)長(zhǎng)度[0] :0- 8位;1-7位 u8 cek:2;//奇偶校驗(yàn)[1:2] :00-無(wú)校驗(yàn); 01-奇校驗(yàn)O; 11-偶校驗(yàn)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;
正常來(lái)說(shuō)數(shù)據(jù)正常我的240開(kāi)始應(yīng)該是我定義的版本數(shù)據(jù):v1.0 :
實(shí)際卻是這樣子,偏移了4位,

2、查找問(wèn)題
既然位置不對(duì),全部賦值檢查位置數(shù)據(jù)哪里開(kāi)始錯(cuò)誤;
一步步找發(fā)現(xiàn)在地址 46和47這邊卻沒(méi)有數(shù)據(jù),我明明已經(jīng)全部賦值了,毛病就在這里!但是是什么原因?qū)е碌哪兀?/p>

檢查數(shù)據(jù)類(lèi)型和長(zhǎng)度

在單字節(jié)類(lèi)型的后面出錯(cuò),后面是浮點(diǎn)型4字節(jié),照理來(lái)說(shuō)沒(méi)錯(cuò)啊;一萬(wàn)個(gè)馬崩騰而過(guò)。。。又來(lái)bug了嗎。。。
3.解決問(wèn)題
突然想到是兩個(gè)有問(wèn)題,上面的單字節(jié)的長(zhǎng)度加起來(lái)只有 14 ,加上2就是16,16才能字節(jié)對(duì)齊。下面還有一個(gè)也是只有2字節(jié)的沒(méi)對(duì)齊,補(bǔ)齊的話加起來(lái)剛好4個(gè),也就是偏移的4個(gè)數(shù)據(jù);
感覺(jué)有戲,把下面的2個(gè)字節(jié)的提上來(lái),修改后的結(jié)構(gòu)體
union { struct { float AD[AD_NUM];//當(dāng)前AD工程量 32 0-31 R u8 DX[DI_NUM];//當(dāng)前輸入 4 32-35 R u8 DY[DO_NUM];//當(dāng)前輸出 2 36-37 RW u8 DO_StopOut[DO_NUM];//停機(jī)輸出 2 38-39 RW u8 AD_EN[AD_NUM]; //使用工程量 8 40-47 不適用默認(rèn)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采樣數(shù) 16 112-127 RW float DISampNum[DI_NUM]; //DI濾波時(shí)間 單位 ms 16 128-143 RW u8 CorreEN[AD_NUM];//修正啟用 默認(rèn)不啟用防止誤操作 8 144-151 RW float ZeroCorre[AD_NUM];//AD零點(diǎn)修正值 32 152-183 RW float CoefCorre[AD_NUM];//AD系數(shù)修正值 32 184-215 RW u8 ZZZZZ[10];//預(yù)留 10 216-225 RW u8 AllCorreEN;//一鍵零點(diǎn)修正 1 226 RW u8 AllDefault;//恢復(fù)默認(rèn)值 1 227 RW u8 NAddr;//從站地址 1 228 RW union { struct { u8 len:1;//數(shù)據(jù)長(zhǎng)度[0] :0- 8位;1-7位 u8 cek:2;//奇偶校驗(yàn)[1:2] :00-無(wú)校驗(yàn); 01-奇校驗(yàn)O; 11-偶校驗(yàn)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;
重新編譯,見(jiàn)證奇跡!!

完美解決
后話:其實(shí)原來(lái)都是理論上說(shuō)道什么字節(jié)對(duì)齊什么的,實(shí)際中遇到的沒(méi)有,有時(shí)可能這輩子都根本不會(huì)遇到,遇到這實(shí)際的問(wèn)題拿出來(lái)分享一下,給大家點(diǎn)實(shí)際體會(huì),希望對(duì)大家有幫助!!

浙公網(wǎng)安備 33010602011771號(hào)