处理字节顺序
一个地址存一个字节?
字节顺序描述如何在计算机系统中表示有多个字节组成的数据。
定义:数据在计算机系统中的存储格式,描述了存储器中地址的MSB和LSB的位置。
字节顺序结构类型:
大端模式:将MSB保存在最低存储器地址处;
小端模式:将LSB保存在最低存储器地址处;
按原生数据类型引用数据时,两种字节顺序存储的多字节数据域相同,但是在按字节或半字类型访问数据时,字域次序和系统的字节顺序配置相关。
小端取址:字的最低有效字节占据存储器中该字的最低字节地址;
大端取址:字的最低有效字节保存在高阶字节地址上,最高有效字节保存在低阶字节低智商。
若以半字方式处理时,存储器的地址必须时2的倍数,两种取址模式的地址安排如下,但在半字中,字节保持与字中相同的次序:
通常字节顺序对于用户是透明的,但是在数据必须跨越字节顺序模式时往往会带来麻烦(以大端模式存储,以小端模式获取?)。
小端模式与大端模式的优点
小端模式:地址偏移量和字节数之间为1:1的关系,对于多精度的数学程序编写相对容易;
大端模式:由于先访问高阶字节,可以通过查看偏移量为0的字节来判断数值的正负;
大多数位图图像(显示和内存安排)为MSB在左的方案,使体系结构能自然移动和存储大于一个字节的图像元素。
大多数嵌入式童星处理器和定制解决方案在数据层采用打断模式,因为这些处理器所写的老程序通常尊徐网络字节顺序(大端模式)。
字节顺序不匹配问题
两个系统中通过存储器通信,两种字节顺序会产生冲突,需要用软件进行重新排序。
或者是在同一网络中,使用不同字节顺序的处理器进行通信,因此网络协议栈和通信协议必须定义字节顺序,否则不同字节顺序的两个节点可能无法通信。
TCP/IP族中所有的协议层都定义为大端模式;即使各终端计算机都是小端模式,他们之间所传输的数据必须在通过网络前先转换为网络字节顺序,然后在接收端再转换为小端模式。
访问32位存储器
对8位,16位和32位存储器的访问。即当字节分别以8、16、32位的形式存放时,分别使用大端模式和小端模式,地址与字节的映射关系以及地址内各个字节的相对顺序。
处理字节顺序不匹配
在若干IP的片上系统中必然会发生字节顺序不匹配的问题,几乎所有第三方公司的IP都支持与处理器相同的字节顺序类型。
处理字节顺序不匹配方法:
系统选择一种字节顺序类型,并将其他不同字节顺序的模块转化为目标字节顺序类型。
在对第三方IP选型时,需要确认其是否支持双字节顺序结构,以便根据系统的字节顺序选择合适的字节顺序。
如果不支持,则需要在将IP集成到SoC的过程中解决该问题。
有两种连接相反字节顺序外设的方法:选择将地址保持稳定或将位顺序保持稳定。
(不理解 看书)保持数据完整性(数据不变)
由于不同的字节顺序模式下多字节域具有不同的字节地址,因此,如果将多字节域作为单个条目进行操作,那么当其在各IP之间移动时,必须保留该条目的位次序。
数据流:
从小端设备到大端存储器,并保持数据不变的数据流如下:
- DMA发出对外设存储器的读字节操作;
- 举个例子,系统产生的地址为0x00,在数据变化的实现中,小端设备RAM看到的地址为0x03;
- 设备存储器对该地址解码,访问31:24;
- 外设输出该值为{‘Type’,'0x000000'};
- DMA对系统的大端存储区发出按字节方式的写操作;
- 再次产生0x00的地址;
- 大端存储器将该访问地址解码为输入为31:24;
- 由于来自于小端存储器的数据处于同样的字节区域,因此可以保持数据的完整性并将数据保存在大端RAM中;
- 对其他需要从外设RAM传输到系统RAM中的数据继续进行该操作;
(不理解 看书)地址不变
- DMA发出对外设存储器的读字节操作;
- 举个例子,系统产生的地址为0x00,地址不变的实现使地址值始终相同;
- 外设RAM对改地址解码,访问7:0区域;
- 外设输出该值为{'0x000000',‘H0’},由于字节顺序匹配值地址不变,给系统RAM的数据变为{‘H0’,'0x000000'};
- DMA对系统的大端存储区发出按字节方式的写操作;
- 再次产生0x00的地址;
- 大端存储器将该访问地址解码为输入为31:24;
- 在字节顺序转换完成后,从小端存储器读出的数据已处在相同的地址区域,吧数据存入大端RAM;
- 对其他需要从外设RAM传输到系统RAM中的数据继续进行该操作;
字节顺序中性代码
为避免由字节顺序所引发问题的最好方式是在设计中使用字节顺序中性,可以通过两种途径完成这一任务:
- 将字节顺序选项作为软件可配置的选项;
- 在设计(IP)中使用字节使能,并将解码的任务留给系统或SoC;
字节顺序中性编码指南(不理解)
字节顺序中性代码可以通过标识外部软件接口实现,遵循下面的指南来访问这种接口:
1) 数据存储和共享存储体——数据必须以独立于字节顺序体系结构的格式保存;可通过使用文本文件或指定仅用来保存数据的字节顺序格式(以使数据总是写成相同的格式)等方法完成;或者使用能理解所存数据字节顺序格式的宏对数据访问进行包装,该宏与主处理器的理解方式,允许宏基于字节顺序进行字节交换;
2) 字节交换宏——宏能用于所有多字节数据接口进行交换操作;
3) 数据传送——可以建立特定宏来从网络读数据或写入网络中,根据输入数据的类型,可以用宏来进行批量字节交换;
4) 数据类型——以本地数据类型访问数据。例如总以init类型读写整数,而不是读写4个字节的方式。一种可供选择的方法是使用自定义的字节顺序中性红来访问多字节数字类型中的特定字节。不遵守这条直男会导致不同字节顺序体系结构间的代码箭筒问题。
5) 位域——避免定义跨越字节边界的位域;
6) 编译器指令——在使用会影响到数据存储(对齐、包装)的编译指令时要特别小心。指令子啊不同编译器之间并不是总能移植的。