ctl calls -> hard fault exception
Hi Guys,
I hope you can help with this, I spent many hours trying to get to the bottom of it yesterda
I use CTL_SEMAPHORE_t to protect calls to an RTC library I have written. There is a library-wide semaphore and also a semaphore for each timer_t object (a structure for my custom timer object). All semaphores are initialised as binary semaphores. I make my calls to initialise timers from the first spawned CTL task from main which I call "monitor task", I think it is "new task" in the CTL demo code.
The following defines are used to wait on and signal the semaphores.
For the library-wide semaphore:
#define RTC_LOCK ctl_semaphore_wait(&rtc_sem, CTL_TIMEOUT_NONE, 0)
#define RTC_UNLOCK ctl_semaphore_signal(&rtc_sem)
And for each timer_t objec
#define RTC_TIMER_LOCK ctl_semaphore_wait(&timer->sem, CTL_TIMEOUT_NONE, 0)
#define RTC_TIMER_UNLOCK ctl_semaphore_signal(&timer->sem)
When I call the function below I get a hard fault exception on the call to RTC_UNLOCK I have marked with asterisks:
rtc_timer_t *rtc_get_timer()
{
u32_t i;
rtc_timer_t *timer;
RTC_LOCK;
for (i = 0 ; i < MAX_NUM_RTC_TIMERS ; i++)
{
timer = &_rtc_timers[i];
RTC_TIMER_LOCK;
if (!timer->used)
{
timer->used = T;
timer->set = F;
timer->epoch = RTC_HW_GET_TIME_CALLBACK();
RTC_TIMER_UNLOCK;
RTC_UNLOCK; ************************ Exception here on ctl_semaphore_signal(&rtc_sem)
return (timer);
}
RTC_TIMER_UNLOCK;
}
RTC_UNLOCK;
return (NULL);
}
Stepping through the code, the exception occurs during ctl_private_reschedule_from_api_call on the line "str r1, [r0, #0]"
481C ldr r0, [pc, #0x70]
6801 ldr r1, [r0, #0]
F0415180 orr r1, r1, #0x10000000
6001 str r1, [r0, #0] ************ exception when this instruction is executed
4770 bx lr
The registers at this point are as follows: r0=0xe000ed04 r1=0x10000000 r2=0x20003a18 r3=0x00000000 r4=0x2000c700 r5=0x00000005 r6=0x00000006 r7=0x2000a354 r8=0x00000008 r9=0x00000009 r10=0x0000000a r11=0x0000000b r12=0x2000ce8c sp(r13)=0x2000a34c lr(r14)=0x08025ad9 pc(r15)=0x0802617e xPSR=0x21000000 SP_main=0x2000a34c SP_process=0xd3b3d5e0 CFBP=0x00000000
I have tried another project I have been working on, previously without problems. Now I get the same fault on a call to ctl_semaphore_wait.
Please help, I'm really stuck with this one and I don't think I can see the wood for the trees anymore. It must be something simple!
Much appreciated!
Jo
-
Hi Michael,
I worked out that the problems were caused by calling CTL from the main high priority task rather than any tasks which it spawns. To save me the headache of going through each instance, I replaced all the affected CTL calls with a JWL (my initials) version which checks the origin of the call via priority level before allowing the call. This was belt and braces since I also adjusted my code to not call the sensitive CTL calls from main. Regardless, here is my library and I hope it helps you.
Jo
#include <ctl_api.h>
#include "jwl_ctl.h"
void jwl_ctl_semaphore_init(CTL_SEMAPHORE_t *s, u32_t count)
{
ctl_semaphore_init(s, count);
}
void jwl_ctl_semaphore_wait(CTL_SEMAPHORE_t *s,
CTL_TIMEOUT_t t,
CTL_TIME_t timeout)
{
if (ctl_task_executing->priority < 0xFF)
ctl_semaphore_wait(s, t, timeout);
}
void jwl_ctl_semaphore_signal(CTL_SEMAPHORE_t *s)
{
if (ctl_task_executing->priority < 0xFF)
{
if (!(u32_t)*s)
ctl_semaphore_signal(s);
}
}
void jwl_ctl_timeout_wait(u32_t ticks)
{
u32_t i = 0;
u32_t ticks_per_loop;
if (ctl_task_executing->priority < 0xFF) ctl_timeout_wait(ticks);
else
{
// TODO - make this accurate
while (i++ < ticks)
{
ticks_per_loop = 10;
while (--ticks_per_loop) {};
}
}
}
u32_t jwl_ctl_get_current_time()
{
return (ctl_get_current_time());
}
-
That is not how my code works. main creates a system thread, then it becomes idle loop per CTL. My main function is less than 30 lines long. The system thread calls all init functions for other systems/devices, some of which create threads of their own. One of these secondary threads is using the ctl_semaphore_wait. There is a ISR that does the signaling, however this has not happen yet due to the hard fault. This hard fault is very real, and is not do to user error. I have years of use of CTL without any major problems on the 21xx/23xx.
Michael Freeman
-
Hi Michael,
The description of your code sounds consistent with the way one would normally implement a CTL-based application. A call to ctl_semaphore_,..... in an ISR normally results in a hard fault for me but I have never bothered delving further into the reason if you get as far as your signal.
Thoughts to investigate if you have not done so already are to check the stack and to check that the call stack trace is not misleading you on the cause of the fault. The waiting task may be waiting fine without any problem whilst the fault lies elsewhere. If you are breaking on the call to ctl_semaphore_wait and then getting the fault when you step-over then this could certainly be the case.
Jo
Please sign in to leave a comment.
Comments
9 comments