搜索
bottom↓
回复: 0

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

[复制链接]

出0入0汤圆

发表于 2012-11-6 11:30:49 | 显示全部楼层 |阅读模式
本帖最后由 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[256];
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[ridx++]);
}

/*----------------------------------------------------------------------------
*       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[widx++] = c;
                isr_evt_set (0x0100, rd_task);/* set event character received        */
                break;
    }
        }       
}
如果各位有解决方法或解决思路,欢迎讨论或指教!
编辑原因:标题不恰当、内容介绍不清楚!

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 23:08

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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