asdf518

    1. 首先这是 startup.s  下的文件。 UND_Stack_Size  EQU     0x00000000 SVC_Stack_Size  EQU     0x00000080 ABT_Stack_Size  EQU     0x00000000 FIQ_Stack_Size  EQU     0x00000000 IRQ_Stack_Size  EQU     0x00000200 USR_Stack_Size  EQU     0x00000500                LDR     R0, =Stack_Top               ;  Enter Undefined Instruction Mode and set its Stack Pointer                 MSR     CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit                 MOV     SP, R0                 SUB     R0, R0, #UND_Stack_Size ;  Enter Abort Mode and set its Stack Pointer                 MSR     CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit                 MOV     SP, R0                 SUB     R0, R0, #ABT_Stack_Size ;  Enter FIQ Mode and set its Stack Pointer                 MSR     CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit                 MOV     SP, R0                 SUB     R0, R0, #FIQ_Stack_Size ;  Enter IRQ Mode and set its Stack Pointer                 MSR     CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit                 MOV     SP, R0                 SUB     R0, R0, #IRQ_Stack_Size ;  Enter Supervisor Mode and set its Stack Pointer                 MSR     CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit                 MOV     SP, R0                 SUB     R0, R0, #SVC_Stack_Size 运行时Stack_Top =IRQ stack top =0x40002178; Supervisor Mode stack top = 0x40001f78; user mode stack top = 0x40001ef8; 串口中断程序如下 void UART0_Exception(void) {     uint8 IIR, temp;         OS_ENTER_CRITICAL();     while(((IIR = U0IIR) & 0x01) == 0)     {                                                   /* 有中断未处理完 */         switch (IIR & 0x0e)         {             case 0x02:                                  /* THRE中断    */                 //for (i = 0; i < UART0_FIFO_LENGTH; i++) /* 向发送FIFO填充数据 */                // {                     if (QueueRead(&temp, UART0SendBuf) == QUEUE_OK)                     {                         U0THR = temp;                     }                     else                     {                         U0IER = U0IER & (~0x02);        /* 队列空,则禁止发送中断 */                     }                // }                 break;             case 0x04:                                  /* 接收数据可用 */             case 0x0c:                                  /* 字符超时指示 */                 do                                      /* 读取FIFO全部数据 */                 {                         QueueWrite((void *)UART0_ReceiveBuf,U0RBR);                 }while((U0LSR & 0x00000001) != 0);                                 OSSemPost(Uart0Sem);                 break;             case 0x06:                     temp = U0LSR;                     break;             default :                 break;         }     }     VICVectAddr = 0;            // 通知中断控制器中断结束     OS_EXIT_CRITICAL(); } 在进入串口中断时SP = 0x400021e8;mode为 system; 子函数   uint8 QueueRead(QUEUE_DATA_TYPE *Ret, void *Buf) {     uint8 err;     DataQueue *Queue;     err = NOT_OK;     if (Buf != NULL)                                            /* 队列是否有效 */     {                                                           /* 有效 */         Queue = (DataQueue *)Buf;                  OS_ENTER_CRITICAL();                  if (Queue->NData > 0)                                   /* 队列是否为空 */         {                                                       /* 不空         */             *Ret = Queue->Out[0];                               /* 数据出队     */             Queue->Out++;                                       /* 调整出队指针 */             if (Queue->Out >= Queue->End)             {                 Queue->Out = Queue->Buf;             }             Queue->NData--;                                     /* 数据减少      */             err = QUEUE_OK;         }         else         {                                                       /* 空              */             err = QUEUE_EMPTY;             if (Queue->ReadEmpty != NULL)                       /* 调用用户处理函数 */             {                 err = Queue->ReadEmpty(Ret, Queue);             }         }         OS_EXIT_CRITICAL();     }     return err; } 在进入上面函数的OS_ENTER_CRITICAL();时 首先经过软中断 ;软件中断 SoftwareInterrupt         LDR     SP, StackSvc            ; 重新设置堆栈指针         STMFD   SP!, {R0-R3, R12, LR}         MOV     R1, SP                  ; R1指向参数存储位置 stackSvc = 0x400021f4; 而中断堆栈也是0x400021e8;这两个堆栈在运行过程中重叠。

最近访客

< 1/1 >

统计信息

已有46人来访过

  • 芯积分:--
  • 好友:--
  • 主题:--
  • 回复:1

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言