#include "drv_chipFlash.h" #include "stm32f1xx.h" //#include "stm32f103xb.h" #include "stm32f1xx_hal_flash.h" #include "drv_IAP.h" //#define TEST //unsigned short ipaFlag = 0; //BASE_CONFIG base_config; Cclient_info client_info; //从指定地址开始读取多个数据 int FLASH_ReadMoreData(uint32_t startAddress, uint32_t *readData, uint32_t countToRead){ #ifdef TEST //解锁 HAL_FLASH_Unlock(); uint32_t offsetAddress = startAddress - FLASH_BASE; //计算实际偏移地址 uint32_t sectorPosition = offsetAddress / SECTOR_SIZE; //计算扇区位置 uint32_t sectorStartAddress = sectorPosition * SECTOR_SIZE + FLASH_BASE; //计算扇区起始地址 if(FLASH_ErasePage(sectorStartAddress, 1) != 0){ //写操作上锁 HAL_FLASH_Lock(); return -1; } HAL_FLASH_Lock(); #endif //数据大小必须双字节对齐 if(countToRead % 2 != 0 ) return -1; uint16_t dataIndex = 0; for(dataIndex = 0; dataIndex < (countToRead / 2); dataIndex++){ readData[dataIndex] = FLASH_ReadHalfWord(startAddress + dataIndex * 2); } return 0; } //读取指定地址的半字(16位数据) uint16_t FLASH_ReadHalfWord(uint32_t address){ return *(volatile uint16_t *)address; } //读取指定地址的全字(32位数据) static uint32_t FLASH_ReadWord(uint32_t address){ uint32_t temp1 = 0, temp2 = 0; temp1 = *(volatile uint16_t *)address; temp2 = *(volatile uint16_t *)(address + 2); return (temp2 << 16) | temp1; } //擦除指定地址的扇区 int FLASH_ErasePage(uint32_t ErasePageAddr, uint32_t PageNumber){ FLASH_EraseInitTypeDef eraseInit = {0}; uint32_t PageError = 0; eraseInit.TypeErase = FLASH_TYPEERASE_PAGES; eraseInit.PageAddress = ErasePageAddr; eraseInit.NbPages = PageNumber; //关闭中断 __disable_irq(); //HAL_NVIC_DisableIRQ(SysTick_IRQn); if(HAL_FLASHEx_Erase(&eraseInit, &PageError) != HAL_OK){ //恢复中断 __enable_irq(); //HAL_NVIC_EnableIRQ(SysTick_IRQn); return -1; } //恢复中断 __enable_irq(); //HAL_NVIC_EnableIRQ(SysTick_IRQn); return 0; } //从指定地址开始写入多个数据 int FLASH_WriteMoreData(uint32_t startAddress, uint32_t *writeData, uint32_t countToWrite){ //非法地址 if(startAddress < FLASH_BASE || ((startAddress + countToWrite) >= (FLASH_BASE + 1024 * CHIPFLASH_SIZE))) return -1; //数据大小必须双字节对齐 if(countToWrite % 2!= 0 ) return -1; //解锁 HAL_FLASH_Unlock(); //计算扇区信息 uint32_t offsetAddress = startAddress - FLASH_BASE; //计算实际偏移地址 uint32_t sectorPosition = offsetAddress / SECTOR_SIZE; //计算扇区位置 uint32_t sectorStartAddress = sectorPosition * SECTOR_SIZE + FLASH_BASE; //计算扇区起始地址 //启用扇区擦除 if(FLASH_ErasePage(sectorStartAddress, 1) != 0){ //写操作上锁 HAL_FLASH_Lock(); return -1; } uint16_t dataIndex = 0; for(dataIndex = 0; dataIndex < (countToWrite / 2); dataIndex++){ __disable_irq(); if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, startAddress + dataIndex * 2 , writeData[dataIndex]) != HAL_OK){ __enable_irq(); //写操作上锁 HAL_FLASH_Lock(); return -1; } } __enable_irq(); //写操作上锁 HAL_FLASH_Lock(); return 0; } int FLASH_INFO_SetFlag(void){ #ifdef FUNC uint8_t *p = (uint8_t *)&client_info; int i; int count = 0; for(i = 0; i < sizeof(client_info); i++){ if(p[i] != 0xFF){ count = 0; } if(p[i] == 0xFF){ count++; } } if(count == sizeof(client_info)){ return -1; } #endif if(client_info._init_flag == 1){ return 0; } return -1; } void erasure_bin_flash(void){ HAL_FLASH_Unlock(); __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_BSY | FLASH_FLAG_WRPERR | FLASH_FLAG_OPTVERR ); //获取APP开始地址所在扇区 uint32_t UserStartSector = (APPLICATION_ADDRESS - FLASH_BASE) / SECTOR_SIZE; //获取APP结束地址所在扇区 uint32_t UserEndSector = UserStartSector + (iap_bin_Size + SECTOR_SIZE - 1) / SECTOR_SIZE; // 如果结束地址错误。APP地址从FLASH_Sector_4开始 if(UserEndSector < UserStartSector){ while(1){ send_mavlink_bootloader_status(BOOTLOADER_STATUS_FLASH_ERASOR_ERROR); HAL_Delay(600); } } // 擦写到FLASH_Sector_7需要3.5s时间 for(uint32_t i = UserStartSector; i <= UserEndSector; i++){ //驱动电压在[2.7V to 3.6V]范围内,擦除操作将按字擦除 if(FLASH_ErasePage(FLASH_BASE + i * SECTOR_SIZE, 1)!= 0){ HAL_FLASH_Lock(); while(1){ //擦除失败 send_mavlink_bootloader_status(BOOTLOADER_STATUS_FLASH_ERASOR_ERROR); HAL_Delay(600); } } } } int FLASH_Write(volatile uint32_t FlashAddress, uint32_t *WriteData, uint32_t DataLength){ uint32_t i =0; //解锁 HAL_FLASH_Unlock(); for(i = 0; (i < DataLength) && (FlashAddress <= (USER_FLASH_END_ADDR - 4)); i++){ __disable_irq(); //if(FLASH_WriteMoreData(FlashAddress, (uint32_t *)(WriteData + i), 4) == 0) if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FlashAddress, *(uint32_t*)(WriteData + i))== HAL_OK) { __enable_irq(); if(*(uint32_t *)FlashAddress != *(uint32_t*)(WriteData + i)){ //FLASH中数据与SRAM中内容不一致 //写操作上锁 HAL_FLASH_Lock(); return -1; } FlashAddress += 4; } else{ __enable_irq(); //写操作上锁 HAL_FLASH_Lock(); //编程Flash memory时发生错误 return -1; } } __enable_irq(); //写操作上锁 HAL_FLASH_Lock(); cur_address = FlashAddress; return 0; } int FLASH_Write_HalfWord(volatile uint32_t FlashAddress, uint16_t *WriteData, uint16_t DataLength){ //解锁 HAL_FLASH_Unlock(); uint32_t i =0; for(i = 0; (i < DataLength) && (FlashAddress <= (USER_FLASH_END_ADDR - 2)); i++) { __disable_irq(); if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FlashAddress, *(uint16_t*)(WriteData + i)) == HAL_OK) { __enable_irq(); if(*(uint16_t *)FlashAddress!= *(uint16_t*)(WriteData + i)){ //FLASH中数据与SRAM中内容不一致 //写操作上锁 HAL_FLASH_Lock(); return -1; } FlashAddress += 2; } else{ __enable_irq(); //写操作上锁 HAL_FLASH_Lock(); //编程Flash memory时发生错误 return -1; } } __enable_irq(); //写操作上锁 HAL_FLASH_Lock(); cur_address = FlashAddress; return 0; }