thilo
驱动牛犊
驱动牛犊
  • 注册日期2002-05-19
  • 最后登录2005-06-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1966回复:1

ARM中中断使用请教

楼主#
更多 发布于:2002-05-22 23:53
小弟我初来乍到的,先问声好!

这段时间我正好遇到一个ARM中断的问题,想请教各位。
我的ARM CPU 是用OKI的uPLAT 7C(ARM7TDMI),RTOS 是用的uITRON 3.0。他们的资料在网上都有(如果找不到,给我mail,我传给你,我现在忘记他们的URL了)。

下面是我的系统的某些方面的描述(不好意思,是用英文写的):

There is a interrupt enable register:  TIE, which is at the address: 0xB000_041C;
There is a interrupt request register: TIREQ, which is at the address: 0xB000_0424;
There is a interrupt status register:  TIRST, which is at the address: 0xB000_0434;

These 3 register is a group, and the \"status register\" = \"enable regsiter\" AND(&) \"request register\". That is mean CPU set the enable register, the hardware set the request register, and the CPU check whether is there interrupt by checking the status register. And the CPU clear the interrupt by clearing the request register.

The TIREQ\'s bit0 indicate: sync word reception interrupt;
The TIREQ\'s bit1 indicate: packet header reception interrupt;
The TIREQ\'s bit2 indicate: receive data read request;
TIREQ\'s bit3 - bit7 are other interrupt.

Actually, I just want to control the sync word reception interrupt correctly at first.
And, all these hardware generated interrupt just affect the IRQ15(my system defined). That is to say it affect the IRQ(0x7800_0000)\'s bit15.

The RTOS has defined the interrupt vector table as following code:
//Code begin
/* Interrupt vector Table */

#ifndef INTVEC
#define INTVEC      0x1000000L
#endif
#ifndef INTVSZ
#define INTVSZ      512
#endif
//code end

But unfortunately, RTOS defined INTVEC value will cause the system halt, because it use a un-exist memory address(0x1000000) in my board.

The RTOS require use the sysini() function to init the system. This function will invoke the following function:
//Code begin
ER intini(void)
{
  #if (INTVSZ!=0)
    int i;

    /* Initialize vector table */

    for (i = 0; i < (INTVSZ) / 4; i++)
        ((UW *)INTVEC) = (UW)interr;//Get problem
here!!!
  #endif

    return E_OK;
}
//Code end

