Autor Tema: error de flash en atmel sam  (Leído 6585 veces)

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

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2980
error de flash en atmel sam
« en: 02 de Septiembre de 2018, 11:32:46 »
Buenas a ver si alguien puede arrojarme luz sobre lo que esta pasando.

Tengo una aplicación que funciona perfectamente en un atmel sam s70, el problema viene al insertarle la funcionalidad de la memoria flash.
utilizo el ejemplo de flash que viene sin cambiar nada (ya lo he probado todo):

Código: [Seleccionar]
static uint8_t src_data[IFLASH_PAGE_SIZE];
static uint8_t chk_data[IFLASH_PAGE_SIZE];

/**
 * Example of using FLASH_0 to read and write buffer.
 */
void FLASH_0_example(void)
{
uint32_t page_size;
uint16_t i;

/* Init source data */
page_size = flash_get_page_size(&FLASH_0);

for (i = 0; i < page_size; i++) {
src_data[i] = i;
}

/* Write data to flash */
flash_write(&FLASH_0, 0x3200, src_data, page_size);

/* Read data from flash */
flash_read(&FLASH_0, 0x3200, chk_data, page_size);
}


La memoria flash funciona correctamente, es decir, graba y lee sin problemas, pero al ejecutar la funcion flash_write, el resto de la aplicacion deja de funcionar, creo que son las interrupciones, que dejan de funcionar, el programa poco despues de ejecutar la instrucción flash_write me lleva a :

Citar
/**
 * \brief Default interrupt handler for unused IRQs.
 */
void Dummy_Handler(void)
{
        while (1) { }
}

y el callstack no me sirve de nada ya que esta "dummy_handler" salta a modo de interrupción desde otra parte del programa que no tiene nada que ver.

alguien sabe que puede estar pasando?

he probado ha habilitar de nuevo las interrupciones pero parece que no funciona, la lectura no produce ningun error

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:error de flash en atmel sam
« Respuesta #1 en: 02 de Septiembre de 2018, 12:08:49 »
Siempre y cuando no este definida la interrupcion, tiene un weak alias a Dummy_Handler.

Es decir si vos definis la funcion de interrupcion utiliza la tuya, sino utiliza la Dummy_Handler.
El tema es que TODAS las demas interrupciones no definidas van al Dummy_Handler.

Debo imaginar entonces que pueden ocurrir 2 cosas.

- Alguna interrupcion que no debe ser activada, se activo
- Algun problema en la grabacion ocurrio, ya sea por mala alineacion, etc.

Mi primer paso seria tratar de determinar CUAL interrupcion ocurrio. Y para eso tenes la funcion _get_IPRS

https://www.keil.com/pack/doc/cmsis/Core/html/group__Core__Register__gr.html#ga2c32fc5c7f8f07fb3d436c6f6fe4e8c8

Citar
uint32_t __get_IPSR   (   void       )   

The function reads the Interrupt Program Status Register (IPSR) using the instruction MRS.

The ISPR contains the exception type number of the current Interrupt Service Routine (ISR). Each exception has an assocciated unique IRQn number. The following bits are used:

ISR_NUMBER (IPSR[8:0])
=0 Thread mode
=1 Reserved
=2 NMI
=3 HardFault
=4 MemManage
=5 BusFault
=6 UsageFault
=7-10 Reserved
=11 SVCall
=12 Reserved for Debug
=13 Reserved
=14 PendSV
=15 SysTick
=16 IRQ0
...
=n+15 IRQ(n-1)

Returns
ISPR register value

Remarks
This register is read-only.

Asi que como primer paso haria un codigo asi:

Código: C
  1. uint32_t phantomISR = 9999;
  2.  
  3. void Dummy_Handler(void)
  4. {
  5.     while(1) {
  6.         phantomISR = __get_IPSR();
  7.     }
  8. }

En tu startup .c, asi determinar desde donde ocurre la interrupcion. ( Para no definir 1 funcion para cada vector de ISR)

