Autor Tema: stm32f0 ayuda con la flash, leer y escribir + hal lib  (Leído 5696 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado xiran

  • PIC16
  • ***
  • Mensajes: 100
stm32f0 ayuda con la flash, leer y escribir + hal lib
« en: 08 de Septiembre de 2015, 19:23:12 »
Hola a todos, me gustaria saber si alguien sabe como leer y escribir en la flash en stm32f0, utilizando las librerias hal. Basicamente he leido q, para poder escribir, hay q desbloquearla con:
HAL_FLASH_Unlock(void);
Despues, se tiene q borrar, ya sea por pagina, o si es toda con:
HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef * pEraseInit,uint32_t * PageError)
De aqui, no se como usarla, sé q la memoria inicia en: 0x08000000, y solo ocupo una pagina, para probar grabar un valor, apagar el dispositivo, leerlo, y corroborar q efectivamente se quede el dato grabado.
Se me ocurre una rutina para comprobar, q si la pagina no esta borrada, significa, q es su 1era vez, por lo tanto, hay q borrarla... pero aqui inicia el 2do problema: no se como leerla. En las librerias hal, viene un comando:
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
No se si ahi se carge, o no tengo idea... Alguien podria darme una luz?

UPDATE: Estoy leyendo q lo q mas me conviene es usar la emulacion de eeprom.
UPDATE2: No, no es lo mas conveniente.
« Última modificación: 09 de Septiembre de 2015, 13:35:06 por xiran »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: stm32f0 ayuda con la flash, leer y escribir + hal lib
« Respuesta #1 en: 11 de Septiembre de 2015, 00:16:02 »
Si no me equivoco ST provee unos ejemplos para la discovery con ese micro. Y un ejemplo es exactamente acerca de programar la Flash

Software: STSW-STM32049

main.c
Código: C
  1. typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
  2. /* Private define ------------------------------------------------------------*/
  3. #define FLASH_PAGE_SIZE         ((uint32_t)0x00000400)   /* FLASH Page Size */
  4. #define FLASH_USER_START_ADDR   ((uint32_t)0x08006000)   /* Start @ of user Flash area */
  5. #define FLASH_USER_END_ADDR     ((uint32_t)0x08007000)   /* End @ of user Flash area */
  6. #define DATA_32                 ((uint32_t)0x12345678)
  7.  
  8. /* Private macro -------------------------------------------------------------*/
  9. /* Private variables ---------------------------------------------------------*/
  10. uint32_t EraseCounter = 0x00, Address = 0x00;
  11. uint32_t Data = 0x3210ABCD;
  12. uint32_t NbrOfPage = 0x00;
  13. __IO FLASH_Status FLASHStatus = FLASH_COMPLETE;
  14. __IO TestStatus MemoryProgramStatus = PASSED;
  15.  
  16. /* Private function prototypes -----------------------------------------------*/
  17. /* Private functions ---------------------------------------------------------*/
  18.  
  19. /**
  20.   * @brief  Main program.
  21.   * @param  None
  22.   * @retval None
  23.   */
  24. int main(void)
  25. {
  26.   /*!< At this stage the microcontroller clock setting is already configured,
  27.        this is done through SystemInit() function which is called from startup
  28.        file (startup_stm32f0xx.s) before to branch to application main.
  29.        To reconfigure the default setting of SystemInit() function, refer to
  30.        system_stm32f0xx.c file
  31.      */
  32.  
  33.   /* Unlock the Flash to enable the flash control register access *************/
  34.   FLASH_Unlock();
  35.    
  36.   /* Erase the user Flash area
  37.     (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
  38.  
  39.   /* Clear pending flags (if any) */  
  40.   FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
  41.  
  42.   /* Define the number of page to be erased */
  43.   NbrOfPage = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE;
  44.  
  45.   /* Erase the FLASH pages */
  46.   for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
  47.   {
  48.     if (FLASH_ErasePage(FLASH_USER_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter))!= FLASH_COMPLETE)
  49.     {
  50.      /* Error occurred while sector erase.
  51.          User can add here some code to deal with this error  */
  52.       while (1)
  53.       {
  54.       }
  55.     }
  56.   }
  57.   /* Program the user Flash area word by word
  58.     (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
  59.  
  60.   Address = FLASH_USER_START_ADDR;
  61.  
  62.   while (Address < FLASH_USER_END_ADDR)
  63.   {
  64.     if (FLASH_ProgramWord(Address, DATA_32) == FLASH_COMPLETE)
  65.     {
  66.       Address = Address + 4;
  67.     }
  68.     else
  69.     {
  70.       /* Error occurred while writing data in Flash memory.
  71.          User can add here some code to deal with this error */
  72.       while (1)
  73.       {
  74.       }
  75.     }
  76.   }
  77.  
  78.   /* Lock the Flash to disable the flash control register access (recommended
  79.      to protect the FLASH memory against possible unwanted operation) *********/
  80.   FLASH_Lock();
  81.  
  82.  
  83.   /* Check if the programmed data is OK
  84.       MemoryProgramStatus = 0: data programmed correctly
  85.       MemoryProgramStatus != 0: number of words not programmed correctly ******/
  86.   Address = FLASH_USER_START_ADDR;
  87.   MemoryProgramStatus = PASSED;
  88.  
  89.   while (Address < FLASH_USER_END_ADDR)
  90.   {
  91.     Data = *(__IO uint32_t *)Address;
  92.  
  93.     if (Data != DATA_32)
  94.     {
  95.       MemoryProgramStatus = FAILED;  
  96.     }
  97.  
  98.     Address = Address + 4;
  99.   }
  100.  
  101.   /* Infinite loop */
  102.   while (1)
  103.   {
  104.   }
  105. }

