1. 问题描述
BK3633 SDK 版本:BK3633_DesignKit_V06_2310
使用 BK3633 UART2 与指纹模块进行通讯,为了降低功耗,通过 GPIO 控制了指纹模块的供电电源。但每次给整个系统板子上电时,BK3633 很大概率会实际而无法正常运行程序,但在拔掉与之相连的指纹模块串口接口(包含了 UART2 串口线)再上电则一切正常。原厂技术支持,说是有漏电流引起模块启动不正常,但继续追问为什么就没有下文了,仅提供在串口线上串电阻进行验证处理(未验证)
2. 问题分析
跟随原厂提供的 UART2 的 TX 和 RX 的漏电流的解决思路,博主测量了指纹模块接口每个引脚的电平,发现在没有初始化 UART2 的情况下,TX 和 RX (GPIO16 和 GPIO17)处于高电平状态,而这两个引脚应该都是 GPIO 默认状态(即作为输出模式默认输出 0),GPIO 默认状态从《BK3633_ADDR Mapping.xlsm》文件中如下图中获取:
一切反常必有妖,博主把应用程序全局检查了一遍,确认没有任何代码关联设置了这两个 GPIO ,
但通过查看官方开发手册,如下图所示:
以及全局搜索 uart2_init(UART2 串口初始化函数),发现如下图所示结果:
在 boot 和 driver 中都存在 uart2_init 函数的实现,并且 boot 中还调用了 uart2_init,作为 boot 引导程序中的调试打印输出串口,如下图所示:
为了验证 boot 引导程序是否真通过 UART2 作为调试输出串口,把 UART2 的 TX 和 RX 接入电脑串口工具,设置波特率为 1000000,重新给模块上电,串口工具打印如下:
由此说明 boot 引导程序运行时初始化了 UART2 并进行了日志打印输出,这也就能对应开头为什么应用程序没有设置,但对应的 TX 和 RX (GPIO16 和 GPIO17) 引脚是高电平状态了,因为 boot 初始化串口时把这两个引脚设置为了第二功能并上拉了。
此时灵光一闪,会不会是 boot 程序里面 UART2 的 RX 接收了啥导致程序起不来了(或者说接收处理异常引起死机了)?因为 boot 上电时有打印输出,那必然会被指纹模块接收到,而指纹模块那边在没有正常供电的情况下,其串口的 TX 会有什么动作不得而知。
3. 问题验证
按照如下串口工具的设置,进行定时(50ms 即以内)发送大量数据给 UART2,如下图所示:
再次给板子上电,发现也很大概率起不来,50ms间隔还是有机会起来,1ms间隔一点机会都没有,并且 50ms 间隔在 boot 程序在打印输出 boot_start1 之后就死掉了。当停止发送数据时,板子每次上电都正常跑起来了。
由此可以说明是 boot 引导程序里面 UART2 的 Rx 接收到了数据引起了 boot 死机了。
3. 问题解决
确认了是 boot 程序调试输出串口 UART2 的接收引起的 boot 死掉的问题,那就好解决了。
一开始发现 boot 程序里面缺失了 uart2_isr 的定义,只声明了该函数,而 intc.c 中又调用了 uart2_isr,所以重新定义了该函数,发现还是有问题
继而发现 boot 中没有使用串口的 Rx,而 UART2 初始化的时候,却初始化了接收中断,于是为了简单验证性的处理,则在 uart2_init 初始化函数中屏蔽了如下处理:
SYS_REG0X10_INT_EN |= (0x01 << POS_SYS_REG0X10_INT_EN_UART1);
即不启用该串口中断,再次验证,问题解决了。
而查看最新版 SDK:BK3633_DesignKit_V06_2614
中的 boot 对应源码,也是如博主一样屏蔽了串口中断的。
4. 结语
真是有苦难言,有悲有喜,
悲的是浪费了那么多时间来排查这个问题,
喜的是自己一步一步探寻到了真像。
一切没有解决的问题都是大问题,一切解决了的问题都是小问题。