OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3883|回复: 2

求STM32的非对齐写入的高效办法?

[复制链接]

4

主题

15

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2016-3-3
在线时间
19 小时
发表于 2016-3-3 13:03:28 | 显示全部楼层 |阅读模式
最近一遇到一个STM32,4byte字写入的问题:
要写一个数据读取的函数,将一个4byte位宽的FIFO的缓冲区的数据读写到一段由一个8bit uchar型指针变量指向的RAM空间数组中,而读取函数要求根据写入字节byte长度和写入起始字节byte偏移量来两个参数值来将FIFO缓冲区读到的数据写入到变量指定的以字节byte为单位的RAM空间中,导致写入RAM空间地址不一定对齐4byte字地址且写入长度又不一定为4byte字的整倍数,那么,编程要怎样才能最高效地作非4byte字对齐的转存操作呢?
这个数据读取的函数声明格式为:"u8 Rfun(u8 *Darr_u8P,u32 offset,u32 RdataL)"
u8* Darr_u8P为要写入RAM空间数组的指针输入。
u32 offset为写入的byte字节偏移量输入。
u32 RdataL为要写入的字节byte长度。

我初时使用一个u32型指针来实现整4byte的读存:
u32 * Darr_u32P=(u32 *)(Darr_u8P+offset);
while(RdataL>=4)
{
    *(Darr_u32P++)= XFIFO;   //XFIFO为FIFO缓冲区的读取寄存器,u32类型。
    RdataL-=4;
}
但当Darr_u32P得到的地址值不是4byte字对齐地址时,就会触发硬件错误中断Hard Fault。
而是当Darr_u32P得到的地址值不是4byte字对齐地址时,我就只能使用一个u32型临时变量Utemp 来转存了:
union {u32 bit32;        u8 bit8[4];} Utemp;
Darr_u8P+=offset;
while(RdataL>=4)
{
      Utemp.bit32 = XFIFO;   //XFIFO为FIFO缓冲区的读取寄存器,u32类型。
      *(Darr_u8P++)=Utemp.bit8[0];
      *(Darr_u8P++)=Utemp.bit8[1];
      *(Darr_u8P++)=Utemp.bit8[2];
      *(Darr_u8P++)=Utemp.bit8[3];
      RdataL-=4;
}

这样虽然不触发硬件错误中断Hard Fault了,但这样是一个32bit MCU在用8bit MCU的方式来转存数据,效率就变低了,那么有哪位大神有更好的办法来实现非4byte字地址对齐的4byte字RAM写入呢?

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

1097

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3571
金钱
3571
注册时间
2014-12-2
在线时间
365 小时
发表于 2016-3-3 14:12:17 | 显示全部楼层
先写1-3个字节,将地址对齐
然后再4字节地写,就不会出错了,
最后再把剩余的1-3个字节写入
如图:

x.png

先写逐字节蓝色,再四字节写绿色,最后再逐字节写紫色。

这其中你只需要在首尾判断地址是否对齐,效率很高
坚决不用寄存器,拒绝重复造轮子。
回复 支持 反对

使用道具 举报

4

主题

15

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2016-3-3
在线时间
19 小时
 楼主| 发表于 2016-3-3 14:26:39 | 显示全部楼层
xkwy 发表于 2016-3-3 14:12
先写1-3个字节,将地址对齐
然后再4字节地写,就不会出错了,
最后再把剩余的1-3个字节写入

我也知道这个方法,但这个方法绿色部分要求XFIFO读到的4byte字要转写入的空间地址也是4byte字对齐才行,否则还要utemp临时变量来缓存,而且还要作位移异或操作。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-21 02:54

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表