Con respecto a las direcciones de memoria, donde este ubicada la flash, la RAM, el espacio externo, etc, eso depende exclusivamente del micro
Los vas a ver en el manual de referencia.
Ahi te aparecen lso limites de la flash, y tambien el tamaño de las paginas, etc.
« Última modificación: 11 de Septiembre de 2015, 00:26:06 por KILLERJC »

Desconectado xiran

  • PIC16
  • ***
  • Mensajes: 100
Re: stm32f0 ayuda con la flash, leer y escribir + hal lib
« Respuesta #2 en: 18 de Septiembre de 2015, 15:02:21 »
Muchas gracias por responder KILLERJC, ya lo logré usando las librerias hal, el problema surge, en q, al momento de borrar con:

HAL_FLASHEx_Erase(&erase_pages, error);

Se cicla, y no continua el programa, pero si quito la linea anterior, y agrego:

HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, 0x08007000,0x0002);

Escribe correctamente, la siguiente vez q lo inicio, pero ovbiamente, ya no puedo escribir mas q solo 1 vez, como dice el datasheet, antes de escribir, hay q borrar, pero se queda atascado. Lo unico q se me ocurre, es traer la funcion al main, y alterar el momento en el q se cicla, q imagino, q ha de ser alguna comprobación de error. Saludos!
« Última modificación: 18 de Septiembre de 2015, 15:47:25 por xiran »

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re: stm32f0 ayuda con la flash, leer y escribir + hal lib
« Respuesta #3 en: 18 de Septiembre de 2015, 16:00:00 »


Seguramente estás borrando la página en la que está el programa que se está ejecutando, por eso tras el borrado, el microcontrolador se queda colgado, porque ha desaparecido el programa.

Mira a ver en el listado de la compilación, cual es la página de la última dirección que ocupa tu programa, y borra a partir de la siguiente página. Esta consideración es típica cuando se programa un bootloader, evitar que la rutina de borrado de páginas machaque al propio bootloader o que el firmware se grabe encima de las direcciones del bootloader.

Desconectado xiran

  • PIC16
  • ***
  • Mensajes: 100
Re: stm32f0 ayuda con la flash, leer y escribir + hal lib
« Respuesta #4 en: 18 de Septiembre de 2015, 17:04:37 »
Muchas gracias por responder planeta9999, segun el datasheet:

0x0800 0000 - 0x0800 03FF 1 Kbyte Page 0

No se si, pueda escribir en la pagina 0, o como distingo en q direccion puedo escribir sin machacar el programa, no uso boot loader.
En donde veo el dato q me aconsejas planeta9999? uso keil v4, saludos.
Esto me marca keil:
Program Size: Code=18876 RO-data=268 RW-data=152 ZI-data=7240, incluso, he escrito en

0x0800 7000 - 0x0800 73FF 1 Kbyte Page 28

con el mismo resultado...
« Última modificación: 18 de Septiembre de 2015, 17:23:57 por xiran »

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re: stm32f0 ayuda con la flash, leer y escribir + hal lib
« Respuesta #5 en: 19 de Septiembre de 2015, 13:14:13 »
.

No he tenido tiempo de profundizar con los STM32 para el borrado de la flash, de hecho tengo un hilo abierto de un bootloader que estaba creando para los STM32F4, y lo tengo por acabar.

http://www.todopic.com.ar/foros/index.php?topic=44131.20

Pero la parte de borrado de la flash para poder escribir en ella debe de ser igual, puede que diferente en el tamaño de página como ocurre con los PIC, y también según la familia de STM32. Creo que también tienes que desbloquear y bloquear la flahs, para realizar ciertas operaciones. En la web de ST deberías de tener ejemplos básicos para leer y escribir en la flash.


