Table of Contents

在STM32F103C8芯片上模拟一个USB CDROM


STMicroelectronics公司给他们流行的STM32芯片提供的源代码中包含了一个USB mass storage device class示例. 我对这个示例源码做了一些增强,用以模拟一个微型的USB-CDROM。我只接了一颗512KB spi flash芯片做为光盘盘片并且向其中写入了一个很小的ISO9660映像文件。这就是为什么我称其为微型CDROM。原始的源代码仅支持一小部分SCSI请求,我扩充了源代码来支持一些扩展的指令。由于flash芯片的容易很小,我不得不做了一个工具用于分析ISO9660映像文件并且剪裁文件尺寸。我还做了一个工具,使用自定义的指令把光盘映像文件写入flash芯片中。不过这两个工具都是运行于WINDOWS平台的,我对LINUX下的软件开发不甚了解。

第一步:硬件设计

我选择了Bluepill板做为主控,它有两个SPI接口可用于连接flash芯片和TF卡。我配置了SPI2做为主接口,使用8bit数据位宽。PB12引脚用做CS线,由固件通过GPIO来控制,固件中也配置了SPI1接口但并没有真正使用它。我连接了一个串行flash芯片做为光盘片,不过我手头只有一些已停产的小容量芯片(AT45DB041B),这意味着我必须做一个尺寸很小的ISO9660映像文件才能写入这个芯片中。

第二步:生成固件

我们用STM32CubeMX来生成基本的固件源码:

第三步:编码及编译

驱动中部分代码(SELECT/DESELECT/SPI_Xxx)是从eziya's STM32_SPI_SDCARD project这个项目借鉴来的。

我使用EmBitz集成开发环境编译这个项目,它带有一个GCC编译器(arm_none_eabi)。我使用我自制的全新的CMSIS-DAP JTAG probe来调试这个项目。 ;-)

第四步:制作并写入ISO9660映像文件

我选择了Folder2Iso这个软件制作ISO9660映像文件。由于AT45DB041B芯片的容量超小,我不得不制作一个工具剪裁映像文件的尺寸。请参考iso9660中的WIN32源码。部分源码来自于gootqt's blog: ISO9660文件系统分析

WINDOWS平台上的盘片烧写工具(MSC_Test)有一点小花活,我使用函数“GetMscDeviceContext”来取得这个小光驱的路径名,如果你有另一个USB光驱插在主机上,你得先把它拔了,要不就得检查INQUIRY指令所取得的manufacturer/product字符串。如果你想尝试使用VID/PID来探测这个小光驱,请参考stackoverflow.com上的这个页面。我在我的项目中留了一些来自这个页面的源码(函数“GetDrivesDevInstByDeviceNumber”和“matchDevInstToUsbDevice”)。