|
本帖最后由 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周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|