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

2023-10-27

更新单片机内的用户程序,方式一般都是仿真器,串口,网络口,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论坛了,需要的可以去那里拿

代码发布在此

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 如何禁用 Android 设备 USB 端口

    我正在尝试搜索是否有一种方法可以禁用 Android 设备 USB 端口 主要是软件级别 因此用户仍然可以为 Android 设备充电 但无法再与 PC 通信 我得到了一些线索link1 https groups google com fo
  • 使用“设备过滤器”解决方案时如何处理 Android 上的 USB 权限对话框事件?

    当我将 已知 USB 设备连接到 Android 手机时出现的自动权限对话框中 用户按下 确定 或 取消 时 我试图处理该事件 我正在使用 android usb host 库 可以在 Android 手机和设备之间发送和接收 此外 我使用
  • 使用 python 检测 Windows 10 上的 USB 设备插入

    我无法获取以下代码检测USB设备插入 http timgolden me uk python win32 how do i detect device insertion html在我的 Windows 10 64 位 计算机上使用 Pyt
  • 是否有可通过 USB 密钥在 Mac OS X 10.6 上运行的便携式 python 解释器?

    我一直在努力寻找一个可以通过工作计算机上的 USB 密钥运行的便携式解释器 Work comp 运行的是 Mac OS X 10 6 环境相当受限 无法访问终端 无法安装应用程序 但我知道便携式应用程序可以从 USB 驱动器运行 我一直在使
  • Android 到 PC USB 读/写

    我在 PC 上有一个程序 从 USB 接收字符串输入 旧程序 我有一个 Android 4 X 平板电脑 需要向在 PC 上运行的程序提供 USB 上的字符串输入 当我在 Android 上使用示例代码时 以下代码给出了空的哈希图 PC 在
  • Ubuntu 10.1下如何识别多个USB串口适配器

    我正在 Ubuntu 10 1 下从多个相同的 USB 串行适配器读取数据 有时 它们的 dev tty 路径会发生变化 例如 如果在启动时连接了其他 USB 设备 我需要一种通过任何此类更改重复引用同一适配器的方法 据 udevadm 称
  • HAL_Delay() 陷入无限循环

    我被 HAL Delay 函数困住了 当我调用此函数 HAL Delay 时 控制陷入无限循环 在寻找问题的过程中 我发现了这个 http www openstm32 org forumthread2145 threadId2146 htt
  • 使用 STM32 USB 设备库将闪存作为大容量存储设备

    我的板上有这个闪存IC 它连接到我的STM32F04 ARM处理器 处理器的USB端口可供用户使用 我希望我的闪存在通过 USB 连接到 PC 时被检测为存储设备 作为第一步 我在程序中将 USB 类定义为 MSC 效果很好 因为当我将主板
  • 从网络浏览器中检测和访问 USB 设备 - 即使用插件

    是否可以通过插件 activeX Java 或 Flex 编写一个能够检测从 USB 设备通道读取数据流的浏览器插件 我做了一些研究 但没有找到答案 http support microsoft com kb 832678 http sup
  • Android:如何以编程方式连接/断开 OTG

    我想在我的 Android 设备中以编程方式连接和断开 USB OTG 笔式驱动器 硬盘驱动器等 对于USB 我使用以下路径在连接到PC时绑定 取消绑定USB sys bus usb drivers usb bind or unbind 我
  • 哪些变量类型/大小在 STM32 微控制器上是原子的?

    以下是 STM32 微控制器上的数据类型 http www keil com support man docs armcc armcc chr1359125009502 htm http www keil com support man d
  • 当端点和 PMA 地址均更改时,CubeMX 生成的 USB HID 设备发送错误数据

    我正在调试我正在创建的复合设备的问题 并在新生成的仅 CubeMX 代码中重新创建了该问题 以使其更容易解决 我添加了少量代码main 让我发送 USB HID 鼠标点击 并在按下蓝色按钮时使 LED 闪烁 uint8 t click re
  • 如何在 C# 中从 USB 令牌读取证书

    我有一个 USB 令牌 其中包含一个加密证书 该证书具有公钥和私钥 现在我想用 C 创建一个应用程序 通过它我可以找到可访问的证书信息 当我插入 USB 令牌时 它会被检测到 但计算机部分上没有显示任何驱动器 就像闪存驱动器一样 如何从 U
  • USB 端口速度 Linux [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何以编程方式确定运行 Linux 内核的嵌入式设备中的 USB 端口速度 你可以阅读 sys bus usb devices usb s
  • 移动数组中的元素

    我需要一点帮助 我想将数组中的元素向上移动一个元素 以便新位置 1 包含位置 1 中的旧值 new 2 包含 old 1 依此类推 旧的最后一个值被丢弃 第一个位置的新值是我每秒给出的新值 我使用大小为 10 的数组 uint32 t TE
  • 如何将 Android USB 连接模式更改为仅充电? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案
  • 使用 BeagleBone Black 内核 >= 3.8 打开/关闭 USB 电源

    我需要 关闭 gt 睡眠几秒钟 gt 打开 beaglebone black 的 USB 电源 能够对连接到 USB 的设备 华为 E220 调制解调器 进行硬件重置 已经尝试过软重置 使用取消绑定 绑定和授权0 1 但软件重置不足以使设备
  • 如何使用 python / pywinusb 将 hid 数据发送到设备?

    我正在尝试使用 pywinusb 将输出报告发送到 pic18f4550 该设备可以接收数据 我已经使用 C 应用程序对其进行了测试 效果很好 另外 我可以使用 pywinusb 从设备读取数据 但我在尝试发送数据时遇到问题 这是我正在运行
  • Linux 源代码中的哪个位置会识别特定的 USB 设备?

    我有一个特定的 USB 设备 我想检查其 Linux 驱动程序源代码 我的理解是 USB 驱动程序执行的第一步是注册自己能够处理具有特定供应商 ID 和产品 ID 的设备 就我而言 供应商 ID 是0BDA产品 ID 是8187 有了这些信
  • Android 3.1 USB 主机 - BroadcastReceiver 未收到 USB_DEVICE_ATTACHED

    我经历过USB 主机的描述和示例位于developer android com http developer android com guide topics usb host html检测连接和分离的 USB 设备 如果我在清单文件中使用

随机推荐

  • Java编程规范(一)

    最近在看一本有关Java编程规范的书 书中精炼阐述了使用java语言时应该遵循的一些原则 接下来的一段时间我将在这里总结我的学习内容 也希望这一系列文章能够对有需要的人有所帮助 不考虑任何编码规范的代码往往存在很多Bug 严重情况下还会制约
  • python迭代器好处_关于Python中迭代器的作用

    迭代器的定义 含有 iter 方法和 next 方法的就是迭代器 即 iterate 含有 iter 方法就可以使用for循环 即iterable 可迭代的 Iterable 可迭代的 gt iter 只要含有 iter 方法的都是可迭代的
  • 小米9能刷鸿蒙系统吗,超大乌龙之后,网友:小米真的不可能会使用鸿蒙系统吗?...

    这几天网上传得沸沸扬扬的华为鸿蒙系统即将在小米手机上使用一事 真的是把大家都给忽悠过去了 就连笔者都差点信以为真 没办法 现在 大忽悠 的IT忽悠手段都太高明 把雷军和任正非的出镜视频剪辑到了一起 还让大家误以为是小米和华为偷偷开了个会 会
  • fio verify数据校验失败

    fio3 7使用verify校验失败 使用本地文件系统也是失败 不知道那块配置的问题 感觉是参数冲突引起的 ioengine psync directory dirs name test bs 4K sync sync numjobs nu
  • 【机器学习 - 2】:数据集的处理

    文章目录 训练集和数据集分离 获取最优模型 超参数 寻找最优模型 网格搜索的使用 训练集和数据集分离 训练集和数据集分离的原理 当我们获取一个数据集时 我们需要将其一小部分拿出来作为测试集 剩余的作为训练集 例如对于一个训练集 将其20 作
  • 分布式文件系统FastDFS设计原理

    转自 http blog yunnotes net index php fastdfs design FastDFS是一个开源的轻量级分布式文件系统 由跟踪服务器 tracker server 存储服务器 storage server 和客
  • goland注册码

    https www jianshu com p fab800e01428 https blog csdn net m0 37323771 article details 82194065 https blog csdn net qq 166
  • 图论之dijkstra

    di jkstra是由迪杰斯特拉提出的一种图论算法 用于求一个点到其他所有点的最短距离 dijkstra的核心思想就是将所有的点分成两个集合A B 从B集合中找到一个离A集合内的点最近的点 把他加入A集合 然后再用这个点去迭代其他所有点 注
  • 更改Jupyter保存位置、路径详细步骤

    修改Jupyter保存位置 路径具体步骤 我安装的是 Anaconda3 64 bit 中的jupyter notebook 问题 在使用Jupyter时 发现它的自动保存路径是在系统盘 由于自己C盘快满了 而且我习惯把软件和文件保存到F盘
  • Mysql数据库的监控

    Mysql是一款开源关系型数据库 在业务系统中广泛的应用 我们监控MYSQL数据库 从以下几个维度进行监控 1 吞吐量 包括数据库的接收和发送吞吐量 2 innodb的指标信息 包括了innodb buffer pool的各项指标信息 数据
  • Nacos 配置实时生效

    在nacos 的yaml文件配置字段根据环境配置成对应的第三方服务接口地址 但是发现时不时地 接口会不稳定地宕掉 原先本地都是调本地服务接口 今天发现 测试服务的接口有数据 而本地服务接口并没有数据 这时候测试环境的接口返回依旧是空 这才发
  • linux如何开发一些自定义命令

    在Linux中 可以通过创建自己的脚本或可执行程序来开发自己的命令 下面是一些具体的步骤 创建脚本或可执行程序 首先 你可以使用文本编辑器创建一个脚本文件或可执行程序 例如使用Bash脚本编写一个名为 mycommand 的命令 bin b
  • 【华为OD机试2023】工作安排 100% C++ Java Python

    华为OD机试2023 工作安排 100 C Java Python 前言 如果您在准备华为的面试 期间有想了解的可以私信我 我会尽可能帮您解答 也可以给您一些建议 本文解法非最优解 即非性能最优 不能保证通过率 Tips1 机试为ACM 模
  • 自动化防火墙放行目标域名IP

    bin bash 设置要获取IP地址的域名 domain yourdomain com 获取域名的IP地址 new ip dig short A domain 移除之前添加放行的IP地址 通过备注找它的编号 rule number ipta
  • L3 操作系统启动

    L3 操作系统启动 1 setup 模块 1 1 setup s 此部分的代码用来完成 OS 启动前的设置 start mov ax INITSEG mov ds ax mov ah 0x03 xor bh bh int 0x10 取光标位
  • zotero文献管理工具的配置与应用

    插件 文献管理 zotero文献管理工具 2 zotero参考文献格式 Zotero 使用JurisM Style实现同时生成 et al 和 等 Zotero修改版 终于可以原生支持同时生成 et al 和 等 了 3 拉取知网文献方法
  • Cas服务端5.3 基于MySQL8数据库,实现用户认证

    第一步 Cas 服务端添加数据库认证依赖jar 文件 找到下图所示代码端 添加如下依赖jar包
  • jenkins ERROR: Failed to parse POMs ProjectBuildingException Non-resolvable parent POM for

    描述 项目 spring boot 项目在本地可以正常启动和打包 但当在jenkins部署运行时报错 Non resolvable parent POM for 无法找到父包的pom文件 错误信息 解决方式 1 设定父包的 relative
  • Shell常用命令

    自以为前端工程师可能用不到Shell命令 但在学习Git时 发现除了Git命令 还有好多是需要Shell命令来配合的 所以 Shell命令需要系统的学习并进行总结 本文将详细介绍shell常用命令 特殊字符 特殊字符对shell具有特殊含义
  • 简单实现stm32f103芯片usb模拟U盘进行IAP更新用户程序

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