简单实现stm32f103芯片usb模拟U盘进行IAP更新用户程序

更新单片机内的用户程序,方式一般都是仿真器,串口,网络口,usb DFU,另类一点CAN也行,但是这些方式都有一个共同点,必须要有相应的上位机配合操作,还要教会别人使用,那么能不能有更简单傻瓜化的升级方式呢?

今天二逼程序猿就来说说另类一点的USB模拟U盘进行IAP更新升级用户程序的方法!USB模拟U盘,顾名思义就是用STM32的usb device接口,根据usb massstorage大容量存储协议连接电脑,由于现在的电脑都自带massstorage的驱动程序,因此可以在任意一台电脑使用而不必担心去了张三李四家但是电脑不能识别然后到处求驱动的问题,听起来似乎很牛逼的样子,那到底这个U盘 能用吗?好用吗?怎么用?

能用必须的,否则我还在这里废话作甚!

好用必须的,只要是个电脑且xp以上系统都可以!

怎么用?将usb捅到电脑菊花,啊不,是插到电脑usb接口,等待识别完成,即可在我的电脑里面发现多了一个U盘,然后将新的程序bin文件复制进去即可,文盲都会做!

实现这个U盘,首先需要准备一块带有stm32f103控制器的板子,然后到st官网下载相应的usb驱动库函数和外设库函数,官方usb库函数包含有多种类型的usb设备,我们只需要massstorage这个就好,然后建立IAR工程如下图一样,添加个main文件,和启动文件,自己想办法让工程能编译通过,出错一般都是找不到头文件,摸索一下即可解决,我就不废话呢么多了。

说说硬件,其实没什么好说的,就是两根usb引脚D+和D-,另外加一根引脚控制D+的上拉电阻,GPIO设置为1就可以让电脑枚举usb设备,设置为0即可断开连接,偷懒直接上拉到电源也行

假设你是个高手,已经将工程建立好并且编译通过了,那么我们现在来聊聊这个关键文件:mass_mal.c 这个文件是跟实际存储介质交互的入口,里面有4个函数和3个关键参数:

u16 MAL_Init(u8 lun)

u16 MAL_Write(u8 lun, u32 Memory_Offset, u32 *Writebuff, u16 Transfer_Length)

u16 MAL_Read(u8 lun, u32 Memory_Offset, u32 *Readbuff, u16 Transfer_Length)

u16 MAL_GetStatus (u8 lun)

u32 Mass_Memory_Size;//U盘容量大小

u32 Mass_Block_Size; //U盘扇区大小一般是512

u32 Mass_Block_Count;//U盘扇区总数=Memory_Size/Block_Size

u8 RAM_DISK[RAMDISK_SIZE];//定义一个缓冲,格式化和收发数据都在这里进行

只要实现了这几个接口就可以将pc发来的数据储存到任意地方,这几个函数即使是空函数,也可以被电脑识别,只不过是显示的U盘无法使用也无法打开而已。当然,我们只是模拟U盘,用RAM来当存储介质好了,先把数据缓存到ram,然后再写入flash,所以设置一个RAM_DISK缓存。

按照下面的样子写这几个函数即可让电脑识别出U盘了,

/*******************************************************************************
* File Name          :
* Author             : 听我说瞎话
* Version            : V1.0
* Date               : 2015.09.9
* QQ                 :0xF8C8DFA
* Description        : 初始化ramdis,建立FAT表让电脑识别U盘
*
*                      欺骗电脑,让电脑显示252k大小,否则会提示空间不足,boot占用24k,stm32f103rc总大小256k
*                      app可用256-24=232k,让电脑虚拟出252kU盘,格式化后正好是可用232k不多不少正好等于app最大长度
*******************************************************************************/
 u16 MAL_Init(u8 lun)
 {
   Mass_Block_Count = 252*1024/SECTOR_SIZE;
   Mass_Block_Size =  SECTOR_SIZE;     //512
   Mass_Memory_Size = 252*1024;
   return lun == 0 ? MAL_OK : MAL_FAIL;
 }
/*******************************************************************************
* File Name          :
* Author             : 听我说瞎话
* Version            : V1.0
* Date               : 2015.09.9
* QQ                 :0xF8C8DFA
* Description        : 电脑发来的数据其实不必真的写入ramdisk,选取自己想要的数据即可
*******************************************************************************/
 u16 MAL_Write(u8 lun, u32 Memory_Offset, u32 *Writebuff, u16 Transfer_Length)
 {
    //其实不需要真的写入ramdisk,注释掉写入ramdisk的话就可以阻止格式化操作,然并卵,让你格又怎样,反正不会丢数据
      if(Memory_Offset<RAMDISK_SIZE)
      {
         for( int i=0;i<Transfer_Length;i+=4)
         {
            *(u32*)(&RAM_DISK[Memory_Offset+i])=Writebuff[i>>2];
         }
      }
      return MAL_OK;
 }