Por ejemplo el mapa de sectores en los F4, da unas páginas mayores, y además no todas las páginas tienen el mismo tamaño.





Borrado de flash (1 sector):

Código: [Seleccionar]
FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_t VoltageRange)
{
  uint32_t tmp_psize = 0x0;
  FLASH_Status status = FLASH_COMPLETE;

  /* Check the parameters */
  assert_param(IS_FLASH_SECTOR(FLASH_Sector));
  assert_param(IS_VOLTAGERANGE(VoltageRange));
  
  if(VoltageRange == VoltageRange_1)
  {
     tmp_psize = FLASH_PSIZE_BYTE;
  }
  else if(VoltageRange == VoltageRange_2)
  {
    tmp_psize = FLASH_PSIZE_HALF_WORD;
  }
  else if(VoltageRange == VoltageRange_3)
  {
    tmp_psize = FLASH_PSIZE_WORD;
  }
  else
  {
    tmp_psize = FLASH_PSIZE_DOUBLE_WORD;
  }
  /* Wait for last operation to be completed */
  status = FLASH_WaitForLastOperation();
  
  if(status == FLASH_COMPLETE)
  {
    /* if the previous operation is completed, proceed to erase the sector */
    FLASH->CR &= CR_PSIZE_MASK;
    FLASH->CR |= tmp_psize;
    FLASH->CR &= SECTOR_MASK;
    FLASH->CR |= FLASH_CR_SER | FLASH_Sector;
    FLASH->CR |= FLASH_CR_STRT;
    
    /* Wait for last operation to be completed */
    status = FLASH_WaitForLastOperation();
    
    /* if the erase operation is completed, disable the SER Bit */
    FLASH->CR &= (~FLASH_CR_SER);
    FLASH->CR &= SECTOR_MASK;
  }
  /* Return the Erase Status */
  return status;
}

 



« Última modificación: 19 de Septiembre de 2015, 13:16:42 por planeta9999 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: stm32f0 ayuda con la flash, leer y escribir + hal lib
« Respuesta #6 en: 19 de Septiembre de 2015, 14:18:52 »
Imagino que lo haran asi esperando por un bootloader y no desperdiciar tanto espacio.

Desconectado xiran

  • PIC16
  • ***
  • Mensajes: 100
Re: stm32f0 ayuda con la flash, leer y escribir + hal lib
« Respuesta #7 en: 19 de Septiembre de 2015, 14:57:34 »
Q tal planeta, copié y pegué tu codigo a keil, pero me da varios errores, imagino por q uso las librerias hal, no las estandar... se me ocurre hacer trampa, creando variables, ver la ubicacion en memoria, y usarlas... voy a seguir investigando el tema, solamente ocupo grabar 4 valores no volatiles, pero es lo de menos la cantidad (siempre y cuando sea menor a la memoria disponible, 64 kb), saludos!

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: stm32f0 ayuda con la flash, leer y escribir + hal lib
« Respuesta #8 en: 19 de Septiembre de 2015, 15:07:05 »
Pero por 4 valores no te conviene la EEPROM ?

Ya que despedicir 64Kb solo por unos 16bytes es Mucho.. Ademas la EEPROM se puede grabar muchas mas veces.

Desconectado xiran

  • PIC16
  • ***
  • Mensajes: 100
Re: stm32f0 ayuda con la flash, leer y escribir + hal lib
« Respuesta #9 en: 19 de Septiembre de 2015, 15:23:31 »
Te refieres a usar la emulacion de eeprom? se podrá con las librerias hal?
UPDATE:
Estoy usando la board discovery con stm32f051r8, saludos.

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re: stm32f0 ayuda con la flash, leer y escribir + hal lib
« Respuesta #10 en: 19 de Septiembre de 2015, 15:33:17 »
.

Échale un ojo a este manual de referencia, sigue los pasos del organigrama para borrar una página previo a la escritura, y no borres la página que contiene el código en ejecución, o como te está ocurriendo el micro se bloquea.

http://www.st.com/web/en/resource/technical/document/reference_manual/DM00031936.pdf

Creo que también tienes que comprobar el bit LOCK en FLASH_CR, antes de intentar borrar. Es importante ver el mapa de memoria, y según el micro, el tamaño de página. Dentro de la familia F0, los hay con tamaño de página de 1K y de 2K.


« Última modificación: 19 de Septiembre de 2015, 15:35:35 por planeta9999 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: stm32f0 ayuda con la flash, leer y escribir + hal lib
« Respuesta #11 en: 19 de Septiembre de 2015, 15:41:17 »
Te refieres a usar la emulacion de eeprom? se podrá con las librerias hal?
UPDATE:
Estoy usando la board discovery con stm32f051r8, saludos.

