| |
|
开发:
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架构下,我们经常会有这种操作:
对一个单字节数组进行取地址,然后强制转换为整数指针后取值,再赋值给IntData变量。 这样赋值后,如果CPU是常规的小端模式(Little End)的话,IntData的赋值结果就是0x5432;如果是大端模式的话,就是0x2345。相当于把数组TestBytes里的元素值依次赋给了IntData的四个字节。如下图所示: 使用地址强制取值操作 白嫖君在以前使用过的芯片中都这样操作过,包括Cortex-M3、M4,还有PowerPC架构的,还有Linux平台下也是这样使用的。但是最近在使用复旦微的Fmql芯片时,在程序里进行了类似的操作,结果程序直接就进入地址访问异常中断了。 白嫖君表示不理解,难道自己的认知有什么局限性吗?我大致猜测和地址对齐是有关系的。于是白嫖君做了个试验,把代码改成下面这样就能够正确执行:
从这次的结果可以看到,只要取得数据地址是按照字节对齐的,就能够正常执行,否则就会执行异常。 或许是因为堆栈定义在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架构支持的子架构 那么既然芯片是支持非对齐访问的,还有什么原因会导致执行出错呢?别急,非对齐访问还是有条件的:
怎么理解这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里面看到这行语句。
这个0xC02就是把这片存储空间定义成了device memory,就是前面提到的不能非对齐访问的情况;那么怎么修改呢?改成normal memory属性。
我们从ARM的手册里可以看到如何去定义memory的属性,如下图所示: memory属性描述表 白嫖君把memory属性设置成了可读可写的normal memory,这样就能愉快地非对齐访问了~ 但是根据这次的教训,我们得知,非字节对齐访问并不是所有的芯片都能支持的,比如Cortex-M0,所以我们编程的时候,还是要尽量避免非字节对齐访问的操作,以提高我们程序的可移植性。 如果您觉得这篇文章帮到了你,请点赞或者留下您的评论,您的鼓励是我前进的动力~ 关注博主公众号 “嵌入式电子创客街” 获取更多及时技术分享~ ??关注+星标公众号,及时获取更多技术分享~? |
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
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- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |