Programmare la FLASH del TMS570

I prodotti della famiglia TMS570 di Texas Instruments sono tutti equipaggiati con una memoria flash in cui è possibile memorizzare i dati o il codice da eseguire. Uno dei metodi per programmare questa memoria con il contenuto desiderato è quello di utilizzare le Flash API, in questo articolo si tratterà questo argomento.

Le Flash API definiscono un insieme di funzioni software per la periferica che permettono di programmare e/o cancellare il modulo flash. Per prima cosa è, però, bene approfondire la struttura della flash integrata nei prodotti della famiglia TMS570, senza entrare troppo nel dettaglio.

Figura 1: suddivisione a banchi della memoria flash.

Figura 1: suddivisione a banchi della memoria flash

LA MEMORIA FLASH

Come detto, tutti i prodotti della famiglia TMS570 hanno a disposizione una memoria flash integrata per memorizzare dati e codice. Solitamente tale memoria è suddivisa in banchi, costituiti da un insieme di settori. L’unità minima di memoria che può essere cancellata è, appunto, un settore. Per esempio il TMS570LS20216S ha 4 banchi di flash, il banco0 è suddiviso in 10 settori, mentre gli altri tre banchi hanno solamente 4 settori ciascuno, per ogni dispositivo è necessario fare riferimento allo specifico datasheet. Il banco di flash nel TMS570LS20216S è ampio 144 bit ed include 128 bit di memoria classica e 2 byte per il controllo ECC. Ogni byte fa riferimento a 64 data bit e a 19 bit di indirizzo. In questo modo, anche se gli stessi dati sono memorizzati in posizione diversa, il byte di ECC è differente includendo anche l’informazione sull’indirizzo. Come si può vedere dalla Figura 2, fisicamente lo spazio per i bit ECC è 1/8 della corrispondente dimensione in bit dello spazio per i dati.

Figura 2: organizzazione dei bit di ECC.

Figura 2: organizzazione dei bit di ECC

PROGRAMMAZIONE DELLA FLASH

Le Flash API definiscono un insieme di funzioni software per la periferica che permettono di programmare e/o cancellare il modulo flash. Esistono più di 50 funzioni, incluso molte funzioni ereditate da TMS470R1x e per la diagnostica. Per gli usi più comuni solamente nove sono le funzioni più utilizzate, nella Tabella 1 un estratto di queste.

Tabella 1: le nove funzioni più utilizzate delle Flash API.

Tabella 1: le nove funzioni più utilizzate delle Flash API

Ci sono una serie di passi richiesti per arrivare a programmare la memoria utilizzando le Flash API:

  1. Includere i file header e le librerie delle Flash API nel proprio progetto software;
  2. Compattare la Flash;
  3. Cancellare la Flash;
  4. Programmare la Flash.

Verificare che sia stata programmata. Probabilmente il primo passo è quello che può destare più insidie. Bisogna partire installando il F035a Flash API, ci si ritroverà una cartella contenente:

  • Tre file header: f035.h, h e Flash470ErrorDefines.h. Includere questo file nel progetto.
  • Tre file di libreria: pf035a_api.lib, pf035a_api_tiabi.lib, pf035a_api_eabi.lib. Ad eccezione del nome, le prime due sono identiche, entrambe sono da includere nel progetto se si compila utilizzando l’opzione tiabi (in Code Composer Studio™ 3.3, Project Build Options, sotto la scheda Compiler and Linker; in Code Composer Studio 4.x, Project ® Properties, sotto la scheda Tool Settings, click Runtime Model Options). In alternativa, se si utilizza l’opzione eabi, includere pf035a_api_eabi.lib nel progetto. Si tratta, essenzialmente, di due diverse convenzioni "abi" per i formati dei file, tipi di dati, utilizzo dei registri, organizzazione dello stack e parametri passati alle funzioni.

Gli esempi che seguiranno utilizzano le convenzioni eabi. Dopo aver incluso tutti i file header e le librerie, l’applicativo può invocare le funzioni API definite in flash470.h. L’operazione di compattazione serve per evitare che l’amplificatore di sensing possa confondere il contenuto di alcune locazioni di flash dopo che queste sono state cancellate più volte o cancellate marginalmente. In tal caso si utilizza la funzione Flash_Compact_B(). Questa funzione valida il contenuto della zona dati e dell’ECC allo stesso tempo. Se viene utilizzata per validare la Flash data del settore 0 nel banco1, viene validata contemporaneamente anche la corrispondente area dedicata all’ECC. L’esempio di listato 1 compatta il banco 2 e il banco 3.

//Compact bank 2 and bank3 the Flash
pstatus=0x0;
for(i=14;i<NUMBEROFSECTORS;i++)
{ temp=Flash_Compact_B(sector[i].start, sector[i].bank,
(FLASH_SECT)sector[i].sectorNumber, delay,
(FLASH_ARRAY_ST)sector[i].FlashBaseAddress,&status);
if(!temp) { pstatus=1;
break; }
}
Listato 1

Dopo la compattazione si può passare alla cancellazione. La flash cancellata se letta è tutta riempita con 0xFFFFFFFF. Tale stato viene detto di blank. Le Flash API mettono a disposizione una funzione per la cancellazione del banco e due funzioni per la cancellazione del settore. Come per le funzioni di compattazione si lavora anche sulla zona di ECC. Le funzioni sono, rispettivamente:

  • Flash_Erase_Bank_B() ;
  • Flash_Erase_B() ;
  • Flash_Erase_Sector_B() ;

Flash_Erase_Bank_B() e Flash_Erase_B() permettono di bypassare alcune condizioni preliminari per la cancellazione. Questo permette di risparmiare tempo se ovviamente la zona di destinazione è già blank. In ogni caso la funzione Flash_Bank_B() permette di verificare queste condizioni. La stessa può essere usata dopo la cancellazione per verificarla. Il listato 2 invoca la Flash_Erase_Bank_B() per cancellare il banco 2 e la Flash_Erase_B() per cancellare il banco 3.

// Erase Antares Flash Bank 2 using Bank Erase
pstatus=0x0;
status.stat1 = 0;//enable preconditioning
temp=Flash_Erase_Bank_B(bank[2].start,bank[2].length,bank[2].bankNumber
, delay,
(FLASH_ARRAY_ST)bank[2].FlashBaseAddress,&status);
if(!temp) { pstatus=1;}
// Erase Antares Flash bank 3 using Sector Erase
pstatus=0x0;
status.stat1 = 0; //enable preconditioning
for(i=18;i<NUMBEROFSECTORS;i++)
{ temp=Flash_Erase_B(sector[i].start,sector[i].length,sector[i].bank,
(FLASH_SECT)sector[i].sectorNumber, delay,
(FLASH_ARRAY_ST)sector[i].FlashBaseAddress,&status);
if(!temp) { pstatus=1;
break;}
}
Listato 2

Le Flash API per procedere con la programmazione mettono a disposizione la funzione Flash_Prog_B() che esegue la scrittura della flash a partire da un indirizzo di start. La zona da programmare non deve trovarsi a cavallo tra due banchi. Nell’esempio di listato 3 che segue, per la scrittura di 1Kbyte di dati in flash la funzione Flash_Prog_B() viene chiamata 2 volte poiché passa dal banco 2 al banco 3.

// Program the 1k byte data from RAM 0x9000 to Flash 0x0017FF00.
pstatus=0x0;
temp=Flash_Prog_B((void *)0x0017FF00 ,(UINT32 *)&Flash_Data, 0x100>>2,
FLASH_CORE2,
delay,(FLASH_ARRAY_ST)0xfff87000,&status);
if(!temp) {pstatus=1;}
temp=Flash_Prog_B((void *)0x00180000 ,(UINT32 *)(&Flash_Data+0x40),
0x300>>2,
FLASH_CORE3, delay,(FLASH_ARRAY_ST)0xfff87000,&status);
if(!temp) {pstatus=1;}
// Program Flash ECC
pstatus=0x0;
temp=Flash_Prog_B((void *)0x004bff80 ,(UINT32 *)&Flash_ECCData,
0x80>>2, FLASH_CORE2,
delay,(FLASH_ARRAY_ST)0xfff87000,&status);
if(!temp) {pstatus=0x20;}
temp=Flash_Prog_B((void *)0x004C0000 ,(UINT32 *)(&Flash_ECCData+0x20),
0x180>>2,
FLASH_CORE3, delay, (FLASH_ARRAY_ST)0xfff87000,&status);
if(!temp) {pstatus=0x20;}
Listato 3

La zona di ECC in questo caso viene programmata separatamente, attraverso il tool nowECC™ si può calcolare il contenuto per procedere con la scrittura. Dopo la programmazione non rimane che da eseguire la verifica. Il codice applicativo può eseguirla invocando la funzione Flash_Verify_B() oppure la funzione Flash_PSA_Verify_B(). Queste due funzioni verificano la corretta programmazione utilizzando una lettura normale, una read-margin 0 e una read-margin 1. L’esempio di listato 4 verifica la scrittura di 1K di dati nel banco 2 e nel banco 3.

// Verify that the 1k byte data from RAM 0x9000 to Flash 0x0017FF00.
pstatus=0x0;
temp=Flash_Verify_B((void *)0x0017FF00 ,(UINT32 *)&Flash_Data,
0x100>>2, FLASH_CORE2,
(FLASH_ARRAY_ST)0xfff87000,&status);
if(!temp) {pstatus=0x1;}
temp=Flash_Verify_B((void *)0x00180000 ,(UINT32 *)((&Flash_Data)+0x40),
0x300>>2,
FLASH_CORE3,(FLASH_ARRAY_ST)0xfff87000,&status);
if(!temp) {pstatus=0x1;}
// Verify Flash ECC
pstatus=0x0;
temp=Flash_Verify_B((void *)0x004bff80 ,(UINT32 *)&Flash_ECCData,
0x80>>2, FLASH_CORE2,
(FLASH_ARRAY_ST)0xfff87000,&status);
if(!temp) {pstatus=0x40;}
temp=Flash_Verify_B((void *)0x004C0000 ,(UINT32
*)(&Flash_ECCData+0x20),
0x180>>2, FLASH_CORE3, (FLASH_ARRAY_ST)0xfff87000,&status);
if(!temp) {pstatus=0x40; }
Listato 4

Per evitare problemi con i bit di ECC, TI raccomanda di disabilitare la Flash ECC durante la compattazione, cancellazione, programmazione e verifica. Inoltre, consiglia di disabilitare interrupt ed eccezioni durante queste fasi per evitare di perdere il conteggio degli impulsi di cancellazione o compattazione.

SETTORI OTP DI FLASH

Ci sono quattro settori di Flash OTP (One Time Programmable) mappati con offset di 6Mbyte dall’indirizzo base della flash. Tra ognuno dei settori ci sono 2K. Questi settori possono essere programmati una sola volta e non bisogna cercare di cancellarli. Le Flash API mettono a disposizione la funzione OTP_Prog_B() per programmare l’area OTP dedicata. Anche su questa area è possibile utilizzare la funzione Flash_Blank_B() per verificare lo stato di blank e le funzioni Flash_PSA_Verify_B() e Flash_Verify_B() per la verifica della programmazione.

Scarica subito una copia gratis

Scrivi un commento

Seguici anche sul tuo Social Network preferito!

Send this to a friend