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

问题背景

在USB移植前期,首先将USB模块移植到裸机板上,运行状态十分稳定,但是当使用RTX时,出现函数重复定义错误,修正这些错误之后,虽然不再有报错信息,但是运行一段时间之后,整个RTX系统滴答计数值不再变化,且程序进入硬件错误(程序死掉)。

问题阶段

1.SysTick_Handler中断处理函数重复定义,导致HAL库无法获取系统时钟滴答;
2.由于RTX在内部实现了SysTick_Handler函数,不开源(实际上是使用汇编语言实现的),只能使用RTX的os_time,但是如果不初始化RTX,则os_time是不会更新的;
3.调试USB移植后的代码,程序很快进入硬件错误(os_time停止更新,并且硬件错误进入到_mutex_acquire函数,从机作为MSC时会死在初始化后不同的地方);
4.初始化成功之后,插入数据线后,程序立刻死掉;
5.程序可以正常运行,但是电脑无法识别显示屏USB设备;

底层分析

由于我们目前使用的USB模块是使用CubeMx产生的代码,其使用的是HAL库,所以首先需要将HAL库移植进我们的显示屏中。
按照同样的步骤,首先是移植到裸机下,目的是为了排除移植过程中RTX对移植对象的干扰,这个过程很顺利。但是当开始使用RTX后,发现存在重复定义的中断函数,分别为SVC_Handler、PendSV_Handler和SysTick_Handler,这三个中断处理函数,刚开始并没有意识到他们的重要性,而且由于RTX不开源,在当前的工程代码中又找不到这三个中断函数的实现代码。
由于HAL库是开源的,所以只能向RTX屈服,将HAL库的实现代码注释掉,重新编译,顺利通过,将程序下载到显示屏中运行,运行指示灯不再闪烁,而且调试发现程序死在了系统时钟初始化函数里面。
也就是说,整个程序都还没有运行起来,就已经死掉了,这个问题十分奇怪,调试运行时全速运行,然后查看程序停在哪里了。
结果发现程序停在了HAL_Delay()函数里面,实际上这个问题不难理解,因为这个延时函数在HAL库中通过SysTick_Handler中断函数产生的。

RTX分析

所以直接将HAL库实现的系统中断函数会导致HAL库的系统时钟滴答停止,如果仅仅是为了提供延时,完全可以替换成一个普通的延时,但是走读代码后发现HAL库中的还有很多地方需要直接获取时钟滴答。
所以我们必须给HAL库提供一个系统时钟滴答,好在HAL库的HAL_GetTick是定义为__weak类型,所以我们可以重新定义和实现。
但是,由于RTX不开源,所以我们只能查看它有没有给我们留出这样的接口或是全局变量,最终通过百度,得知可以直接使用os_time这一全局变量,这个变量就是由RTX来更新的系统时钟滴答。
以为这样就可以解决前面的问题,但是下载程序后,运行程序,依旧像刚才一样死掉,于是就开启调试模式,将os_time添加到watch1窗口,发现在程序执行时os_time是不变的,而且程序依旧是死在HAL_Delay处,死的地方是可以理解的,因为os_time的数值未发生变化。
由于当前使用的外设都是没有RTX依赖性的,所以都是在初始化/开启RTX系统之前进行初始化的,而这些外设(最一开始的晶振初始化)有使用到HAL_Delay函数来进行必须的初始化延时。
经过验证,os_time只有在RTX启动之后才会有效(数值才会更新),所以之前在RTX系统任务外初始化硬件是不合适的。
经过如上的分析后,将硬件初始化(包括晶振的初始化)都放在RTX系统任务中,该问题得到解决。
实际上之前也考虑过直接修改RTX的有限源码,在Keil安装目录C:\Keil_v5\ARM\RL\RTX\SRC\CM下可以找到一个文件名为HAL_CM4.c的文件,该文件就是RTX实现的一些系统中断和一些系统函数,其中可以找到我们需要的SysTick_Handler系统中断函数。

该篇小结

在RTX的源码中,是通过汇编语言实现的,其中调用了RTX中实现的(未开源)rt_systick,我也有尝试过仿照这种格式,在该中断汇编中添加我的一个外部函数,但是实测,程序并不会跳转到我定义的这个函数中(无法理解,可能RTX内部有保护机制)。
完成HAL库的移植之后,开始移植USB模块(后续下一篇介绍USB底层分析过程)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值