So, I change INTVEC as the other value. I have change it to: 0x78000000(IRQ\'s address) and 0xB0000434(TIRST\'s address), just let the RTOS can init the system. Actually, I don\'t know what the right value should be set here.

And the following is the uPLAT ARM CPU\'s interrupt
controller define(provided by the RTOS):
/* Interrupt Controller Register Address */
#define IRQ             0x78000000  /* IRQ Status Register */
#define IRQS            0x78000004  /* IRQ Software Interrupt Register */
#define FIQ             0x78000008  /* FIQ Status Register */
#define FIQRAW          0x7800000C  /* FIQRAW Status Register */
#define FIQEN           0x78000010  /* FIQ Enable Register */
#define IRNR            0x78000014  /* IRQ Number Register */
#define CILR            0x78000018  /* Current IRQ Level Register */
#define IRL             0x7800001C  /* IRQ Level Register */
#define ILCR0           0x78000020  /* IRQ Level Control Register0 */
#define ILCR1           0x78000024  /* IRQ Level Control Register1 */


/* Interrupt Number */
#define INT_nIR0        0
#define INT_TIMER       0
#define INT_nIR1        1
#define INT_nIR2        2
#define INT_nIR3        3
#define INT_nIR4        4
#define INT_nIR5        5
#define INT_nIR6        6
#define INT_nIR7        7
#define INT_nIR8        8
#define INT_nIR9        9
#define INT_nIR10       10
#define INT_SIO         10
#define INT_nIR11       11
#define INT_nIR12       12
#define INT_nIR13       13
#define INT_nIR14       14
#define INT_nIR15       15

我写下面两个中断出来测试程序。一个是ARM的例子,另外一个是iTRON的用法。
In the iTRON, there are several related functions:
ent_ini: interrupt handler start;
ret_int: return from the interrupt handler;

debug_counter is global structure in the program.
And the counter debug_counter.interrupt is the counter for interrupt.

//Code begin
//ISR 方法1
__irq void IRQ_handler(void)
{
  volatile u32 *source = (u32 *)0xB0000434;
  if (*source & 0x01 )
  {
    debug_counter.interrupt = debug_counter.interrupt
+ 1;
    if (debug_counter.interrupt>=0xefffffff)
     debug_counter.interrupt = 0;
  }
  *(source+1) = 0;
}


//ISR 方法2
INTHDR inthdr_test(void)
{
  ent_int();
    debug_counter.interrupt = debug_counter.interrupt
+ 1;
    if (debug_counter.interrupt>=0xefffffff)
     debug_counter.interrupt = 0;
  ret_int();
}
//Code end

我的main函数如下:
//Code begin
void main(void)
{
  volatile s32 iTRON_error_flg;
  u32 i,j,k;

/* Initialize processor Please customize !!*/
  init_peripheral();

/* Initialize system */
  sysini();
  ini_pio();

/*Test function is here!*/
IRQ_handler();
//inthdr_test();

  iTRON_error_flg = cre_tsk(TSK_MAIN, &ctsk_main);
  iTRON_error_flg = cre_tsk(TSK_RCV_BB, &ctsk_rcv_BB);
  iTRON_error_flg = cre_tsk(TSK_SND_BB, &ctsk_snd_BB);
  iTRON_error_flg = cre_tsk(TSK_RCV_HCI,
&ctsk_rcv_HCI);
  iTRON_error_flg = cre_tsk(TSK_SND_HCI,
&ctsk_snd_HCI);

//  cre_sem(SEM_BB_SEND, &csem_BB_send);
  iTRON_error_flg = cre_mbx(MBX_ID_BB_SEND,
&cmbx_BB_send);

  iTRON_error_flg = sta_tsk(TSK_RCV_BB, 0);
  iTRON_error_flg = sta_tsk(TSK_SND_BB, 0);
  iTRON_error_flg = sta_tsk(TSK_RCV_HCI, 0);
  iTRON_error_flg = sta_tsk(TSK_SND_HCI, 0);
  iTRON_error_flg = sta_tsk(TSK_MAIN, 0);
//  iTRON_error_flg = sta_tsk(TSK_MAIN_SUB, 0);
/* Start multitask system */

  intsta();                   /* Start interval timer
interrupt */
  syssta();                   /* enter into multi task
*/

}
//Code end


If I use the IRQ_handler function, if there is interrupt(TIRST\'s bit0, I can check it in the ADW by its address), the counter will change. But, the program always there. When it finished IRQ_handler function\'s code, and it jump out, but the cursor still stay in this function, and the program will jump into this function again(no relationship whether is there interrupt). So, the program can\'t run the following other code.
If I use the inthdr_test function, when the program run the ret_int(), the program will get an error and return to the  ENTRY area.


我的问题有如下几个:
1、INTVEC 的define应该是多少?
2、我的中断服务程序(ISR)的写法对吗?(我其实只要相应IRQ中的IRQ15就可以了,然后再在ISR中根据相应寄存器的哪个比特是1来判断作什么工作)我应该用上面两种中的哪种?
3、ISR程序应该怎样用?
  是把他放在main()中,当成一个函数一样呢(如前面的main函数)?还是就定义ISR,然后不管它,有硬件中断(IRQ15)时它自动跑进来(但是这样我的counter一直是0)?
4、怎样清中断?
  是不是直接对TIREQ寄存器的相应比特置0。
 

最新喜欢:

flyhuanflyhua...
飞天猩猩
驱动巨牛
驱动巨牛
  • 注册日期2001-09-24
  • 最后登录2008-06-17
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望22点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-05-23 16:02
不是很明白,我有一个在UC/OS系统上运行的程序,启动代码是用汇编做的,具体的处理是用C写的。
游客

返回顶部