Estoy trabajando en la creación de un flujo de programa basado en interrupciones utilizando el módulo PIC24FV32KA302 de Microchip. Sin embargo, estoy teniendo algunos problemas con los reinicios intermitentes (parece).
Actualmente estoy usando el simulador MPLAB X, tratando de averiguar dónde está ocurriendo el problema. Originalmente estaba usando un PICKit3 en hardware real, pero me encontré con un problema en el que, después de algunos ciclos a través del bucle principal, el depurador se detendría y lanzaría un error "PC en 0x0", que es una dirección sin una instrucción válida. No creo que estos problemas estén relacionados, pero realmente no puedo eliminar la posibilidad.
En esencia, el flujo de mi programa es el siguiente:
main()
{
init();
print_an_init_message();
while(1)
{
check_some_flags();
if(flags_are_set)
{
do_something_about_them();
}
}
}
Durante la simulación, el programa imprime repetidamente el mensaje de inicio. Se atrapa en un punto de interrupción en el bucle while (1), por lo que debe estar entrando. Además, si continúo desde ese punto de interrupción, se repetirá (no se restablecerá). Si salgo de ese punto de interrupción, el depurador se bloquea.
Entonces, intenté imprimir los valores del registro RSON (que se supone que se debe establecer durante cualquier condición de reinicio) en el mensaje de inicio. Ninguno de los valores está establecido. Si agrego un retraso simple (XC16 __delay_ms () incorporado al bucle while, se llama a la interrupción _AddressError. La instrucción a partir de la cual se origina el error de dirección es siempre una instrucción ULNK de una de las funciones utilizadas en do_something_about_them () (que representa múltiples indicadores y funciones, parece posible que sea cualquiera de las funciones, pero la mayoría de las veces es la primero o último).
También vale la pena señalar, si coloco un punto de interrupción en la última línea de main (retorno -1), nunca se alcanza, pero el simulador imprime continuamente el mensaje de inicio.
¿Es probable que esto sea un problema con el simulador o con mi programa? ¿Podría estar relacionado con el problema de mi PC 0x0 cuando se ejecuta en hardware real, o es probable que sean diferentes?
Si alguien quiere un código real para ayudar, puedo proporcionarlo, simplemente no lo proporcioné de inmediato porque creo que podría ofuscar mi problema real, que no creo que esté causado por mi código C.
Gracias de antemano!
Después de un poco de depuración, logré que desapareciera el error de PC 0x0. Todavía estoy tratando de aterrizar en el error de dirección ISR. Ahora está programando hardware real con PICKit3.
Creo que el código que está causando el problema es una cola con la que estoy tratando.
typedef struct uint16_queue_tag {
uint16_t *contents;
int front;
int back;
int maxSize;
int cnt;
} uint16_queue;
bool uint16_InitQueue(uint16_queue *queueP, uint8_t queueSize)
{
uint16_t newContents[queueSize];
queueP->contents = &newContents[0];
queueP->maxSize = queueSize;
queueP->cnt = 0;
queueP->front = -1;
queueP->back = -1;
return true;
}
bool uint16_IsQueueEmpty(uint16_queue *queueP)
{
return (bool) (queueP->cnt == 0);
}
bool uint16_IsQueueFull(uint16_queue *queueP)
{
return (bool) (queueP->cnt == queueP->maxSize);
}
bool uint16_ClearQueue(uint16_queue *queueP)
{
queueP->front = -1;
queueP->back = -1;
queueP->cnt = 0;
return true;
}
bool uint16_PushQueue(uint16_queue *queueP, uint16_t element)
{
if (uint16_IsQueueFull(queueP))
{
return false; // We can't push to the queue, its full
}
else
{
queueP->back++;
queueP->contents[(queueP->back % queueP->maxSize)] = element;
queueP->cnt++;
return true;
}
}
uint16_t uint16_PullQueue(uint16_queue *queueP)
{
if (uint16_IsQueueEmpty(queueP))
{
return NULL;
}
else
{
queueP->front++;
queueP->cnt--;
return queueP->contents[(queueP->front % queueP->maxSize)];
}
}
Parece que todo funciona bien para algunas iteraciones, pero en algún momento un uint16_PushQueue(&queue_obj, value)
rompe el código. Una vez que se inicializa la cola, todo lo que hago es verificar si está llena, Push y Pull. Extrañamente, parece que el valor del puntero del contenido es diferente: después de que se rompe, el puntero apunta al mismo valor que "frente", que definitivamente no es el mismo valor en el que comenzó. Además, el elemento en el lugar al que apunta se informa, por MPLAB, como 0.0 (que definitivamente no es un flotador).
Supongo que esto es solo una especie de estupidez de asignación de punteros, lo que explica también todo el problema de la dirección: de alguna manera me estoy moviendo hacia donde apunta el puntero del contenido.