天嵌 ARM开发社区

 找回密码
 注册
查看: 2863|回复: 4

关于DM9000的裸机程序

[复制链接]
mia_ym 发表于 2014-4-11 17:17:10 | 显示全部楼层 |阅读模式
    问题是,当我执行DM9000_ID_check()的时候,输出的是0x46464646。我单步调试时发现,地址0x20000004处的值没有变化,所以才会有前面的0x46464646出现,可是这个程序第一次却能读出“46”这个ID的最低字节,后来就不会变了,这是怎么回事呢?!

下面是一些程序语句:
int DM9000_ID_check(void)
{
  U32 ID;
  ID =REGR8(DM9000_VIDL);
  ID|=REGR8(DM9000_VIDH)<<8;
  ID|=REGR8(DM9000_PIDL)<<16;
  ID|=REGR8(DM9000_PIDH)<<24;
  
  if(ID!=DM9000_ID)                //DM9000_ID=0x90000a46
    return 1;           //不匹配
  else
    return 0;           //匹配
}


#define ADDRW(r)    (*(volatile U8*)DM9000A_INDEX=r)
#define DATAW8(d)   (*(volatile U8*)DM9000A_DATA=d)
#define DATAR8()    (*(volatile U8*)DM9000A_DATA)
#define DATAW16(d)  (*(volatile U16*)DM9000A_DATA=d)
#define DATAR16()   (*(volatile U16*)DM9000A_DATA)

static void REGW8(U8 reg,U8 data){
  ADDRW(reg);
  DATAW8(data);
}
static U8 REGR8(U8 reg){
  ADDRW(reg);
  return DATAR8();
}
static void REGW16(U8 reg,U16 data){
  ADDRW(reg);
  DATAW16(data);
}
static U16 REGR16(U8 reg){
  ADDRW(reg);
  return DATAR16();
}


 楼主| mia_ym 发表于 2014-5-7 15:08:07 | 显示全部楼层
好吧,最后还是自问自答:
这个问题和ARM的内存管理单元(mmu)、协处理器CP15有关。
ARM为了实现地址重映射,将内存进行分段处理,每段为1MB大小。段还可以根据需要再分为页,页可以为1KB4KB64KB大小。这是两级页表。
Mmu的另一个作用就是访问控制。
mmu.c的初始化程序中有以下程序:
         MMU_SetMTT(0x00000000,0x03f00000,(int)__ENTRY,RW_CB);  //bank0
         MMU_SetMTT(0x04000000,0x07f00000,0,RW_NCNB);                        //bank0
         MMU_SetMTT(0x08000000,0x0ff00000,0x08000000,RW_CNB);  //bank1
         MMU_SetMTT(0x10000000,0x17f00000,0x10000000,RW_NCNB);//bank2
         MMU_SetMTT(0x18000000,0x1ff00000,0x18000000,RW_NCNB);//bank3
         //MMU_SetMTT(0x20000000,0x27f00000,0x20000000,RW_CB);//bank4
         MMU_SetMTT(0x20000000,0x27f00000,0x20000000,RW_CNB);//bank4 for STRATA Flash
         MMU_SetMTT(0x28000000,0x2ff00000,0x28000000,RW_NCNB);//bank5
         //30f00000->30100000,31000000->30200000
         MMU_SetMTT(0x30000000,0x30100000,0x30000000,RW_CB);   //bank6-1
         MMU_SetMTT(0x30200000,0x33e00000,0x30200000,RW_NCNB);//bank6-2
         //
         MMU_SetMTT(0x33f00000,0x33f00000,0x33f00000,RW_CB);   //bank6-3
         MMU_SetMTT(0x38000000,0x3ff00000,0x38000000,RW_NCNB);//bank7
   
         MMU_SetMTT(0x40000000,0x47f00000,0x40000000,RW_NCNB);//SFR
         MMU_SetMTT(0x48000000,0x5af00000,0x48000000,RW_NCNB);//SFR
         MMU_SetMTT(0x5b000000,0x5b000000,0x5b000000,RW_NCNB);//SFR
         MMU_SetMTT(0x5b100000,0xfff00000,0x5b100000,RW_FAULT);//notused
这里语句MMU_SetMTT()实际上就是在对内存分段处理,因为每个bank128MB,所以可以分为128段,我没有看到程序里再对段进行分页,所以这里大概就只有到分段为止了。不过这些还和我要解决的问题无关,我要解决问题的关键是MMU_SetMTT()的第三个参数,我将上面涉及到的参数写一下:
RW_CB;  RW表示定义的段可读可写(这就是访问控制),C表示使用cacheB表示使用写缓冲器
RW_NCNB;  RW同上,NC表示不使用cacheNB表示不使用写缓冲器
RW_FAULT;  这个表示定义的段不可读写
其他依次类推。
由于DM9000接的是nGCS4,所以与上面的bank4那段程序有关,它原来的参数是RW_CNB,就是说可读可写,使用cache,不使用写缓冲。将这个参数改为RW_NCNB(可读写,不使用cache,不使用写缓冲)或者RW_NCB(可读写,不使用cache,使用写缓冲)就可以输出正确结果了,总之就是这里不用cache
当然,至于为何不用cache就可以了,我还是不知道,需要的知识真是太多了。希望对遇到和我有类似问题的人有所帮助。

回复

使用道具 举报

 楼主| mia_ym 发表于 2014-5-7 15:26:36 | 显示全部楼层
话说有没有人可以告诉我怎么把问题设置为“已解决”的
回复

使用道具 举报

saturn_dna 发表于 2014-12-30 14:33:32 | 显示全部楼层
在访问内存时使用Cache是不会出现问题的,但如果访问数据易变外设(数据不依赖于CPU写操作而改变)时使用Cache就可能出现问题。问题在于外设数据的改变不仅仅依靠CPU写操作,CPU第一次读取外设数据时将外设的数据和地址信息保存到Cache,第二次读取外设数据时就可能有问题出现。这是因为数据直接从Cache提取,而外设的数据可能有改变。

因此,在访问易变外设时要禁止使能Cache,直接读取外设数据到CPU,而不经过Cache的任何环节,即保证不改变Cache映射表和Cache数据区内容。
回复

使用道具 举报

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

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号-2 )

GMT+8, 2025-8-21 08:50 , Processed in 2.041958 second(s), 19 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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