C18 RAM c-string - Sin copia

1

En mi compilador C18 (PIC, PIC18F66K22) El siguiente código:

char *message = "Test";

Conduce a una cadena vacía. Es porque "Test" se guardaría en la ROM, aprendí que por las malas ...

Pero creo que es válido C para hacer char *message = "Test"; , por lo que C18 no cumple con el estándar C o ¿cómo podría describirlo mejor ?

¿Existe una forma sencilla (sin copiar de la memoria RAM a la ROM o usando sprintf para poner el texto de la ROM en una variable de la RAM) para especificar que el texto debe ser RAM ? Lo intenté:

ram char *message;
message = (ram char *)"Test";

Sin éxito.

    
pregunta Paul

3 respuestas

3

En el compilador HiTech C, se presumirá que un char * apunta a RAM; un const char* será capaz de acceder a RAM o ROM. No estoy seguro de que esa convención haya seguido a otros compiladores, pero es un enfoque útil y práctico.

    
respondido por el supercat
4

No conduce a una cadena vacía, es solo que el contexto en el que está utilizando la cadena es incorrecto.

Con los chips PIC más pequeños y, de hecho, con la mayoría de los chips de arquitectura de Harvard, hay dos rangos de direcciones de memoria distintos: la RAM y los espacios de direcciones ROM. Ambos espacios de direcciones tienen los mismos números de direcciones, por lo que puede resultar confuso si no estás seguro de lo que estás haciendo.

Para ilustrar, su cadena podría estar en la dirección 100. Ahora, ¿es esa la dirección RAM 100 o la dirección ROM 100? Ambos son la dirección 100, pero cada uno necesita instrucciones diferentes para llegar a ellos.

Por supuesto, usar una función que lea la dirección RAM 100 no devolverá los mismos datos que una función que lee la dirección 100 de la ROM, por lo que su cadena parecerá estar vacía, o no tendrá sentido.

C18 coloca automáticamente todas las constantes de cadena en la ROM:

  

El uso principal de los datos ubicados en la memoria del programa es para cadenas estáticas. En mantenimiento   Con esto, MPLAB C18 coloca automáticamente todas las constantes de cadena en la memoria del programa.   Este tipo de constante de cadena es “array de char ubicado en la memoria del programa”, (const   rom char []). La sección .stringtable es un romdata (ver Sección 2.9.1   "#Pragma sectiontype") sección que contiene todas las cadenas constantes.

     

Debido al hecho de que las cadenas constantes se mantienen en la memoria del programa, hay múltiples   Versiones de las funciones estándar que tratan con cadenas. Por ejemplo, el strcpy   La función tiene cuatro variantes, lo que permite la copia de una cadena hacia y desde los datos y   memoria del programa

Por lo tanto, debe asegurarse de utilizar las funciones correctas para acceder a la ROM y no a la RAM.

Las cadenas deben pasarse a las funciones de la manera correcta para garantizar que se acceda con el código correcto. Todos los parámetros de cadena deben ser:

static const rom char *

La mayoría de las funciones de cadena estándar tienen variantes adicionales, que terminan en pgm2ram , ram2pgm o pgm2pgm . Aquellos que necesitan solo un parámetro tienen el sufijo pgm para el acceso basado en ROM.

La familia de funciones printf tiene el parámetro adicional "% S" para cadenas basadas en ROM (a diferencia de "% s" para cadenas basadas en RAM).

    
respondido por el Majenko
3

El problema es una combinación de estos factores:

  1. El lenguaje C fue pensado para las máquinas de Von Neuman.

  2. El PIC 18 no es una máquina de von Neuman.

  3. Usted está esperando ciegamente que un compilador para un lenguaje que no sea adecuado para su máquina simplemente lo arregle todo de acuerdo con las reglas que no puede aplicar a la arquitectura del hardware.

Este es el caso del póster de por qué necesita realmente saber algo sobre la arquitectura de la máquina cuando está en un sistema pequeño con recursos limitados, especialmente uno en el que el lenguaje nunca fue diseñado para admitir.

El PIC 18 es una arquitectura de Harvard, lo que significa que tiene memorias físicas separadas para el programa y los datos. En el caso de PIC 18, la memoria del programa se organiza en palabras de 16 bits y se direcciona como bytes con direcciones de 20 bits. La memoria de datos es bytes con direcciones de 12 bits, organizados en bancos de 256 bytes cada uno. En algunos PIC 18, también hay EEPROM en otro espacio de direcciones.

El lenguaje C solo tiene el concepto de punteros o direcciones en un solo espacio de direcciones. Por lo tanto, cualquier implementación de C útil en un PIC 18 no puede seguir el estándar de la letra. Por supuesto, todo esto está bien documentado en el manual C18. Debe leer el manual .

En este caso, tiene una confusión entre un puntero a una cadena en la memoria del programa y la dirección de una cadena en la RAM. Como indica claramente el manual C18, e incluso una comprensión superficial de la arquitectura lo llevaría a sospechar (y luego seguir leyendo el manual, o curso), coloca constantes de cadena en la memoria del programa.

Por lo tanto, la primera línea que muestra está creando la variable "mensaje", que se inicializará al inicio con la dirección de la memoria del programa donde quiera que el enlazador ponga la cadena constante "Prueba". Por supuesto, esto no va a producir el resultado esperado si luego intenta usar el mensaje como un puntero a una cadena en la RAM. Una vez más, debe saber realmente lo que está haciendo en sistemas tan pequeños con recursos limitados.

    
respondido por el Olin Lathrop

Lea otras preguntas en las etiquetas