Microchip PIC: ¿Cómo recuperar el contexto guardado en interrupciones o desactivar el guardado automático del contexto?

0

Estoy creando un distribuidor para que los microcontroladores PIC cambien las tareas que guardan sus contextos.

El despachador se activa cuando ocurre una interrupción. El problema es que el compilador que estoy usando (C18 V3.x) guarda / restaura el contexto automáticamente cuando ocurre una interrupción, pero no sé cómo recuperar la información guardada.

Quiero desactivar el guardado automático del contexto y hacerlo por mí mismo, eligiendo solo los registros que quiero guardar.

Parte del código del ISR es:

void isr_dispatcher()
{
    uint8 w_temp, status_temp, bsr_temp;

    INTCONbits.GIE = 0; 

    // save the context
    _asm
        movwf   w_temp, 0
        movff   STATUS_REG, status_temp
        movff   BSR_REG, bsr_temp
    _endasm

    // ...   
}

Cuando se produce una interrupción (desbordamiento de TMR0, en mi caso), isr_dispatcher comienza a ejecutarse. El problema es que el compilador traduce mi isr_dispatcher a este código de ensamblaje:

!void isr_dispatcher()
0x1308: MOVFF FSR2H, PREINC1
0x130A: NOP
0x130C: MOVFF FSR1H, FSR2H
0x130E: NOP
0x1310: MOVFF FSR0, PREINC1
0x1312: NOP
0x1314: MOVFF FSR0H, PREINC1
0x1316: NOP
0x1318: MOVFF TBLPTR, PREINC1
0x131A: NOP
0x131C: MOVFF TBLPTRH, PREINC1
0x131E: NOP
0x1320: MOVFF TABLAT, PREINC1
0x1322: NOP
0x1324: MOVFF PROD, PREINC1
0x1326: NOP
0x1328: MOVFF PRODH, PREINC1
0x132A: NOP
0x132C: MOVFF PCLATH, PREINC1
0x132E: NOP
0x1330: LFSR 0, 0x0
0x1332: NOP
0x1334: MOVLW 0x14
0x1336: DECF WREG, W, ACCESS
0x1338: BNC 0x1340
0x133A: MOVFF POSTINC0, PREINC1
0x133C: NOP
0x133E: BRA 0x1336
0x1340: LFSR 0, 0x14
0x1342: NOP
0x1344: MOVLW 0x7
0x1346: DECF WREG, W, ACCESS
0x1348: BNC 0x1350
0x134A: MOVFF POSTINC0, PREINC1
0x134C: NOP
0x134E: BRA 0x1346
0x1350: MOVF POSTINC1, F, ACCESS
0x1352: MOVFF FSR2, POSTINC1
0x1354: NOP
0x1356: MOVFF FSR1, FSR2
0x1358: NOP
0x135A: MOVLW 0x3
0x135C: ADDWF FSR1, F, ACCESS
!{
!    uint8 w_temp, status_temp, bsr_temp;
!    INTCONbits.GIE = 0; 
0x135E: BCF INTCON, 7, ACCESS
!    // save the context
!    _asm
!        movwf   w_temp, 0
0x1360: MOVWF nova_tarefa, ACCESS
!        movff   STATUS_REG, status_temp
0x1362: MOVFF STATUS, status_temp
0x1364: NOP
!        movff   BSR_REG, bsr_temp
0x1366: MOVFF BSR, bsr_temp
0x1368: NOP
!    _endasm

Como puede ver, el compilador inserta varias instrucciones de ensamblaje antes de mi código original isr_dispatcher. Ojalá el compilador no lo hiciera. Solo para que pudiera guardar el contexto.

    
pregunta

2 respuestas

4

Primero, esto es totalmente inapropiado para escribir en otra cosa que no sea el ensamblador. Jugar con partes del sistema que el compilador cree que está administrando hace un desastre. Realizar actos no naturales en la pila, que es necesario para un conmutador de contexto, califica para lo anterior.

En segundo lugar, ¿realmente desea un sistema de tareas preventivo? He hecho más de 100 proyectos PIC, y la multitarea preventiva no ha sido la respuesta correcta todavía en microcontroladores tan pequeños que realizan funciones dedicadas. La multitarea puede ser una abstracción útil, particularmente cuando se procesa un flujo de comunicación recibido de forma asíncrona. Sin embargo, en los sistemas de recursos limitados pequeños que realizan una función fija, la multitarea cooperativa es casi siempre una mejor opción. Evita por completo la necesidad de "secciones críticas" y otros tipos de exclusión mutua en torno a las estructuras de datos compartidas, ya que los intercambios de tareas solo se producen cuando se realizan.

Mi administrador de tareas cooperativas está disponible de forma gratuita como parte del lanzamiento de las herramientas de desarrollo PIC en enlace . Busque archivos con "tarea" en su nombre en la FUENTE > Directorio PIC dentro del directorio de instalación del software.

Tercero, si está utilizando el desbordamiento del temporizador 0 para desencadenar la interrupción que intercambiará las tareas, es mejor que esté usando un preescalador de tamaño decente. De lo contrario, el intercambio de tareas cada 256 instrucciones hará que el procesador pase la mayor parte del tiempo intercambiando tareas y pocas tareas realmente en ejecución. Tenga en cuenta que dado que un PIC 18 tiene una pila de llamadas de hardware dedicada fija, tiene que copiar realmente los datos de pila existentes en un área de guardado, luego restaurar los nuevos datos de pila desde el área de guardado de la siguiente tarea. Eso lleva ciclos.

    
respondido por el Olin Lathrop
0

Esta respuesta se escribió para una versión anterior de la pregunta. Desde los comentarios a esta respuesta, la intención del OP quedó clara, haciendo que esta respuesta sea inválida.

No me queda del todo claro lo que quieres decir. ¿Desea restaurar el contexto después de procesar el ISR? ¿O quieres acceder al contexto en el ISR?

Si solo quiere restaurarlo en el ISR, puede hacerlo con el comando retfie (Devolver desde interrupción). Puede encontrar más información en estas diapositivas , especialmente en la página 11.

Si desea acceder al contexto desde el ISR, eso podría ser posible, dependiendo de su situación exacta. Eche un vistazo a la sección 10.9 de la hoja de datos de PIC18F4620 (solo tomé una al azar, verifique su hoja de datos también):

  

Durante las interrupciones, la dirección de retorno de la PC se guarda en la pila. Además, los registros WREG, STATUS y BSR se guardan en la pila de devolución rápida. Si no se utiliza un retorno rápido de la interrupción (consulte Sección 5.3 "Organización de la memoria de datos" ), es posible que el usuario deba guardar los registros WREG, STATUS y BSR al ingresar a la rutina de servicio de interrupción.

Creo que "Sección 5.3" debería ser realmente "Sección 5.1.3". Si miras allí:

  

Se proporciona una pila de registro rápido para los registros de ESTADO, WREG y BSR, para proporcionar una opción de "retorno rápido" para las interrupciones. La pila para cada registro tiene solo un nivel de profundidad y no se puede leer ni escribir. Se carga con el valor actual del registro correspondiente cuando el procesador se envía para una interrupción. Todas las fuentes de interrupción insertarán valores en los registros de pila. Los valores en los registros se vuelven a cargar en sus registros asociados si se usa la instrucción RETFIE, FAST para regresar de la interrupción.

Como puede ver, si se utiliza la pila de registro rápido, no puede recuperar el contexto dentro del ISR. En el resto de esta sección, se explica cuándo se usa la pila de registro rápido no :

  

Si las interrupciones de prioridad alta y baja están habilitadas, los registros de pila no se pueden usar de manera confiable para regresar de las interrupciones de prioridad baja. [...] En estos casos, los usuarios deben guardar los registros clave en el software durante una interrupción de baja prioridad.

Entonces, si es posible en su configuración actual habilitar ambas prioridades (o ya es así), el PIC no guarda el contexto por sí mismo y usted mismo debe hacerlo. Eso significa que tienes control total sobre el contexto.

    
respondido por el Keelan

Lea otras preguntas en las etiquetas