rkfch 发表于 2012-11-6 11:30:49

疑问:使用keil的FlashFS时,调用函数死机!

本帖最后由 rkfch 于 2012-10-25 14:21 编辑

概述:采用KEIL的RL-ARM + FlashFS.CPU为LPC1754.
正常工作情况:当调用printf函数的串口使用查询方式时,调用static void cmd_dir (char *par)函数正常。
不正常情况   :当调用printf函数的串口使用中断方式时(如果不使用FlashFS,则串口功能正常),调用static void cmd_dir (char *par)函数则进入void os_error (U32 err_code)。
static void cmd_dir (char *par) {
FINFO info;

printf ("\nFile System Directory...");
        info.fileID = 0;
        while (ffind ("R:*.*",&info) == 0) {
                printf ("\n%-32s %5ld bytes, ID: %04d",info.name, info.size, info.fileID);
        }
        if (info.fileID == 0) {
                printf ("\nNo files...");
        }
        printf ("\nFree: %ld bytes.\n",(U32)ffree(""));
}

使用汇编窗口进行观察发现是调用printf函数引起的。如果在static void cmd_dir (char *par)函数内注释掉所有printf,则程序内正常运行。
串口操作函数如下:
static BIT sendstop;               /* flag: marks XOFF character         */
static char recbuf;
static U8 ridx;
static U8 widx;

OS_TID wr_task;
OS_TID rd_task;

/*----------------------------------------------------------------------------
*       init_serial:Initialize Serial Interface
*---------------------------------------------------------------------------*/
void init_serial (void) {
U16 usFdiv;

LPC_UART0->LCR    = 0x83;                        //允许设置波特率 8 bits, no Parity, 1 Stop bit
usFdiv = (FPCLK / 16) / UART0_BPS;                //设置波特率      
LPC_UART0->DLM= usFdiv/256;   
LPC_UART0->DLL= usFdiv%256;
LPC_UART0->LCR= 0x03;                                                      /*锁定波特率,8位数据,无校验    */
LPC_UART0->FCR= 0x01;                                                      /*使能FIFO,1字节产生中断 */
LPC_UART0->IER= 0x03;

        NVIC_SetPriority(UART0_IRQn,2);                               
        NVIC_EnableIRQ(UART0_IRQn);
       
        sendstop = __FALSE;               /* CtrlQ not received                  */
        ridx = widx = 0;                  /* clear buffer indexes                */
}

/*----------------------------------------------------------------------------
Write character to Serial Port
*----------------------------------------------------------------------------*/
int sendchar (int ch) {

wr_task = os_tsk_self ();          /* identify task for serial interrupt   */
os_evt_clr (0x0100, wr_task);
if (ch == '\n') {                   /* expand new line character:         */
    LPC_UART0->THR = (char)'\r';
    os_evt_wait_or (0x0100, 0xffff); /* wait till character transmited       */
}
LPC_UART0->THR = (char)ch;          /* transmit a character               */
os_evt_wait_or (0x0100, 0xffff);   /* wait till character transmited       */
return (ch);                        /* return character: ANSI requirement   */
}


/*----------------------------------------------------------------------------
Read character from Serial Port   (blocking read)
*----------------------------------------------------------------------------*/
int getkey (void) {
if (ridx == widx) {
    rd_task = os_tsk_self ();
    os_evt_clr (0x0100, rd_task);
    os_evt_wait_or (0x0100, 0xffff); /* wait till character received         */
}
return (recbuf);
}

/*----------------------------------------------------------------------------
*       serial:serial receive and transmit interrupt
*---------------------------------------------------------------------------*/
void UART0_IRQHandler(void)
{
        U8 lsr,iir,c;
        BIT rvflag;

        rvflag = __FALSE;
        iir =LPC_UART0->IIR;
        lsr =LPC_UART0->LSR;

        if((iir & 0x01) == 0)//有中断发生
        {
                switch(iir & 0x0F)//判断中断
                {
                        case 0x04: //接收数据
                        {
                                c = (char) LPC_UART0->RBR;
                                rvflag = __TRUE;
                                break;
                        }
                        case 0x0C: //Character Time-out Indicator字符超时中断,读取已接收的字节
                        {
                                c = (char) LPC_UART0->RBR;
                                rvflag = __TRUE;
                                break;
                        }
                        case 0x02://发送中断
                        {
                                if(lsr & 0x20)//发送寄存器空
                                {
                                        if (!sendstop){                   /* if not Control+S received         */
                                  isr_evt_set (0x0100, wr_task);    /* Go on, set event transmit ready   */
                                  }       
                                }
                                break;
                        }
                        default:break;
                }               
        }
        if(rvflag == __TRUE)
        {
                switch (c){                     /* process character                   */
              case CTRL_S:
                sendstop = __TRUE;            /* if Control+S stop transmission      */
                break;
       
              case CTRL_Q:
                sendstop = __FALSE;         /* if Control+Q start transmission   */
                break;
       
              default:                        /* send character to a mailbox         */
                recbuf = c;
                isr_evt_set (0x0100, rd_task);/* set event character received      */
                break;
    }
        }       
}
如果各位有解决方法或解决思路,欢迎讨论或指教!
编辑原因:标题不恰当、内容介绍不清楚!
页: [1]
查看完整版本: 疑问:使用keil的FlashFS时,调用函数死机!