STM32 - correctly use the built-in flash

Foreword

It's no secret to anyone that STMicroelectronics produces the remarkable 32-bit ARM microcontrollers STM32. Recently, they are gaining more and more popularity, and for good reason, which I do not intend to repeat in this article. Who cares - one , two and three .

However, the sharp increase in popularity has unpleasant drawbacks - quite often article authors repeat the same mistakes. And if also in the official document of the manufacturer the necessary moment is described superficially - then the devil will break his leg until he finds a solution to the problem.

It is about this moment that I want to tell. Namely - how to properly use the ability to record in the built-in flash of our MK. Welcome to cat.


We smoke mana, we read articles

The vast majority of articles (or more precisely - generally all that I saw) offer an implementation of the algorithm recommended in the official flash programming manual . Here's one:



Code, compile, check - everything works. It works well. Exactly until you turn on optimization. I use gcc and checked with the -O1 and -O2 switches. Without optimization, it works. With optimization - does not work. We nervously smoke, drink coffee, and spend a day or two searching for problems and thoughts about the transience of being.

How to

I don’t know why the manufacturer advises using an incorrectly working algorithm. Perhaps this was explained somewhere, but in two days I could not find anything. The solution turned out to be quite simple - in the FLASH-> SR register, to control the end of the operation, it is necessary to use not the BSY bit (I sincerely do not understand why even ST recommends using it), but the EOP bit set at the end of the current erase / write operation.

The reason is simple - for one reason or another, at the time of verification, the BSY bit may not have been set yet. However, the EOP bit is set when, and only when, the operation is completed. This bit is reset manually by writing units to it. We code, verify, enjoy life.

Raw

To complete the picture, you need to find and read other articles on this topic (a link to one of them is given above). Here I also attach the source with a brief description.

Unlocking work with flash - these two lines must be inserted into the MK initialization function:
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;


Erasing the flash page - before recording, you need to erase the data at the desired addresses, this is a flash feature:
//pageAddress - любой адрес, принадлежащий стираемой странице
void Internal_Flash_Erase(unsigned int pageAddress) {
	while (FLASH->SR & FLASH_SR_BSY);
	if (FLASH->SR & FLASH_SR_EOP) {
		FLASH->SR = FLASH_SR_EOP;
	}
	FLASH->CR |= FLASH_CR_PER;
	FLASH->AR = pageAddress;
	FLASH->CR |= FLASH_CR_STRT;
	while (!(FLASH->SR & FLASH_SR_EOP));
	FLASH->SR = FLASH_SR_EOP;
	FLASH->CR &= ~FLASH_CR_PER;
}


Record:
//data - указатель на записываемые данные
//address - адрес во flash
//count - количество записываемых байт, должно быть кратно 2
void Internal_Flash_Write(unsigned char* data, unsigned int address, unsigned int count) {
	unsigned int i;
	while (FLASH->SR & FLASH_SR_BSY);
	if (FLASH->SR & FLASH_SR_EOP) {
		FLASH->SR = FLASH_SR_EOP;
	}
	FLASH->CR |= FLASH_CR_PG;
	for (i = 0; i < count; i += 2) {
		*(volatile unsigned short*)(address + i) = (((unsigned short)data[i + 1]) << 8) + data[i];
		while (!(FLASH->SR & FLASH_SR_EOP));
		FLASH->SR = FLASH_SR_EOP;
	}
	FLASH->CR &= ~(FLASH_CR_PG);
}


These are the pies. Enjoy all the coding and fewer bugs.

Also popular now: