Autor Tema: Grabar y leer variable en ROM interna, PIC24, C30  (Leído 7494 veces)

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

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Grabar y leer variable en ROM interna, PIC24, C30
« en: 15 de Octubre de 2010, 14:36:32 »
Hola

Necesito guardar, leer y re-escribir unas variables en la memoria interna Flash del PIC24FJ64GB002. Este PIC no tiene Data EEPROM.

Lo normal para guardarlas es usar const, pero para cuando quiero regrabarlas ya no sé cómo hacerlo.

De lo que he investigado es que se puede lograr por 2 formas: usando tablas o usando el PSV.

Con tablas es como con los PIC18, en donde hay instrucciones en assembler para lograrlo. Con el Program Space Visibility se puede leer la ROM como si fuera RAM con una ventana de 32kB (muy práctico), pero no se puede grabar nada (hasta dónde sé).

Quisiera preguntarles si alguien conoce un método o trozo de código para usar la internal ROM como espacio para variables. No se cambiará mucho la variable que grabaré por lo que no preocupa el desgaste de la misma.

Agradeceré cualquier pista.  :)

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Grabar y leer variable en ROM interna, PIC24, C30
« Respuesta #1 en: 15 de Octubre de 2010, 15:12:11 »
Este es un ejemplo de cómo leer una tabla en ROM apuntada con PSV. Creo que por aquí va el asunto.

Código: [Seleccionar]
#if defined(__dsPIC30F__)
#include <p30fxxxx.h>
#elif defined(__dsPIC33F__)
#include <p33Fxxxx.h>
#elif defined(__PIC24F__)
#include <p24Fxxxx.h>
#elif defined(__PIC24H__)
#include <p24Hxxxx.h>
#endif
#include <stdio.h>

const unsigned __attribute__ ((space(psv), address (0x2000)))
table[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};


int main( void )
{
    unsigned psv_shadow;
    unsigned sum=0, u;
    long addr;

    /* enable PSV functionality */
    CORCONbits.PSV=1;

    /* compute the address of table and print it */
    addr = ((long) __builtin_tblpage(table) << 16) +
    __builtin_tbloffset( table );

    /* print the address of table */
    printf ("table[ ] is stored at address 0x%lx\n", addr);
   
    /* save the PSVPAG */
    psv_shadow = PSVPAG;
   
    /* set the PSVPAG for accessing table[] */
    PSVPAG = __builtin_psvpage ( table );

    /* sum the values in table[] */
    for (u=0; u<10; u++) {
        sum += table[u];
    }

    /* restore the PSVPAG for the compiler-managed PSVPAG */
    PSVPAG = psv_shadow;
   
    /* print the sum */
    printf ("sum is %d\n", sum);

    while ( 1 );
}

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Grabar y leer variable en ROM interna, PIC24, C30
« Respuesta #2 en: 15 de Octubre de 2010, 16:01:18 »
Ya encontré los pasos a realizar, pero el código es lo que me falta escribir.  :?

PIC24F Family Reference Manual, Sect. 04 Program Memory
4.7.1 Flash Program Memory Programming Algorithm
http://ww1.microchip.com/downloads/en/DeviceDoc/39715a.pdf

Es como en los PIC18...

- Se borra un bloque alineado de 512 instrucciones (1536bytes)
- Se programa un bloque de 64 instrucciones (192 bytes)

Se logra sin usar PSV, sólo TBLRDx, TBLWTx y el registro TBLPAG.
« Última modificación: 15 de Octubre de 2010, 16:03:49 por migsantiago »

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Grabar y leer variable en ROM interna, PIC24, C30
« Respuesta #3 en: 15 de Octubre de 2010, 16:05:56 »
Más código, empezamos con el borrado de las 512 instrucciones en ROM:

