Autor Tema: Pasar Constante String por parametro CCS  (Leído 13748 veces)

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

Desconectado Dancrazy

  • PIC16
  • ***
  • Mensajes: 134
Pasar Constante String por parametro CCS
« en: 26 de Diciembre de 2007, 16:42:10 »
Hola a Todos  (y Feliz Navidad)

Voy al grano, he encontrado un problemilla con mi querido Compilador CCS, que no doy con la manera de resolver...
Segun la ayuda, el ccs NO pasa Constantes string como Parametro...  Es decir, lo siguiente (por ejemplo) es ilegal en este compilador:

Código: [Seleccionar]
<Includes, defines y otros>

void UsaTexto(char Texto[16],int8 Posicion)
{
     <operaciones>
}

void main()
{
  <operaciones>
  UsaTexto("Una Prueba",1);
 <Operaciones>
}

eso es legal en otros compiladores.... y usando punteros..  ( es decir: void UsaTexto(char *Texto,int8 Posicion) )
pero aqui no...
incluso probe esto que encontre en el fondo del baúl

#device PASS_STRINGS=IN_RAM
 
pero ni aun asi funciona....

hasta el momento me he tenido que contentar con

Código: [Seleccionar]
<Includes, defines y otros>

void UsaTexto(char Texto[16],int8 Posicion)
{
     <operaciones>
}
void main()
{
  char Mensaje[16];
  <operaciones>
  strcpy(Mensaje,"un texto");
  UsaTexto(Mensaje,1);

alguien sabe si hay algun truco para hacer esto?
alguien sabe por qué los punteros fallan en este caso?

gracias a todos por su atencion y felices fiestas....

PS: ah! uso el CCS PIC C version 4...
Daniel 
Caracas, Venezuela 

-----------------

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Pasar Constante String por parametro CCS
« Respuesta #1 en: 26 de Diciembre de 2007, 18:55:46 »
Hasta lo que yo sé la gente de CCs todavía no a solucionado el tema de pasar un puntero a una constante. Así que por ahora hay que hacerlo de la segunda forma que presentado, copiarlo sobre RAM y pasarle el puntero de tu variable.  :?
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado marcegoncba

  • PIC10
  • *
  • Mensajes: 17
Re: Pasar Constante String por parametro CCS
« Respuesta #2 en: 23 de Enero de 2008, 14:59:16 »
Antes que nada saludos y espero que lo siguiente los ayude a manejar vectores de string en ROM usando el compilador CCS. De acuerdo a ellos (CCS) y cito al propio fabricante:
Citar
/*
A more complex example that creates an array of pointers to constant strings:
*/
ROM char *strings[] =
{
   "HELLO",
   "WORLD",
   "CONST",
   "STRINGS"
};

/*
Access the above const pointers
*/
ROM char *ptr;
while (i = 0; i < (sizeof(strings) / sizeof(const char *)); i++)
{
   ptr = strings;
   printf("%s", ptr);
}
que lo pueden leer aquí, es posible guardar vectores de constantes de longitud aleatoria y luego poder leerlas dentro del código. Por supuesto quién lo pueda hacer con la explicación que dan en lo citado merecería un premio.
Lo siguiente tiene la limitación de que solo es aplicable a controladores donde se permita el uso de la función "read_program_memory()".
Basandomé en el código enviado al foro de CCS (ver código) y aunque este no compile (tiene errores menores) y tampoco funcione (asumo que el autor copió un código aún no probado) si dá la punta del ovillo de como el compilador maneja los vectores de constantes. Después de varias horas de pelea pude determinar como los diseñadores de CCS han resuelto el tema de ubicar en la memoria ROM un array con strings de longitudes arbitrarias, es muy ingenioso pero desgraciadamente para nosotros no está bien documentado.
Asumiendo el array
Código: [Seleccionar]
ROM char *strings[] =
{
   "HELLO",
   "WORLD",
   "CONST",
   "STRINGS"
};

&strings nos dá una valor de 32 bits (para los 18F) que es la posición de la memoria ROM donde comienza el vector "strings" pero al comienzo no está el contenido del vector en sí, si no los offsets de 16 bits que hay que sumarle a &strings para encontrar  la dirección exacta donde empieza el miembro del vector que queremos. Por esto la función original que fué publicada en el foro de CCS necesita las siguientes modificaciones para que funcione
Código: [Seleccionar]
void MsgSend(int32 msgAddress, int language, int align){
 int buffer[LCD_TYPE_WIDTH + 1]; //Temp RAM storage
 //Actual address of the text in the chosen language:
 int32 languageMsgAddress = 0; //si no se hace 0 funciona en el simulador pero no en el micro real
 int i, msgLength = 0, startPosition;

//Read the CCS compiled address of our sub-string
//read_program_memory(address + (language * 2), &languageMsgAddress, 2);

read_program_memory(msgAddress + (language * 2), &languageMsgAddress, 2);
//la variable languageMsgAddress ahora tiene el offset del vector
//por lo que hay que sumarle la dirección de memoria original
languageMsgAddress += msgAddress;
 
//Copy the string into the temporary RAM buffer, for formatting
read_program_memory(languageMsgAddress, buffer, LCD_TYPE_WIDTH);
for (i = 0; i < LCD_TYPE_WIDTH; i++) { //Fills with spaces
bufferLcdFinal[i] = ' ';
}
msgLength = strlen(buffer);
 
switch (align) { //Picks the correct start position for alignment
case ALIGN_CENTER: startPosition = (LCD_TYPE_WIDTH - msgLength) / 2; break;
case ALIGN_LEFT:   startPosition = 0; break;
case ALIGN_RIGHT:  startPosition = LCD_TYPE_WIDTH - msgLength; break;
  }

//We copy the message into the final buffer at the correct position.
//Note that we use strncpy instead of strcpy to avoid writing
//a terminating 0x00 at the end.
strncpy(bufferLcdFinal + startPosition, buffer, msgLength);
 
//Here, bufferLcdFinal is ready to be sent to your display device.
}
Espero haber sido claro, falta determinar si para los 16F en que la dirección es de 16bits el offset es de 8 bits pero eso se lo dejo para alguno de Uds.
Saludos desde Córdoba, Argentina

Marcelo

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Pasar Constante String por parametro CCS
« Respuesta #3 en: 23 de Enero de 2008, 15:03:18 »
Seguro que será muy útil tu magnífica explicación Marcelo. Muchas gracias

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Pasar Constante String por parametro CCS
« Respuesta #4 en: 23 de Enero de 2008, 16:22:54 »
Buenisimo aporte Marcelo !! :-/

felicitaciones !! :lol:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Pasar Constante String por parametro CCS
« Respuesta #5 en: 23 de Enero de 2008, 18:16:13 »
Muy buen aporte Marcelo. Voy a probarlo y te cuento.  :mrgreen:
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado Dancrazy

  • PIC16
  • ***
  • Mensajes: 134
Re: Pasar Constante String por parametro CCS
« Respuesta #6 en: 23 de Enero de 2008, 20:30:09 »
gracias por el aporte,

aun lo estoy digiriendo, jeje...

tengo una pregunta mas, que no se si sera a proposito del tema...

mi pregunta es basicamente de CCS

el tipo char  (un byte) es basicamente distinto a el tipo int8 (1 byte). en todo lo que he programado no habia visto algo asi, y siempre char era igual a cualquier tipo de longitud equivalente....  demonios, esto me plantea un terrible problema, pues a veces lo que almaceno cambia segun como defina....

por ejemplo, me paso esto:
Código: [Seleccionar]
#use rs232(baud=9600,RCV=PIN_C7, XMIT=PIN_C6,Parity=N,Bits=8)
//Variable Global
int8 Enviado[20];
//Procedimiento
void Comando(char Temporal[20])
{
      int8 i;
      Enviado[0]=0x42;
      Enviado[1]=0x00;
      Enviado[2]=strlen(Temporal);
      Enviado[3]=8F;
      strcpy(&Enviado[4],&Temporal[0]);
      Enviado[strlen(Temporal)+4]=0xA4;
      for(i=0;i<=strlen(Temporal)+5;i++)
         putc(Enviado[i]);
}

void main()
{
char Mensaje[18];
strcpy(Mensaje,"BIENVENIDOS");
Comando(Mensaje);
}
si observan bien, lo que hago es que en un arreglo char copio una cadena de caracteres, llamo un procedimiento Comando, en el cual coloco una cabecera, y la cadena, y la envio serialmente... entonces estoy enviando
(en hexadecimal)   
        --->42  00   11   8F   42  49  45  4E  56  45  4E  49  44  4F   53  A4
                                         B    I     E   N    V   E    N     I    D   O    S

a que no adivinan qué recibo?

              42  00   11  8F    2A  8D  C4  D5  15  4D  08  A0  92  07  55  A4

no le veo el sentido.  El "Bienvenidos" se cambio totalmente, pero el resto esta correcto....  y ha pasado en varias formas distintas

alguna idea?
« Última modificación: 23 de Enero de 2008, 20:43:46 por Dancrazy »
Daniel 
Caracas, Venezuela 

-----------------

Desconectado marcegoncba

  • PIC10
  • *
  • Mensajes: 17
Re: Pasar Constante String por parametro CCS
« Respuesta #7 en: 24 de Enero de 2008, 10:17:46 »
Daniel
Más allá de que tu código me parece que derrocha muchos recursos de memoria, te adjunto el código que compilado con el CCS 4.057 y simulado en el MPLAB 7.62 funciona, probalo y fijate.

Saludos
Marcelo

Código: [Seleccionar]
#use rs232(baud=9600,RCV=PIN_C7, XMIT=PIN_C6,Parity=N,Bits=8)
//Variable Global
int8 Enviado[20];
//Procedimiento
void Comando(char Temporal[20]){
int8 i;

Enviado[0]=0x42;
Enviado[1]=0x00;
Enviado[2]=strlen(Temporal);
Enviado[3]=0x8F;
strcpy(&Enviado[4],&Temporal[0]);
Enviado[strlen(Temporal)+4]=0xA4;
//Hasta acá todo bien, ahora yo lo cambiaría de la
//siguiente manera
for(i=0;i<sizeof(Enviado);i++){
    putc(Enviado[i]);
    if(Enviado[i] == 0xA4) break;
    }
    //asume que se vá a enviar todo el array, pero cuando
    //encuentra el carácter 0xA4 (que vos lo agregas al final
    //de la trama) finaliza la acción

//for(i=0;i<=strlen(Temporal)+5;i++)
    //     putc(Enviado[i]);
}

void main(){
char Mensaje[18];

strcpy(Mensaje,"BIENVENIDOS");
Comando(Mensaje);
}

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Pasar Constante String por parametro CCS
« Respuesta #8 en: 24 de Enero de 2008, 17:58:02 »
¿Seguro que funciona? en PROTEUS no funciona.

Desconectado Dancrazy

  • PIC16
  • ***
  • Mensajes: 134
Re: Pasar Constante String por parametro CCS
« Respuesta #9 en: 24 de Enero de 2008, 18:15:10 »
bueno, lo probe en el PIC, claro, con algunas cosas mas....
por alguna razon que desconozco, el sizeof() no funciona, solo transcribe 2 bytes (BI)

este es un ejemplo de los tipos de datos que debo enviar, mas adelante (es ciclico) incluso llega a pasar que

        --->42  00   11   8F   42  49  45  4E  56  45  4E  49  44  4F   53  A4
                                       B    I    E   N    V   E    N     I    D   O   S

recibo

              42  00   01  8F  A4

se tragó el Bienvenidos

(que maleducado ¿no?)  :lol:

el problema es que a veces lo que envio consta de puros bytes y no hay caracteres

pero diablos...  int8 no es igual a char a int, que no es igual que BYTE (en otros compiladores) es solo una posicion de memoria de 8 bits.... ¿no? eso es lo que no me cabe en la cabeza....

« Última modificación: 24 de Enero de 2008, 19:47:25 por Dancrazy »
Daniel 
Caracas, Venezuela 

-----------------

Desconectado Dancrazy

  • PIC16
  • ***
  • Mensajes: 134
Re: Pasar Constante String por parametro CCS
« Respuesta #10 en: 24 de Enero de 2008, 21:00:58 »
si, es seguro...

es un problema de definicion de variables

porque los caracteres que indico manualmente, (y el numero de parametros que voy a enviar) o los envia completos o no envia ninguno... pero eso indica que el procedimiento funciona.  el problema esta en el strcpy()


Repito, ocurre que
-->42  00  0B   2B   80  49  45  4E  56  45  4E  49  44  4F   53  72-->deberia enviar
-->42  00  0B   2B   80  2A  95  C0  DC 15  4C  0C  A0  12  07   72--> Envia 
    |<---correcto----->|<------errado---------------------->|  \
y a veces                                                                            correcto
-->42  00  02   2B   80  EB-->deberia enviar
-->42  00  02   2B   80  EB--> Envia 

en ambos casos la ultima cifra es un checksum y esta bien calculada y el numero de caracteres (la tercera cifra esta bien expresada....  el problema es de paso de parametros...

pueden ser dos cosas, o un error mio, o un bug de ccs
Daniel 
Caracas, Venezuela 

-----------------

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Pasar Constante String por parametro CCS
« Respuesta #11 en: 24 de Enero de 2008, 22:38:42 »

en ambos casos la ultima cifra es un checksum y esta bien calculada y el numero de caracteres (la tercera cifra esta bien expresada....  el problema es de paso de parametros...

pueden ser dos cosas, o un error mio, o un bug de ccs

Que version del CCS utilizas??
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado marcegoncba

  • PIC10
  • *
  • Mensajes: 17
Re: Pasar Constante String por parametro CCS
« Respuesta #12 en: 25 de Enero de 2008, 11:34:07 »
Tanto para pocher como para Dancrazy. Sería muy bueno, como lo sugiere MGLSOFT, que pusieran las versiones de las herramientas que están utilizando (compilador, simulador, etc.) y si no verfiquen aquí si la versión del compilador que están usando no es la fuente de los problemas.

Saludos

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: Pasar Constante String por parametro CCS
« Respuesta #13 en: 25 de Enero de 2008, 11:39:34 »
Dancrazy, hasta donde sé, en C no se pasan los strings por copia sino por referencia.

En C++ si se permite pasar por copia.  Tal vez allí esté tu problema...

Estas queriendo hacer algo que no solo no está permitido sino que además consume enormes recursos en manejo de stack provocando un muy probable desborde.  Como ves, solo te copia los 4 primeros bytes como si de un float de 32 bits se tratase...


Saludos
- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado Dancrazy

  • PIC16
  • ***
  • Mensajes: 134
Re: Pasar Constante String por parametro CCS
« Respuesta #14 en: 25 de Enero de 2008, 12:14:31 »
jejeje,
pido disculpas a los tres...  claro! cada version del CCS tiene problemas resueltos y quizas algun bug...

fijense, tengo
IDE=4.032
PCB=4.032
PCM=4.032
PCH=4.032

pero tambien puedo conseguir que me presten, si es necesario, una anterior la 3.227 que tienen unos amigos...

bueno, creo que a lo mejor maunix da en el clavo... lo que pasa es que yo me acostumbre a programar puntos de venta en C++ y que tienen cerca de 1MByte  de memoria de programa y 1Mbyte o 512 de memoria ram y 64K de flash, y tambien para programas de computadora, y el ambos casos la memoria es "ilimitada" (ojo, lo de ilimitada, es una impresion, que aunque falsa, puede parecer aproximadamente cierta en tales casos, pues es dificil llegar a usarla toda, por muy despilfarrador que se sea) lo que evidentemente, en el PIC no es cierto en absoluto, de hecho, por ello trate de limitar todo el uso a cerca de 100 bytes en los arreglos principales

pense en declarar una estructura, o quiza enumeracion de mensajes para mostrar en pantalla, y luego segun un indice, pasarlos por parametro
Daniel 
Caracas, Venezuela 

-----------------


 

anything