We have several tasks running on an STM32 MCU. In the main.c file we call all the init functions for the various threads. Currently there is one renewing xTimer to trigger a periodic callback (which, at present, does nothing except print a message that it was called). Declarations as follows, outside any function:
TimerHandle_t xMotorTimer;
StaticTimer_t xMotorTimerBuffer;
EventGroupHandle_t MotorEventGroupHandle;
In the init function for the thread:
xMotorTimer = xTimerCreateStatic("MotorTimer",
xTimerPeriod,
uxAutoReload,
( void * ) 0,
MotorTimerCallback,
&xMotorTimerBuffer);
xTimerStart(xMotorTimer, 100);
One thread starts an infinite loop that pauses on an xEventGroupWaitBits() to determine whether to enter an inner loop, which is then governed by its own state:
DeclareTask(MotorThread)
{
bool done = false;
EventBits_t event;
for (;;)
{
Packet * pkt = NULL;
event = xEventGroupWaitBits( MotorEventGroupHandle,
EVT_MOTOR_START | EVT_MOTOR_STOP, // EventBits_t uxBitsToWaitFor
pdTRUE, // BaseType_t xClearOnExit
pdFALSE, // BaseType_t xWaitForAllBits,
portMAX_DELAY //TickType_t xTicksToWait
);
if (event & EVT_MOTOR_STOP)
{
MotorStop(true);
}
if (event & EVT_MOTOR_START)
{
EnableMotor(MOTOR_ALL);
done = false;
while (!done && !abortTest)
{
xQueueReceive(motorQueue, &pkt, portMAX_DELAY);
if (pkt == NULL)
{
done = true;
} else {
done = MotorExecCmd(pkt);
done = ( uxQueueMessagesWaiting(motorQueue) == ( UBaseType_t ) 0);
FreePacket(pkt);
}
}
}
}
}
xEventGroupWaitBits() fires successfully once, the inner loop enters, then exits when the program state meets the expected conditions. The outer loop repeats as it should, but when it arrives again at the xEventGroupWaitBits() call, it crashes almost instantly. In fact, it crashes a few lines down into the wait function, at a call to uxTaskResetEventItemValue(). I can't even step the debugger into the function, as if calling a bad address. But if I check the disassembly, the memory address for the BL instruction hasn't changed since the previous loop, and that address is valid. The expected function is actually there.
I can prevent this chain of events happening altogether by not calling that xTimerStart() and leaving everything else as-is. Everything runs just fine, so it's definitely not xEventGroupWaitBits() (or at least not just that). We tried switching to xEventGroupGetBits() and adding a short osDelay to the loop just as an experiment. That also froze the whole system.
So, main question. Are we doing something FreeRTOS is not meant to do here, using xEventGroupWaitBits() with xTimers running? Or is there supposed to be something between xEventGroupWaitBits() calls, possibly some kind of state reset that we've overlooked? Reviewing the docs, I can't see it, but I could have missed a detail. The
Related
I've been working on some RTOS MicroC project and whenever I've implemented some function it works just fine outside the task, but whenever I put in the task it just wouldn't do anything. I know I might not get answer to this, but any tips where to start looking would be a big help, thanks in advance.
a_sem = OSSemCreate(1);
static void AppTask1(void *p_arg)
{
(void) p_arg;
INT8U perr;
while (1)
{
OSSemPend(a_sem, 0, &perr);
planeAngles();// Functon that works outside the task
OSSemPost(a_sem);
OSTimeDly(OS_TICKS_PER_SEC/20);
}
}
static void AppTask2(void *p_arg)
{
(void) p_arg;
INT8U perr;
while (1)
{
OSSemPend(a_sem, 0, &perr);
servoTurns(); // Functon that works outside the task
OSSemPost(a_sem);
OSTimeDly(OS_TICKS_PER_SEC/20);
}
}
Both tasks wait on a semaphore, but it is not clear where that semaphore is initially given. It seems likely that neither task ever returns from the OSSemPend call.
Somewhere in your code, before AppTask1 and AppTask2 are created, you should have a line of code like this:
OSSemCreate(a_sem, 1, &perr);
You are creating a semaphore, a_sem with an initial value of 1 so that the first task that calls OSSemPend will successfully acquire the semaphore.
Also, you should not block forever on OSSemPend. Wait for awhile and then check the error status:
OSSemPend(a_sem, 10, &perr);
if(perr == OS_ERR_NONE)
{
/* You have the semaphore */
}
else
{
/* Error! Maybe a timeout */
}
I have two modes that I want to switch between with an interrupt that is generated by a sliding switch. Initially I read the current position and choose a mode/function. I want to switch between the two right when the position of the switch is changed. I have an interrupt which occurs on both edges (whenever the position is changed). However since both functions run continuously in a while loop, I can't just call them in the interrupt. Basically I have something like this:
interrupt()
{
//not sure how to switch between modes here
}
main()
{
//choose mode on startup
if (switch_HIGH)
modeA();
else
modeB();
}
modeA()
{
while(1)
{
//do something
}
}
modeB()
{
while(1)
{
//do something
}
}
I don't know if it's a good idea to just leave a function where it is and just move to something else but I can't think of any other way to do it. I'd really appreciate it if someone could tell me how I can go about this.
The language I'm using is C and the platform is a NIOS system on a Altera DE1 development board.
Using an interrupt for this seems very pointless; it's much simpler to just poll the input on each loop, and call the proper function just as you're doing.
UPDATE: I just relized your code doesn't have a loop, so the above is a bit hard to understand, of course.
I meant that you can structure your program like this:
int main(void)
{
initialize_hardware();
while(1)
{
if(switch_HIGH)
modeA();
else
modeB();
}
}
This makes the CPU go around in an infinite loop, and on each iteration it checks the switch and calls either modeA() or modeB() depending on the current mode.
Adding an interrupt gains you nothing except adding more complexity.
That said, what I would do is use a function pointer to indicate the current mode, and change the function pointer's value inside the interrupt, depending on the state of the switch. Then in the main loop just call the pointed-at function.
Remember to initialize the function properly, since you probably won't get an interrupt when teh device comes out of reset. This is another argument against this solution; the complexity is much bigger than just checking the switch on each iteration.
How about calling the two functions as threads. The interrupt function can kill the active thread and start the other thread. Pseudo code:
thread threada,threadb;
flag a=0;
interrupt()
{
if(a==0)
{
thread_kill(threada);
threadb=thread_create(modeB);
a=1;
}
else
{
thread_kill(threadb);
threada=thread_create(modeA);
a=0;
}
}
main()
{
thread_create(threada);
a=1;
}
modeA()
{
while(1)
{
//do something
}
}
modeB()
{
while(1)
{
//do something
}
}
Rather than killing the thread, you can have graceful shutdown mechanism using some kind of synchronization.
I have this loop, how would I end the loop?
void loop() {
// read the pushbutton input pin:
a ++;
Serial.println(a);
analogWrite(speakerOut, NULL);
if(a > 50 && a < 300){
analogWrite(speakerOut, 200);
}
if(a <= 49){
analogWrite(speakerOut, NULL);
}
if(a >= 300 && a <= 2499){
analogWrite(speakerOut, NULL);
}
This isn't published on Arduino.cc but you can in fact exit from the loop routine with a simple exit(0);
This will compile on pretty much any board you have in your board list. I'm using IDE 1.0.6. I've tested it with Uno, Mega, Micro Pro and even the Adafruit Trinket
void loop() {
// All of your code here
/* Note you should clean up any of your I/O here as on exit,
all 'ON'outputs remain HIGH */
// Exit the loop
exit(0); //The 0 is required to prevent compile error.
}
I use this in projects where I wire in a button to the reset pin. Basically your loop runs until exit(0); and then just persists in the last state. I've made some robots for my kids, and each time the press a button (reset) the code starts from the start of the loop() function.
Arduino specifically provides absolutely no way to exit their loop function, as exhibited by the code that actually runs it:
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
Besides, on a microcontroller there isn't anything to exit to in the first place.
The closest you can do is to just halt the processor. That will stop processing until it's reset.
Matti Virkkunen said it right, there's no "decent" way of stopping the loop. Nonetheless, by looking at your code and making several assumptions, I imagine you're trying to output a signal with a given frequency, but you want to be able to stop it.
If that's the case, there are several solutions:
If you want to generate the signal with the input of a button you could do the following
int speakerOut = A0;
int buttonPin = 13;
void setup() {
pinMode(speakerOut, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
}
int a = 0;
void loop() {
if(digitalRead(buttonPin) == LOW) {
a ++;
Serial.println(a);
analogWrite(speakerOut, NULL);
if(a > 50 && a < 300) {
analogWrite(speakerOut, 200);
}
if(a <= 49) {
analogWrite(speakerOut, NULL);
}
if(a >= 300 && a <= 2499) {
analogWrite(speakerOut, NULL);
}
}
}
In this case we're using a button pin as an INPUT_PULLUP. You can read the Arduino reference for more information about this topic, but in a nutshell this configuration sets an internal pullup resistor, this way you can just have your button connected to ground, with no need of external resistors.
Note: This will invert the levels of the button, LOW will be pressed and HIGH will be released.
The other option would be using one of the built-ins hardware timers to get a function called periodically with interruptions. I won't go in depth be here's a great description of what it is and how to use it.
The three options that come to mind:
1st) End void loop() with while(1)... or equally as good... while(true)
void loop(){
//the code you want to run once here,
//e.g., If (blah == blah)...etc.
while(1) //last line of main loop
}
This option runs your code once and then kicks the Ard into
an endless "invisible" loop. Perhaps not the nicest way to
go, but as far as outside appearances, it gets the job done.
The Ard will continue to draw current while it spins itself in
an endless circle... perhaps one could set up a sort of timer
function that puts the Ard to sleep after so many seconds,
minutes, etc., of looping... just a thought... there are certainly
various sleep libraries out there... see
e.g., Monk, Programming Arduino: Next Steps, pgs., 85-100
for further discussion of such.
2nd) Create a "stop main loop" function with a conditional control
structure that makes its initial test fail on a second pass.
This often requires declaring a global variable and having the
"stop main loop" function toggle the value of the variable
upon termination. E.g.,
boolean stop_it = false; //global variable
void setup(){
Serial.begin(9600);
//blah...
}
boolean stop_main_loop(){ //fancy stop main loop function
if(stop_it == false){ //which it will be the first time through
Serial.println("This should print once.");
//then do some more blah....you can locate all the
// code you want to run once here....eventually end by
//toggling the "stop_it" variable ...
}
stop_it = true; //...like this
return stop_it; //then send this newly updated "stop_it" value
// outside the function
}
void loop{
stop_it = stop_main_loop(); //and finally catch that updated
//value and store it in the global stop_it
//variable, effectively
//halting the loop ...
}
Granted, this might not be especially pretty, but it also works.
It kicks the Ard into another endless "invisible" loop, but this
time it's a case of repeatedly checking the if(stop_it == false) condition in stop_main_loop()
which of course fails to pass every time after the first time through.
3rd) One could once again use a global variable but use a simple if (test == blah){} structure instead of a fancy "stop main loop" function.
boolean start = true; //global variable
void setup(){
Serial.begin(9600);
}
void loop(){
if(start == true){ //which it will be the first time through
Serial.println("This should print once.");
//the code you want to run once here,
//e.g., more If (blah == blah)...etc.
}
start = false; //toggle value of global "start" variable
//Next time around, the if test is sure to fail.
}
There are certainly other ways to "stop" that pesky endless main loop
but these three as well as those already mentioned should get you started.
This will turn off interrupts and put the CPU into (permanent until reset/power toggled) sleep:
cli();
sleep_enable();
sleep_cpu();
See also http://arduino.land/FAQ/content/7/47/en/how-to-stop-an-arduino-sketch.html, for more details.
just use this line to exit function:
return;
I have an issue in my use of critical sections. My app has a large number of threads, say 60, which all need access to a global resource. I therefore protect that resource with a critical section. This works perfectly during operation, however when my application shuts down, I trigger the threads to quit, and then destroy the critical section.
The problem comes if some of those threads are waiting on the critical section at exit time, and thus are blocked from quitting themselves.
I've written a wrapper around the windows CriticalSection calls that has an 'Initialised' flag, which I set to true when the crit is created, and set to false when I'm about to leave the crit (both cases are set when inside the crit). This flag is checked before the 'enter crit' wrapper function tries entering the crit, bypassing the request if the flag is false. The flag is also checked the moment any thread successfully enters the crit, making it immediately leave the crit if it's false.
What I to do prior to deleting the crit is set the flag to false, then wait for any waiting threads to: be allowed into the crit; see the Initialised flag is false; then leave the crit (which should be a pretty quick operating for each thread).
I check the number of threads waiting for access to the crit by checking the LockCount inside the CRITICAL_SECTION struct, and waiting until it hits 0 (in XP, that's LockCount - (RecursionCount-1); in 2003 server and above, the lock count is ((-1) - (LockCount)) >> 2), before I then destroy the critical section.
This should be sufficient, however I'm finding that the LockCount reaches 0 when there's still one thread (always just one thread, never more) waiting to enter the crit, meaning if I delete the crit at that point, the other thread subsequently wakes up from waiting on the crit, and causes a crash as the CRITICAL_SECTION object has by that time been destroyed.
If I keep my own internal lock count of threads waiting for access, I have the correct count; however this isn't ideal as I have to increment this count outside of the crit, meaning that value isn't protected and therefore can't be entirely relied upon at any one time.
Does anyone know why the LockCount in the CRITICAL_SECTION struct would be out by 1? If I use my own lock count, then check the CRITICAL_SECTION's lock count after that last thread has exited (and before I destroy the crit), it's still 0...
Or, is there a better way for me to protect the global resource in my app with that many threads, other than a critical section?
This is my wrapper struct:
typedef struct MY_CRIT {
BOOL Initialised;
CRITICAL_SECTION Crit;
int MyLockCount;
}
Here's my Crit init function:
BOOL InitCrit( MY_CRIT *pCrit )
{
if (pCrit)
{
InitializeCriticalSection( &pCrit->Crit );
pCrit->Initialised = TRUE;
pCrit->MyLockCount = 0;
return TRUE;
}
// else invalid pointer
else
return FALSE;
}
This is my enter crit wrapper function:
BOOL EnterCrit( MY_CRIT *pCrit )
{
// if pointer valid, and the crit is initialised
if (pCrit && pCrit->Initialised)
{
pCrit->MyLockCount++;
EnterCriticalSection( &pCrit->Crit );
pCrit->MyLockCount--;
// if still initialised
if (pCrit->Initialised)
{
return TRUE;
}
// else someone's trying to close this crit - jump out now!
else
{
LeaveCriticalSection( &pCrit->Crit );
return FALSE;
}
}
else // crit pointer is null
return FALSE;
}
And here's my FreeCrit wrapper function:
void FreeCrit( MY_CRIT *pCrit )
{
LONG WaitingCount = 0;
if (pCrit && (pCrit->Initialised))
{
// set Initialised to FALSE to stop any more threads trying to get in from now on:
EnterCriticalSection( &pCrit->Crit );
pCrit->Initialised = FALSE;
LeaveCriticalSection( &pCrit->Crit );
// loop until all waiting threads have gained access and finished:
do {
EnterCriticalSection( &pCrit->Crit );
// check if any threads are still waiting to enter:
// Windows XP and below:
if (IsWindowsXPOrBelow())
{
if ((pCrit->Crit.LockCount > 0) && ((pCrit->Crit.RecursionCount - 1) >= 0))
WaitingCount = pCrit->Crit.LockCount - (pCrit->Crit.RecursionCount - 1);
else
WaitingCount = 0;
}
// Windows 2003 Server and above:
else
{
WaitingCount = ((-1) - (pCrit->Crit.LockCount)) >> 2;
}
// hack: if our own lock count is higher, use that:
WaitingCount = max( WaitingCount, pCrit->MyLockCount );
// if some threads are still waiting, leave the crit and sleep a bit, to give them a chance to enter & exit:
if (WaitingCount > 0)
{
LeaveCriticalSection( &pCrit->Crit );
// don't hog the processor:
Sleep( 1 );
}
// when no other threads are waiting to enter, we can safely delete the crit (and leave the loop):
else
{
DeleteCriticalSection( &pCrit->Crit );
}
} while (WaitingCount > 0);
}
}
You are responsible to make sure that CS is not in use any longer before destroying it. Let us say that no other thread is currently trying to enter, but there is a chance that it is going to attempt very soon. Now you destroy the CS, what this concurrent thread is going to do? At its full pace it hits deleted critical section causing memory access violation?
The actual solution depends on your current app design, but if you are destroying threads, then you will perhaps want to flag your request to stop those threads, and then wait on theit handles to wait for their destruction. And then complete with deleting critical section when you are sure that threads are done.
Note that it is unsafe to rely on CS member values such as .LockCount, and having done things right way you will prehaps not even need thing like IsWindowsXPOrBelow. Critical section API suggest that you use CRITICAL_SECTION structure as "black box" leaving the internals to be implementation specific.
I have an ISR defined to trigger on an external interrupt. The external interrupt may not always be enabled, but under certain circumstances I want to be able to register a function to be called ONCE within the interrupt from within the main code. The function might be replaced by another one, or removed, before the next interrupt.
I don't know much about techniques for synchronisation on the PIC32, but I've come up with the following:
volatile BOOL callbackInterrupted = FALSE;
volatile BOOL callbackWritten = FALSE;
void (*myCallback)() = NULL;
void RegisterCallback(void (*callback)())
{
do
{
callbackWritten = FALSE;
myCallback = callback;
}
while(callbackInterrupted);
callbackWritten = (callback != NULL);
}
void interrupt MyExternalInterrupt() #EXTERNAL_1_VCTR
{
// Do a bunch of other things here...
if(callbackWritten)
{
myCallback();
myCallback = NULL;
callbackInterrupted = TRUE;
callbackWritten = FALSE;
}
}
I'm having trouble reasoning about it though. Does this actually do what I hope, ie. prevent the ISR calling a half-set function pointer, or calling a function twice? Is the do ... while loop superfluous? Is there a better way?
Added: disabling this interrupt is out of the question. It is used for timing.
Instructions generated for flag = TRUE:
lui s1,0x0
ori s1,s1,0x1
addiu at,s1,0
or t0,at,zero
Instructions generated for fnc1 = &testfunc:
lui a2,0x9d00
ori a2,a2,0x50
or a1,a2,zero
sw a1,16376(gp)
Assuming setting the bool is an atomic operation (disassemble & read the manual to be sure) - I would use a flag to set the function pointer, but this flag shold only be read by the ISR, and only written by the normal code, giving you a simple semaphore. If writing the function pointer is atomic (again, check by disassembling), you can use it instead of the flag.
Like this (off the top of my head)
void (*myCallback)() = NULL;
void RegisterCallback(void (*callback)())
{
myCallback = callback;
}
void interrupt MyExternalInterrupt() #EXTERNAL_1_VCTR
{
// Do a bunch of other things here...
if (myCallback!=NULL)
myCallback();
myCallback = NULL;
}
Edit
After seeing disassembled instructions, using the function pointer as a flag will work. Modified code to show usage.
Given the fact that the ISR is there to time pulses why call the function within the ISR at all? Why not call it in the main code where ever it is that the main code checks up on the results of the pulse timing?
If your answer is that its critical the code is executed on the fire of the ISR, then i assume its also critical that you have the opportunity to set a function to call prior to every execution of the interrupt. In this case your only options are to determine the proper function to call for the next interrupt within the ISR or to disable the interrupt while you determine the proper function to call elsewhere in the code. If timing is critical you should also make sure this ISR can't be bumped by a higher priority interrupt.
I would use only a function pointer and check that for non-null in the interrupt, call and set it to null. Where you set the pointer the standard solution would be to disable interrupts.