Código: [Seleccionar]
// C example using MPLAB C30
unsigned long progAddr = 0xXXXXXX;// Address of row to write
unsigned int offset;
//Set up pointer to the first memory location to be written
TBLPAG = progAddr>>16;// Initialize PM Page Boundary SFR
offset = progAddr & 0xFFFF;// Initialize lower word of address
__builtin_tblwtl(offset, 0x0000);// Set base address of erase block
// with dummy latch write
NVMCON = 0x4042;// Initialize NVMCON
asm("DISI #5");// Block all interrupts with priority <7
// for next 5 instructions
__builtin_write_NVM();// C30 function to perform unlock
// sequence and set WR

Y después se cargan las 64 instrucciones (sí, se borra más de lo que hace falta, pero el PIC así funciona).

Código: [Seleccionar]
// C example using MPLAB C30
#define NUM_INSTRUCTION_PER_ROW 64
unsigned int offset;
unsigned int i;
unsigned long progAddr = 0xXXXXXX;// Address of row to write
unsigned int progData[2*NUM_INSTRUCTION_PER_ROW];// Buffer of data to write
//Set up NVMCON for row programming
NVMCON = 0x4001;// Initialize NVMCON
//Set up pointer to the first memory location to be written
TBLPAG = progAddr>>16;// Initialize PM Page Boundary SFR
offset = progAddr & 0xFFFF;// Initialize lower word of address
     
//Perform TBLWT instructions to write necessary number of latches
for(i=0; i < 2*NUM_INSTRUCTION_PER_ROW; i++)
{
__builtin_tblwtl(offset, progData[i++]);// Write to address low word
__builtin_tblwth(offset, progData[i]);// Write to upper byte
offset = offset + 2;// Increment address
}

Esto viene en la datasheet específica del PIC24. Lo pruebo y les digo si funciona.
« Última modificación: 15 de Octubre de 2010, 16:09:19 por migsantiago »

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Grabar y leer variable en ROM interna, PIC24, C30
« Respuesta #4 en: 15 de Octubre de 2010, 18:20:37 »
Tendré que desistir de usar este método. El desperdiciar 1536 bytes para guardar menos no me conviene. Sobre todo porque ya ando al 73% de ROM del PIC con el stack TCPIP y ya me siento limitado. Aún me falta el programa principal del PIC  :?

http://img651.imageshack.us/img651/2559/sinrom.png


Pero dejo semi-instrucciones por si alguien quiere seguir con esto...

- Declarar la variable con atributos PSV en una localidad de memoria empatada con un bloque de 64 bytes (ver mensaje 2)
- Borrar el bloque de 512 instrucciones (1536 bytes)
- Grabar ya sean 64 bytes de la RAM a la ROM con las rutinas que puse o sólo grabar el byte o word necesarios.

Las rutinas de código sólo vienen en la datasheet del PIC específico y no en el manual de la familia.

Usaré una EEPROM externa 25AA1024 y ahí almacenaré las variables y página web porque esto se está poniendo feo  :D

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Grabar y leer variable en ROM interna, PIC24, C30
« Respuesta #5 en: 16 de Octubre de 2010, 02:15:38 »
Tú te lo guisas y tú te lo comes.

Muchas gracias, muy ilustrativo, Santiago.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Grabar y leer variable en ROM interna, PIC24, C30
« Respuesta #6 en: 16 de Octubre de 2010, 10:42:11 »
Pues no quedó guisado... sólo quedó la teoría. Pero dejo todo lo que encontré por si alguien quiere terminar de cocinarlo.  ;-)

La desventaja de los PIC24 en cuanto a ROM es que cada instrucción pesa 3 bytes, por lo que mi PIC24FJ64GB002 que tiene 64kB de ROM sólo puede almacenar 22k instrucciones. El 65% se me fue en el stack TCPIP (HTTP2 y SMTP), un 5% en las páginas web y el 25% restante será para mi programa principal.

Usaré un 24LC65 para las variables de configuración e historiales.

Desconectado manwenwe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2211
Re: Grabar y leer variable en ROM interna, PIC24, C30
« Respuesta #7 en: 16 de Octubre de 2010, 11:23:15 »
Buenas,

