之优盘自动升级固件(结项)
时间:10-02
整理:3721RD
点击:
项目概述:
结项弄的有点不完美希望小编,和各位同行见谅。
自己做项目有用到了自动更新固件,所以想弄个更新程序。最近学习了心得固件库HAL 和stm32cubemx软件发现,节省了很多不必要的工作。所以准备以后的开发项目采用HAL库和stm32cubemx软件配合上来。
项目需求:
开发板NUCLEO-F412ZG, miniusb的优盘,STM32cubeMx软件加java环境, STM32Cube_FW_F4_V1.14.0固件,keil5.
项目步骤:
第一步.STM32cubeMx配置支持RCC高速外部时钟系统时钟100MHz.通过串口usart3收发数据作为调试信息。
第二步.usb配置USB-host 采用mass storage host协议。 使用第三方库FATFS文件系统.
有了这个系统我们的程序就能识别到优盘里的内容了。因为优盘大多都是FAT32格式的,为了方便识别升级固件文件。STM32cubeMx软件配置如下
第三部,配置系统时钟和USB时钟。
如图:
接下来就可以点击向齿轮一样的按钮生成源码工程了。不过在这之前要把工程配置设置好如图是本工程个人的设置。
编译IDE根据个人平台工具可选。
第四步.在keil5平台编辑,估计是STM32cubeMx的bug,每次自动生成工程代码都会把系统时钟的内部高速系统时钟配置上,有可能导致系统跑到这里就进error中断了。开始找了好一会才发现是它的问题。现在我经常会自动生成代码后把时钟改为外部晶振(RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;),编译调式运行下看看能不能成功的运行到结尾。
下面进入加入具体功能:
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t bootflag = *(__IO uint8_t *) (UPDATA_FLAG);
uint8_t i;
uint32_t file_byte,file_byte_Index;
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
FLASH_If_Init();
/* USER CODE BEGIN 2 */
switch (bootflag)
{
case BOOT_FLAG_2NDBOOT_USB:
MX_USART3_UART_Init();
MX_USB_HOST_Init();
MX_FATFS_Init();
HAL_GPIO_WritePin(GPIOB, LD2_Pin, GPIO_PIN_SET);
printf("hello word\r\n");
/* Register the file system object to the FatFs module */
if(f_mount(&USBH_fatfs, "", 0) != FR_OK)
{
USBH_ErrLog("ERROR : Cannot Initialize FatFs! \n");
}
HAL_GPIO_WritePin(USB_PowerSwitchOn_GPIO_Port, USB_PowerSwitchOn_Pin, GPIO_PIN_SET);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
MX_USB_HOST_Process();
/* USER CODE BEGIN 3 */
if(Appli_state == APPLICATION_READY)
{
if(f_open(&MyFile, "0:USBHost.bin", FA_READ) != FR_OK)
{
USBH_ErrLog("Cannot Open 'USBHost.bin' file for read.\n");
}
else
{
USBH_UsrLog("INFO : Text written on the 'USBHost.bin' file \n");
FLASH_If_EraseApp();
file_byte=f_size(&MyFile);
for(file_byte_Index = 0; file_byte_Index < file_byte;)
{
res = f_read(&MyFile, rtext, sizeof(rtext), (void *)&bytesread);
if((bytesread == 0) || (res != FR_OK)) /*EOF or Error*/
{
USBH_ErrLog("Cannot Read from the 'USBHost.bin' file \n");
break;
}
else
{
USBH_UsrLog("Read bin : %d\n", bytesread);
FLASH_If_Write((APPLICATION_ADDRESS + file_byte_Index), (uint32_t *)rtext, (uint32_t)bytesread/4);
file_byte_Index += bytesread;
}
}
f_close(&MyFile);
///////////////////////////////////////////
//ìáê??μí3ò??-?üD?íê3é
//////////////////////////////////////
IAP_Jump_App();
}
}
}
/* USER CODE END 3 */
break;
case BOOT_FLAG_2NDBOOT_UPDATE:
break;
case BOOT_FLAG_APP_NORMAL:
//?′DD3ìDò
IAP_Jump_App();
break;
default:
i = GetSector(UPDATA_FLAG);
EraseInitStruct.TypeErase = TYPEERASE_SECTORS;
EraseInitStruct .VoltageRange =VOLTAGE_RANGE_3 ;
EraseInitStruct.Sector = i ;
EraseInitStruct.NbSectors = 1;
while(HAL_FLASHEx_Erase(&EraseInitStruct, (uint32_t *)&i) != HAL_OK);
HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, UPDATA_FLAG, BOOT_FLAG_2NDBOOT_USB);
//reset
HAL_NVIC_SystemReset();
}
while (1)
{;}
}
main实现了整个流程原来的代码是可以实现上电按按键进入二级boot模式但是由于自己的失误还原回去了。我使用的是64K作为二级boot.此处可以根据项目需求更改。
用到更改的文件都在application中。
串口打印的日志如图
实物图如下,这可多亏老婆的优盘要不还得用个OTG。
不知道描述的够详细不,如果有问题可以随时沟通,希望大家共同学习进步。
第五步.应用固件的开发
首先应用固件的起始地址编程0x8010000如图
这个需要生成.bin文件配置如图。
F:\Program Files\Keil5\ARM\ARMCC\bin\fromelf.exe --bin --output ./RTC/RTC.bin ./RTC/RTC.axf,根据自己的工程名,文件路径进行相应修改。
应用的功能就要看自己的实际需求了。我只是简单的实现相应RTC功能如上篇主题。
希望看到此文的童鞋,如果有什么想法提出来,帮忙指正自动升级这块应该怎么做比较好。大家一起学习。
结项弄的有点不完美希望小编,和各位同行见谅。
自己做项目有用到了自动更新固件,所以想弄个更新程序。最近学习了心得固件库HAL 和stm32cubemx软件发现,节省了很多不必要的工作。所以准备以后的开发项目采用HAL库和stm32cubemx软件配合上来。
项目需求:
开发板NUCLEO-F412ZG, miniusb的优盘,STM32cubeMx软件加java环境, STM32Cube_FW_F4_V1.14.0固件,keil5.
项目步骤:
第一步.STM32cubeMx配置支持RCC高速外部时钟系统时钟100MHz.通过串口usart3收发数据作为调试信息。
第二步.usb配置USB-host 采用mass storage host协议。 使用第三方库FATFS文件系统.
有了这个系统我们的程序就能识别到优盘里的内容了。因为优盘大多都是FAT32格式的,为了方便识别升级固件文件。STM32cubeMx软件配置如下
第三部,配置系统时钟和USB时钟。
如图:
接下来就可以点击向齿轮一样的按钮生成源码工程了。不过在这之前要把工程配置设置好如图是本工程个人的设置。
编译IDE根据个人平台工具可选。
第四步.在keil5平台编辑,估计是STM32cubeMx的bug,每次自动生成工程代码都会把系统时钟的内部高速系统时钟配置上,有可能导致系统跑到这里就进error中断了。开始找了好一会才发现是它的问题。现在我经常会自动生成代码后把时钟改为外部晶振(RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;),编译调式运行下看看能不能成功的运行到结尾。
下面进入加入具体功能:
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t bootflag = *(__IO uint8_t *) (UPDATA_FLAG);
uint8_t i;
uint32_t file_byte,file_byte_Index;
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
FLASH_If_Init();
/* USER CODE BEGIN 2 */
switch (bootflag)
{
case BOOT_FLAG_2NDBOOT_USB:
MX_USART3_UART_Init();
MX_USB_HOST_Init();
MX_FATFS_Init();
HAL_GPIO_WritePin(GPIOB, LD2_Pin, GPIO_PIN_SET);
printf("hello word\r\n");
/* Register the file system object to the FatFs module */
if(f_mount(&USBH_fatfs, "", 0) != FR_OK)
{
USBH_ErrLog("ERROR : Cannot Initialize FatFs! \n");
}
HAL_GPIO_WritePin(USB_PowerSwitchOn_GPIO_Port, USB_PowerSwitchOn_Pin, GPIO_PIN_SET);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
MX_USB_HOST_Process();
/* USER CODE BEGIN 3 */
if(Appli_state == APPLICATION_READY)
{
if(f_open(&MyFile, "0:USBHost.bin", FA_READ) != FR_OK)
{
USBH_ErrLog("Cannot Open 'USBHost.bin' file for read.\n");
}
else
{
USBH_UsrLog("INFO : Text written on the 'USBHost.bin' file \n");
FLASH_If_EraseApp();
file_byte=f_size(&MyFile);
for(file_byte_Index = 0; file_byte_Index < file_byte;)
{
res = f_read(&MyFile, rtext, sizeof(rtext), (void *)&bytesread);
if((bytesread == 0) || (res != FR_OK)) /*EOF or Error*/
{
USBH_ErrLog("Cannot Read from the 'USBHost.bin' file \n");
break;
}
else
{
USBH_UsrLog("Read bin : %d\n", bytesread);
FLASH_If_Write((APPLICATION_ADDRESS + file_byte_Index), (uint32_t *)rtext, (uint32_t)bytesread/4);
file_byte_Index += bytesread;
}
}
f_close(&MyFile);
///////////////////////////////////////////
//ìáê??μí3ò??-?üD?íê3é
//////////////////////////////////////
IAP_Jump_App();
}
}
}
/* USER CODE END 3 */
break;
case BOOT_FLAG_2NDBOOT_UPDATE:
break;
case BOOT_FLAG_APP_NORMAL:
//?′DD3ìDò
IAP_Jump_App();
break;
default:
i = GetSector(UPDATA_FLAG);
EraseInitStruct.TypeErase = TYPEERASE_SECTORS;
EraseInitStruct .VoltageRange =VOLTAGE_RANGE_3 ;
EraseInitStruct.Sector = i ;
EraseInitStruct.NbSectors = 1;
while(HAL_FLASHEx_Erase(&EraseInitStruct, (uint32_t *)&i) != HAL_OK);
HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, UPDATA_FLAG, BOOT_FLAG_2NDBOOT_USB);
//reset
HAL_NVIC_SystemReset();
}
while (1)
{;}
}
main实现了整个流程原来的代码是可以实现上电按按键进入二级boot模式但是由于自己的失误还原回去了。我使用的是64K作为二级boot.此处可以根据项目需求更改。
用到更改的文件都在application中。
串口打印的日志如图
实物图如下,这可多亏老婆的优盘要不还得用个OTG。
不知道描述的够详细不,如果有问题可以随时沟通,希望大家共同学习进步。
第五步.应用固件的开发
首先应用固件的起始地址编程0x8010000如图
这个需要生成.bin文件配置如图。
F:\Program Files\Keil5\ARM\ARMCC\bin\fromelf.exe --bin --output ./RTC/RTC.bin ./RTC/RTC.axf,根据自己的工程名,文件路径进行相应修改。
应用的功能就要看自己的实际需求了。我只是简单的实现相应RTC功能如上篇主题。
希望看到此文的童鞋,如果有什么想法提出来,帮忙指正自动升级这块应该怎么做比较好。大家一起学习。
IAP部分需要的可以参考我的串口IAP
学习了,谢谢!
学习了,谢谢!
谢谢小编的分享,学习了
谢谢分享,值得学习。