最近要做一款一头USB接电脑模拟U盘, 一头通过串口与终端设备交互的设备, 好久没有接触单片机, 安装最新的KEIL5.24a, 发现好多功能都不会用了, 在适应了几天后开始着手进行开发, 在开发中遇到了一些问题和一些心得, 记录一下.
现在KEIL的中间件比较丰富, 但相对于VS来说还是太弱太弱, 写了两个插入注释的小工具插件才算感觉好一点, 连插入当前时间的模板都没有, 愁人......言归正传, 创建工程, 一开始我选择了USB Device的大容量存储器, 文件系统, SPI, UART等设备用到的中间件, 如果缺少依赖项则会有黄色提示, 点击提示自动定位选中即可, RTX选择的是4.81, 没有选择RTX5, 跟USB中间件貌似有冲突, 编译会出现错误....
接下来就是创建代码分组之类的东西了, 没啥好说的, 根据模板创建main文件, 设置线程堆栈空间等....
CMSIS-RTOS+RTX启动USB模拟U盘真是非常简单, 但是坑比较多, 资料太少, 下面两句即可,
USBD_Initialize(0);
// 等待设备0的连接
USBD_Connect(0);
但是要在RTX_Conf_CM.c中设置两个自定义线程, 总大小为1024, 因为USB有两个线程, 一个核心线程需要512字节空间, 一个USB存储线程也需要512存储空间. 到这里如果硬件正常的话在电脑上就可以识别出U盘来了, 但是不能对U盘进行操作, 因为还要实现USB对存储器的操作, 这个直接用模板添加USB大容量存储器代码即可, 默认为USBD_User_MSC_0.c, 在里面进行初始化以及读写操作即可. SPI设备要注意进行修改对应的读写驱动, 这里要注意的一个坑是Keil中间件里的文件系统对SPI Flash是不支持FAT文件格式的~!~!~!~用的是一种嵌入式文件系统, 根本不是FAT, 我被坑了好久好久...., 所以直接用开源的FATFS方案吧, diskio.c中的读写可直接用于USBD_User_MSC_0.c中的扇区读写, USBD_User_MSC_0.c中的块指的是扇区的意思, 不是存储器中块的意思, 要注意了~!~!
硬件设计中将JTAG引脚PA15当作通用IO口了, 开始没注意, 设置引脚电平总是无效, 很是郁闷, 翻了翻数据手册发现是JTAG口, 需要禁用, 但CMSIS-RTOS中间件没有定义GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);这个函数, 那就自己找吧, 找到了GPIO_AFConfigure函数, 引脚复用映射设置, GPIO_AFConfigure(AFIO_SWJ_JTAG_NO_SW);这个参数不是禁用SW, 而是禁用JTAG, 真不知道怎么想的, 一共四个相关参数:
AFIO_SWJ_FULL = AFIO_FUNC_DEF (24, 7, 0, 0),
AFIO_SWJ_FULL_NO_NJTRST = AFIO_FUNC_DEF (24, 7, 1, 0),
AFIO_SWJ_JTAG_NO_SW = AFIO_FUNC_DEF (24, 7, 2, 0),
AFIO_SWJ_NO_JTAG_NO_SW = AFIO_FUNC_DEF (24, 7, 4, 0),
开始看着哪个都不对啊, 对照数据手册对数据进行挨个拆分, 查看GPIO_AFConfigure函数的实现, 才最终确认应该使用AFIO_SWJ_JTAG_NO_SW这个参数, 然而, 你直接这么调用是没有用的, 查看GPIO_AFConfigure函数代码你就会发现还有个宏定义AFIO_MAPR_SWJ_CFG_VAL需要关注下, 如果没有定义这个宏的话他的值是AFIO_SWJ_FULL, 这就导致了你不管传入什么值, JTAG跟SW都不会被禁用的, 我就在RTE_Components.h中提前进行了该宏的定义
#define AFIO_MAPR_SWJ_CFG_VAL AFIO_SWJ_JTAG_NO_SW
这样就可以禁用JTAG并保留SW调试了.
PS: 以上这种方式很不安全, 因为文件注释说明是自动生成的, 而且我发现每次重新打开项目会重新生成该文件, 修改的代码会丢失, 所以找到了一个比较安全的方式, 在Keil的项目属性中进行宏定义设置中添加以下定义即可:
AFIO_MAPR_SWJ_CFG_VAL=AFIO_SWJ_JTAG_NO_SW
这样就不需要修改RTE_Components.h文件了.
CMSIS-RTOS + RTX总体来说是很方便的, Keil调试也非常方便, 但是实用资料并不多, 比如说串口在该系统里就不需要使用中断了, 都给你包装好了, 但需要使用线程来接收, 自己摸索的一种接收方式, 也不知道是不是正规方法, 官方也没给出案例, 在这个产品中我都接触不到中断函数, SPI, 定时器等等都给包装好了, 但对我来说长时间没接触还保留着以前的STM32开发的观念, 冲突比较痛苦, 先写这些吧....