主题 : 裸机调试时不能进入中断 复制链接 | 浏览器收藏 | 打印
勺饮不器盛沧海,拳石频移磊泰山
级别: 侠客
UID: 15752
精华: 0
发帖: 71
金钱: 355 两
威望: 71 点
贡献值: 0 点
综合积分: 142 分
注册时间: 2010-03-09
最后登录: 2010-10-19
楼主  发表于: 2010-05-22 15:58

 裸机调试时不能进入中断

各位大侠:小弟愚钝,按照网上许多大侠的建议,小弟仍然没有调通裸机下的中断实验。小弟利用的H-JTAG,将代码下载到0x30000000处,以NorFlash方式启动,小弟将源代码奉上:
//中断方式实现键盘扫描
#include <stdlib.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2440addr.h"    
#include "2440lib.h"
#include "2440slib.h"
#include "mmu.h"      
//================================
#define LED1 (1<<5)
#define LED2 (1<<6)
#define LED3 (1<<7)
#define LED4 (1<<8)

#define KEY1 (1<<0)
#define KEY2 (1<<3)
#define KEY3 (1<<5)
#define KEY4 (1<<6)

void dely(U32 tt)
{
   U32 i;
   for(;tt>0;tt--)
   {
     for(i=0;i<10000;i++){}
   }
}

void LightLED(void)
{
    if(!(rGPGDAT & KEY1))
        rGPBDAT = rGPBDAT & ~LED1;
    if(!(rGPGDAT & KEY2))
        rGPBDAT = rGPBDAT & ~LED2;
    if(!(rGPGDAT & KEY3))
        rGPBDAT = rGPBDAT & ~LED3;
    if(!(rGPGDAT & KEY4))
        rGPBDAT = rGPBDAT & ~LED4;
    dely(500);
    rGPBDAT = 0xfff;
}

void __irq EINT_8_11_13_14(void)
{  
   if(rEINTPEND &(1<<8))            
   {      
      rEINTPEND = (1<<8);           //CLEAR  rEINTPEND
      ClearPending(BIT_EINT8_23);
      LightLED();
   }
   if(rEINTPEND &(1<<11))            
   {      
      rEINTPEND = (1<<11);           //CLEAR  rEINTPEND
      ClearPending(BIT_EINT8_23);
      LightLED();
   }
   if(rEINTPEND &(1<<13))            
   {      
      rEINTPEND = (1<<13);           //CLEAR  rEINTPEND
      ClearPending(BIT_EINT8_23);
      LightLED();
   }
   if(rEINTPEND &(1<<14))            
   {      
      rEINTPEND = (1<<14);           //CLEAR  rEINTPEND
      ClearPending(BIT_EINT8_23);
      LightLED();
   }
   else
   {
     rEINTPEND = 0xffffff;           //CLEAR  rEINTPEND
     ClearPending(BIT_EINT8_23);
   }
    
}

void EINT_Init(void)
{  
   rINTMSK=0xFFFFFFDF;//enable EINT8_23
   rEXTINT1 = 0x22202002;
   rEXTINT2 = 0x2000;
   rEINTMASK = 0xF716FF;//enable EINT8,EINT11,EINT13,EINT14
   rINTMOD = 0x0;
   //我这里的按键接口是
   // k1-GPG0
   // k2-GPG3
   // k3-GPG5
   // k4-GPG6
  
   pISR_EINT8_23 = (unsigned int) EINT_8_11_13_14;              

}

int Main(int argc, char **argv)
{
    int i;
    U8 key;
    U32 mpll_val=0;
    int data;
  
    mpll_val = (92<<12)|(1<<4)|(1);
    
    //init FCLK=400M, so change MPLL first
    ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);
    ChangeClockDivider(key, 12);    
    MMU_Init();

    rGPBCON = 0x015550;
    rGPBUP = 0xfff;
    rGPBDAT = 0xfff;
    rGPGCON = 0x2822;//0000 0000 0000 0000 0010 1000 0010 0010     //set function as interupt
    
    EINT_Init();
       while(1);

   return 0;
}
如今打开了MMU,并将MMU.c函数中的MMU-SetMTT(0x00000000,0x03f00000,(int)__ENTRY,RW_CB)代码的(int)__ENTRY改成了0x30000000,同时在主函数中调用MMU_Init();,可执行时程序在mov r1,r1,asr #20处跑飞,请各位大侠指教!
勺饮不器盛沧海,拳石频移磊泰山
级别: 侠客
UID: 4843
精华: 0
发帖: 102
金钱: 810 两
威望: 554 点
贡献值: 0 点
综合积分: 204 分
注册时间: 2009-03-31
最后登录: 2012-11-14
1楼  发表于: 2010-05-22 21:58

 回 楼主(云鹤九霄) 的帖子

研究了一下,出现问题的原因是ADS工程中各个文件的链接顺序出现了问题。
发觉很多人编写自己的裸机程序的时候都出现了这个问题,而且很难发现这个问题。

一般情况下,如果你首先添加2440init.s这个文件,则它会被链接在程序的开头:



如果不是的话,比较麻烦,即使你在“Link Order”那里修改,2440init.s这个文件也不会被重新链接在程序开头。
这个问题不知道是不是编译器的bug,或则是我的操作有误?
不过还是有补救的方法,我们可以在Layout那里把2440init.s这个文件链接到程序的开头:



再加上MMU,中断程序就可以运行了。
另补充一个问题,原程序有错误,GPGCON没有设置Key2为中断模式,我改正了过来。

ofme_key.rar (31 K) 下载次数:62