分类: 嵌入式
2010-05-14 13:23:44
通常,中断调用excJobAdd(),将不能在中断上下文调用的函数,通过msgQSend (excMsgQId)送到excTask任务执行。
消息队列excMsgQId的最大消息数是10(EXC_MAX_MSGS)。
如果中断调用excJobAdd()太频繁,将导致消息队列excMsgQId溢出,报告"%d messages from interrupt level lost.\n"的错误。
串口读中断处理函数调用tyIRd(),将从串口上读取的字节写入ty的读缓冲,然后调用selWakeupAll,唤醒挂在select上的串口接收任务。
如果不是line-mode,则来一个读中断,就调用一次selWakeupAll,调用一次excJobAdd()。
void selWakeupAll
{
if (intContext ())
{
excJobAdd (selWakeupAll, (int)pWakeupList, (int)type, 0, 0, 0, 0);
return;
}
}
如果select的超时非0,则串口接收任务在两次读readFds之间,可能频繁调用excJobAdd()。如果按下ctrl+c,则串口读中断处理函数调用tyIRd() --> dbgTyAbort() --> dbgTyAbort。
LOCAL void dbgTyAbort (void)/* reset the standard input and output channels in case they are hung up */
ioctl (STD_IN, FIOFLUSH, 0);
ioctl (STD_OUT, FIOFLUSH, 0);
ioctl (STD_ERR, FIOFLUSH, 0);
tt (shellTaskId);
if ((taskRestart (shellTaskId)) != ERROR)
printErr ("%s restarted.\n", taskName (shellTaskId));
else
{
printErr ("spawning new shell.\n");
if (shellInit (0, TRUE) == ERROR)
printErr ("shell spawn failed!\n");
}
tyAbortFuncSet ((FUNCPTR) dbgTyAbort); /* set abort routine */
}
重启shell的过程需要时间,延迟了任务串口接收任务的读操作。
同时,tt (shellTaskId)向串口打印大量信息。
如果多次按ctrl+c,则串口来不及输出,则excTask任务挂起等待串口输出(应该是select,具体代码没有看)。
在串口输出中断处理函数调用的tyITx()中,有一个调用selWakeupAll,进而调用excJobAdd(),唤醒挂在select上任务的过程。