Luego de determinar desde donde viene esa interrupcion:
- Si es una interrupcion que no deberia haberse activado, entonces buscar la causa de porque se activo, o donde.
- Si es una interrupcion que se debio haber activado, pero vos no la tuviste en cuenta, con esto te vas a dar cuenta.
- Si es un error de alineacion, te vas a dar cuenta tambien, ya que las interrupciones que lo causan son MemFault/HardFault por ahi andan.

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2980
Re:error de flash en atmel sam
« Respuesta #2 en: 02 de Septiembre de 2018, 13:10:57 »
Ok buena idea, la causa del error ha sido la numero 3, es decir hardfault tiene que ser algo relacionado con la flash.

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2980
Re:error de flash en atmel sam
« Respuesta #3 en: 02 de Septiembre de 2018, 13:25:59 »
Bien parece ser que esta relacionado con la dirección donde lo estaba guardando, revisando el mapa de memoria veo que la SRAM esta a partir de la dirección 0x00400000

al cambiar a esa dirección, ya funciona el programa, pero al leer la región me da 0, cuando me deberia dar 0,1,2,3,4....

Código: [Seleccionar]
uint32_t page_size;
uint16_t i;

/* Init source data */
page_size = flash_get_page_size(&FLASH_0);

for (i = 0; i < page_size; i++) {
src_data[i] = i;
}

/* Write data to flash */
flash_write(&FLASH_0, 0x00400000, src_data, page_size);

/* Read data from flash */
flash_read(&FLASH_0, 0x00400000, chk_data, page_size);

el programa se ejecuta sin problemas, pero no lee lo que deberia o no graba en la region marcada.
« Última modificación: 02 de Septiembre de 2018, 13:29:58 por juaperser1 »

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:error de flash en atmel sam
« Respuesta #4 en: 02 de Septiembre de 2018, 13:49:41 »
 
¿ Has ejecutado el flash_erase antes de escribir en la flash ?.

Si no borras previamente la página completa, no puedes escribir en la dirección correspondiente a esa página. Y hay que cuidarse de que en esa página no esté parte o la totalidad del programa que se está ejecutando.


Código: C++
  1. /**
  2.  * \brief Execute erase in the internal flash
  3.  */
  4. int32_t flash_erase(struct flash_descriptor *flash, const uint32_t dst_addr, const uint32_t page_nums)
  5. {
  6.         ASSERT(flash && page_nums);
  7.         uint32_t page_size   = _flash_get_page_size(&flash->dev);
  8.         uint32_t total_pages = _flash_get_total_pages(&flash->dev);
  9.         int32_t  rc;
  10.  
  11.         rc = flash_is_address_aligned(flash, dst_addr);
  12.         if (rc) {
  13.                 return rc;
  14.         }
  15.  
  16.         if ((page_nums > total_pages) || (dst_addr / page_size + page_nums > total_pages)) {
  17.                 return ERR_INVALID_ARG;
  18.         }
  19.  
  20.         _flash_erase(&flash->dev, dst_addr, page_nums);
  21.  
  22.         return ERR_NONE;
  23. }

« Última modificación: 02 de Septiembre de 2018, 13:53:41 por planeta9999 »

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2980
Re:error de flash en atmel sam
« Respuesta #5 en: 02 de Septiembre de 2018, 14:03:41 »
Hola planeta, pues acabo de probar lo que comentas, pero el comportamiento es el mismo, cuando leo solo leo 0, cuando deberia leer un buffer ascendente (1,2,3,4...)

tambien he probado a desbloquear la pagina:

Código: [Seleccionar]
void LeerFlash(void)
{
uint32_t page_size;
uint16_t i;

/* Init source data */
page_size = flash_get_page_size(&FLASH_0);

for (i = 0; i < page_size; i++) {
src_data[i] = i;
}

flash_unlock(&FLASH_0, 0x0047F800, page_size);

flash_erase(&FLASH_0, 0x0047F800,page_size);

/* Write data to flash */
flash_write(&FLASH_0, 0x0047F800, src_data, page_size);

/* Read data from flash */
flash_read(&FLASH_0, 0x0047F800, chk_data, page_size);

i=1;
}

el "i=1" es para parar el debug y ver los arrays src_data y chk_data, la dirección he usado esa que seria la direccion base 0x04000000 + 0x80000 (512B) -512*4

asi tendria 2048 bytes para guardar. pero nada cuando para en i=1; tengo el src_data[0]=0,src_data[1]=1, etc. pero el chk_data todo a 0.

no se que puede ser.

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:error de flash en atmel sam
« Respuesta #6 en: 02 de Septiembre de 2018, 14:06:13 »

Puede que necesites también bloquear y desbloquear la página con flash_lock y flash_unlock.

Lo que si es seguro, es que para escribir en la flash, siempre hay que borrar previamente la página completa en la que esté la dirección a escribir, si no el resultado puede ser imprevisible o no escribe nada.

