都是Semaphore惹得祸

本文记录了一次RTOS系统中HTFDLow中断处理任务无法正常执行的问题排查过程。问题表现为中断正常触发并给予信号量,但处理任务Main_TFDL却未能获取信号量。通过逐步调试与实验,最终定位问题源于另一任务FPGA_FIFO_DAEMON的无限循环,并成功通过调整优先级解决。

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()中初始化此信号量。折腾了一天,原来问题出在这,还真有点让人出乎意料。

【电力系统】单机无穷大电力系统短路故障暂态稳定Simulink仿真(带说明文档)内容概要:本文档围绕“单机无穷大电力系统短路故障暂态稳定Simulink仿真”展开,提供了完整的仿真模型与说明文档,重点研究电力系统在发生短路故障后的暂态稳定性问题。通过Simulink搭建单机无穷大系统模型,模拟不同类型的短路故障(如三相短路),分析系统在故障期间及切除后的动态响应,包括发电机转子角度、转速、电压和功率等关键参数的变化,进而评估系统的暂态稳定能力。该仿真有助于理解电力系统稳定性机理,掌握暂态过程分析方法。; 适合人群:电气工程及相关专业的本科生、研究生,以及从事电力系统分析、运行与控制工作的科研人员和工程师。; 使用场景及目标:①学习电力系统暂态稳定的基本概念与分析方法;②掌握利用Simulink进行电力系统建模与仿真的技能;③研究短路故障对系统稳定性的影响及提高稳定性的措施(如故障清除时间优化);④辅助课程设计、毕业设计或科研项目中的系统仿真验证。; 阅读建议:建议结合电力系统稳定性理论知识进行学习,先理解仿真模型各模块的功能与参数设置,再运行仿真并仔细分析输出结果,尝试改变故障类型或系统参数以观察其对稳定性的影响,从而深化对暂态稳定问题的理解。
本研究聚焦于运用MATLAB平台,将支持向量机(SVM)应用于数据预测任务,并引入粒子群优化(PSO)算法对模型的关键参数进行自动调优。该研究属于机器学习领域的典型实践,其核心在于利用SVM构建分类模型,同时借助PSO的全局搜索能力,高效确定SVM的最优超参数配置,从而显著增强模型的整体预测效能。 支持向量机作为一种经典的监督学习方法,其基本原理是通过在高维特征空间中构造一个具有最大间隔的决策边界,以实现对样本数据的分类或回归分析。该算法擅长处理小规模样本集、非线性关系以及高维度特征识别问题,其有效性源于通过核函数将原始数据映射至更高维的空间,使得原本复杂的分类问题变得线性可分。 粒子群优化算法是一种模拟鸟群社会行为的群体智能优化技术。在该算法框架下,每个潜在解被视作一个“粒子”,粒子群在解空间中协同搜索,通过不断迭代更新自身速度与位置,并参考个体历史最优解和群体全局最优解的信息,逐步逼近问题的最优解。在本应用中,PSO被专门用于搜寻SVM中影响模型性能的两个关键参数——正则化参数C与核函数参数γ的最优组合。 项目所提供的实现代码涵盖了从数据加载、预处理(如标准化处理)、基础SVM模型构建到PSO优化流程的完整步骤。优化过程会针对不同的核函数(例如线性核、多项式核及径向基函数核等)进行参数寻优,并系统评估优化前后模型性能的差异。性能对比通常基于准确率、精确率、召回率及F1分数等多项分类指标展开,从而定量验证PSO算法在提升SVM模型分类能力方面的实际效果。 本研究通过一个具体的MATLAB实现案例,旨在演示如何将全局优化算法与机器学习模型相结合,以解决模型参数选择这一关键问题。通过此实践,研究者不仅能够深入理解SVM的工作原理,还能掌握利用智能优化技术提升模型泛化性能的有效方法,这对于机器学习在实际问题中的应用具有重要的参考价值。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值