hay funciones precompiladas que te te evitan tener que "tocar" directamente los punteros de ROM como has hecho:

Citar
The following helper functions for erasing and writing to FLASH memory have been added to libpic30.a:

    * _erase_flash() - erase a page of FLASH memory
    * _write_flash16() - write a row of FLASH memory with 16-bit data
    * _write_flash24() - write a row of FLASH memory with 24-bit data
    * _write_flash_word16() - write a word of FLASH memory with 16-bit data
    * _write_flash_word24() - write a word of FLASH memory with 24-bit data


La info la he sacado de:

http://ww1.microchip.com/downloads/en/DeviceDoc/C30_v302B_README.html#DocUpdates

Aunque la primera vez que lo ví fue en la ayuda de MPLAB: ahora no lo encuentro... :mrgreen:

Yo utilicé estas funciones en una placa con LCD+Touch donde olvidé añadir una EEPROM y necesitaba una memoria no volatil para guardar las variables de calibración del Touchscreen.

Eso sí: lo malo como tú comentas, migsantiago, es que no hay forma de borrar menos de un bloque de 512 instrucciones así que las sacrificas todas aq sólo utilices unos pocos bytes.

Saludos
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado manwenwe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2211
Re: Grabar y leer variable en ROM interna, PIC24, C30
« Respuesta #8 en: 16 de Octubre de 2010, 11:47:51 »
Se me acaba de ocurrir que quizá sería posible utilizar parte de tu  código para guardar entre medias esas variables de configuración: así no tendrías que desperdiciar un bloque entero de 512 instrucciones.

Sería algo así:

- Dentro de una función cualquier dejas tantos Nop(); como instrucciones (3 bytes) necesites para las variables de configuración.
- En otra función lees todos las instrucciones del bloque donde estan alojados los Nop()  (para esto tendrás que compilar primero y buscar ese bloque con un visor hexadecimal pe: WinPic800) y las almacenas en RAM. Luego borras el bloque y reescribes las instrucciones cambiando los Nop();  por tus variables de configuración.

Para esto necesitas:

- 512 x 3 bytes de RAM libre.
- Estas seguro de que las 2 funciones no comparten un mismo bloque de instrucciones.
- Tiempo para: leer, borrar y escribir.

Bueno ... doy por hecho que no es una solución nada elegante pero es que no se me ocurre nada mejor: Todo es probarlo XD

Saludos

Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Grabar y leer variable en ROM interna, PIC24, C30
« Respuesta #9 en: 16 de Octubre de 2010, 12:53:32 »
Hola Manwenwe

Yo sabía que los de Microchip tenían alguna macro para facilitar esto, pero no la supe encontrar. Te agradezco que la publiques.

Lo que me desagrada es lo de las 512 instrucciones... ¿por qué crear una Flash tan pobre en la que se deban borrar tantos bytes para sólo grabar menos bytes? Como comentaba arriba, ya ando apretado en ROM y la eeprom externa será una solución más limpia.

Así, si quiero meter imágenes más grandes en las páginas web, aprovecho la ROM sobrante. Ahora mismo estoy usando miniaturas de 140x80 pixeles que no rebasan los 2kB.

Queda entonces publicada más info para atacar a la ROM interna del PIC24. Gracias de nuevo Manwenwe.

Desconectado manwenwe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2211
Re: Grabar y leer variable en ROM interna, PIC24, C30
« Respuesta #10 en: 16 de Octubre de 2010, 14:43:39 »
Así, si quiero meter imágenes más grandes en las páginas web, aprovecho la ROM sobrante. Ahora mismo estoy usando miniaturas de 140x80 pixeles que no rebasan los 2kB.

