linux 下ARM 与X86之间对外部设备IO映射的区别

最近在做CAN驱动的移植工作,具体就是将X86平台的驱动移植到ARM上面。芯片采用的是philips的sja1000芯片,ARM pxa27x。将CAN的驱动直接交叉编译比较容易通过,不过,编译完成后,运行的时候驱动始终无法发出第一帧。

以下是发送原理

        芯片及程序的工作原理是这样的,首先通过发送寄存器发出第一帧数据,然后会触发一个中断,中断处理程序会将驱动 buffer的数据copy到硬件FIFO中,COPY到FIFO中后,硬件会自动发送(应该是通过移位寄存器)。然后每发发送一侦,就会触发中断,这样只要驱动 buffer 中有数据就会一直发送,直道发送完毕!

我的第一帧没有发送出去,所以中断肯定无法上来。最终就确定查找为何第一帧无法上来,读取状态寄存器,发现状态寄存器一直是0,而X86下的值就会一直变化。所以就怀疑是硬件的基地址错了,再次确认后,硬件基地址并没有错。那到底是什么地方错了呢?

经过了好多次尝试,想到了linux device driver 一书关于内核数据结构的那一章,里面有讲跨平台应该注意的数据结构。然后就仔细看了一下CAN寄存器对应的数据结构。

 

typedef struct canregs {
    uint8    canmode;        /* 0 */
    uint8    cancmd;
    uint8    canstat;
    uint8     canirq;
    uint8     canirq_enable;
    uint8     reserved1;        /* 5 */
    uint8     cantim0;
    uint8     cantim1;
    uint8     canoutc;
    uint8     cantest;
    uint8     reserved2;        /* 10 */
    uint8     arbitrationlost;    /* read only */
    uint8     errorcode;        /* read only */
    uint8     errorwarninglimit;
    uint8     rxerror;
    uint8     txerror;        /* 15 */
    uint8     frameinfo;
    union    frame frame;
    uint8     reserved3;
    uint8     canrxbufferadr        /* 30 */;
    uint8     canclk;      
} __attribute__((packed)) canregs_t;

 

其中 联合体 frame 的定义如下:

union frame {
 struct {
     u32    canid1;
     u32   canid2;
     u32   canid3;
     u32   canid4;
     u32   canxdata[8];
 } extframe;
 struct {
     u32   canid1;
     u32   canid2;
     u32          candata[8];
 } stdframe;
};

uint8 定义:typedef unsigned char uint8;

sja1000里面的寄存器都是8bit的。
将canregs_t里面的  canmode cancmd canstat canirq canirq_enable 的地址值打印出来,发现在ARM和X86下面它们的地址值都是相差1,在X86平台上面地址值相差1比较容易理解,而ARM上面地址值相差1就有点奇怪了。尝试将uint8改为 u32,重新编译运行,问题解决了。分析原因,应该是ARM地址是字对齐(aligned)的,而X86允许地址是不对齐(unaliged)所以两个平台有如此的差别。

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值