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);
}/**
* \brief Default interrupt handler for unused IRQs.
*/
void Dummy_Handler(void)
{
while (1) { }
}
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.
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); 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;
}
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.
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);
}
Este es un ejemplo completo de escritura.Código: C++
/** * \brief Test flash writing. * * This test tests the flash writing function in the test page of the flash. * * \param test Current test case. */ static void run_flash_write_test(const struct test_case *test) { uint32_t ul_page_buffer[IFLASH_PAGE_SIZE / sizeof(uint32_t)]; uint32_t ul_rc=0; uint32_t ul_idx; uint32_t ul_test_page_addr = TEST_PAGE_ADDRESS; uint32_t *pul_test_page = (uint32_t *) ul_test_page_addr; /* Unlock the whole flash */ flash_unlock(IFLASH_ADDR, ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0); /* Write the test page with walking bit pattern */ for (ul_idx = 0; ul_idx < (IFLASH_PAGE_SIZE / 4); ul_idx++) { ul_page_buffer[ul_idx] = 1 << (ul_idx % 32); } #if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || \ SAMV71 || SAMV70 || SAMS70 || SAME70) /* Write the test page */ flash_erase_sector(ul_test_page_addr); flash_write(ul_test_page_addr, (void *)ul_page_buffer, IFLASH_PAGE_SIZE, 0); #else flash_write(ul_test_page_addr, (void *)ul_page_buffer, IFLASH_PAGE_SIZE, 1); #endif /* Validate page contents */ for (ul_idx = 0; ul_idx < (IFLASH_PAGE_SIZE / 4); ul_idx++) { if (pul_test_page[ul_idx] != ul_page_buffer[ul_idx]) { ul_rc =1; } } /* Validate the flash write function */ test_assert_true(test, ul_rc == 0, "Test flash write: flash write error!"); }
#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)*/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);
}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;
}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;
}#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};
Bueno como nadie ha vuelto a constestar
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.
habrá algún motivo
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
if ((page_nums > total_pages) || (dst_addr / page_size + page_nums > total_pages)) {
return ERR_INVALID_ARG;
}dst_addr / page_size + page_nums > total_pages pero solo el dst_addr / page_size ya es mayor que 1024 :? :?CitarBueno como nadie ha vuelto a constestar
Yo no poseo demasiado tiempo, estoy un rato, contesto y tengo que salir.
Haciendo ingenieria inversa a las librerias y condiciones que me iba encontrando a en la depuración he sacado que la maxima memoria accesibe es la direccion 0x80000=512MB de la flash
Internal ROM
The SAM S70 embeds an Internal ROM for the SAM Boot Assistant (SAM-BA®), In Application Programming functions (IAP) and Fast Flash Programming Interface (FFPI).
At any time, the ROM is mapped at address 0x0080 0000
Y esa es la maxima direccion que podes escribir. Ya que la ROM es otra cosa. No es programable
Internal ROM
The SAM S70 embeds an Internal ROM for the SAM Boot Assistant (SAM-BA®), In Application Programming functions (IAP) and Fast Flash Programming Interface (FFPI).
At any time, the ROM is mapped at address 0x0080 0000
a pensaba que ninguno se estaba comercializando mas alla de las muestras o poco mas.
que herramienta usas para depurar?