A mi me pasa idem de idem con los bmp que utilizo con la librería gráfica: te comes los 512KB  de un PIC32 en un abrir y cerrar de ojos. Y como las funciones de decodificación de jpg y gif no andan del todo bien al final toca utilizar una flash externa; lo que tp es una gran solución porque el PMP es bastante lento... en fin, la pescadilla que se muerde la cola...nve

Expuse una idea que no he probado pero sin duda lo mejor es la solución de la EEPROM. En el último proyecto con LCD he dejado de lado el invento de la FLASH para guardar el offset del TouchScreen más que nada porque cada vez que depuras/reprogramas el PIC se borra toda la FLASH y te toca volver a calibrar el Touch... un por saco increible. Ahora ando liado intentando comunicarme por SPI con una 25AA010 utilizando la librería para 25LC256...

Bueno dejo de contar historietas.... jejej Saludos.
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Re: Grabar y leer variable en ROM interna, PIC24, C30
« Respuesta #11 en: 16 de Octubre de 2010, 19:56:05 »
Hola Mig, casi todos los micros con Flash tienen esta limitación, en si la limitación es por la propia Flash, se programa por byte pero se borra por páginas.

Saludos !

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Grabar y leer variable en ROM interna, PIC24, C30
« Respuesta #12 en: 17 de Octubre de 2010, 10:58:19 »
Hola Mig, casi todos los micros con Flash tienen esta limitación, en si la limitación es por la propia Flash, se programa por byte pero se borra por páginas.

Saludos !

Efectivamente Richi, mi inconformidad es que los PIC18 requieren menos bytes de borrado que los PIC24.  :(

Citar
6.4 Erasing Flash Program Memory
The minimum erase block is 32 words or 64 bytes. Only
through the use of an external programmer, or through
ICSP control, can larger blocks of program memory be
Bulk Erased. Word Erase in the Flash array is not
supported.

Un PIC18 puede borrar 64 bytes como mínimo y el PIC24 borra 1536 bytes como mínimo. Quién sabe por qué el gran cambio que desencadena en un desperdicio de ROM en ciertas aplicaciones como la mía.
« Última modificación: 17 de Octubre de 2010, 11:08:33 por migsantiago »

Desconectado manwenwe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2211
Re: Grabar y leer variable en ROM interna, PIC24, C30
« Respuesta #13 en: 17 de Octubre de 2010, 12:08:50 »
Un PIC18 puede borrar 64 bytes como mínimo y el PIC24 borra 1536 bytes como mínimo. Quién sabe por qué el gran cambio que desencadena en un desperdicio de ROM en ciertas aplicaciones como la mía.

Creo que esto se deberá a que el direccionamiento es distinto en cada arquitectura: en PIC18 hay bloques de bytes y en PIC24 bloques de "rows" de instrucciones... vamos quien diseño esta parte del micro pensó que con borrar de bloque en bloque ya era suficiente... supongo que pensando en que si programas secuencialmente cuantas más operaciones de borrado ejecutes más relentizas el proceso...

En cualquier caso no es menos cierto que eliminando la EEPROM de casi todos los micros más modernos han fastidiado un poco al personal. De hecho no les costaría nada habilitar un pequeño bloque de FLASH extra (p.e. 1KB) para configuración. Al final y al cabo la diferencia entre un PIC24 con 128KB de ROM y otro con 16KB es que  en el segundo "o no han dibujado" todas las celdas de memoria o simplemente "han capado" el acceso a parte de ella... porque fabricarlo cuesta lo mismo: pólitica de ventas pura y dura. Supongo que tb pensarán que si te dan FLASH para config... la gente deja de comprarles chips EEPROM...

Todo especulaciones ;-)
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Grabar y leer variable en ROM interna, PIC24, C30
« Respuesta #14 en: 17 de Octubre de 2010, 12:43:15 »
 :D :D

Pues sí, nos obligan a comprar EEPROMs  :D

De veras que la Data EEPROM hace falta. Podría elegir el PIC24 que sigue en la familia, pero ya es SMD y como premisa del proyecto no debo usar esos componentes :S