Controlador Flash STM32WB55xx con longitud arbitraria y escritura de dirección arbitraria

El destello de wb, un chip muerto, no se puede escribir incluso si toda la página es 0xff y debe borrarse antes de escribir.
Primero agregue dos líneas en APP_BLE_Init ()

// 这一行防止flash操作导致断开链接
SHCI_C2_SetFlashActivityControl(FLASH_ACTIVITY_CONTROL_SEM7);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
void APP_BLE_Init( void )
{
    
    
...
/* Select which mechanism is used by CPU2 to protect its timing versus flash operation */
  SHCI_C2_SetFlashActivityControl(FLASH_ACTIVITY_CONTROL_SEM7);
  /**
   * The error flag shall be cleared before moving forward
   */
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
  /**
	* Initialize P2P Server Application
	*/
	P2PS_APP_Init();
	....
}
/**
 ******************************************************************************
 * File Name          : McuFlash.c
 * Description        : Flash driver for STM32WB55xx
 * @author            : zxk
 ******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "app_common.h"

#include "flash_driver.h"
#include "shci.h"
#include "hw_conf.h"
#include "utilities_conf.h"

#include <stdio.h>
#include "cmsis_os.h"
#include "dbg_trace.h"
#include "McuFlash.h"
#include "main.h"

/* Private typedef -----------------------------------------------------------*/

/* Private defines -----------------------------------------------------------*/
#define FLASH_DBG			APP_DBG_MSG//PRINT_NO_MESG//

#define Rd64Bit(addr)       (*(uint64_t *)(addr))
#define USR_DATA_START		(ADDR_FLASH_PAGE_24)
#define USR_DATA_SIZE       (FLASH_PAGE_SIZE * 15)
#define USR_DATA_END		(USR_DATA_START + USR_DATA_SIZE - 1)
/* Private macros ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint8_t pageBuff[FLASH_PAGE_SIZE];
/* Global variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/

inline uint32_t GetPage(uint32_t Addr)
{
    
    
  return (Addr - FLASH_BASE) >> 12;
}

FlashWrRet McuFlashErase(uint32_t FirstPage, uint32_t NbOfPages)
{
    
    
	FLASH_EraseInitTypeDef EraseInitStruct;
	uint32_t PageError = 0;
	
	/* Fill EraseInit structure*/
	EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
	EraseInitStruct.Page        = FirstPage;
	EraseInitStruct.NbPages     = NbOfPages;
	/* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
		you have to make sure that these data are rewritten before they are accessed during code
		execution. If this cannot be done safely, it is recommended to flush the caches by setting the
		DCRST and ICRST bits in the FLASH_CR register. */
	if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
	{
    
    
		FLASH_DBG("<0x%x>Erase once fail!\r\n",PageError);
		/* Try again. */
		if(HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
		{
    
    
			FLASH_DBG("<0x%x>Erase twice Error!\r\n",PageError);
			return 1;
		}
		/*Error occurred while  erase.user can call function 'HAL_FLASH_GetError()'*/
	}
	return 0;
}

FlashWrRet McuWriteNoChk(uint32_t addr, uint8_t * data, uint16_t len)
{
    
    
	Data64   tempData = {
    
    .buff = {
    
    0}};
	uint32_t tempAddr = 0;
	uint16_t tempLen  = 0;
	/* step.1 write head */
	if(addr & 0x07)
	{
    
    
		tempLen  = 8 - (addr & 0x07);
		tempLen  = (tempLen > len) ? len : tempLen;
		tempAddr = addr - (addr&0x07);
		memcpy(tempData.buff, (uint8_t *)tempAddr, 8);
		memcpy(&tempData.buff[addr & 0x07], data, tempLen);
		
		if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, tempAddr, tempData.num) != HAL_OK)
		{
    
    
			return 0x01;
		}
		len  -= tempLen;
		addr += tempLen;
		data += tempLen;
	}
	/* step.2 write body */
	while(len >= 8)
	{
    
    
		memcpy(tempData.buff, data, 8);
		if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr, tempData.num) != HAL_OK)
		{
    
    
			return 0x02;
		}
		len  -= 8;
		addr += 8;
		data += 8;
	}
	/* step.3 write tail */
	if(len)
	{
    
    
		memcpy(tempData.buff, (uint8_t *)addr, 8);
		memcpy(tempData.buff, data, len);
		
		if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr, tempData.num) != HAL_OK)
		{
    
    
			return 0x03;
		}
	}
	return 0;
}

