Lets see if it works this time ...
I'm having a problem with rtc interrupts with the MCF52269 and MQX.
I'm building a simple clock module based on the rtc. I've enabled the 1Hz
interrupt and installed an isr that triggers my code to update the display time
every second.
It's pretty simple, I guess I'm missing something stupid, but I just can't see
it.
The problem is that the module freezes after only running for between a few
minutes and a couple of hours. It hasn't crashed, the debugger shows it's
still running, but it's no longer responsive. Breaking into the app doesn't
show anything odd, the stack trace doesn't point to any obvious problems.
In my test app, all I have is this module running in the main mqx task, along with
the display driver, and another task listening on a network port for incoming
control signals.
The code is shown below, error checking has been removed for clarity.
Odd things which may or may not be relevant -
Chaining to the previous isr doesn't work. The code hangs immediately if this
call is not commented out.
The call to _int_get_isr_data() returns NULL. I'm not clear whether this is
an actual error or whether the old isr simply has no data.
Any insight would be most gratefully recieved.
paulm
/* globals */
typedef struct isrInfoStruct
{
void (_CODE_PTR_ oldIsr)(pointer);
pointer oldIsrData;
boolean isrDone;
} isrInfo, _PTR_ isrInfoPtr;
/* my isr */
void rtcIsr(pointer dataPtr)
{
uint_32 intSource;
VMCF52XX_RTC_STRUCT_PTR rtc;
rtc = _bsp_get_rtc_base_address();
/* check which interrupt */
intSource = rtcReadReg((pointer)&rtc->RTCISR, TRUE) &
rtcReadReg((pointer)&rtc->RTCIENR, TRUE);
if (intSource & (MCF52XX_RTC_RTCISR_1HZ))
((isrInfoPtr)dataPtr)->isrDone = TRUE;
/* Chain to the previous notifier */
//XXX DOESNT WORK - must be commented out
(*((isrInfoPtr)dataPtr)->oldIsr)(((isrInfoPtr)dataPtr)->oldIsrData);
isrInfoPtr info = (isrInfoPtr)dataPtr;
(*info->oldIsr)(info->oldIsrData);
/* clear interrupt flag(s) */
rtcWriteReg((pointer)&rtc->RTCISR, TRUE, intSource);
} /* rtcIsr */
// In Main():
/* install rtc isr */
isrInfoPtr isrDataPtr = _mem_alloc_zero((_mem_size)sizeof(isrInfo));
isrDataPtr->oldIsr = _int_get_isr(_bsp_get_rtc_vector());
isrDataPtr->oldIsrData = _int_get_isr_data(MCF5225_INT_RTC);
isrDataPtr->isrDone = FALSE;
_int_install_isr(MCF5225_INT_RTC, rtcIsr, isrDataPtr);
/* set up rtc */
/* ... */
retval = _rtc_int_enable(TRUE, MCF52XX_RTC_RTCIENR_1HZ);
// In processing loop:
if (isrDataPtr->isrDone) {
/* do stuff once per sec */
It'd be interesting to know why you have to comment that code out. Do you need to check for a NULL value of oldIsr?
Maybe the problem of freezing is unrelated to this code? For example, if interrupts are getting fenced somewhere else, the ISR would stop being called. At the time of the freeze, have you checked that interrupt fence in the SR, and also the bits in the IMRH/IMRL registers in the interrupt controller?
Does the problem still occur if you remove all other code, e.g. the task listening on the network port?