都是Semaphore惹得祸
来源:互联网 发布:土耳其财经数据 编辑:程序博客网 时间:2024/05/16 17:16
NP向CPU发包,CPU通过中断的方式接收。HTFD High的中断正常,可以调用ISR用来give相应的信号量,Main_TFDH可以take到信号量;HTFD Low的中断也正常,也可正常give信号量,但是Main_TFDL却不能take信号量。调试步骤如下:
1. 利用EZmde由HTFD Low队列发包到CPU,终端显示:
AHE_Isr --- Channel=0 cause reg bit 2 is set
uqCauseReg=0x00000004 HTFD Low
send semaphore to Main_TFDL
由此可见,中断确实发生了,但是相应的中断处理任务(Main_TFDL)并没有执行。
2. 在终端上查看当前系统中的任务状态:
-> i
NAME ENTRY TID PRI STATUS PC SP ERRNO DELAY
---------- ------------ -------- --- ---------- -------- -------- ------- -----
…… …… …… … …… …… …… …… ……
TFDH_0 Main_TFDH_0 43e6ae0 145 PEND a25f74 43e6960 0 0
TFDL_0 Main_TFDL_0 43e0860 150 PEND a25f74 43e06d0 0 0
FPGA_FIFO_Dnp_load_FPGA 43af7d0 150 READY 23df90 43af6e8 3d0001 0
…… …… …… … …… …… …… …… ……
value = 0 = 0x0
3.查看中断处理任务Main_TFDL的函数调用堆栈:
-> tt 0x43e0860
989800 vxTaskEntry +54 : Main_TFDL ()
823584 Main_TFDL +74 : semTake ()
a26a50 semTake +130: a25df8 ()
value = 0 = 0x0
终端处理任务也是正常的。无意间发现FPGA FIFO 溢出检测任务的状态似乎有点不正常,这个任务跟中断处理任务一样,也是需要take相应的信号量才能作相应处理,按理说它的状态也应该是PEND才对,但是此处却是READY。
4. 查看FPGA FIFO 溢出检测任务的函数调用堆栈:
-> tt 0x43af7d0
989800 vxTaskEntry +54 : np_load_FPGA_standby ()
828558 np_load_FPGA_standby+90 : FPGA_check_fifo_overflow ()
242788 FPGA_check_fifo_overflow+20 : BspNPCheckBoard ()
value = 0 = 0x0
-> Main_TFDL -- channel 0 HTFD Low interrupt happen!
HTFD Low Msg queue is empty
奇怪的事发生了,tt FPGA FIFO 溢出检测任务后,刚刚没有执行的Main_TFDL现在却得到了执行。NP通过HTFD Low队列向CPU发包,CPU产生中断give信号量,但是Main_TFDL却不能take,但只要一执行
tt 0x43af7d0 (FPGA FIFO 溢出检测任务)
Main_TFDL就会take到信号量。尝试了好多次,都是这样的结果。
5.在代码中去掉FPGA检测任务,重新编译版本,启动后,再从NP向CPU发包。这次中断果然正常了:
AHE_Isr --- Channel=0 cause reg bit 2 is set
uqCauseReg=0x00000004 HTFD Low
send semphomore to Main_TFDL
Main_TFDL -- channel 0 HTFD Low interrupt happen!
HTFD Low Msg queue is empty
从以上几步诊断结果来看,问题应该出在FPGA FIFO 溢出检测任务上,但是实在想不通FPGA检测任务怎么会影响到HTFD Low中断处理任务!这两个任务没有共享全局变量,也没有任何进程间通信。
查阅了VxWorks的相关资料,得知ready状态表示任务除了等待CPU外不等待其它资源,执行i命令时此任务是ready状态,那么这个任务有可能平时一直处于无限循环中。
对比了一下创建FPGA FIFO 溢出检测任务和创建HTFD Low中断处理任务的语句,如下:
EZ_TSK_SPAWN( "FPGA_FIFO_DAEMON",
NORMAL_PRIORITY_TSK_DEF1/*BELOW_NORMAL_PR_TSK_DEF1*/,
ISR_TSK_STK_SIZE_DEF,
(EZ_FUNCPTR ) np_load_FPGA_standby,/*lint !e64 */
0 );
g_EZisrTaskId[i][1] = EZ_TSK_SPAWN(NP_EZIsrTFDL_Name[i],
NORMAL_PRIORITY_TSK_DEF1,
ISR_TSK_STK_SIZE_DEF,
(EZ_FUNCPTR)NP_EZIsrTFDL_Entry[i],
0);
发现这两个任务处于同一优先级上(NORMAL_PRIORITY_TSK_DEF1)。会不会是FPGA_FIFO_DAEMON 任务中某个地方出错导致了无限循环,而使得处于同一优先级上的HTFD Low中断处理任务得不到执行呢?抱着这个猜想,我把FPGA_FIFO_DAEMON任务的优先级调低(BELOW_NORMAL_PR_TSK_DEF1),如果猜想正确的话,即使FPGA_FIFO_DAEMON任务一直占着CPU进行无限循环,一旦发生HTFD Low中断,高优先级的中断处理任务还是会抢占CPU从而得以执行的。
修改了FPGA_FIFO_DAEMON任务的优先级后,重编版本,下载运行后,果然验证了刚才的猜测。此时只要产生硬件HTFD Low中断,HTFD Low的中断处理任务便立刻被执行。
现在问题已经明朗,问题肯定出在FPGA_FIFO_DAEMON任务中。此任务的入口函数框架如下:
void np_load_FPGA_standby()
{
……
while(TRUE)
{
/*每200ms对FPGA的状态进行一次检测*/
EZ_SEM_TAKE(g_EZPhiId.EZFpgaFifoSem);
/*检查FPGA的FIFO是否溢出*/
fpga_fifo_state = FPGA_check_fifo_overflow();
if( fpga_fifo_state && bFPGALoadFlg )
{
……
}
……
}
}
按理说此任务不应该一直在循环呀,它需要获得g_EZPhiId.EZFpgaFifoSem这个信号量才可以循环一次,而这个信号量是由时钟中断定时give的。再次检查了时钟中断处理函数,感觉并没有地方出错。请教单位的某老鸟,他问我此信号量有没有初始化,一句话惊醒了梦中人!这个信号在以前的版本是中没有的,是我后加入到v3.5中的,当时只在时钟中断函数中give了一下,在FPGA_FIFO_DAEMON任务中take了一下,还真忘了在NP_Sem_Create()中初始化此信号量。折腾了一天,原来问题出在这,还真有点让人出乎意料。
- 都是Semaphore惹得祸
- 都是索引惹得祸
- 都是缓存惹得祸
- 都是MAC惹得祸!!
- 都是自动更新惹得祸
- 都是缓存惹得祸
- 都是缓存惹得祸
- 都是大雾惹得祸
- 都是大雾惹得祸
- 都是“引用”惹得祸!
- 都是积分惹得祸
- 都是编译器惹得祸
- 都是“世界杯”惹得祸
- 都是虚拟机惹得祸
- 都是JDBC-ODBC惹得祸
- 都是appfuse Constants 惹得祸?
- 都是CSS惹得的祸
- 都是�(65533)惹得祸~
- Operating Systems Design and Implementation, Third Edition
- 设置vxWorks硬件断点调试
- C++的static关键字
- 系统架构逻辑参考图【强调了领域模型+面向服务编程理念】
- 管理类软件中常见的【一人多职问题】的解决方法参考交流
- 都是Semaphore惹得祸
- 【草根总结】软件质量可以得到明显提高的10个环节
- 程序员赚的辛苦钱及好朋友借钱[借钱时你是爷爷,借出去后丢一个朋友不说还多出一个爷爷]
- 真不容易啊
- 内存显示函数
- 【商场如战场】IT人才外包创业过程中的钩心斗角
- Linux shell脚本全面学习
- 我的GVIM配置文件(windows)
- win7运行命令大全