본문 바로가기

개발 이야기/STM32 보드

[펌웨어] STM32G0xx - 내부 Flash(2KB)를 데이터 저장 메모리로 사용

728x90

 

이번에는 STM32G030 의 일부 메모리(2KB)를 데이터 저장 메모리로 사용해 봤습니다.

STM32G030F6 은 Flash가 32KB 로 작아서 맨 뒤의 메모리 2K만 저장 용도로 사용했습니다.

다음 그림의 PAGE15 를 저장 공간으로 사용하고, PAGE0~14 는 프로그램 메모리로 사용합니다.

CUBEIDE에서 2K를 프로그램 메모리에서 제외시켜야 하는데,

STM32G030F6PX_FLASH.id 파일을 열고 FLASH LENGTH를 32K->30K 로 수정하면 됩니다.

다음과 같은 파일을 2개 만들고 flash 관련 함수들을 만들어 넣었습니다.

이 함수들은 PAGE15 에 해당하는 Flash 메모리를 읽고 쓰고 지우는 기능을 하고 있습니다.

<iflash.h>

/*
 * iflash.h
 *
 *  Created on: 2021. 4. 11.
 *      Author: trion
 */

#ifndef INC_IFLASH_H_
#define INC_IFLASH_H_

#include "main.h"

#define FLASH_USER_START_PAGE	15
#define FLASH_USER_START_ADDR   (FLASH_BASE + (FLASH_USER_START_PAGE * FLASH_PAGE_SIZE))   /* Start @ of user Flash area */
#define FLASH_USER_END_ADDR     (FLASH_BASE + FLASH_SIZE - 1)   /* End @ of user Flash area */

void eraseFlash(uint32_t startAddress,uint32_t eraseSize);
void writeFlash(uint32_t startAddress,uint8_t *wr_buff,uint32_t length);
void iflash_mem_dump(uint32_t t_addr,uint32_t mem_size);


#endif /* INC_IFLASH_H_ */

<iflash.c>

/*
 * iflash.c
 *
 *  Created on: 2021. 4. 11.
 *      Author: trion
 */


#include "main.h"

uint32_t FirstPage = 0, NbOfPages = 0;
uint32_t Address = 0, PageError = 0;
__IO uint32_t data32 = 0 , MemoryProgramStatus = 0;

static uint32_t GetPage(uint32_t Addr)
{
  return (Addr - FLASH_BASE) / FLASH_PAGE_SIZE;;
}

void eraseFlash(uint32_t startAddress,uint32_t eraseSize)
{
	static FLASH_EraseInitTypeDef EraseInitStruct = {0};
  /* Unlock the Flash to enable the flash control register access *************/
  HAL_FLASH_Unlock();

  /* Erase the user Flash area
	(area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/


  /* Get the 1st page to erase */
  FirstPage = GetPage(startAddress);

  /* Get the number of pages to erase from 1st page */
  NbOfPages = GetPage(startAddress+eraseSize) - FirstPage + 1;

  /* 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. */
  while (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK);

  HAL_FLASH_Lock();
}

void writeFlash(uint32_t startAddress,uint8_t *wr_buff,uint32_t length)
{
  uint32_t Address;//,size_of_data;

	eraseFlash(startAddress,length);

	Address = startAddress;
  /* Unlock the Flash to enable the flash control register access *************/
	HAL_FLASH_Unlock();

	while (Address < (startAddress+length))
	{
		if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, *((uint64_t *)wr_buff)) == HAL_OK)
		{
		  Address = Address + 8;
		  wr_buff = wr_buff + 8;
		}
	}

	/* Lock the Flash to disable the flash control register access (recommended
	 to protect the FLASH memory against possible unwanted operation) *********/
	HAL_FLASH_Lock();
}

저장할 데이터를 struct 를 포함한 union 타입으로 만들었고,

 
#define WRITE_IDY   0xA5A5
#define DEFAUT_ID	0x12
#define FW_VER		0x0100

// flash writable data memory
struct wr_par_ST {
  uint8_t slave_ID;
  uint16_t fw_ver;
  uint16_t check_wr;
};

union wr_par_UT {
  struct wr_par_ST wr_dat_ST;
  uint8_t wr_p_u8[sizeof(struct wr_par_ST)];
};

union wr_par_UT dt_par_UT = {0};

값을 바꾼 다음에 저장이 필요하면 union 타입의 변수를 수정하고 저장하면 됩니다.

<저장 함수>

void save_flash(void)
{
  // write data to flash
  writeFlash(FLASH_USER_START_ADDR,dt_par_UT.wr_p_u8,sizeof(union wr_par_UT));
}

<저장 테스트 >

버튼을 누르면 다음의 코드가 실행되도록 해 놓고,

dt_par_UT.wr_dat_ST.slave_ID++;
save_flash();

전원을 껐다 켜면 union 타입의 데이터가 변경된 상태로 그대로 남아 있으면 기능 테스트 완료 입니다.

저는 그냥 uart 로 출력해 봤는데 데이터가 잘 저장되어 있었습니다.

 

 

(출처1)

https://cafe.naver.com/cortexsh/3482

 

 

 

(사족)

더 좋은 정보를 공유하도록 저에게 힘을 실어 보내주세요.

그런 의미에서 커피 한잔 사주실래요 ^^

=> https://www.buymeacoffee.com/openbini

 

 

그럼,

    정보 공유합니다. https://freenanum.github.io/Market/#/