/*******************************************************************************
* File Name          :
* Author             : 听我说瞎话
* Version            : V1.0
* Date               : 2015.09.9
* QQ                 :0xF8C8DFA
* Description        : 读取出的数据只是RAM内容,不会有真正的app程序被读出
*******************************************************************************/
 u16 MAL_Read(u8 lun, u32 Memory_Offset, u32 *Readbuff, u16 Transfer_Length)
 {
        if(Memory_Offset<RAMDISK_SIZE)//防止溢出,这里读出的是ramdisk的内容,不会包含app程序
      {
         for( i=0;i<Transfer_Length;i+=4)
         {
           Readbuff[i>>2] = *(u32*)(&RAM_DISK[Memory_Offset+i]);
         }
      }
      return MAL_OK;
 }
/*******************************************************************************
* File Name          :
* Author             : 听我说瞎话
* Version            : V1.0
* Date               : 2015.09.9
* QQ                 :0xF8C8DFA
* Description        :
*******************************************************************************/
 u16 MAL_GetStatus (u8 lun)
 {

   if(lun == 0)
   {
     return MAL_OK;
   }

   return MAL_FAIL;
 }

假设你有stm32使用经验,会处理编译产生的一些错误和警告会精简官方库代码中用不到的东西,那么现在你只要控制一下刚才的usb上拉电阻,然后初始化一下usb主循环就while(1);空函数即可,现在插电脑上应该可以识别成252k的一个U盘了。打开这个U盘,电脑会提示U盘未格式化,按照提示进行格式化然后就可以跟普通U盘一样用了,不过数据是写在RAM_DISK这个缓冲内,并没有写进flash

Mass_Memory_Size

Mass_Block_Size

Mass_Block_Count。

这三个参数可以随意修改,欺骗pc你是个1TB的硬盘都没问题,奸商的扩容盘就是这么干的!

捅了几次电脑菊花后你就会发现,尼玛每次插进去都要格式化一遍,真他妈坑爹呢,没错,我当时也是这么认为的,这样简直没天理了!二逼程序猿都有强迫症,怎么可能接受这种脑残设计?

下面就让我们来处理这个问题,首先看看格式化之前和格式化之后,RAM_DISK缓冲内的数据发生了什么变化,接上仿真器,IAR进入debug,将板子插入电脑,正常格式化,完毕后stop停下cpu,打开IAR memory观察窗

可以看到缓冲内已经多了不少数据,想想格式化前和格式化后就这点区别,如果我把格式数据事先保存内flash,初始化的时候直接还原到RAM_DISK那不就可以了吗?

其实就是这么简单,格式化后的RAM_DISK保存的是FATFS的MBR表格(详细格式请另外百度),这个表格告诉电脑我是FATFS文件系统,我有多大,每个扇区有多大,有几个文件,文件存在哪个位置等等,如果我们将整个RAM_DISK都保存在flash,那简直太浪费flash了,因为RAM_DISK只有部分位置有数据,其余位置大都是0,所以保存关键位置信息数据就好了,由于我本来的板子除了U盘,还有模拟串口功能,因此我存了一个inf串口驱动文件到虚拟的U盘里面,这样打开U盘后即可看到里面有一个inf驱动文件,你可以将这个文件替换为升级说明.txt。

格式化U盘,然后放入我的inf串口驱动文件,然后我就得到了下面的fat数据表:

#define RAMDISK_SIZE    32*1024  /* 放FAT表*/
#define SECTOR_SIZE     512     /* 一包数据大小,boot是以512位单位分包*/

