stm32f030f4p6 Flash Kullanımı

Başlatan Furkaneerdem, 26 Ocak 2023, 12:38:39

Furkaneerdem

Merhaba.
Elimde stm32f030f4p6 modülü var.
Flash kısmını kullanarak içeriye sayı yazmaya çalışıyorum ama ne yaptıysam yazmadan önceki silme aşamasında
Failed to execute MI command:
-data-disassemble -s 4294967294 -e 4294967338 -- 3
Error message from debugger back end:
Cannot access memory at address 0xfffffffe

hatasından kurtulamadım.
İnternette 32f103 ile ilgili olan örnekte bulunan kütüphaneyi kullanıyorum. Kütüphane içeriğini stm32f030 a göre düzenlemeye çalıştım. Nerede yanlış yaptığım konusunda bilgilendirme yapabilir misiniz?

Kullandığım kodlar ve oluşturulan flash kütüphanesi aşağıdaki gibidir.

Main.c
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "flash.h"
#include "string.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint32_t data2[] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9};

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
    Flash_Write_Data(0x08000000, data2, 2);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

flash.h
/**
  ***************************************************************************************************************
  ***************************************************************************************************************
  ***************************************************************************************************************
  File:	      FLASH_PAGE_F1.h
  Modifier:   ControllersTech.com
  Updated:    27th MAY 2021
  ***************************************************************************************************************
  Copyright (C) 2017 ControllersTech.com
  This is a free software under the GNU license, you can redistribute it and/or modify it under the terms
  of the GNU General Public License version 3 as published by the Free Software Foundation.
  This software library is shared with public for educational purposes, without WARRANTY and Author is not liable for any damages caused directly
  or indirectly by this software, read more about this on the GNU General Public License.
  ***************************************************************************************************************
*/

#ifndef INC_FLASH_PAGE_F0_H_
#define INC_FLASH_PAGE_F0_H_

#include "stm32f0xx_hal.h"


uint32_t Flash_Write_Data (uint32_t StartPageAddress, uint32_t *Data, uint16_t numberofwords);

void Flash_Read_Data (uint32_t StartPageAddress, uint32_t *RxBuf, uint16_t numberofwords);

void Convert_To_Str (uint32_t *Data, char *Buf);

void Flash_Write_NUM (uint32_t StartSectorAddress, float Num);

float Flash_Read_NUM (uint32_t StartSectorAddress);



/********************  FLASH_Error_Codes   ***********************//*
HAL_FLASH_ERROR_NONE      0x00U  // No error
HAL_FLASH_ERROR_PROG      0x01U  // Programming error
HAL_FLASH_ERROR_WRP       0x02U  // Write protection error
HAL_FLASH_ERROR_OPTV      0x04U  // Option validity error
*/


#endif /* INC_FLASH_PAGE_F0_H_ */

Flash.c
/**
  ***************************************************************************************************************
  ***************************************************************************************************************
  ***************************************************************************************************************
  File:	      flash.c
  Modifier:   ControllersTech.com
  Updated:    27th MAY 2021
  ***************************************************************************************************************
  Copyright (C) 2017 ControllersTech.com
  This is a free software under the GNU license, you can redistribute it and/or modify it under the terms
  of the GNU General Public License version 3 as published by the Free Software Foundation.
  This software library is shared with public for educational purposes, without WARRANTY and Author is not liable for any damages caused directly
  or indirectly by this software, read more about this on the GNU General Public License.
  ***************************************************************************************************************
*/

#include "flash.h"
#include "string.h"
#include "stdio.h"


/* STM32F103 have 128 PAGES (Page 0 to Page 127) of 1 KB each. This makes up 128 KB Flash Memory
 * Some STM32F103C8 have 64 KB FLASH Memory, so I guess they have Page 0 to Page 63 only.
 */

/* FLASH_PAGE_SIZE should be able to get the size of the Page according to the controller */
static uint32_t GetPage(uint32_t Address)
{
  for (int indx=0; indx<15; indx++)
  {
	  if((Address < (0x08000000 + (FLASH_PAGE_SIZE *(indx+1))) ) && (Address >= (0x08000000 + FLASH_PAGE_SIZE*indx)))
	  {
		  return (0x08000000 + FLASH_PAGE_SIZE*indx);
	  }
  }

  return 0;
}


uint8_t bytes_temp[4];


