irpas技术客

stm32将flash虚拟成U盘来下载程序_you~link_stm32虚拟u盘

网络投稿 2884

序言 基础工程准备修改进入U盘的条件添加IAP跳转代码准备一个生成bin文件的例程将bin文件放入指定位置运行工程连接 经过将stm32的内部flash做成U盘以后,我一直在思考可不可以使我的程序脱离下载器下载呢?也就是说在我没带下载器,也没有带340串口的时候,我写了个程序想立刻玩一玩看看效果。现在用的芯片是103的c8t6,反正,最小的操作空间是1k,也就是一个扇区。我知道这个FAT32文件系统也是从最开始的最开始的指定控件去存放的,那么我只要把程序的开始运行地址给跳转到FAT32文件系统开始操作的地址即可。

基础工程准备

首先准备一个flashU盘的工程,可以直接下载我的链接工程 当然,我也出了制作教程,看我写的文章即可

修改进入U盘的条件

首先要确定的一个条件就是,当芯片启动时需要满足何种条件接入电脑的usb芯片会虚拟出U盘,或者说直接运行bin文件。 这时候我想到了一个最简单方法就是通过添加一个引脚的输入,使得在芯片启动后直接读取引脚的高低电平,如果为高就进入U盘模式,如果为低就跳转运行bin文件即可。 进入cubemx随便添加一个PB13作为这个功能的引脚,重新生成代码后展开。

添加IAP跳转代码

这里的跳转地址有必要说明一下,(字有点丑请勿介意)芯片内部的flash区域被分成了四个区域,像我们平时用的顶多就是一个芯片厂商提供的bootloader以及用户写程序的部分,但是我想要一个跳转的效果的话就得分区域,其中文件系统部分是由电脑进行初始化的。 接下来将跳转部分的代码添加一下;其中跳转地址有必要说明一下,U盘通过电脑格式化以后显示我的U盘的可用空间为25K,而我这块芯片型号stm32f103c8t6的总内存大小为64k;又因为第1k的地址为0x08000000, 所以计算出第前面39k中第39k的地址为0x08009800,所以后面25k的起始地址为0x08009C00;

typedef void (*pFunction)(void); #define ApplicationAddress 0x08009C00 //跳转地址 uint32_t JumpAddress; pFunction Jump_To_Application; void ProgramIapJump() { __ASM("CPSID I"); if(((*(__IO uint32_t *) ApplicationAddress) & 0x2FFE0000) == 0x20000000) { JumpAddress = *(__IO uint32_t *) (ApplicationAddress + 4); Jump_To_Application = (pFunction) JumpAddress; __set_MSP(*(__IO uint32_t *) ApplicationAddress); Jump_To_Application();// } }

相应的在main函数中做一些条件判断。

/** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); // MX_USB_DEVICE_Init(); /* USER CODE BEGIN 2 */ if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_13))//如果是高就进入U盘 { MX_USB_DEVICE_Init(); } else { ProgramIapJump();//程序跳转 } /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ //HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_12); //HAL_Delay(200); } /* USER CODE END 3 */ }

至此,一个能判断是否跳转运行bin文件的U盘程序就制作完成。

准备一个生成bin文件的例程

接下来就准备写一个bin文件,运行一下看看效果,跑个led试试水(点灯大法)。 同样的用cubemx随便生成一个led的工程后,在main函数中添加闪烁代码;

/* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_12); HAL_Delay(200); } /* USER CODE END 3 */

然后在main函数的开头需要将中断向量进行偏移操作,然后再把中断打开;

/* USER CODE BEGIN 1 */ SCB->VTOR=FLASH_BASE|0x9C00;// __ASM("CPSIE I");//汇编,开启中断 /* USER CODE END 1 */

然后再将target中ROM1的地址重置一下

接下来也是最重要的就是让它生成bin文件;生成bin文件主要是通过MDK中的fromelf.exe这个程序来完成的,这个MDK的编译有点类似与Linux里面的makefile,在我们写好程序进行编译的时候就会生成一堆的(.o文件),然后这些文件再链接起来形成hex或者bin文件。 具体操作,在User选项下添加如下代码,并勾选Run #1 其中D:\MDK529是我的MDK安装的地址,下面这段代码的基本意思就是,调用我的MDK自带的fromelf.exe文件,通过依赖./led目录下的led.axf文件生成一个名叫led.bin的文件,并将其放到./led目录下。

D:\MDK529\ARM\ARMCC\bin\fromelf.exe --bin -o ./led/led.bin ./led/led.axf

将bin文件放入指定位置运行

通过简单的复制粘贴,或者直接将bin文件拖动到U盘里面即可; 最后将PB13引脚置为低电平,复位芯片即可看到led闪起来了。

工程连接

最后附上工程的链接,主要是两个程序,一个U盘跳转的,另外一个则是led应用。


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #stm32虚拟u盘