STM32移植USB驱动到RTX系统无法使用问题(malloc分析篇)

前景提要

上一篇RTX篇首先移植的是USB 从机Slave工作模式的VCP(虚拟串口)类,在移植之前都是在裸机上进行了初步测试,都很正常,但是首次移植到RTX系统下之后,又出现了之前的死机现象,只是这次死掉的地方不一样,这次是进入到硬件错误,并且是在USB初始化之后(是最后初始化的)。

分析过程

任务分析

猜测是由于初始化过程被RTX打断,于是就给初始化过程添加任务锁,如图4所示,禁止任务的调度。
但是采用加锁的措施之后,程序依旧死掉,并且依旧死在了延时那里,主要原因还是os_time的数值在任务锁中不再更新,仔细查看RTX的RTX_lib.c文件也可以找到不发生变化的原因,是任务锁的实现函数。
任务锁实际上就是关闭了系统时钟中断,自然也就导致os_time不再更新,所以延时函数会一直死等。
将任务锁去除掉,继续分析刚移植进来时出现的死机,调试时使用任务监测窗口对任务的状态进行查看。
通过窗口查看可以看出程序一直处于等待状态,并且一直处于空闲任务,于是只能停止程序,看看程序死在了哪里。程序进入硬件错误时的查看窗口,右键HardFault处,点击弹框的第一项,查看死在哪个函数里。

系统堆栈

点开后可以看到窗口跳转到RTX_lib.c文件中,分析箭头指向,根据该文件的注释,可以看到是一个申请资源的函数,并且用于锁住标准库资源的函数,由于保护的资源外泄导致程序进入硬件错误。
但是具体是保护的哪个标准库资源,还不清楚,首先猜测的是malloc,但是由于USB模块的代码非常多,并且调用关系比较深,所以不知道具体是在哪里出现的问题。
将malloc问题先放在了一边,根据先前移植到裸机上的经验,首先将启动文件中的堆栈大小都增大。
进行增大后,依旧没有改善(但是这两个数值是不许增大的,在裸机下已经验证),然后猜测是系统寄存器存在问题,于是查找资料,在网上找到RTX中对OS_RUNPRIV的解释。
网上关于该宏定义的解释如下:In privileged mode user may access and configure the system and control registers like NVIC interrupt controller etc. This is however not allowed from unprivileged mode. An access to NVIC registers from unprivileged mode will result in Hard Fault.
默认是使用特权运行模式,实测该宏定义需要打开,不然无法访问和修改系统寄存器。

USB中断

排除了这个问题后,又猜测是USB的中断导致的,进入中断次数过多或是和RTX的系统中断相冲突,于是将RTX的系统中断主要的两个中断(SysTick_IRQn系统时钟滴答中断,PendSV_IRQn任务切换中断)优先级调到最大(0),并且在裸机上也验证过,USB的中断优先级不能过低,不然也会导致通信异常。所以讲USB的中断优先级也调到最大(主要是为了排除干扰)。
并且在USB中断中添加调试变量来计数进入中断的次数,这里首先将中断处理函数注释掉,调试发现程序虽然可以运行了,但是这个计数变量在疯狂地增加,1s内增加的次数在变化,实际上注释掉这个处理函数是错误的,因为在该函数中有将中断标志位清除,所以去除后导致标志位无法清除。
修改后,调试发现程序死的时候,计数值也就相对稳定了。

确认死机位置

接下来就开始尝试确定程序是死在哪一行代码处,而不是硬件错误指向的地方,也就是找到我们的代码究竟是哪一行代码的执行触发了这个硬件错误。
首先在中断处理函数中添加指示标志位(实际上也就是在代码的每一行给状态变量赋一个特定的值),调试发现程序是死在了状态值为99的地方。
然后根据标志位找到相应的函数然后一层一层的往下找,根据这种方式依次再添加一些标志位。

malloc重入问题

malloc是不可重入函数,如果在其还没返回就再对其调用将出现灾难性后果,并且在RTX文件中,也有提到过,RTX内部也有使用到malloc申请缓存,如果在RTX申请过程中(虽然有加互斥锁),USB中断来到,执行到该函数就会导致malloc冲突,从而触发了一次硬件错误(也即是前面最一开调试时硬件错误中断指向的函数中对标准库资源的保护)。
但是我们又必须在USB模块中动态地申请缓存,所以也就将此处的malloc换成之前写的MallocRam_Dr模块中的相应的接口函数,下载程序,USB VCP设备可以正常使用(电脑端需要安装ST的虚拟串口驱动)。

在这里插入图片描述

总结

经过前面的分析终于解决了USB的死机问题,但是当使用主机模式时,发现部分U盘插入后无法识别,但是使用电脑是能够识别的,关于这部分的问题,后面再继续分析(USB篇)。

注:灵活运用调试变量能够快速定位死机问题的位置,并且缩小问题范围。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值