PD: vaya, no había leído que ya has probado el unlock de la página. Tal vez necesites hacer un lock, escribir y luego el unlock. Por algún documento anda un organigrama del proceso completo de escritura en la flash, me parece que tanto el lock como el unlock estaban involucrados tras borrar la página.
« Última modificación: 02 de Septiembre de 2018, 14:11:21 por planeta9999 »

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:error de flash en atmel sam
« Respuesta #7 en: 02 de Septiembre de 2018, 14:19:07 »

Este es un ejemplo completo de escritura.


Código: C++
  1. /**
  2.  * \brief Test flash writing.
  3.  *
  4.  * This test tests the flash writing function in the test page of the flash.
  5.  *
  6.  * \param test Current test case.
  7.  */
  8. static void run_flash_write_test(const struct test_case *test)
  9. {
  10.         uint32_t ul_page_buffer[IFLASH_PAGE_SIZE / sizeof(uint32_t)];
  11.         uint32_t ul_rc=0;
  12.         uint32_t ul_idx;
  13.         uint32_t ul_test_page_addr = TEST_PAGE_ADDRESS;
  14.         uint32_t *pul_test_page = (uint32_t *) ul_test_page_addr;
  15.  
  16.         /* Unlock the whole flash */
  17.         flash_unlock(IFLASH_ADDR,  ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);
  18.  
  19.         /* Write the test page with walking bit pattern */
  20.         for (ul_idx = 0; ul_idx < (IFLASH_PAGE_SIZE / 4); ul_idx++) {
  21.                 ul_page_buffer[ul_idx] = 1 << (ul_idx % 32);
  22.         }
  23.  
  24. #if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || \
  25.          SAMV71 || SAMV70 || SAMS70 || SAME70)
  26.         /* Write the test page */
  27.         flash_erase_sector(ul_test_page_addr);
  28.  
  29.         flash_write(ul_test_page_addr,
  30.                         (void *)ul_page_buffer,
  31.                         IFLASH_PAGE_SIZE, 0);
  32. #else
  33.         flash_write(ul_test_page_addr,
  34.                         (void *)ul_page_buffer,
  35.                         IFLASH_PAGE_SIZE, 1);
  36. #endif
  37.  
  38.         /* Validate page contents */
  39.         for (ul_idx = 0; ul_idx < (IFLASH_PAGE_SIZE / 4); ul_idx++) {
  40.                 if (pul_test_page[ul_idx] != ul_page_buffer[ul_idx]) {
  41.                         ul_rc =1;
  42.                 }
  43.         }
  44.  
  45.         /* Validate the flash write function */
  46.         test_assert_true(test, ul_rc == 0, "Test flash write: flash write error!");
  47. }

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2980
Re:error de flash en atmel sam
« Respuesta #8 en: 02 de Septiembre de 2018, 14:23:09 »

Puede que necesites también bloquear y desbloquear la página con flash_lock y flash_unlock.

Lo que si es seguro, es que para escribir en la flash, siempre hay que borrar previamente la página completa en la que esté la dirección a escribir, si no el resultado puede ser imprevisible o no escribe nada.

PD: vaya, no había leído que ya has probado el unlock de la página. Tal vez necesites hacer un lock, escribir y luego el unlock. Por algún documento anda un organigrama del proceso completo de escritura en la flash, me parece que tanto el lock como el unlock estaban involucrados tras borrar la página.


Pues revisando la funcion unlock veo lo siguiente:

Código: [Seleccionar]
int32_t flash_unlock(struct flash_descriptor *flash, const uint32_t dst_addr, const uint32_t page_nums)
{
ASSERT(flash && page_nums);
uint32_t page_size   = _flash_get_page_size(&flash->dev);
uint32_t total_pages = _flash_get_total_pages(&flash->dev);
int32_t  rc;

rc = flash_is_address_aligned(flash, dst_addr);
if (rc) {
return rc;
}

if ((page_nums > total_pages) || (dst_addr / page_size + page_nums > total_pages)) {
return ERR_INVALID_ARG;
}

return _flash_unlock(&flash->dev, dst_addr, page_nums);
}

para devolver error, el segundo if tiene una condicion que es:

dst_addr / page_size + page_nums > total_pages 

si cogemos dst_addr como 0x400000 (4194304) el tamaño de pagina que es de 512 y el numero de paginas que como maximo son 1024 me parece que siempre es error ¿no? o estoy haciendo algo mas o esto no cuadra:

4194304/512 solo eso ya es 8192 >1024 siempre va  ha ser error :? :?

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2980
Re:error de flash en atmel sam
« Respuesta #9 en: 02 de Septiembre de 2018, 14:26:36 »

Este es un ejemplo completo de escritura.


Código: C++
  1. /**
  2.  * \brief Test flash writing.
  3.  *
  4.  * This test tests the flash writing function in the test page of the flash.
  5.  *
  6.  * \param test Current test case.
  7.  */
  8. static void run_flash_write_test(const struct test_case *test)
  9. {
  10.         uint32_t ul_page_buffer[IFLASH_PAGE_SIZE / sizeof(uint32_t)];
  11.         uint32_t ul_rc=0;
  12.         uint32_t ul_idx;
  13.         uint32_t ul_test_page_addr = TEST_PAGE_ADDRESS;
  14.         uint32_t *pul_test_page = (uint32_t *) ul_test_page_addr;
  15.  
  16.         /* Unlock the whole flash */
  17.         flash_unlock(IFLASH_ADDR,  ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);
  18.  
  19.         /* Write the test page with walking bit pattern */
  20.         for (ul_idx = 0; ul_idx < (IFLASH_PAGE_SIZE / 4); ul_idx++) {
  21.                 ul_page_buffer[ul_idx] = 1 << (ul_idx % 32);
  22.         }
  23.  
  24. #if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || \
  25.          SAMV71 || SAMV70 || SAMS70 || SAME70)
  26.         /* Write the test page */
  27.         flash_erase_sector(ul_test_page_addr);
  28.  
  29.         flash_write(ul_test_page_addr,
  30.                         (void *)ul_page_buffer,
  31.                         IFLASH_PAGE_SIZE, 0);
  32. #else
  33.         flash_write(ul_test_page_addr,
  34.                         (void *)ul_page_buffer,
  35.                         IFLASH_PAGE_SIZE, 1);
  36. #endif
  37.  
  38.         /* Validate page contents */
  39.         for (ul_idx = 0; ul_idx < (IFLASH_PAGE_SIZE / 4); ul_idx++) {
  40.                 if (pul_test_page[ul_idx] != ul_page_buffer[ul_idx]) {
  41.                         ul_rc =1;
  42.                 }
  43.         }
  44.  
  45.         /* Validate the flash write function */
  46.         test_assert_true(test, ul_rc == 0, "Test flash write: flash write error!");
  47. }

ese ejemplo que has puesto es de las librerias antiguas, yo estoy usando las nuevas, aunque estoy haciendo mas o menos lo mismo lo que pasa es que la funcion unlock difiere, solo se le pasan 3 argumentos y como he puesto en mi post anterior creo que siempre da error???

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2980
Re:error de flash en atmel sam
« Respuesta #10 en: 02 de Septiembre de 2018, 15:09:44 »
a ver, recapitulando, como hemos visto para grabar en la flash tenemos uqe desbloquer la región borrar y luego escribir vale, hasta aqui todo claro pero en este micro es:


Código: [Seleccionar]
#define IFLASH_SIZE              _U_(0x00080000)       /*  512kB Memory segment type: flash */
#define IFLASH_PAGE_SIZE         _U_(       512)
#define IFLASH_NB_OF_PAGES       _U_(      1024)
#define IFLASH_ADDR              _U_(0x00400000)       /**< IFLASH base address (type: flash)*/

Que coincide con lo que dice la hoja de datos: http://ds.arm.com/media/resources/db/chip/atmel/sams70/Atmel-11242-32-bit-Cortex-M7-Microcontroller-SAM-S70Q-SAM-S70N-SAM-S70J_Datasheet.pdf

tenemos que la region de memoria de la flash empieza en 0x00400000 que el tamaño de la pagina son 512 y que tenemos 1024 paginas, vale hasta aqui todo perfecto, pero ahora vemso en la funcion unlock:

Código: [Seleccionar]
int32_t flash_unlock(struct flash_descriptor *flash, const uint32_t dst_addr, const uint32_t page_nums)
{
ASSERT(flash && page_nums);
uint32_t page_size   = _flash_get_page_size(&flash->dev);
uint32_t total_pages = _flash_get_total_pages(&flash->dev);
int32_t  rc;

rc = flash_is_address_aligned(flash, dst_addr);
if (rc) {
return rc;
}

if ((page_nums > total_pages) || (dst_addr / page_size + page_nums > total_pages)) {
return ERR_INVALID_ARG;
}

return _flash_unlock(&flash->dev, dst_addr, page_nums);
}

 que si vemos la segunda condición tomando el mejor de los casos como dst_addr como la base 0x00400000 y una sola pagina, tenemos que siempre va a soltar error:

ya que dst_addr/512+nº de paginas siempreeeeee es mayor que 1024

si vamos a la función erase:

Código: [Seleccionar]
int32_t flash_erase(struct flash_descriptor *flash, const uint32_t dst_addr, const uint32_t page_nums)
{
ASSERT(flash && page_nums);
uint32_t page_size   = _flash_get_page_size(&flash->dev);
uint32_t total_pages = _flash_get_total_pages(&flash->dev);
int32_t  rc;

rc = flash_is_address_aligned(flash, dst_addr);
if (rc) {
return rc;
}

if ((page_nums > total_pages) || (dst_addr / page_size + page_nums > total_pages)) {
return ERR_INVALID_ARG;
}

_flash_erase(&flash->dev, dst_addr, page_nums);

return ERR_NONE;
}

exactamente lo mismo

y si vamos a write:

Código: [Seleccionar]
int32_t flash_write(struct flash_descriptor *flash, uint32_t dst_addr, uint8_t *buffer, uint32_t length)
{
ASSERT(flash && buffer && length);

uint32_t page_size   = _flash_get_page_size(&flash->dev);
uint32_t total_pages = _flash_get_total_pages(&flash->dev);

/* Check if the address is valid */
if ((dst_addr > page_size * total_pages) || (dst_addr + length > page_size * total_pages)) {
return ERR_BAD_ADDRESS;
}

if (_flash_is_locked(&flash->dev, dst_addr)) {
return ERR_DENIED;
}

_flash_write(&flash->dev, dst_addr, buffer, length);

return ERR_NONE;
}

tambien va a saltar siempre error ERR_BAD_ADDRESS por que la direccion de la base 0x00400000 solo eso ya es mayor que 512*1024

asi que, o esto esta mal, o yo lo estoy entendiendo mal o ya no se que hacer...  :? :? quiere decir que debo grabarlo en la region de memoria ITCM, lo he probado y el programa se queda colgado asi que no puede ser asi que a ver si alguien me puede ayudar, estoy perdiendo mucho tiempo con esta tontería.





PD: otra cosa curiosa, si coloco la direccion 0x0 si graba y lee, pero claro, me pisa el programa y me lo fastidia.
« Última modificación: 02 de Septiembre de 2018, 15:49:52 por juaperser1 »

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2980
Re:error de flash en atmel sam
« Respuesta #11 en: 03 de Septiembre de 2018, 02:40:26 »
Bueno como nadie ha vuelto a constestar, supongo que mi premisa de que esto es absurdo es correcta, asi que solo se me ocurre una idea, reservar memoria de programa para que no me lo pise, alguien sabe como hacerlo? con 512 bytes tendría suficiente, en este micro no se exactamente como se hace, o hacer que el programa se guarde a partir de tal dirección, en PIC lo hacia de la siguiente manera:

Código: [Seleccionar]
#if defined (__PIC32C__)
#define KEEP
#else
#define KEEP    __attribute__ ((keep)) __attribute__((address(DRV_NVM_MEDIA_START_ADDRESS)))
#endif

#define APP_NVM_MEMORY_AREA_SIZE (DRV_NVM_MEDIA_SIZE * 1024) //32KB

//Reservamos 32KB de Flash
const uint8_t gAppFlashReserveArea[APP_NVM_MEMORY_AREA_SIZE] KEEP = {0};

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:error de flash en atmel sam
« Respuesta #12 en: 03 de Septiembre de 2018, 07:44:41 »
Utiliza la última página de la flash para tus datos y arreglado. Reubicar el programa solo tiene razón de ser para un sistema de bootloader y se suele hacer en el linker script.

Si no puedes usar una página cualquiera, no ocupada por el programa, habrá algún motivo, como el bloqueo desbloqueo de memoria, previo o posterior al borrado de pagina. Si lo intentas forzar, en direcciones de páginas usadas por el programa, tendras que salvar y restaurar la pagina tras la grabación, no tiene sentido salvo que vayas justo de flash, y aun así te podría colgar el micro.