static const u8 FAT_DBR_TABLE[]=
{ //FAT表的第0号扇区,有这个表就不用每次连接电脑都要格式化一遍,这个产生的方法是在电脑格式化成功后dump出整个ramdisk取前面512字节即可
0xEB,0x3C,0x90,0x4D,0x53,0x44,0x4F,0x53,0x35,0x2E,0x30,0x00,0x02,0x01,0x04,0x00,
0x02,0x00,0x02,0xF8,0x01,0xF8,0x02,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x80,0x00,0x29,0x9C,0xF8,0x5B,0x50,0x4E,0x4F,0x20,0x4E,0x41,
0x4D,0x45,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x31,0x32,0x20,0x20,0x20,0x33,0xC9,
0x8E,0xD1,0xBC,0xF0,0x7B,0x8E,0xD9,0xB8,0x00,0x20,0x8E,0xC0,0xFC,0xBD,0x00,0x7C,
0x38,0x4E,0x24,0x7D,0x24,0x8B,0xC1,0x99,0xE8,0x3C,0x01,0x72,0x1C,0x83,0xEB,0x3A,
0x66,0xA1,0x1C,0x7C,0x26,0x66,0x3B,0x07,0x26,0x8A,0x57,0xFC,0x75,0x06,0x80,0xCA,
0x02,0x88,0x56,0x02,0x80,0xC3,0x10,0x73,0xEB,0x33,0xC9,0x8A,0x46,0x10,0x98,0xF7,
0x66,0x16,0x03,0x46,0x1C,0x13,0x56,0x1E,0x03,0x46,0x0E,0x13,0xD1,0x8B,0x76,0x11,
0x60,0x89,0x46,0xFC,0x89,0x56,0xFE,0xB8,0x20,0x00,0xF7,0xE6,0x8B,0x5E,0x0B,0x03,
0xC3,0x48,0xF7,0xF3,0x01,0x46,0xFC,0x11,0x4E,0xFE,0x61,0xBF,0x00,0x00,0xE8,0xE6,
0x00,0x72,0x39,0x26,0x38,0x2D,0x74,0x17,0x60,0xB1,0x0B,0xBE,0xA1,0x7D,0xF3,0xA6,
0x61,0x74,0x32,0x4E,0x74,0x09,0x83,0xC7,0x20,0x3B,0xFB,0x72,0xE6,0xEB,0xDC,0xA0,
0xFB,0x7D,0xB4,0x7D,0x8B,0xF0,0xAC,0x98,0x40,0x74,0x0C,0x48,0x74,0x13,0xB4,0x0E,
0xBB,0x07,0x00,0xCD,0x10,0xEB,0xEF,0xA0,0xFD,0x7D,0xEB,0xE6,0xA0,0xFC,0x7D,0xEB,
0xE1,0xCD,0x16,0xCD,0x19,0x26,0x8B,0x55,0x1A,0x52,0xB0,0x01,0xBB,0x00,0x00,0xE8,
0x3B,0x00,0x72,0xE8,0x5B,0x8A,0x56,0x24,0xBE,0x0B,0x7C,0x8B,0xFC,0xC7,0x46,0xF0,
0x3D,0x7D,0xC7,0x46,0xF4,0x29,0x7D,0x8C,0xD9,0x89,0x4E,0xF2,0x89,0x4E,0xF6,0xC6,
0x06,0x96,0x7D,0xCB,0xEA,0x03,0x00,0x00,0x20,0x0F,0xB6,0xC8,0x66,0x8B,0x46,0xF8,
0x66,0x03,0x46,0x1C,0x66,0x8B,0xD0,0x66,0xC1,0xEA,0x10,0xEB,0x5E,0x0F,0xB6,0xC8,
0x4A,0x4A,0x8A,0x46,0x0D,0x32,0xE4,0xF7,0xE2,0x03,0x46,0xFC,0x13,0x56,0xFE,0xEB,
0x4A,0x52,0x50,0x06,0x53,0x6A,0x01,0x6A,0x10,0x91,0x8B,0x46,0x18,0x96,0x92,0x33,
0xD2,0xF7,0xF6,0x91,0xF7,0xF6,0x42,0x87,0xCA,0xF7,0x76,0x1A,0x8A,0xF2,0x8A,0xE8,
0xC0,0xCC,0x02,0x0A,0xCC,0xB8,0x01,0x02,0x80,0x7E,0x02,0x0E,0x75,0x04,0xB4,0x42,
0x8B,0xF4,0x8A,0x56,0x24,0xCD,0x13,0x61,0x61,0x72,0x0B,0x40,0x75,0x01,0x42,0x03,
0x5E,0x0B,0x49,0x75,0x06,0xF8,0xC3,0x41,0xBB,0x00,0x00,0x60,0x66,0x6A,0x00,0xEB,
0xB0,0x42,0x4F,0x4F,0x54,0x4D,0x47,0x52,0x20,0x20,0x20,0x20,0x0D,0x0A,0x52,0x65,
0x6D,0x6F,0x76,0x65,0x20,0x64,0x69,0x73,0x6B,0x73,0x20,0x6F,0x72,0x20,0x6F,0x74,
0x68,0x65,0x72,0x20,0x6D,0x65,0x64,0x69,0x61,0x2E,0xFF,0x0D,0x0A,0x44,0x69,0x73,
0x6B,0x20,0x65,0x72,0x72,0x6F,0x72,0xFF,0x0D,0x0A,0x50,0x72,0x65,0x73,0x73,0x20,
0x61,0x6E,0x79,0x20,0x6B,0x65,0x79,0x20,0x74,0x6F,0x20,0x72,0x65,0x73,0x74,0x61,
0x72,0x74,0x0D,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0xCB,0xD8,0x55,0xAA
//下面是两个FAT偏移,手动输入数据
//0x800 = F8 FF FF 03 40 00 05 F0 FF
//0xC00 = F8 FF FF 03 40 00 05 F0 FF
};
//这个是usb转串口的inf驱动的文件名和盘符信息
static const u8 FAT_FILE_NAME[]=
{//offect 0x1000
0x42,0x69,0x00,0x76,0x00,0x65,0x00,0x72,0x00,0x2E,0x00,0x0F,0x00,0x61,0x69,0x00,
0x6E,0x00,0x66,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
0x01,0x59,0x00,0x61,0x00,0x6E,0x00,0x48,0x00,0x75,0x00,0x0F,0x00,0x61,0x61,0x00,
0x2D,0x00,0x43,0x00,0x4F,0x00,0x4D,0x00,0x2D,0x00,0x00,0x00,0x44,0x00,0x72,0x00,
0x59,0x41,0x4E,0x48,0x55,0x41,0x7E,0x31,0x49,0x4E,0x46,0x20,0x00,0xC6,0x63,0x8C,
0x29,0x47,0x29,0x47,0x00,0x00,0x2A,0x8C,0x29,0x47,0x02,0x00,0x49,0x07,0x00,0x00,
0x59,0x41,0x4E,0x48,0x55,0x41,0x20,0x4F,0x42,0x44,0x20,0x08,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x6F,0x8C,0x29,0x47
};
//这个是usb转串口的inf驱动文件内容,连接电脑识别U盘后可以直接复制出来,可以说自带驱动
static const u8 FAT_FILE_DATA[]=
{//offect 0x5000
0x3B,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x0D,
0x0A,0x3B,0x20,0x59,0x61,0x6E,0x68,0x75,0x61,0x20,0x43,0x6F,0x6D,0x75,0x6E,0x69,
0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x44,0x65,0x76,0x69,0x63,0x65,0x20,0x43,0x6C,
0x61,0x73,0x73,0x20,0x64,0x72,0x69,0x76,0x65,0x72,0x20,0x28,0x43,0x44,0x43,0x29,
0x20,0x49,0x4E,0x46,0x20,0x46,0x49,0x4C,0x45,0x0D,0x0A,0x3B,0x20,0x28,0x43,0x29,
0x32,0x30,0x31,0x30,0x20,0x43,0x6F,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x59,
0x61,0x6E,0x48,0x75,0x61,0x2D,0x54,0x45,0x43,0x48,0x20,0x43,0x4F,0x2E,0x4C,0x74,
0x64,0x0D,0x0A,0x3B,0x20,0x4C,0x52,0x4D,0x20,0x32,0x30,0x31,0x35,0x2E,0x30,0x39,
0x2E,0x30,0x39,0x0D,0x0A,0x3B,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x0D,0x0A,0x0D,0x0A,0x5B,0x56,0x65,0x72,0x73,0x69,0x6F,0x6E,
0x5D,0x0D,0x0A,0x53,0x69,0x67,0x6E,0x61,0x74,0x75,0x72,0x65,0x3D,0x22,0x24,0x57,
0x69,0x6E,0x64,0x6F,0x77,0x73,0x20,0x4E,0x54,0x24,0x22,0x0D,0x0A,0x43,0x6C,0x61,
0x73,0x73,0x3D,0x50,0x6F,0x72,0x74,0x73,0x0D,0x0A,0x43,0x6C,0x61,0x73,0x73,0x47,
0x75,0x69,0x64,0x3D,0x7B,0x34,0x44,0x33,0x36,0x45,0x39,0x37,0x38,0x2D,0x45,0x33,
0x32,0x35,0x2D,0x31,0x31,0x43,0x45,0x2D,0x42,0x46,0x43,0x31,0x2D,0x30,0x38,0x30,
0x30,0x32,0x42,0x45,0x31,0x30,0x33,0x31,0x38,0x7D,0x0D,0x0A,0x50,0x72,0x6F,0x76,
0x69,0x64,0x65,0x72,0x3D,0x25,0x50,0x52,0x56,0x44,0x52,0x25,0x0D,0x0A,0x43,0x61,
0x74,0x61,0x6C,0x6F,0x67,0x46,0x69,0x6C,0x65,0x3D,0x73,0x74,0x6D,0x63,0x64,0x63,
0x2E,0x63,0x61,0x74,0x0D,0x0A,0x44,0x72,0x69,0x76,0x65,0x72,0x56,0x65,0x72,0x3D,
0x30,0x34,0x2F,0x32,0x35,0x2F,0x32,0x30,0x31,0x30,0x2C,0x31,0x2E,0x33,0x2E,0x31,
0x0D,0x0A,0x0D,0x0A,0x5B,0x53,0x6F,0x75,0x72,0x63,0x65,0x44,0x69,0x73,0x6B,0x73,
0x4E,0x61,0x6D,0x65,0x73,0x5D,0x0D,0x0A,0x31,0x3D,0x25,0x44,0x72,0x69,0x76,0x65,
0x72,0x73,0x44,0x69,0x73,0x6B,0x25,0x2C,0x2C,0x2C,0x0D,0x0A,0x0D,0x0A,0x5B,0x53,
0x6F,0x75,0x72,0x63,0x65,0x44,0x69,0x73,0x6B,0x73,0x46,0x69,0x6C,0x65,0x73,0x5D,
0x0D,0x0A,0x0D,0x0A,0x5B,0x4D,0x61,0x6E,0x75,0x66,0x61,0x63,0x74,0x75,0x72,0x65,
0x72,0x5D,0x0D,0x0A,0x25,0x4D,0x46,0x47,0x4E,0x41,0x4D,0x45,0x25,0x3D,0x44,0x65,
0x76,0x69,0x63,0x65,0x4C,0x69,0x73,0x74,0x2C,0x4E,0x54,0x2C,0x4E,0x54,0x61,0x6D,
0x64,0x36,0x34,0x0D,0x0A,0x0D,0x0A,0x5B,0x44,0x65,0x73,0x74,0x69,0x6E,0x61,0x74,
0x69,0x6F,0x6E,0x44,0x69,0x72,0x73,0x5D,0x0D,0x0A,0x44,0x65,0x66,0x61,0x75,0x6C,
0x74,0x44,0x65,0x73,0x74,0x44,0x69,0x72,0x20,0x3D,0x20,0x31,0x32,0x0D,0x0A,0x0D,
0x0A,0x3B,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x0D,0x0A,0x3B,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x56,
0x49,0x44,0x2F,0x50,0x49,0x44,0x20,0x53,0x65,0x74,0x74,0x69,0x6E,0x67,0x73,0x0D,
0x0A,0x3B,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x0D,0x0A,0x5B,0x44,0x65,0x76,0x69,0x63,0x65,0x4C,0x69,0x73,0x74,0x2E,0x4E,0x54,
0x5D,0x0D,0x0A,0x25,0x44,0x45,0x53,0x43,0x52,0x49,0x50,0x54,0x49,0x4F,0x4E,0x25,
0x3D,0x44,0x72,0x69,0x76,0x65,0x72,0x49,0x6E,0x73,0x74,0x61,0x6C,0x6C,0x2C,0x55,
0x53,0x42,0x5C,0x56,0x49,0x44,0x5F,0x30,0x34,0x38,0x33,0x26,0x50,0x49,0x44,0x5F,
0x35,0x37,0x34,0x30,0x0D,0x0A,0x0D,0x0A,0x5B,0x44,0x65,0x76,0x69,0x63,0x65,0x4C,
0x69,0x73,0x74,0x2E,0x4E,0x54,0x61,0x6D,0x64,0x36,0x34,0x5D,0x0D,0x0A,0x25,0x44,
0x45,0x53,0x43,0x52,0x49,0x50,0x54,0x49,0x4F,0x4E,0x25,0x3D,0x44,0x72,0x69,0x76,
0x65,0x72,0x49,0x6E,0x73,0x74,0x61,0x6C,0x6C,0x2C,0x55,0x53,0x42,0x5C,0x56,0x49,
0x44,0x5F,0x30,0x34,0x38,0x33,0x26,0x50,0x49,0x44,0x5F,0x35,0x37,0x34,0x30,0x0D,
0x0A,0x0D,0x0A,0x5B,0x44,0x72,0x69,0x76,0x65,0x72,0x49,0x6E,0x73,0x74,0x61,0x6C,
0x6C,0x2E,0x4E,0x54,0x5D,0x0D,0x0A,0x49,0x6E,0x63,0x6C,0x75,0x64,0x65,0x3D,0x6D,
0x64,0x6D,0x63,0x70,0x71,0x2E,0x69,0x6E,0x66,0x0D,0x0A,0x43,0x6F,0x70,0x79,0x46,
0x69,0x6C,0x65,0x73,0x3D,0x46,0x61,0x6B,0x65,0x4D,0x6F,0x64,0x65,0x6D,0x43,0x6F,
0x70,0x79,0x46,0x69,0x6C,0x65,0x53,0x65,0x63,0x74,0x69,0x6F,0x6E,0x0D,0x0A,0x41,
0x64,0x64,0x52,0x65,0x67,0x3D,0x44,0x72,0x69,0x76,0x65,0x72,0x49,0x6E,0x73,0x74,
0x61,0x6C,0x6C,0x2E,0x4E,0x54,0x2E,0x41,0x64,0x64,0x52,0x65,0x67,0x0D,0x0A,0x0D,
0x0A,0x5B,0x44,0x72,0x69,0x76,0x65,0x72,0x49,0x6E,0x73,0x74,0x61,0x6C,0x6C,0x2E,
0x4E,0x54,0x2E,0x41,0x64,0x64,0x52,0x65,0x67,0x5D,0x0D,0x0A,0x48,0x4B,0x52,0x2C,
0x2C,0x44,0x65,0x76,0x4C,0x6F,0x61,0x64,0x65,0x72,0x2C,0x2C,0x2A,0x6E,0x74,0x6B,
0x65,0x72,0x6E,0x0D,0x0A,0x48,0x4B,0x52,0x2C,0x2C,0x4E,0x54,0x4D,0x50,0x44,0x72,
0x69,0x76,0x65,0x72,0x2C,0x2C,0x75,0x73,0x62,0x73,0x65,0x72,0x2E,0x73,0x79,0x73,
0x0D,0x0A,0x48,0x4B,0x52,0x2C,0x2C,0x45,0x6E,0x75,0x6D,0x50,0x72,0x6F,0x70,0x50,
0x61,0x67,0x65,0x73,0x33,0x32,0x2C,0x2C,0x22,0x4D,0x73,0x50,0x6F,0x72,0x74,0x73,
0x2E,0x64,0x6C,0x6C,0x2C,0x53,0x65,0x72,0x69,0x61,0x6C,0x50,0x6F,0x72,0x74,0x50,
0x72,0x6F,0x70,0x50,0x61,0x67,0x65,0x50,0x72,0x6F,0x76,0x69,0x64,0x65,0x72,0x22,
0x0D,0x0A,0x0D,0x0A,0x5B,0x44,0x72,0x69,0x76,0x65,0x72,0x49,0x6E,0x73,0x74,0x61,
0x6C,0x6C,0x2E,0x4E,0x54,0x2E,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x5D,0x0D,
0x0A,0x41,0x64,0x64,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x3D,0x75,0x73,0x62,0x73,
0x65,0x72,0x2C,0x20,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x2C,0x20,
0x44,0x72,0x69,0x76,0x65,0x72,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x49,0x6E,0x73,
0x74,0x0D,0x0A,0x0D,0x0A,0x5B,0x44,0x72,0x69,0x76,0x65,0x72,0x53,0x65,0x72,0x76,
0x69,0x63,0x65,0x49,0x6E,0x73,0x74,0x5D,0x0D,0x0A,0x44,0x69,0x73,0x70,0x6C,0x61,
0x79,0x4E,0x61,0x6D,0x65,0x3D,0x25,0x53,0x45,0x52,0x56,0x49,0x43,0x45,0x25,0x0D,
0x0A,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x54,0x79,0x70,0x65,0x20,0x3D,0x20,0x31,
0x20,0x3B,0x20,0x53,0x45,0x52,0x56,0x49,0x43,0x45,0x5F,0x4B,0x45,0x52,0x4E,0x45,
0x4C,0x5F,0x44,0x52,0x49,0x56,0x45,0x52,0x0D,0x0A,0x53,0x74,0x61,0x72,0x74,0x54,
0x79,0x70,0x65,0x20,0x3D,0x20,0x33,0x20,0x3B,0x20,0x53,0x45,0x52,0x56,0x49,0x43,
0x45,0x5F,0x44,0x45,0x4D,0x41,0x4E,0x44,0x5F,0x53,0x54,0x41,0x52,0x54,0x0D,0x0A,
0x45,0x72,0x72,0x6F,0x72,0x43,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x20,0x3D,0x20,0x31,
0x20,0x3B,0x20,0x53,0x45,0x52,0x56,0x49,0x43,0x45,0x5F,0x45,0x52,0x52,0x4F,0x52,
0x5F,0x4E,0x4F,0x52,0x4D,0x41,0x4C,0x0D,0x0A,0x53,0x65,0x72,0x76,0x69,0x63,0x65,
0x42,0x69,0x6E,0x61,0x72,0x79,0x3D,0x20,0x25,0x31,0x32,0x25,0x5C,0x75,0x73,0x62,
0x73,0x65,0x72,0x2E,0x73,0x79,0x73,0x0D,0x0A,0x4C,0x6F,0x61,0x64,0x4F,0x72,0x64,
0x65,0x72,0x47,0x72,0x6F,0x75,0x70,0x20,0x3D,0x20,0x42,0x61,0x73,0x65,0x0D,0x0A,
0x0D,0x0A,0x3B,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x0D,0x0A,0x3B,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x20,0x20,0x53,0x74,0x72,0x69,0x6E,0x67,0x20,0x44,0x65,0x66,0x69,0x6E,0x69,0x74,
0x69,0x6F,0x6E,0x73,0x0D,0x0A,0x3B,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,
0x2D,0x2D,0x2D,0x2D,0x2D,0x0D,0x0A,0x0D,0x0A,0x5B,0x53,0x74,0x72,0x69,0x6E,0x67,
0x73,0x5D,0x0D,0x0A,0x50,0x52,0x56,0x44,0x52,0x20,0x3D,0x20,0x22,0x59,0x61,0x6E,
0x48,0x75,0x61,0x20,0x54,0x65,0x63,0x68,0x22,0x0D,0x0A,0x4D,0x46,0x47,0x4E,0x41,
0x4D,0x45,0x20,0x3D,0x20,0x22,0x59,0x61,0x6E,0x48,0x75,0x61,0x20,0x54,0x65,0x63,
0x68,0x2E,0x22,0x0D,0x0A,0x44,0x45,0x53,0x43,0x52,0x49,0x50,0x54,0x49,0x4F,0x4E,
0x20,0x3D,0x20,0x22,0x59,0x48,0x2D,0x54,0x45,0x43,0x48,0x20,0x56,0x69,0x72,0x74,
0x75,0x61,0x6C,0x20,0x43,0x4F,0x4D,0x20,0x50,0x6F,0x72,0x74,0x22,0x0D,0x0A,0x53,
0x45,0x52,0x56,0x49,0x43,0x45,0x20,0x3D,0x20,0x22,0x59,0x48,0x2D,0x54,0x45,0x43,
0x48,0x20,0x56,0x43,0x4F,0x4D,0x22,0x0D,0x0A,0x44,0x72,0x69,0x76,0x65,0x72,0x73,
0x44,0x69,0x73,0x6B,0x20,0x3D,0x20,0x22,0x59,0x48,0x20,0x44,0x72,0x69,0x76,0x65,
0x72,0x73,0x20,0x44,0x69,0x73,0x6B,0x22,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

然后初始化函数改成如下样子

/*******************************************************************************
* File Name          :
* Author             : 听我说瞎话
* Version            : V1.0
* Date               : 2015.09.9
* QQ                 :0xF8C8DFA
* Description        : 初始化ramdis,建立FAT表让电脑识别U盘
*
*                      欺骗电脑,让电脑显示252k大小,否则会提示空间不足,boot占用24k,stm32f103rc总大小256k
*                      app可用256-24=232k,让电脑虚拟出252kU盘,格式化后正好是可用232k不多不少正好等于app最大长度
*******************************************************************************/
 u16 MAL_Init(u8 lun)
 {
   u16 i=0;

   Mass_Block_Count = 252*1024/SECTOR_SIZE;
   Mass_Block_Size =  SECTOR_SIZE;
   Mass_Memory_Size = 252*1024;

   for(i=0;i<sizeof(FAT_DBR_TABLE);i++)//重建FAT表
   {
     RAM_DISK[i]=FAT_DBR_TABLE[i];
   }
   for(i=0;i<sizeof(FAT_FILE_NAME);i++)
   {
     RAM_DISK[i+0x1000]=FAT_FILE_NAME[i];
   }
   for(i=0;i<sizeof(FAT_FILE_DATA);i++)
   {
     RAM_DISK[i+0x5000]=FAT_FILE_DATA[i];
   }
   RAM_DISK[0x800]=0xF8;
   RAM_DISK[0x801]=0xFF;
   RAM_DISK[0x802]=0xFF;
   RAM_DISK[0x803]=0x03;
   RAM_DISK[0x804]=0x40;
   RAM_DISK[0x805]=0x00;
   RAM_DISK[0x806]=0x05;
   RAM_DISK[0x807]=0xF0;
   RAM_DISK[0x808]=0xFF;

   RAM_DISK[0xC00]=0xF8;
   RAM_DISK[0xC01]=0xFF;
   RAM_DISK[0xC02]=0xFF;
   RAM_DISK[0xC03]=0x03;
   RAM_DISK[0xC04]=0x40;
   RAM_DISK[0xC05]=0x00;
   RAM_DISK[0xC06]=0x05;
   RAM_DISK[0xC07]=0xF0;
   RAM_DISK[0xC08]=0xFF;
   return lun == 0 ? MAL_OK : MAL_FAIL;
 }

然后重新编译,下载,再试试,现在是不是直接插上就能显示U盘并且不用格式化就能打开了呢?打开以后还发现里面有一个xxxx.inf的虚拟串口驱动文件呢,是不是很神奇啊?

U盘实现了,IAP升级要怎么办呢?其实到这里已经很简单了,进入IAR的debug模式,在MAL_Write函数内打一个断点,然后往你虚拟出的U盘内扔进一个bin文件,仔细调试,你就会发现MAL_Write函数会一包一包的接收到你下发的bin文件数据,你只要将这些数据表缓冲一下,然后再参考官方串口IAP的写入flash代码将bin文件写入你想要的地址即可,老板要来敲脑袋了,不能再写了!!!

写了一大堆,竟然越写越糊涂,语文老师是教体育出身哎!!!

完整代码我发在amobbs论坛了,需要的可以去那里拿

代码发布在此

时间: 2024-12-06 10:36:50

简单实现stm32f103芯片usb模拟U盘进行IAP更新用户程序的相关文章

STM32解密STM32F103芯片解密ST32F103R6单片机破解多少钱?

STM32F系列单片机芯片解密型号: STM32F100  |  STM32F101  |  STM32F102  |  STM32F103  |  STM32F105  |  STM32F107 STM32F103芯片解密型号: STM32F103C4  |  STM32F103C6  |  STM32F103C8  |  STM32F103CB  |  STM32F103R4 STM32F103R6  |  STM32F103R8  |  STM32F103RB  |  STM32F103R

野火STM32 Flash&amp;sd卡模拟U盘

在USB库文件mass_mal.c中添加对flash和sd读写的函数,USB库调用这些函数从而实现模拟U盘的功能 1 //mass_mal.c 2 /* Includes ------------------------------------------------------------------*/ 3 #include "..\User\sdcard\bsp_sdio_sdcard.h" 4 #include "..\User\spi_flash\fatfs_fla

[Openwrt 项目开发笔记]:USB挂载&amp; U盘启动(三)

在上一篇中,我结合Netgear Wndr3700讲解了如何对Openwrt进行必要的配置.接下来,我们就想要在Openwrt上安装必要的软件了.可是这时候新的问题又来了:当安装一些软件之后,存储空间不足了.这时候该怎么办呢?以4M的Flash为例,当大家讲Openwrt固件刷到自己的路由器后,大家会发现剩余的空间往往只剩下不到2M.当我们需要安装许多Openwrt本身不带的软件时,就会发现如此小的空间实在是太寒酸了.那么,该如何解决这样的问题呢? 一. 添加USB扩展(注:本文默认大家的路由器

LInux下使用USB模拟ACM串口设备

这个想法之前就在脑袋里有过,最近公司产品要用到,所以多做了些了解. 1. USB 简介 USB 是 Universal Serial Bus 的缩写,从字面上看,就是通用串行总线的意思.从物理上看,其实就是一对差分线,连接两台设备后,相互间进行数据传输.加上另外两路供电( 5V 和 GND)线,一共是 4 根线. 那么,既然是只有一对差分线,那么该如何决定由谁传给谁呢(如果两边同时在线上建立电平,线路上的电平会是不确定态的,以致无法通信)?这就要说到 USB 传输的一个重要基础:“询问-应答”

Universal-USB-Installer、UItralSO、LinuxLive USB Creator U盘安装linux实战

生产环境中很多旧服务器光驱是CD-ROM的,识别不了DVD盘,光盘无法使用:再者有部分阉割定制版的linux建议使用U盘部署,所以用U盘引导来安装Linux系统自然成为一种需求:同时应朋友生产环境实施需要,网上搜索N多教程安装总是报错,所以特出一版整合实战可行教程供大家参考,个人建议选择UItralSO.Universal-USB-Installer部署方式. 准备工作: UItralSO .Universal-USB-Installer-1.9.5.5.测试U盘(建议大于4GB).测试机 rh

STM32F103之USB(一)

初识USB 由于项目需求,需要USB这块,花了几天时间了解了下USB方面的知识,的确挺难的!USB是个挺难啃的家伙,当时看了一遍看的一头雾水,不过几天下来还是有所收获的.顺便记录下自己学习的过程,一遍以后查看. 一.USB介绍 USB(Univetsal Serial Bus)的缩写,即通用串行总线.是现在通讯设备中不可或缺的一部分,可以这么说,电子工程师不懂USB那就太OUT了. 二.USB的发展史 ?1994年     Philips公司  Access.Bus规范(USB的前身) ?199

(最简单)MIUI7系统的usb调试模式在哪里打开的流程

在我们使用安卓手机链接Pc的时候,或者使用的有些软件比如我们团队营销小组在使用的软件引号精灵,以前老版本就需要开启Usb开发者调试模式下使用,不过,现在新版本不需要了,如果手机没有开启Usb开发者调试模式,Pc则不能够成功检测到我们的手机,部分软件也不能够正常使用,这个时候我们需要想办法将手机的Usb开发者调试模式打开,以下内容我们记录一下MIUI7系统如何开启Usb开发者调试模式的方法.首先,在MIUI7系统应用程序界面启动设置ICON,进入MIUI7系统系统设置界面.第二步点击设置界面上的我

协议实现:如何实现一个最简单的通信协议(线程模拟)

/*  *Author  : DavidLin       *Date    : 2014-12-20pm       *Email   : [email protected] or [email protected]       *world   : the city of SZ, in China       *Ver     : 000.000.001       *For     : threads for rxtx!    *history :     editor      time

简单计算器(用数组模拟栈写的)

1 #include<stdio.h> 2 #include<stdlib.h> 3 const int maxn=1000+5; 4 typedef struct{ 5 int top; 6 int a[maxn]; 7 }opn; 8 typedef struct{ 9 int top; 10 char a[maxn]; 11 }opt; 12 void opn_init(opn *s){ 13 s->top=-1; 14 } 15 void opt_init(opt *