GOTO una dirección específica en el compilador HI-TECH C PIC18F

3

Estoy intentando saltar a una dirección específica en el compilador HI-TECH y la dirección se da de forma dinámica.

Intenté usar la función asm() pero parece que el argumento debe ser un carácter constante []. ¿Hay otra solución para saltar a una dirección usando goto u otra función como goto_address(address) en el compilador CCS?

He intentado esto:

long address = 0xA20;
char addr[15];
sprintf(addr, "goto %s", address)
asm(addr); // Here argument error.

Gracias.

    
pregunta jaspher

4 respuestas

3

Este es el tipo de cosa que se hace más fácilmente en ensamblador.

Si necesita hacer esto con regularidad, puede crear una subrutina de ensamblador que siga las convenciones de vinculación de la subrutina C. Esto tomaría un argumento de 24 bits que es la dirección a la que saltar. Recuerde que la subrutina extraiga su propia dirección de retorno de la pila antes de realizar el salto. La subrutina escribiría los bits 23:16 de la dirección a PCLATU, los bits 15: 8 a PCLATH y luego los bits 7: 0 a PCL. Esa última instrucción realmente hará el salto, por lo que todo lo demás debe configurarse correctamente antes de escribir en PCL.

    
respondido por el Olin Lathrop
2

Se supone que la directiva asm () que estás tratando de usar se usa para "incrustar" una única instrucción de ensamblador con el formato correcto, escrita como una cadena de caracteres de estilo C.

En otras palabras, algo como asm ("BCF 0,3");

El compilador mira esa cadena durante el tiempo de compilación e inserta esa instrucción exacta del ensamblador en su código, por eso le pide un carácter constante [], tiene que ser una cadena constante con el formato correcto cuando se compila el código. Entonces, lo que intentas hacer al construir la cadena con sprintf durante la ejecución nunca podrá funcionar.

Además, si observa la descripción de las instrucciones del ensamblador GOTO para su PIC, verá que toma un valor fijo constante como la dirección para saltar. La dirección forma parte de la instrucción en el momento de la compilación y no puede cambiarla sobre la marcha durante la ejecución.

Lo que estás tratando de hacer podría servir mejor utilizando los punteros de función. Consulte Diseño de codificación C: ¿punteros a funciones? . Pero deberás tener cuidado al administrar & no destrozando la pila.

    
respondido por el brhans
2

Estás muy confundido entre lo que sucede en el tiempo de compilación y lo que sucede en el tiempo de ejecución . El argumento para asm() debe ser una cadena que esté completamente especificada en el momento de la compilación. Si el valor de la dirección solo se conoce en el tiempo de ejecución, debe crear una secuencia de instrucciones que puedan tomar un valor de tiempo de ejecución y copiarlo en la PC.

Una de las maneras más directas de hacer esto en la mayoría de las arquitecturas, y creo que funcionará en PIC18, es PUSH el valor de la dirección en la pila de retorno y luego ejecutar una instrucción RETURN .

    
respondido por el Dave Tweed
2

Para hacer un goto computado puedes cambiar el contador del programa.

En el PIC18F4550 el contador del programa está compuesto por 3 registros, PCU (bits 20:16), PCH (bits 15: 8) y PCL (bits 7: 0).

Solo el PCL puede escribirse directamente. Para cambiar el valor de todos los registros simultáneamente, debe escribir en los registros PCLATU, PCLATH y PCL como se explica en la sección 5.1.1 de la hoja de datos.

Primero debe escribir los bits más significativos en PCLATU y PCLATH, luego escribir los bits menos significativos en PCL, esto también copia PCLATU y PCLATH en PCU y PCH respectivamente.

    
respondido por el Bruno Ferreira

Lea otras preguntas en las etiquetas