2022年11月29日星期二
2022年11月7日星期一
duagon D013模块的调试及串口不通问题的解决
duagon D013模块(下文简称“模块”)是一款MVB通信模块。它对外是MVB接口,对内是并口、串口、SPI接口中任选一种,相当于给“电脑”接了一个“MVB网卡”。而这个“电脑”,既可以是PC机,也可以是嵌入式设备。近期我就接了一个活,在一块以NXP i.MX6ULL为CPU的板子上,对接这个模块。而我们选择的内部接口是串口。
模块的三种内部接口具体用哪一种,通过模块上2个Mode管脚的高低电平来设置,具体参见这个模块的规格书。选中串口后,串口是TTL电平的UART口,可直接接在CPU的UART口上。波特率、校验位等也通过给对应管脚设置高低电平配置到模块上,具体参见规格书。这里要注意的是,这个模块的串口是有硬件流控的。它有个MVB_TX_HOLD管脚和一个MVB_RX_HOLD管脚。TX和RX是站在模块的立场上说的。如果MVB_TX_HOLD是高电平,那么模块就认为电脑一方已经处理不过来数据了,让模块不要发送,所以模块就不会发送。而如果模块自己处理不过来数据了,会把MVB_RX_HOLD拉高,告诉电脑不要再发送数据了。因此,你既可以把这两个管脚接在CPU的硬件流控管脚上,也可以忽略流控功能,但前提是不要把MVB_TX_HOLD管脚拉高,也不要让它处于浮空状态,而应该把它拉低。否则该管脚的电平一旦变成高电平,那模块就不给串口发数据了。我就因为这个地方耽误了很长时间,也是决心写这篇文章的原因。
我们用的这款CPU支持多个串口,但是默认的设备树可能只打开了一两个。如果与模块通信的串口在/dev目录下找不到的话,还需要修改设备树把对应的串口打开。具体方法网上有很多文章,这里就不赘述了。需要注意的是Linux代码树中这款CPU的UART5的寄存器配置有个BUG,如果使用UART5的话要注意避坑,网上讲这个的也很多,这里就不赘述了。
自认为串口没问题了,可以写个程序尝试给连接D013的串口发送0x43 0x01 0x23 0x53四个字节. 如果串口工作正常,模块没有损坏,那么可以立即收到模块返回的0x01 0x23.到此为止,CPU和D013模块之间的串口就调通了。下一步可以移植厂家提供的api了。
duagon厂家提供的api分为devel和app两个目录,均是以C语言源代码的形式提供的。devel目录下的源代码编译后,执行make copy生成api目录下的头文件和库。用于app目录下demo程序的编译,以及自己开发的程序的编译。
devel目录下又分为common和target两个子目录. common中是对duagon模块接口的封装函数,比较复杂,移植过程中几乎不需要做改动,厂家也在文档中注明需要改的话联系厂家,不要自行修改。target是针对不同软硬件平台进行适配的代码,移植也主要是改这里。target/inc下有两个头文件,里面是接口类型、调试打印等级等信息,使用串口访问D013时波特率等参数也在这里配置。target/src下有几个osl_开头的源文件,其中osl_ser.c是用串口访问duagon模块的代码,需要注意的是原始代码中的串口文件名是针对PC上的USB转串口线的,大多数情况下需要改成和所用平台一致的文件名。osl_spi.c是SPI接口访问duagon模块所用的代码,是针对FTDI的一款USB转SPI线写的。在我的嵌入式Linux使用场景下,这套代码是完全无法使用的。我目前也正在开发Linux下SPI接口的驱动,这部分调通了再具体说。
代码改好后,可在devel目录下运行make程序对代码进行编译。如果要使用交叉编译器,需要修改build_env.mk文件中的工具链名称。编译成功会生成libhost.a静态库文件。需要注意的是,如果改动了头文件,重新编译时,make检测不到需要重新编译相关的源文件(Makefile写得不好),所以libhost.a也不会更新,对头文件所做的修改无法生效。这时候要运行make clean把.o文件和listhost.a全部删掉重新编译。编译好后,执行make copy, 会将编译好的静态库文件和一些头文件复制到api目录下,不过复制的头文件不全,后文再说。
刚才说的厂家提供的代码,除了devel目录还有个app目录。这里面就是厂家提供的demo程序。涉及MVB和D013模块的就是一个叫tcn_pd_demo的目录,还是老办法,直接make就行了。这时可能会报找不到头文件的错误。要注意在Makefile中把头文件的路径指向刚刚提到的api目录。不过即使指过去也还是会报错误,这时就要把devel/common/inc下的头文件复制过去,也可以把devel/common/inc加到头文件路径中。当然最好还是改一下devel/Makefile文件,把漏复制的头文件加上,我就是这样做的,可以一劳永逸,而且以后只发布api目录,不用带着devel目录。
tcn_pd_demo编译成功后运行,这个程序会反复给D013模块发送和读取数据,如果失败了会报错并退出,没有失败就一直持续运行下去,没有尽头。千万不要像我一样,第一次傻傻地盯着屏幕半个多小时在想怎么还没运行完。另外需要说明的是,这个程序成功执行,也只能说明CPU到D013模块之间的通信是正常的,并不能说明D013模块对外收发正常。这后面还有一段路要走。
以上是我调试D013模块的一点心得,目标读者是嵌入式软件开发经验和我差不多的朋友,所以没有写一些过于细节的东西。如果您哪里没有看明白,欢迎和我交流,我们互相学习。