void float2Bytes(uint8_t * ftoa_bytes_temp,float float_variable)
{
    union {
      float a;
      uint8_t bytes[4];
    } thing;

    thing.a = float_variable;

    for (uint8_t i = 0; i < 4; i++) {
      ftoa_bytes_temp[i] = thing.bytes[i];
    }

}

float Bytes2float(uint8_t * ftoa_bytes_temp)
{
    union {
      float a;
      uint8_t bytes[4];
    } thing;

    for (uint8_t i = 0; i < 4; i++) {
    	thing.bytes[i] = ftoa_bytes_temp[i];
    }

   float float_variable =  thing.a;
   return float_variable;
}

uint32_t Flash_Write_Data (uint32_t StartPageAddress, uint32_t *Data, uint16_t numberofwords)
{

	static FLASH_EraseInitTypeDef EraseInitStruct;
	uint32_t PAGEError;
	int sofar=0;

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

	   /* Erase the user Flash area*/

	  uint32_t StartPage = GetPage(StartPageAddress);
	  uint32_t EndPageAdress = StartPageAddress + numberofwords*4;
	  uint32_t EndPage = GetPage(EndPageAdress);

	   /* Fill EraseInit structure*/
	   EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
	   EraseInitStruct.PageAddress = StartPage;
	   EraseInitStruct.NbPages     = ((EndPage - StartPage)/FLASH_PAGE_SIZE) +1;

	   if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)
	   {
	     /*Error occurred while page erase.*/
		  return HAL_FLASH_GetError ();
	   }

	   /* Program the user Flash area word by word*/

	   while (sofar<numberofwords)
	   {
	     if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, StartPageAddress, Data[sofar]) == HAL_OK)
	     {
	    	 StartPageAddress += 4;  // use StartPageAddress += 2 for half word and 8 for double word
	    	 sofar++;
	     }
	     else
	     {
	       /* Error occurred while writing data in Flash memory*/
	    	 return HAL_FLASH_GetError ();
	     }
	   }

	   /* 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;
}


void Flash_Read_Data (uint32_t StartPageAddress, uint32_t *RxBuf, uint16_t numberofwords)
{
	while (1)
	{

		*RxBuf = *(__IO uint32_t *)StartPageAddress;
		StartPageAddress += 4;
		RxBuf++;
		if (!(numberofwords--)) break;
	}
}
void Convert_To_Str (uint32_t *Data, char *Buf)
{
	int numberofbytes = ((strlen((char *)Data)/4) + ((strlen((char *)Data) % 4) != 0)) *4;

	for (int i=0; i<numberofbytes; i++)
	{
		Buf[i] = Data[i/4]>>(8*(i%4));
	}
}


void Flash_Write_NUM (uint32_t StartSectorAddress, float Num)
{

	float2Bytes(bytes_temp, Num);

	Flash_Write_Data (StartSectorAddress, (uint32_t *)bytes_temp, 1);
}


float Flash_Read_NUM (uint32_t StartSectorAddress)
{
	uint8_t buffer[4];
	float value;

	Flash_Read_Data(StartSectorAddress, (uint32_t *)buffer, 1);
	value = Bytes2float(buffer);
	return value;
}

volkanunal

Gözüme çarpan nokta şurası oldu ilk bakışta hocam

Flash_Write_Data(0x08000000, data2, 2);

0x08000000 bu adres özel bir konfigürasyon yapmadıysanız STM32 flash başlangıç adresi, yani sizin kodunuzun koştuğu alanın başlangıç adresi. Siz kodunuz koşarken, kodunuz koştuğu yerin başlangıç adresinden itibaren silmeye çalışıyorsunuz. Flash içerisinde uygun olan başka bir yere yazmayı deneyin.

Söylediklerime ek olarak, kullandığınız kütüphane FLASH_TYPEPROGRAM_WORD şeklinde yazma yapıyor. İşlemci ailesinin farklı modellerinde bu desteklenmiyor olabilir. Tabi öncelikle yukarda söylediğim mutlaka denenmeli buna geçmeden.
Primum nil nocere

Furkaneerdem

#2
@volkanunal hocam ben datasheette öyle yazıyor diye denemeyi ordan yapayım dedim ama galiba datasheeti yanlış anlamışım. Adresi 0x08000800 olarak düzenledim Şimdi de silme işlemi sonrası Hard Faulta düşüyor. bahsettiğiniz FLASH_TYPEPROGRAM_WORD kısmı 32f0 ın hal kütüphanesinde tanımlı gözüküyor. Nerde hata yapıyorum acaba. Ekran hataya gireceği noktadaki ekran görüntüsünü ekledim.



argelojik

Merhaba ben bir projemde aşağıdaki adresi kullanıyorum. Sorun yaşamadım. İşlemci STM32f030K8T6

#define MY_FLASH_PAGE        0x08006000 
#define MY_FLASH_END_ADDR  0x080063FF + FLASH_PAGE_SIZE

Flash' a yazarken de aşağıdaki kod bloğu ile yazıyorum.
    
    HAL_FLASH_Unlock();
    FLASH_EraseInitTypeDef EraseInitStruct;
    EraseInitStruct.TypeErase  = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.PageAddress =  MY_FLASH_PAGE;
    EraseInitStruct.NbPages    = (  MY_FLASH_END_ADDR -  MY_FLASH_PAGE) / 400;
    uint32_t PAGEError = 0;
    if(HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)    //Fill FF, as -1.
        Error_Handler();
    Start_adress =  MY_FLASH_PAGE;
    for( uint8_t i=0; i<HANE; i++)
    {
      if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Start_adress,  Pass[i]) == HAL_OK)        
            Start_adress+= 2;
    }    
    HAL_FLASH_Lock();

Furkaneerdem

@argelojik Sorunumu sizin verdiğiniz adresleri vererek çözdüm ama flash olayı kafama takıldı. Datasheette 0x08000000 olarak başlangıç adresi yazıyor. Bunun kontrolünü normalde nasıl yapacağız. Yani bizim yazabileceğimiz adres kaçtan başlayıp kaçta bitiyor o kısmı anlayamadım.

argelojik

Sizin veri yazacağınız alan sizin yazdığınızın kodun uzunluğuna göre değişir. Yazdığınız kod başlangıç adresinden itibaren adreslendiği için son kısımlar boş kalmaktadır. Burada mantık sondaki adreslere veri yazmak.

serdararikan

Alıntı yapılan: Furkaneerdem - 27 Ocak 2023, 17:57:51@argelojik Sorunumu sizin verdiğiniz adresleri vererek çözdüm ama flash olayı kafama takıldı. Datasheette 0x08000000 olarak başlangıç adresi yazıyor. Bunun kontrolünü normalde nasıl yapacağız. Yani bizim yazabileceğimiz adres kaçtan başlayıp kaçta bitiyor o kısmı anlayamadım.

Datasheet e bakacaksınız. Orada memory map var

kimlenbu

#7
Sorun çözülmüş ama eeprom emulasyon yaparken orjinal kütüphaneyi kullanırsanız sizin belirlediğiniz uzunlukta 2 page kullanıyor. Rom'un belli bir yazma ömrü olduğu için rom'a zarar vermemek için alınmış bir önlem.

Ben istediğim adrese istediğim veriyi yazabilmek için ayrı bir fonksiyon oluşturdum, genellikle cihaz ayarlarını tutmak için kullanıyorum, ayarlar devamlı değiştirilecek ayarlar olmuyor, sadece kurulumda yapılması gereken ayarları tutuyorum.


Her yazma öncesi rom'un ilgili bölgesini  formatlamak gerekiyor
uint16_t EE_DirectReadVariable(uint16_t PageNo, uint16_t VirtAddress, uint16_t* Data){
	uint32_t Address = 0x08010000;
	Address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(PageNo * PAGE_SIZE)+(uint32_t)(VirtAddress*2));
	*Data = (*(__IO uint16_t*)(Address));
	
	return 1;
}

uint16_t EE_DirectWriteVariable(uint16_t PageNo, uint16_t VirtAddress, uint16_t Data){
	uint32_t Address = 0;
	
	HAL_StatusTypeDef FlashStatus = HAL_OK;
	Address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(PageNo * PAGE_SIZE)+(uint32_t)(VirtAddress*2));
	
	/* Set variable data */
	FlashStatus =  HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, Address, Data);   
//	sprintf(tmpStr,"Direct Write Address : 0x%08X Data : 0x%04X FlashStatus : 0x%02X \r\n",Address,Data,FlashStatus);
//	USART_puts(USART6,tmpStr);
//	/* If program operation was failed, a Flash error code is returned */
//	if (FlashStatus != FLASH_COMPLETE)
//	{
//		return FlashStatus;
//	}
	
	return FlashStatus;
}