Reubicar el programa para que salte a otra direccion en el arranque, sin un bootloader, no lo he hecho nunca, y no tiene sentido. Es intentar calzar el programa a la fuerza, por desconocer porque no te graba en una determinada página , es una solución chapucera, si es que se puede hacer.
« Última modificación: 03 de Septiembre de 2018, 11:56:14 por planeta9999 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:error de flash en atmel sam
« Respuesta #13 en: 03 de Septiembre de 2018, 08:14:39 »
Citar
Bueno como nadie ha vuelto a constestar

Yo no poseo demasiado tiempo, estoy un rato, contesto y tengo que salir.

Si fuera ese el problema que vos comentas, de que nunca se cumpliria esa condicion. Nunca comenzaria a escribir realmente. Y te devolveria el valor ERR_INVALID_ARG o ERR_BAD_ADDRESS. Y no continuaria con la escritura, haciendo que no se produzca un Hard Fault. Si podes debugearlo paso a paso, considero que deberias ver cuando es que ocurre, si entra o no a las funciones, si sale con algun error o no. Es lo mas simple de ver sin renegar con el codigo fuente.

Sino la otra es buscar el codigo para Hard Fault, el cual te arrojaria la direccion del PC antes de que ocurra, y asi saber que instruccion es la que lo produjo. Pero esos micros ya deben tener modulos extras para eso ( que no me acuerdo el nombre, trace y algo )

https://mcuoneclipse.com/2012/11/24/debugging-hard-faults-on-arm-cortex-m/
« Última modificación: 03 de Septiembre de 2018, 08:17:28 por KILLERJC »

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2980
Re:error de flash en atmel sam
« Respuesta #14 en: 03 de Septiembre de 2018, 08:41:35 »
Citar
Si no puedes usar una página cualquiera, no ocupada por el programa, habrá algún motivo, como el bloqueo desbloqueo de memoria, previo o posterior al borrado de pagina. Si lo intentas forzar, en direcciones
de páginas usadas por el programa, tendras que salvar y restaurar la pagina tras la grabación, no tiene sentido salvo que vayas justo de flash, y aun así te podría colgar el micro.

No se puede usar ninguna otra por que nunca se cumple la condicion, no puedes desbloquear la flash, ya que con la condicion dentro de la funcion unlock nunca se cumple con la dirección de memoria de la flash.

si reservo la memoria como he comentado no es una chapuza, el programa no se cambia de sitio, solo que ocupara mas por que tendrá una "variable muy grande vacia", y cuando graves en esa zona no se pisará el programa, solo se guardara en esa "variable grande". es como se hace en pic32 que comparte la flash para la memoria de programa.

Simplemente si se selecciona otra direccion que no sea la 0 o una muy baja no se graba.

Citar
habrá algún motivo


El motivo puede ser simplemente que este mal hecho, en este mismo proyecto he tenido que crear librerias para manerjar el RTT por que en las librerias no aparece, y modificar los fuentes del driver RTC para poder leer el dia de la semana por que no esta implementado en las librerías, tambien he tenido que modificar los fuentes de la uart asyncrona, las librerías son una basura asi que no te extrañe que para el caso de la flash también esten mal hechas, y no encontraras, mas ejemplo que el que puse yo al principio.


Citar
Si podes debugearlo paso a paso, considero que deberias ver cuando es que ocurre, si entra o no a las funciones, si sale con algun error o no. Es lo mas simple de ver sin renegar con el codigo fuente

precisamente vi lo de las condiciones a raiz de ir depurando, siempre saltaban las condiciones que comento y viendo los valores tenemos

Código: [Seleccionar]
if ((page_nums > total_pages) || (dst_addr / page_size + page_nums > total_pages)) {
return ERR_INVALID_ARG;
}

total_pages=1024

page_size =512

poniendo un page_num de 1, para tener el mejor de los casos y la direccion base de la flash 0x00400000 (‭4194304‬)

dentro de la condición tenemos que salta error si
Código: [Seleccionar]
dst_addr / page_size + page_nums > total_pages pero solo el dst_addr / page_size ya es mayor que 1024  :? :?

PD:
Citar
Bueno como nadie ha vuelto a constestar

Yo no poseo demasiado tiempo, estoy un rato, contesto y tengo que salir.

No se si ha sonado mal, no era por meter prisa ni por nada por el estilo simplemente que suponía que nadie sabia el porque pasa esto.

un saludo


* Sin título.png
(151.6 kB, 1480x480 - visto 504 veces)






 

anything