一种嵌入式系统中诊断设备无响应的方法与流程

    专利2022-07-08  124

    本发明属于相关嵌入式系统技术领域,具体涉及一种嵌入式系统中诊断设备无响应的方法。



    背景技术:

    在嵌入式系统中,rtos的使用已经无处不在了,而且诊断trap的手段很多。在嵌入式设备中,有部分流程是这样的,按键中断触发需要转到对应的task去处理该中断事件,当task接收到这样的事件时,会有相应的log通过usb口从log助手(windows工具)输出,还有,在系统中加了shell命令行功能,用于处理串口输入的命令并执行(类似linux的shell),shell作为一个task在rtos系统中运行,它的任务优先级较高,而且系统中也加了诊断trap的功能,比如取指令异常、总线错误以及内存错误等都会触发相应的处理流程,并且会有trap信息同时从log助手和串口输出。但我遇到的情况是,系统在某种特殊情况下,我按了相应的按键,本该触发该按键中断,并从log助手输出相应的log,但无论尝试多少次,都没有效果,同时我尝试shell命令,看是否能够执行,结果也是一样,shell没有任何反应。这时串口和log助手都没有任何log,所以排除了正常trap的可能性。这种情况下,就需要其他手段了。



    技术实现要素:

    本发明的目的在于提供一种嵌入式系统中诊断设备无响应的方法,以解决上述背景技术中提出的不能很好的处理该条件下设备无响应的问题。

    为实现上述目的,本发明提供如下技术方案:

    一种嵌入式系统中诊断设备无响应的方法,所述在嵌入式系统中,诊断设备或者系统无响应的方法,具体包括如何确定task的当前执行的位置、如何触发追踪流程和如何追踪系统运行时状态几个部分。具体操作步骤包括如下:

    步骤一:通过在task任务控制块中增加当前pc指针值,来定位每个task当前(或者最后)执行的位置。

    步骤二:异常时,通过bootmode拨码开关,控制触发问题追踪流程。

    步骤三:在追踪问题时,增加打印taskpc指针值和诊断rtos运行过程。

    优选的,所述在步骤一中,先在tcb任务控制块的定义中增加一个pc成员,用于保存task最后的运行位置,将pc成员保存在第一个word后,这里pc成员为tsk_pc,如下所示:

    typedefstruct

    {

    uint32_t*pxtop_of_stack;

    uint32_ttsk_pc;/*<tosavelastlocation.*/

    }tsktcb;

    在tcb中添加tsk_pc成员之后,需要在任务切换之前,将实际的pc指针保存到tcb的tsk_pc中,由于设备使用的是cortex-m4的核,根据m4核的特性,响应异常的第一个动作,就是自动保存现场的必要部分,依次把xpsr,pc,lr,r12以及r3‐r0由硬件自动压入适当的堆栈中,所以代码可以这样将pc值取出来:

    __asmvoidxportpendsvhandler(void)

    {

    mrsr0,psp

    isb

    /*getthelocationofthecurrenttcb.*/

    ldrr3,=pxcurrenttcb

    ldrr1,[r0,#24]

    ldrr2,[r3]

    strr1,[r2,#4]

    nop

    }

    其中:

    mrsr0,psp表示取栈指针sp

    ldrr1,[r0,#24]表示获取已经保存到堆栈中的pc值

    ldrr2,[r3]表示取当前tcb的地址

    strr1,[r2,#4]表示将pc值存到tcb的tsk_pc中。

    优选的,所述在步骤二中,设备使用了mcu的bootmode引脚,在系统启动后,bootmode引脚就不会再被硬件检测,之后在系统起来后,将bootmode的一个引脚boot1用作gpio,该gpio作为输入,假设boot1为高电平时可以正常启动系统,那么在上电时,boot1必须为高电平,系统起来后,idletask里不断检测该gpio引脚是否为低电平来触发相应的诊断流程。所以一旦boot1对应的拨码开关被拨到了低电平位置,则立即触发诊断流程。

    优选的,所述在步骤三中,触发诊断流程条件下,诊断是否为rtos操作系统问题。在设备使用的rtos中,涉及进程间通信,而事件处理属于进程间通信的一部分。这里,以事件来举例,收发事件使用的是os_eventgrpwait和os_eventgrpset接口,为了定位问题,在这两个函数内部及相应的流程上增加了串口log(日志),用于确定事件是否正常发送出去,即可诊断某个task。这样在boot引脚为低电平时,诊断开关被打开的情况下,通过os_eventgrpset给某个task发测试事件,当该task收到该测试事件时,会执行它,如果没有收到,则通过这两个函数内部及流程上的串口log可以综合查一下原因。

    优选的,所述在步骤三中,根据打印出所有task的各种信息,主要是tcb成员tsk_pc中的pc值,然后在汇编文件中查找各个task的tsk_pc对应的实际位置,并结合c语言代码,就可以分析出各个task最后在哪个函数的哪个位置了。

    与现有技术相比,本发明提供了一种嵌入式系统中诊断设备无响应的方法,具备以下有益效果:

    本发明嵌入式系统中诊断设备无响应的方法通过三个步骤结合的方式,使得在系统发生异常时,可以比较容易的分析系统问题。一般通过步骤1(保存task的pc值),即可解决很多问题,因为它可以了解每个task在做些什么事,系统情况一目了然。再辅助另外两个步骤,使得分析更加高效。

    具体实施方式

    对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。

    本发明提供一种技术方案:

    一种嵌入式系统中诊断设备无响应的方法,在嵌入式系统中,诊断设备或者系统无响应的方法,具体包括如何确定task的当前执行的位置、如何触发追踪流程和如何追踪系统运行时状态几个部分。具体操作步骤包括如下:

    步骤一:通过在task任务控制块中增加当前pc指针值,来定位每个task当前(或者最后)执行的位置。

    步骤二:异常时,通过bootmode拨码开关,控制触发问题追踪流程。

    步骤三:在追踪问题时,增加打印taskpc指针值和诊断rtos运行过程。这样通过三个步骤的结合,从而在处理的时候更加的便利,运用这样的trace手段可以有效定位出问题。比如系统中某个task使用了二值信号量却没有释放,后面其他多个task又继续来申请使用该信号量,因为这些task都获取不到该信号量,导致都会被挂起,此时表现出的现象就是系统无响应。这时,开发人员就可以利用以上几种方式进行诊断。

    进一步,在步骤一中,先在tcb任务控制块的定义中增加一个pc成员,用于保存task最后的运行位置,将pc成员保存在第一个word后,pc成员为tsk_pc,如下所示:

    typedefstruct

    {

    uint32_t*pxtop_of_stack;

    uint32_ttsk_pc;/*<tosavelastlocation.*/

    }tsktcb;

    并且在tcb中添加tsk_pc成员之后,需要在任务切换之前,将实际的pc指针保存到tcb的tsk_pc中,由于设备使用的是cortex-m4的核,根据m4核的特性,响应异常的第一个动作,就是自动保存现场的必要部分,依次把xpsr,pc,lr,r12以及r3‐r0由硬件自动压入适当的堆栈中。代码可以这样将pc值取出来:

    __asmvoidxportpendsvhandler(void)

    {

    mrsr0,psp

    isb

    /*getthelocationofthecurrenttcb.*/

    ldrr3,=pxcurrenttcb

    ldrr1,[r0,#24]

    ldrr2,[r3]

    strr1,[r2,#4]

    nop

    }

    其中:

    mrsr0,psp表示取栈指针sp

    ldrr1,[r0,#24]表示获取已经保存到堆栈中的pc值

    ldrr2,[r3]表示取当前tcb的地址

    strr1,[r2,#4]表示将pc值存到tcb的tsk_pc中。

    这样,在系统运行时,每次任务切换,都可以将pc值保存到对应task的tcb中,方便以后追踪问题的时候使用。

    进一步,在步骤二中,设备使用了mcu的bootmode引脚,在系统启动后,bootmode引脚就不会再被硬件检测,之后在系统起来后,将bootmode的一个引脚boot1用作gpio,该gpio作为输入,假设boot1为高电平时可以正常启动系统,那么在上电时,boot1必须为高电平,系统起来后,idletask里不断检测该gpio引脚是否为低电平来触发相应的诊断流程。所以一旦boot1对应的拨码开关被拨到了低电平位置,则立即触发诊断流程。

    进一步,在步骤三中,设备使用的rtos中,收发事件使用的是os_eventgrpwait和os_eventgrpset接口,为了定位问题,在这两个函数内部及相应的流程上增加了串口log(日志),用于确定事件是否正常发送出去,即可诊断某个task。这样在boot引脚为低电平时,诊断开关被打开的情况下,通过os_eventgrpset给某个task发测试事件,当该task收到该测试事件时,会执行它,如果没有收到,则通过这两个函数内部及流程上的串口log可以综合查一下原因。另外,在调用完os_eventgrpset后等待一段时间,通过os_eventgrpgetbits来判断该测试事件是否被对应的task处理,一旦该事件被正确接收处理,那么调用os_eventgrpgetbits函数的返回值为0,否则为非零值。

    进一步,在步骤三中,根据打印出所有task的各种信息,主要是状态和tsk_pc值,然后在汇编文件中查找各个task的tsk_pc对应的实际位置,并结合c语言代码,就可以分析出各个task最后在哪个函数的哪个位置了。

    在系统检测到boot1为低电平后,就可以触发诊断流程,使用os_eventgrpset发送测试事件,然后根据输出的函数调用流程中的串口log,来进行辨别。当测试事件发出后,该测试事件所绑定的task会被加入到就绪队列,等待调度运行,从而一旦task被调度后,会调用os_eventgrpwait来获取发送的测试事件了,如果从串口log看到的不是这样的过程,可能为系统调度存在问题,从而便于进行辨别。

    本发明的工作原理及使用流程:本发明嵌入式系统中诊断设备无响应的方法在辨别的时候,通过三个步骤进行辨别处理,具体包括保存并打印task的运行位置、利用boot引脚触发诊断流程、诊断rtos系统调度等。打印task的状态及运行位置是为了全面了解各个task的运行情况,通过运行位置就可以知道每个task在让出cpu时在执行什么指令,结合堆栈也可以分析出函数的调用关系等;利用boot引脚触发诊断流程是因为可以节省一个外部引脚,利用它作为诊断触发条件,打开系统正常运行时被屏蔽的log;诊断rtos调度问题是因为在系统无响应的原因未明的情况下,任何情况都可能存在,通过该方式可以确定是否是系统调度问题,从而可以进行进一步的分析。

    而新型嵌入式系统中诊断设备无响应的方法具体操作步骤包括如下:

    步骤一:通过在task任务控制块中增加当前pc指针值,来定位每个task当前(或者最后)执行的位置。

    步骤二:异常时,通过bootmode拨码开关,控制触发问题追踪流程。

    步骤三:在追踪问题时,增加打印taskpc指针值和诊断rtos运行过程。

    具体实施方式:

    (1)、保存task的运行位置

    在rtos系统中,存在任务的概念,每个任务都在负责自己的事情,并且从宏观上看,这些任务都是并行的,对这些task的诊断,一般的做法是打印当前task的状态、优先级、堆栈等信息。

    这样先在tcb任务控制块的定义中增加一个pc成员,用于保存task最后的运行位置,而将pc成员为tsk_pc,在tcb中添加tsk_pc成员之后,需要在任务切换之前,将实际的pc指针保存到tcb的tsk_pc中,由于设备使用的是cortex-m4的核,根据m4核的特性,响应异常的第一个动作,就是自动保存现场的必要部分:依次把xpsr,pc,lr,r12以及r3‐r0由硬件自动压入适当的堆栈中,上下文切换之前可以将pc值取出来。这样,在系统运行时,每次任务切换,都可以将pc值保存到对应task的tcb中,方便以后追踪。

    (2)、如何触发诊断流程

    由于外部按键是通过中断方式触发的,现在系统无响应,也无法确定中断是否能够正常使用,也有可能被异常屏蔽了。而系统中加了看门狗定时器,在idletask中不断进行喂狗操作,在无响应时,系统并没有触发看门狗超时,从而导致系统复位,这样猜测idletask是可以正常工作的。

    在系统启动后,bootmode引脚就不会再被硬件检测,所以可以根据这个特性,在系统起来后,将bootmode的一个引脚boot1用作gpio,该gpio作为输入,假设boot1为高电平时可以正常启动系统,那么在上电时,boot1必须为高电平,使得可以在idletask里不断检测该gpio引脚是否为低电平来触发相应的诊断流程。

    (3)、如何实现诊断流程

    由于无法获知系统到底是一个什么样的情况,而通过前面保存task的pc值的方法可以基本知道task的运行情况,但还有一种情况不能排除,那就是使用的rtos本身的调度问题。

    a、在设备使用的rtos中,收发事件使用的是os_eventgrpwait和os_eventgrpset接口,为了定位问题,在该函数的执行流程中增加了一些串口打印log,用于确定事件是否正常发送出去。而这些串口log的打印,是通过一个全局的开关来控制的,因为不能在系统正常运行过程中,一直打印该串口log,所以才需要这个开关。而这个开关的触发就是通过前面讲到的boot1引脚为低电平时触发。所以想要触发该功能,需要手动将boot1开关拨到低电平。

    b、通过a步骤的方法,就可以诊断某个task了。在诊断开关打开的情况下,给某个task发事件,比如怀疑前面讲到的shelltask并没有收到shell命令,可以诊断shelltask,给shelltask发一个测试事件,这样的测试事件一旦发出去,就可以看到函数调用流程的串口log了。另外,为了看到这个测试是否成功,在发出测试事件之后,可以通过os_eventgrpgetbits来判断该事件是否被对应的task处理。如果系统调度没有问题,当os_eventgrpset发出后,该eventgroup对应的task会被加入到就绪队列,等待调度运行。一旦task被调度后,会调用os_eventgrpwait来获取发送的测试事件,如果从串口log看到的不是这样的过程,可能系统调度存在问题,可以结合前面的各个task的信息综合分析。

    尽管已经示出和描述了本发明的实施例,对于本领域的普通技术人员而言,可以理解在不脱离本发明的原理和精神的情况下可以对这些实施例进行多种变化、修改、替换和变型,本发明的范围由所附权利要求及其等同物限定。


    技术特征:

    1.一种嵌入式系统中诊断设备无响应的方法,其特征在于:所述在嵌入式系统中,诊断设备或者系统无响应的方法,具体包括如何确定task的当前执行的位置、如何触发追踪流程和如何追踪系统运行时状态几个部分;具体操作步骤包括如下:步骤一:通过在task任务控制块中增加当前pc指针值,来定位每个task当前(或者最后)执行的位置;步骤二:异常时,通过bootmode拨码开关,控制触发问题追踪流程;步骤三:在追踪问题时,增加打印taskpc指针值和诊断rtos运行过程。

    2.根据权利要求1所述的一种嵌入式系统中诊断设备无响应的方法,其特征在于:所述在步骤一中,先在tcb任务控制块的定义中增加一个pc成员tsk_pc,用于保存task最后的运行位置,另外,在任务切换之前,将实际的pc指针保存到tcb的tsk_pc中。

    3.根据权利要求1所述的一种嵌入式系统中诊断设备无响应的方法,其特征在于:所述在步骤二中,设备使用了mcu的bootmode引脚,在系统启动后,bootmode引脚就不会再被硬件检测,之后在系统起来后,将bootmode的一个引脚boot1用作gpio,该gpio作为输入,假设boot1为高电平时可以正常启动系统,那么在上电时,boot1必须为高电平,系统起来后,idletask(空闲任务)里不断检测该gpio引脚是否为低电平来触发相应的诊断流程。

    4.根据权利要求1所述的一种嵌入式系统中诊断设备无响应的方法,其特征在于:所述在步骤三中,设备使用的rtos中,收发事件使用的是os_eventgrpwait和os_eventgrpset接口,为了定位问题,在这两个函数内部增加串口打印log,用于确定事件是否正常发送出去,从而诊断某个task;在步骤二诊断流程触发的前提下,会触发一个开关,打开该串口log,同时通过os_eventgrpset给某个task发测试事件,当该task收到该测试事件时,会执行它,如果没有收到,则通过这两个函数内的串口log可以查一下原因。

    5.根据权利要求1所述的一种嵌入式系统中诊断设备无响应的方法,其特征在于:所述在步骤三中,根据打印出所有task的各种信息,主要是保存到tcb成员tsk_pc中的pc值,然后在汇编文件中查找各个task的tsk_pc对应的实际位置,并结合c语言代码,就可以分析出各个task最后在哪个函数的哪个位置了。

    技术总结
    本发明公开了一种嵌入式系统中诊断设备无响应的方法。具体包括保存并打印TASK的运行位置、利用BOOT引脚触发诊断流程、诊断RTOS系统调度这几个部分。通过以上几种手段的结合,再结合汇编代码和C语言代码,可以比较快速的定位到问题产生的原因。比如系统中某个TASK使用了二值信号量却没有释放,后面其他多个TASK又继续来申请使用该信号量,因为这些TASK都获取不到该信号量,导致都会被挂起,此时表现出的现象就是系统无响应。此时,开发人员就可以利用以上几种方式进行诊断。

    技术研发人员:冯海强
    受保护的技术使用者:北京简约纳电子有限公司
    技术研发日:2019.09.11
    技术公布日:2021.03.12

    转载请注明原文地址:https://wp.8miu.com/read-22857.html

    最新回复(0)