Esto no es tan complicado de hacer.
Básicamente, lo que necesitas es una variable global constante que se colocará en flash y definirá la ubicación utilizando un pragma.
En C ++, el encabezado podría verse así:
class FlashLookUpTable
{
public:
struct LookUpTable_t
{
uint32_t table[100];
};
public:
static LookUpTable_t const * GetLookUpTablePointer();
private:
static const uint32_t FLASH_PAGE_SIZE = 1024U; // or whatever the flash smallest deletable size is
// This variable contains the number of bytes needed to store the structure in complete flash pages
static const uint32_t ARRAY_SIZE = (sizeof(LookUpTable_t)/FLASH_PAGE_SIZE) + FLASH_PAGE_SIZE;
union FlashPageSizedStructure
{
LookUpTable_t t;
uint8_t flashpage[ARRAY_SIZE];
}
static const FlashPageSizedStructure tableInFlash;
};
Y así es como se ve la implementación:
// the exact pragma depends on the compiler used, this one works for IAR
// the location should be at the start of a page boundary, especially when using this union approach
#pragma location=0x800FC00U
const FlashLookUpTable::FlashPageSizedStructure FlashLookUpTable::tableInFlash =
{
// initialize values here
}
FlashLookUpTable::LookUpTable_t const * FlashLookUpTable::GetLookUpTablePointer(void) const
{
return &tableInFlash.t;
}
Para escribir esa página en flash, necesita un búfer (ya sea en RAM o en flash) con el mismo tamaño de una página de flash porque tiene que borrar la página antes de volver a escribirla, por lo que puede cambiar la ubicación de una página. un solo valor no es posible.
Dependiendo de cómo lo use exactamente, es posible que deba declarar la estructura como volatile
. Esto sucede especialmente si accede directamente a la tabla (no con un puntero como en este caso).
Algunos compiladores optimizan el código de tal manera, que eliminan la constante de la tabla directamente en el código. El resultado es que, si cambia el valor en su tabla, el valor no se tiene en cuenta en el código.
El compilador IAR tuvo algunos problemas (está arreglado en la versión actual) al manejar static volatile const
, así que cambié a usar un puntero.
Si desea cambiar los valores, necesita algún tipo de algoritmo flash.
El flash de escritura siempre consiste en:
- contenido de la página de copia de seguridad
- Actualizar copia de seguridad con valores modificados
- Borrar página
- escribir página
- por seguridad: compare la página escrita con la copia de seguridad
Nota para los avanzados:
En algunos casos, puede explotar que puede escribir ceros en las posiciones donde se encontraba uno, por lo que podría cambiar un 0x7F a 0x3F, pero no al revés. En ese caso no es necesario hacer un borrado de página. Algunos controladores podrían no admitir esto.