IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 复旦微FMQL(国产Zynq) 【IAR裸机开发之PS】——非字节对齐访问 -> 正文阅读

[嵌入式]复旦微FMQL(国产Zynq) 【IAR裸机开发之PS】——非字节对齐访问

关注+星标公众,及时获取更多技术分享~?

?作者 | 冰茶奥利奥

微信公众号?|?嵌入式电子创客街?


在x86架构下,我们经常会有这种操作:

uint8_t?TestBytes[10]?=?{0,?1,?2,?3,?4,?5,?6, 7};
uint32_t?IntData;
IntData?=?*(uint32_t?*&)TestBytes[2];
//输出结果
>>IntData?=?0x05040302;?//大端
>>IntData?=?0x02030405;?//小端

对一个单字节数组进行取地址,然后强制转换为整数指针后取值,再赋值给IntData变量。

这样赋值后,如果CPU是常规的小端模式(Little End)的话,IntData的赋值结果就是0x5432;如果是大端模式的话,就是0x2345。相当于把数组TestBytes里的元素值依次赋给了IntData的四个字节。如下图所示:

使用地址强制取值操作

白嫖君在以前使用过的芯片中都这样操作过,包括Cortex-M3、M4,还有PowerPC架构的,还有Linux平台下也是这样使用的。但是最近在使用复旦微的Fmql芯片时,在程序里进行了类似的操作,结果程序直接就进入地址访问异常中断了。

白嫖君表示不理解,难道自己的认知有什么局限性吗?我大致猜测和地址对齐是有关系的。于是白嫖君做了个试验,把代码改成下面这样就能够正确执行:

uint8_t?TestBytes[10]?=?{0,?1,?2,?3,?4,?5, 6, 7};
uint32_t IntData;
IntData = *(uint32_t *&)TestBytes[4];
uint16_t ShortData;
ShortData= *(uint16_t *&)TestBytes[2];
//输出结果
>>IntData = 0x07060504;
>>ShortData?=?0x0302;

从这次的结果可以看到,只要取得数据地址是按照字节对齐的,就能够正常执行,否则就会执行异常。

或许是因为堆栈定义在DDR的问题么?毕竟DDR的地址取用一次是64位的。于是白嫖君重新写了个程序,把堆栈定义在芯片内部的RAM中,现象一致,说明并不是DDR的问题,可是之前用Xilinx的芯片也没有类似的问题啊!

莫非是IAR的问题吗?白嫖君上网搜索后发现有人用Keil做实验,也出现过这种现象,但是在stm32上做却能正常执行。原来在《Cortex-M3权威指南》中有写道:

The Cortex-M3 processor also supports unaligned data accesses, a feature previously available only in high-end processors.

大概意思就是说,Cortex-M3 处理器还支持非对齐的数据访问,这是以前仅在高端处理器中可用的功能...?好吧知道你厉害行了吧?在这里我们注意到了一个词:unaligned access(非对齐访问),也就是这篇文章的核心了。下面这张图形象的展示了芯片非对齐访问时的实际操作步骤:即跨对齐边界,底层要拆成两个访问 ,然后把数据合并之返回,这个是指令底层微架构,软件层是看不到底层细节的。

非对齐访问指令层操作

Cortex-M3支持非字节对齐访问,那么我们用的Fmql的ARM核支持吗?莫非是芯片架构的问题?白嫖君在前面的文章中提到过,Xilinx用的是两片Cortex-A9,而复旦微用的是四片Cortex-A7,是不是这两种芯片有什么细微的差异呢?

查阅了一系列资料后,白嫖君发现,自从ARM-v7架构后,都支持了非对齐访问,我们常用的Cortex-M3和M4就属于ARM-v7架构,A7和A9两种芯片也都是该架构下的。

ARM-v7架构支持的子架构

那么既然芯片是支持非对齐访问的,还有什么原因会导致执行出错呢?别急,非对齐访问还是有条件的:

  1. SCTRL.A寄存器必须配置为0;

  2. 只有部分访存指令支持非对齐访问;

  3. 所访问的地址空间存储器类型不能为strongly-order或device-memory;

  4. 编译器使能了非对齐访问。

怎么理解这4个条件呢?

ARM-v7支持非对齐访问的条件

从上图可以看到汇编指令LDRB,LDRH,LDR,分别对应 C语言的char,short,int。LDRB是按字节访存的,没有对齐要求,LDRH是2字节对齐(地址要求是 2的倍数),LDR则是4字节对齐(地址要求是4的倍数)。

那么白嫖君就把问题定位到第3条和第4条了,针对第4条,首先检查IAR的设置,网络上有一个答案说在IAR的编译选型里加上一条“–no_unaligned_access”语句,但是这只是让编译器避免编译出非对齐访问的情况,对于我们这种强制非对齐访问的根本起不到什么作用。

既然问题的根本不在编译器,那么白嫖君的问题出在哪了呢?其实是在MMU Table表里面。首先要使能MMU,就是分页内存管理单元,如果不使能,直接按strongly-ordered处理(类似寄存器的地址都是无法非对齐访问的)。

非对齐访问必须使能MMU

那么为啥在Cortex-M3、M4里不需要使能MMU呢?因为它本身就没有MMU啊。

那么使能MMU后,怎么才能更改存储空间的属性呢?在mmu_table.s里面看到这行语句。

/*  (DDR Cacheable) */
SECT    set     SECT+0x100000
        rept    DDR_REG_CACHE  
/* S=b0 TEX=b000 AP=b11, Domain=b0000, C=b0, B=b0 */
/*重点是这个值*/
????????DC32????SECT?+?0xC02?
SECT    set     SECT+0x100000
????????endr

这个0xC02就是把这片存储空间定义成了device memory,就是前面提到的不能非对齐访问的情况;那么怎么修改呢?改成normal memory属性。

/*  (DDR Cacheable) */
SECT    set     SECT+0x100000
        rept    DDR_REG_CACHE  
/* S=b1 TEX=b101 AP=b11, Domain=b1111, C=b0, B=b1 */  
/*重点是这个值*/      
        DC32    SECT + 0x15DE6 
SECT    set     SECT+0x100000
        endr

我们从ARM的手册里可以看到如何去定义memory的属性,如下图所示:

memory属性描述表

白嫖君把memory属性设置成了可读可写的normal memory,这样就能愉快地非对齐访问了~

但是根据这次的教训,我们得知,非字节对齐访问并不是所有的芯片都能支持的,比如Cortex-M0,所以我们编程的时候,还是要尽量避免非字节对齐访问的操作,以提高我们程序的可移植性。


如果您觉得这篇文章帮到了你,请点赞或者留下您的评论,您的鼓励是我前进的动力~

关注博主公众号 “嵌入式电子创客街” 获取更多及时技术分享~

??关注+星标公众,及时获取更多技术分享~?

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:39:38  更:2022-07-17 16:40:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 0:49:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码