TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Thulsa Doom en 11 de Junio de 2015, 09:37:10
-
Hola a todos.
Antes de nada he de decir que estoy programando en C18 y un PIC18F2455 pero puedo cambiar a otro modelo de PIC sin problemas, resulta que tengo que hacer un o crear un array de 101 posiciones y al crearlo el compilador me da un error de tamaño demasiado grande.
Probé a crear el array en la ROM, de esta manera rom doule array[101]; (Tiene que ser double) lo cree global porque en local no me deja. intento escribir en el array desde una función pero no escribe nada.
He probado a crearlo con near y fast pero obtengo los mismos resultados.
¿Hay alguna manera o menor dicho, cuál es la manera correcta de crearlo y de escribir/leer en el?
La verdad que lo de crear variables y arrays en ROM no lo tengo muy claro a ver si alguien me puede echar una mano
-
No puedes crear un array de lectura/escritura en flash, porque la flash no se puede escribir por direcciones individuales sin un borrado previo de una página completa. Además el borrado y escritura requiere el uso de unos registros y funciones especiales, no se puede tratar como cualquier variable.
Si no tienes suficiente espacio en RAM, tendrás que cambiar a un PIC con más memoria.
-
Ahora si lo entiendo, ¿entonces si ponemos ROM a una variable/array creamos ese objeto en la memoria flash del micro?.
-
Bueno, que yo sepa solo hay 3 tipos de memoria en los micros PIC, la RAM, la Flash y la Eprom. Entiendo que cuando te refieres a la ROM, en realidad te refieres a la Flash, porque la ROM solo es de lectura y salvo que todavía existan micros PIC OTP, el programa se almacena en Flash. En un micro OTP, ni siquiera se podría borrar o grabar en la Rom, desde el programa.
Solo puedes leer y grabar con comodidad en la Ram y la Eprom, en la eprom no tengo experiencia porque solo uso PIC32 y estos no tienen eprom.
-
Ok, la eeprom es inviable utilizarla ya que como es un array que se va ha estar escribiendo con frecuencia se rompería al tiempo y eso no me interesa, pues no queda otra si no cambiar de micro :(
-
Ok, la eeprom es inviable utilizarla ya que como es un array que se va ha estar escribiendo con frecuencia se rompería al tiempo y eso no me interesa, pues no queda otra si no cambiar de micro :(
Y la flash igual... asi como bien decis si es algo que tenes que estar modificando constantemente , entonces mas RAM, o una RAM externa.
-
¿Y eso de una ram externa cómo sería?,
Me ha parecido leer que el micro PIC18F87J50 tiene implementado unos puertos para ese menester, ¿estoy en lo correcto? y en cual caso si alguien puede explicar algo al respecto.....
-
si quieres ram externa te vas a tener que buscar un micro bastante mas tocho y olvidate de PIC, ademas implementar una ram en un PCB no es facil por temas de rotado, tienes que tener control de impedancias y pares diferenciales.
puedes usar ram externa pero por quadspi eso es mas facil pero tendras que buscaar de nuevo un micro mas tocho que tenga quadspi, algunos de PIC tienen creo.
hace un tiempo se ideo un tipo de memoria llamada MRAM (ram magnetica o magnetoresistiva) ideada para las estaciones y transbordadores espaciales, ya que esta memoria no se ve afectada por las radiaciones y evitaban con esto el problema de borrado de la memoria en los satelites.
esta memoria esta llegando ahora al mercado con capacidades pequeñas, pero ya estan aqui, una buena mejora con respecto a las ram normales es que son NO VOLATILES, quizá esto te sirva para tu aplicacion. Empresas como por ejemplo sagitron las vende, pero no recuerdo si habia formato spi y I2C.
un saludo.
-
RAM en PCB depende de la velocidad que quieras tener.
Microchip vende memorias SRAM y NVSRAM (podes mantener los datos con bateria ) de hasta 20Mhz, y se puede acceder con el SPI.
Esto quiere decir que para leer un dato son 24 ciclos de reloj para el setup el puntero de memoria (instruccion + 16bit adress) y luego de ahi en adelante son 8 ciclos de reloj por cada dato, si los lees secuencialemnte te ahorras esos 24ciclos al comienzo. El tema es que tu SPI deberia llegar a 20Mhz.
http://www.microchip.com/pagehandler/en-us/products/memory/serialSRAM/home.html
Con lo cual tal ves necesites del array copiarlo al PIC, una parte mientras la otra se recibe si es que la usas en orden..
si es un acceso aleatorio si vas a necesitar mas velocidad podes buscar algun otro con acceso paralelo o como dijeron convenga mas cambiar de micro y te olvidas de todos esos problemas. Lo que lo hace mas simple y menos componentes y tal ves mas economico
Mi pregunta, ahora que veo lo que ocupa es: por que no directamente en la RAM? Tanto ocupa de RAM tu programa?
101 lugares de 24 bits, 2Kbits o 303 bytes
El 18F2455 tiene 2048 bytes de RAM..., 1024 que no son usados por el USB, supongamos que usas el USB y este te utiliza esos otros 1024 bytes (creo que no se puede cambiar), te quedarian 721 bytes , No es mucho pero algo es algo :)
Si no queres cambiar mucho tenes el PIC18F25J50 tiene un poco mas de Flash (de 24k a 32k), tiene 3776 bytes de RAM (aunque crece la RAM del USB no se como se puede cambiar esto), y es mas barato que el modelo viejo que pasaste
http://ww1.microchip.com/downloads/en/DeviceDoc/39931d.pdf
Creo que es compatible pin a pin si se remapea correctamente. Al menos todos los puertos, pines de alimentacion, USB, MCLR estan en el mismo lugar. con respecto al PIC18F2455
-
Hola de nuevo, un poco complicado lo de una ram externa :?
Y haciendo pruebas he visto que algo raro pasa, he probado hasta con un PIC18F67J50 y me pasa lo mismo que con el PIC18F2455 y PIC18F4620, el array que quiero hacer es global y sería como este.
double array[101];
Lo máximo que me deja hacer es uno como este:
double array[42];
Y eso pasa en todos los micros, el tamaño máximo es de [42].
Al compilar el código con esta última declaración de array, lo que veo es que tiene es espacio de sobra.
El error que me da dice algo como esto:
Error - section '.udata_PID_AutoTune_v0.o' can not fit the section. Section '.udata_PID_AutoTune_v0.o' length=0x000001eb
¿Será un problema de limitación del compilador?, ¿Cómo puedo crear un array de ese tamaño?
-
Hola thulsa doom
yo tuve muchos problemas de memoria al hacer este proyecto, http://www.todopic.com.ar/foros/index.php?topic=44114.0 ya que el dibujo se metia en una array y este se encargaba de dibujarlo, era una matriz de [48]x[254] = 12192 variables, y tuve que hacerme una matriz software para guardar tamaño bit, por que ni de coña entraba todo en la memoria con tamaño byte.
que quiero decir con esto, que tus variables son double, eso se va a comer la memoria que da gusto, y lo de que veas una region libre en la memoria, puede ser por varias cosas, puede ser que el compilador hasta que no inicializas esas variables no te come la memoria, ya que simplemente esta reservando ese espacio, y al mostrartelo te lo muestra vacio pero en uso.
puede ser que tu linker scrip este dando ese margen por que es un espacio reservado para algo, o viniendo de microchip un fallo que seria bastante comun.
para ese nivel de memoria vas a tener que colocar una memoria externa, las svram y las sram suelen ser muy pequeñas y quiza tampoco sirvan para tu aplicacion mira cuando ocupa un double de tu compilador y calcula si te entraria en un Mbit (cuidado bit, no byte) si no entra, me temo que deberas usar una flash, o cambiar de estrategia, si usas una flash puedes hacer cosas para no grabar tan a menudo, puedes tomar 10 posiciones de ese vector para trabajar con el en la ram del micro y una vez terminado grabarlo, cosas que minimicen la grabación en flash
un saludo
-
Deberías de leerte bien el manual sobre el Linker Script, porque si te queda espacio libre puede ser cuestión de organizarlo correctamente si un array supera cierto tamaño.
Googleando un poco:
http://www.microchip.com/forums/m120538.aspx
-
Pues creo que ya he solucionado el tema.
Resulta que la memoria está dividida en bloques de 256 bytes y por eso no entraba el array, hay una manera de redimensionar la memoria del pic, para ello hay que editar el archivo linker del pic.
según la guía MPLAB_C18_Getting_Started_51295f.pdf en la sección FAQ-10 How do I create a large object in data memory (> 256 bytes)? te dice como crear un bloque donde contener ese array y como trabajar con el una vez creado.
FAQ-10 How do I create a large object in data memory (> 256 bytes)?
By default, MPLAB C18 assumes that an object will not cross a bank boundary. The
following steps are required to safely use an object that is larger than 256 bytes:
1. The object must be allocated into its own section using the #pragma idataor
#pragma udatadirective:
#pragma udata buffer_scn
static char buffer[0x180];
#pragma udata
2. Accesses to the object must be done via a pointer:
char * buf_ptr = &buffer[0];
...
// examples of use
buf_ptr[5] = 10;
if (buf_ptr[275] > 127)
...
3. A region that spans multiple banks must be created in the linker script:
- Linker script before modification:
DATABANK NAME=gpr2 START=0x200 END=0x2FF
DATABANK NAME=gpr3 START=0x300 END=0x3FF
- Linker script after modification:
DATABANK NAME=big START=0x200 END=0x37F PROTECTED
DATABANK NAME=gpr3 START=0x380 END=0x3FF
4. The object’s section (created in Step 1) must be assigned into the new region
(created in Step 3) by adding a SECTIONdirective to the linker script:
SECTION NAME=buffer_scn RAM=big
El micro que estoy utilizando para hacer estas pruebas es el PIC18F2455 y de esta manera quedaría el linker para un array de 404bytes
// File: 18f2455_g.lkr
// Generic linker script for the PIC18F2455 processor
LIBPATH .
#IFDEF _CRUNTIME
#IFDEF _EXTENDEDMODE
FILES c018i_e.o
FILES clib_e.lib
FILES p18f2455_e.lib
#ELSE
FILES c018i.o
FILES clib.lib
FILES p18f2455.lib
#FI
#FI
CODEPAGE NAME=page START=0x0 END=0x5FFF
CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED
CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED
CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED
CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED
#IFDEF _EXTENDEDMODE
DATABANK NAME=gpre START=0x0 END=0x5F
#ELSE
ACCESSBANK NAME=accessram START=0x0 END=0x5F
#FI
DATABANK NAME=gpr0 START=0x60 END=0xFF
DATABANK NAME=gpr1 START=0x100 END=0x1FF
DATABANK NAME=big START=0x200 END=0x394 PROTECTED
DATABANK NAME=gpr3 START=0x395 END=0x3FF
DATABANK NAME=gpr4 START=0x400 END=0x4FF
DATABANK NAME=gpr5 START=0x500 END=0x5FF
DATABANK NAME=gpr6 START=0x600 END=0x6FF
DATABANK NAME=gpr7 START=0x700 END=0x7FF
ACCESSBANK NAME=accesssfr START=0xF60 END=0xFFF PROTECTED
SECTION NAME=buffer_scn RAM=big
#IFDEF _CRUNTIME
SECTION NAME=CONFIG ROM=config
#IFDEF _DEBUGSTACK
STACK SIZE=0x194 RAM=big
#ELSE
STACK SIZE=0x6A RAM=gpr3
#FI
#FI
Lo que está en rojo es lo que he modificado, ahora ya no me da error y si que guarda y lee los valores del array.
-
enorabuena, has resuelto tu problema y de una manera muy correcta ((:-)) ((:-))
-
Habiendo información todo es fácil, gracias a ustedes, sin ustedes me sería imposible haber llegado hasta donde he llegado en conocimientos.
Otra pregunta, me ha parecido leer que los micros que tiene USB se reserva una porción de memoria para el manejo del USB, ¿viendo el Linker se puede saber a que corresponde cada banco o para que se reserva cada banco?
-
Eso lo desconocía, el linker sólo lo he tocado para temas de memoria o bootloader, para el USB siempre he usado las librerías y no he tenido que modificar nada del linker scrip, pero quizás se pueda tocar para algo de lo que mencionas no lo se.
Un saludo
-
Otra pregunta, me ha parecido leer que los micros que tiene USB se reserva una porción de memoria para el manejo del USB, ¿viendo el Linker se puede saber a que corresponde cada banco o para que se reserva cada banco?
No del linker no.
Tenes que leer el datasheet, ahi habla que el usuario NO debe tocar el banco 4 (0x400 a 0x4FF), ese banco tiene una porcion para tener tablas de los descriptores:
Bank 4 (400h through 4FFh) is used specifically for endpoint buffer control, while Banks 5 through 7 are available for USB data. Depending on the type of buffering being used, all but 8 bytes of Bank 4 may also be available for use as USB buffer space.
La unica forma que me parecio para reservar memoria para el usuario y no para el USB, es crear una entrada en esa tabla de descriptores ( 4 registros ) que indican inicio, largo y la propiedad de ese espacio.
Pero luego en el programa que use el USB hay que limitarlo para que no lo "pise" a ese descriptor.
Ya que ese pedazo de memoria puede ser accedido tanto por el USB como el micro y tiene un semaforo ( 1 bit ) de esa tabla para indicar a quien pertenece.
-
Vaya, como siempre vuelvo a cometer el mismo error, ¡¡NO LEER EL DATSHEET!!, pido disculpas por ello,
Gracias por la información y la ayuda, la verdad que pudiendo redimensionar la memoria, le da a un pic mucha más flexibilidad de la que pensaba que tenía.
gracias de nuevo :-/ :-/