FlashWrRet McuFlashWrie(uint32_t addr, uint8_t * data, uint16_t lenToWr)
{
    
    
	uint16_t pageOff    		= addr & 0x0FFF;
	uint16_t pageRemain 		= FLASH_PAGE_SIZE - pageOff;
	uint32_t pageAddr			= addr - pageOff;
	
	/* Check the input parameter.*/
	if((addr < USR_DATA_START) 	  || \
		(NULL == data)			  || \
		(lenToWr > USR_DATA_SIZE) || (0 == lenToWr))
		return 0x01;
	
	/* Unlock the Flash to enable the flash control register access *************/
	HAL_FLASH_Unlock();
	do{
    
    
		/* Updata the number of data to be written in this page. */
		pageRemain = (pageRemain > lenToWr) ? lenToWr : pageRemain;
		/* Copy the old data of this page before erase it. */
		memcpy(pageBuff, (uint8_t *)pageAddr, FLASH_PAGE_SIZE);
		/* Refresh the buff of this page. */
		memcpy(pageBuff+pageOff, data, pageRemain);
		/* Refresh flash data. */
		if(0 != McuFlashErase(GetPage(pageAddr), 1))
		{
    
    
			HAL_FLASH_Lock();
			FLASH_DBG("-<Err> McuFlashErase... 0x02.\n");
			return 0x02;
		}
		if(0 != McuWriteNoChk(pageAddr, pageBuff, FLASH_PAGE_SIZE))
		{
    
    
			HAL_FLASH_Lock();
			FLASH_DBG("-<Err> McuWriteNoChk... 0x03.\n");
			return 0x03;
		}
		/* Updata addr and length. */
		data 		+= pageRemain;
		lenToWr 	-= pageRemain;
		pageAddr 	+= FLASH_PAGE_SIZE;
		pageOff 	= 0;
		pageRemain 	= FLASH_PAGE_SIZE;		
	}while(lenToWr);
	/* Lock the Flash to disable the flash control register access (recommended
     to protect the FLASH memory against possible unwanted operation) *********/
	HAL_FLASH_Lock();
	
	return 0;
}

Verifique que la página que se va a escribir sea 0xff y que no se pueda escribir directamente. Se debe borrar la última acción flash de esta página.

static void DbgFlash(const char * str,uint32_t addr, short len)
{
    
    
	if(str != NULL)
	{
    
    
		MAIN_DBG("%s addr[0x%x]-%d\r\n",str,addr,uwTick);osDelay(1);
	}
	while(len--)
	{
    
    
		MAIN_DBG("0x%02x, ",*(uint8_t *)addr);
		addr++;
	}//osDelay(4);
	MAIN_DBG("\n\n\n"); osDelay(1);
}
void test_flash(void)
{
    
    
	uint32_t addr = FLASH_USER_START_ADDR;
	
	osDelay(64);
	
	DbgFlash("Before test operation:", addr, 16);

	HAL_FLASH_Unlock();
	
	McuFlashErase(GetPage(addr), 1);
	DbgFlash("-1-erase.", addr, 16);
	
	if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr, 0xFFFFFFFFFFFFffFF) != HAL_OK)
	{
    
    
		MAIN_DBG("--<Err> ... HAL_FLASH_Program 0xff.\n");osDelay(2);
	}
	DbgFlash("after write 0xff.", addr, 16);
	
	if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr, 0xFFFFFFFFFFFF07FF) != HAL_OK)
	{
    
    
		MAIN_DBG("--<Err> ... HAL_FLASH_Program 0x07.\n");osDelay(2);
	}
	DbgFlash("after write 0x07.", addr, 16);
	HAL_FLASH_Lock();
}

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_28851611/article/details/107653844
Recomendado
Clasificación