Un error mio, pense que tenia EEPROM.
Ahora que me fijo en la seleccion de productos, los ST ninguno sale con EEPROM, todos tiene un "-"

Desconectado xiran

  • PIC16
  • ***
  • Mensajes: 100
Re: stm32f0 ayuda con la flash, leer y escribir + hal lib
« Respuesta #12 en: 19 de Septiembre de 2015, 15:58:02 »
Un error mio, pense que tenia EEPROM.
Ahora que me fijo en la seleccion de productos, los ST ninguno sale con EEPROM, todos tiene un "-"
Asi es, pensé q te referias a la emulacion de EEPROM, pero he leido q es lenta, y complicada.



Planeta, mira, estas son las instrucciones q uso:

HAL_FLASH_Unlock();

HAL_FLASHEx_Erase(&erase_pages, errores);

HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, 0x08007C00,0x0002);
HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, 0x08007C04,0x0003);

HAL_FLASH_Lock();

Por probar un valor cualquiera, y lo q hace
HAL_FLASH_Unlock();
Es
HAL_StatusTypeDef HAL_FLASH_Unlock(void)
{
  if((READ_BIT(FLASH->CR, FLASH_CR_LOCK)) != RESET)
  {
    /* Authorize the FLASH Registers access */
    WRITE_REG(FLASH->KEYR, FLASH_FKEY1);
    WRITE_REG(FLASH->KEYR, FLASH_FKEY2);
  }
  else
  {
    return HAL_ERROR;
  }
  
  return HAL_OK;
}
Hace el chequeo del bit en FLASH_CR q me comentas, voy a ver el rm q me recomiendas, saludos.

UPDATE:
Esto hace HAL_FLASHEx_Erase:

HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
{
  HAL_StatusTypeDef status = HAL_ERROR;
  uint32_t address = 0;
 
  /* Process Locked */
  __HAL_LOCK(&pFlash);

  /* Check the parameters */
  assert_param(IS_TYPEERASE(pEraseInit->TypeErase));

  /* Wait for last operation to be completed */
  status = FLASH_WaitForLastOperation((uint32_t)HAL_FLASH_TIMEOUT_VALUE);

  if (status == HAL_OK)
  {
    if (pEraseInit->TypeErase == TYPEERASE_MASSERASE)
    {
      /*Mass erase to be done*/
      FLASH_MassErase();

      /* Wait for last operation to be completed */
      status = FLASH_WaitForLastOperation((uint32_t)HAL_FLASH_TIMEOUT_VALUE);
     
      /* If the erase operation is completed, disable the MER Bit */
      CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
    }
    else
    {
      /* Check the parameters */
      assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
      assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));

      /*Initialization of PageError variable*/
      *PageError = 0xFFFFFFFF;
   
      /* Erase by page by page to be done*/
      for(address = pEraseInit->PageAddress;
          address < (pEraseInit->PageAddress + (pEraseInit->NbPages)*FLASH_PAGE_SIZE);
          address += FLASH_PAGE_SIZE)
      {
        FLASH_PageErase(address);

        /* Wait for last operation to be completed */
        status = FLASH_WaitForLastOperation((uint32_t)HAL_FLASH_TIMEOUT_VALUE);
   
        /* If the erase operation is completed, disable the PER Bit */
        CLEAR_BIT(FLASH->CR, FLASH_CR_PER);

        if (status != HAL_OK)
        {
          /* In case of error, stop erase procedure and return the faulty address */
          *PageError = address;
          break;
        }
      }
    }
  }

  /* Process Unlocked */
  __HAL_UNLOCK(&pFlash);

  return status;
}
« Última modificación: 19 de Septiembre de 2015, 18:22:23 por xiran »

Desconectado xiran

  • PIC16
  • ***
  • Mensajes: 100
Re: stm32f0 ayuda con la flash, leer y escribir + hal lib
« Respuesta #13 en: 19 de Septiembre de 2015, 19:22:01 »
Acabo de hacer una prueba haciendo trampas como comenté, y no se trunca, voy a probar un poco mas, ya q ahorita no alcanzo...

UPDATE:
Hice diferentes trampas, pero no funcionaron. La ultima fue, configurar el algoritmo de programacion de la flash en keil, quitarle 1 kb (de 64 kb q trae de default para mi micro, le quité 1 kb), y ponerlo a programar de manera independiente.

Pero se sigue ciclando con:

HAL_FLASHEx_Erase(&erase_pages, errores);

Tendré q seguir investigando...
« Última modificación: 20 de Septiembre de 2015, 18:12:45 por xiran »


 

anything