读取Flash中128位值遇字节序问题:如何转换为目标值?
解决Flash读取128位值的字节异常问题
嘿,我帮你仔细对比了目标值和你读取到的结果,发现了问题所在——这其实不是传统的大小端字节序问题,而是每个字节的高低四位(半字节)被反转了!咱们一步步来解决:
首先看你的目标128位值 0171EC07F2E6C383FFFFFFFFFFFFFFFF,拆成单个字节(按大端高位在前的顺序)是:0x01, 0x71, 0xEC, 0x07, 0xF2, 0xE6, 0xC3, 0x83, 0xFF, ..., 0xFF
再看你读取到的字节:0x10, 0x17, 0xCE, 0x70, 0x2F, 0x6E, 0x3C, 0x38, 0xFF, ..., 0xFF
你仔细看每个字节:0x01变成了0x10,0x71变成0x17,0xEC变成0xCE——这明显是把每个字节的高低四位交换了!比如0x01是0000 0001,交换后就是0001 0000也就是0x10,完全对应上你的读取结果。
接下来咱们用代码修正这个问题:
1. 写个半字节交换的小函数
先搞个辅助函数,专门用来交换单个字节的高低四位:
uint8_t swap_nibbles(uint8_t byte) { // 提取低四位左移4位,提取高四位右移4位,再合并 return ((byte & 0x0F) << 4) | ((byte & 0xF0) >> 4); }
2. 修改你的读取逻辑
在原来的读取循环里,给每个读到的字节做个半字节交换再存起来,顺便把printf的格式改成%02x,这样输出的十六进制会是两位,方便对比:
uint8_t *address = (uint8_t *)0x34576; uint8_t reg[16] = {0}; for (int i = 0; i < 16; i++) { uint8_t read_byte = *address++; reg[i] = swap_nibbles(read_byte); // 这里加个半字节交换 printf("reg[%d]= 0x%02x\r\n", i, reg[i]); }
3. 验证结果
跑这个修正后的代码,你应该就能得到和目标值完全匹配的字节序列了:
reg[0]= 0x01 reg[1]= 0x71 reg[2]= 0xec reg[3]= 0x07 reg[4]= 0xf2 reg[5]= 0xe6 reg[6]= 0xc3 reg[7]= 0x83 reg[8]= 0xff ... reg[15]= 0xff
补充:如果真的是大小端问题的处理(备用)
要是后续排查发现确实是大小端字节序的问题(比如Flash用大端存,你的CPU是小端),那可以反转整个16字节的顺序,代码大概是这样:
uint8_t reversed_reg[16]; for (int i = 0; i < 16; i++) { reversed_reg[i] = reg[15 - i]; }
不过根据你现在的读取结果,这个方案肯定不适用,优先用半字节交换的方法就好。
内容的提问来源于stack exchange,提问作者tester123
相关产品推荐
相关产品推荐

