« 上一篇下一篇 »

ST代码移植到ARTERY总结

多的就不说了,今年IC严重缺乏,ST的MCU更是水涨船高,迫不得已需要更换为国产的MCU,选择了ARTERY的。

原MCU为STM32F103RCT6,更换为AT32F413RCT7,pin to pin的,然后FLASH和SRAM大小一致。以下为移植过程中需要注意的点。

1、AT32F413RCT7没有SPI3

说是说pin to pin的,但其实STM32F103RCT6有3个SPI接口,但是AT32F413RCT7只有2个,所以说是少了一个,如果原来在ST上用了3个SPI的,那AT这款芯片是不适合用于移植的。然后如果原来用了SPI3,但是并没有用到3个SPI口的,还是可以的,AT的SPI3虽然没有,但是在ST的SPI3对应的IO上,AT支持其他两个SPI的重映射,就是说,可以用AT的SPI1或SPI2来取代原来ST的SPI3。

2、AT32F413RCT7 SPI2重映射

这里需要注意一下,AT的库的用法和ST并不完全相同的,在AT上重映射这个SPI2接口,因为其默认用作JTAG的功能,所以重映射时需要关掉JTAG功能,仅开启SW功能,同时还需要使能SPI2的重映射。注意这里,在重映射函数调用时,不能把关闭JTAG和使能SPI2重映射在同一次函数调用的参数中使用异或来同时处理,否则AT的库里判断会认为参数不合法,这里需要使用两次重映射函数,分别关闭JTAG和使能SPI2重映射。

3、FLASH擦除

AT的MCU,其FLASH分为零等待区和非零等待区两部分,当然,零等待区和非零等待区各自的空间大小是可以软件来配置的,在默认情况下,AT32F413RCT7的FLASH零等待区大小为前面96K,后面的空间全为非零等待区。为什么要着重说明这个设计呢?那是因为AT的FLASH擦除操作与此有关,在AT中擦除FLASH时,如果擦除的是零等待区,且擦除时存在有从零等待区取指令和非零等待区取指令的混合操作,则会导致程序跑飞,就像这里,擦除零等待区FLASH时,会执行零等待区的指令,如果过程中产生了中断,而中断的指令处于非零等待区,则此时程序就跑飞了。

对于这个问题,官方给出了两个解决方案,一是保证芯片在擦除期间所有执行的函数代码都位于零等待区,二是擦除前后,关开中断,如下:

_disable_irq();
Erase();
_enable_irq();

下面截图为官方给出的FAQ说明。

4、USB移植

USB真的是个大问题,真的是需要好好的钻研一下,但是空闲时又好像总是忙这个忙那个,唉。USB移植,比较重要的其实就是各描述符的移植了,我最开始试了,除了一个报告描述符之外,其他的都移植了,结果发现有bus hound监测,收发是没问题的,但是用其他的上位机软件来联机,竟然收不到下发的数据,后来把报告描述符也改成和之前一样的,就可以了。这里是需要注意下,之前看了一部分USB AUDIO的文档,但是那个是没有报告描述符这种东西的,它只存在于HID通讯类中,这里需要好好研究一下。

5、USB重新枚举

这里主要是BOOT与应用层的跳转问题,原来的ST的,在BOOT中初始化USB后,跳转到应用层,再次初始化USB,中间过程USB一直是插着的,在跳转完后电脑仍然可以识别到USB设备,但是AT的是不可以的。官方给出的重新枚举的方案是断电再上电,当然,是软件上设置USB断电与上电。所以这里的设计就是在BOOT中,跳转前先将USB电源关闭,跳转后由USB初始化操作重新来打开电源,也就是重新枚举。这样跳转前后,USB不需要插拨电脑也能够正常识别了。示例代码如下:

Power_Off (); 
Delay_ms(3000); 
Power_On (); 
Delay_ms(3000);

还有一个问题就是,我试了在应用层中,如果USB中断配置在时钟配置之前,则在跳转后,程序就卡在中断配置完后,没法继续往下执行了,原因不知道是啥,但是如果先配置好了时钟,把中断配置放在最后面的话,就不会有这个问题。

6、GPIO速率

根据AT的官方说明文档,原来ST的GPIO配置代码(一般速率是配置为50M,实际翻转的速率当然远没这么高),最好是修改成2M,否则会存在过冲现象,就是说输出电压原来是3.3V的,过冲时可能会冲到4.3V,这样可能会导致外接器件损坏。不过,还有其他官方文档说这个问题只存在比较低版本的AT库中,换成最新的库就不会有这个问题了。

7、SRAM配置

AT32F413RCT7的SRAM是可配置的,默认为32K,如果直接移植ST的程序,原程序用到的SRAM大于32K,那么程序是会进入HardFault的,所以,在程序运行之前,需要先行配置AT的SRAM为64K。具体如何配置就不多说了,官方文档有,例程也有。

8、ST库与AT库的差异

说实话,其实AT的库,我觉得就是照着ST的库抄的,哈哈,只是改动了少量了名称,比如说小写改成了大写,我估计AT是不敢完全用一模一样的,是怕收到律师函吧。这里要说一下的就是,中断服务例程的名字差异比较大,如果移植到AT上,一定要记得一个一个的修改所有使用到的中断服务函数的名称,否则中断执行时找不到入口,会直接跑飞的。

9、KEIL MDK开发环境问题1

KEIL有时分明包含了某个头文件的路径,但是编译时一直提示找不到该文件。这时可以重新删除路径,再重新更改下顺序进行包含就能解决。

10、KEIL MDK开发环境问题2

还是和上面AT库的名称有关,前面说了ST的库有时某些函数名称是小写的,AT的库改成了大写,本来是有区别,但奇葩就奇葩在,大小写都不一样的地方,KEIL中竟然能够跳转,比如说实际的函数名称是大写的,程序调用时使用了小写,本来名字是错的,但是KEIL可以跳转到正确的函数代码,于是我就以为没有错,但是编译器一直报错说变量未定义,浪费我大半天时间才看出来,原来字母都是不一样的,这编译器,我也真是服了。

11、其他问题1——调试接线

一个调试的问题,MCU和其他器件用的是UART连接,然后我在没有断开这二者的线路连接的情况下,外接了个UART转串口到这里的TX、RX上面,发现用外接的UART转串口接收到的数据存在有误码、遗漏的情况,不知道是接收的问题还是发送的问题。以后还是不要这样搞,容易出现错误的结果,导致测试一直都是在非正常情况下进行,很浪费时间的,更会影响到问题的判断与分析。如果实在是需要用串口工具单独发命令给器件,那就必须要断开MCU的连接;如果只是想看MCU发送到器件的数据,可以用另外的串口同步打印出来,这样就连接线都不需要。

12、其他问题2——代码兼容性

以后写代码要多注意下兼容性,比如写4进8出时,要考虑下3进6出或者2进4出使用同一条代码时会不会有问题,尤其是涉及到宏的,比如通道宏,不同的机型这个值不同,代码执行起来可能就不是自己的本意了。

反正是代码写完后要仔细的检查至少一遍,尤其是复制粘贴比较多的,又带有宏定义的,很容易搞错。


2021年7月11日 于广州花都