# Problem vTaskSuspend and xTaskResumeFromISR

**URL:** <https://forums.freertos.org/t/problem-vtasksuspend-and-xtaskresumefromisr/3805>\
**Category:** Kernel\
**Created:** [May 26, 2008, 4:52am UTC](https://forums.freertos.org/t/problem-vtasksuspend-and-xtaskresumefromisr/3805 "2008-05-26T04:52:38Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [May 26, 2008, 4:52am UTC](https://forums.freertos.org/t/problem-vtasksuspend-and-xtaskresumefromisr/3805/1 "2008-05-26T04:52:38Z")

</div>

**[wellingj](https://sourceforge.net/u/wellingj/)** wrote on [Monday, May 26, 2008](https://sourceforge.net/p/freertos/discussion/382005/thread/a89fc636/#04b8):

Hi.  
I’m using gcc version 4.3.0 and FreeRTOS V5.0.0 for reference.

I’m trying to use the vTaskSuspend and xTaskResumeFromISR to debug some servo code that I had modified.  
Theory of operation is that I have a task that does nothing, until all my ticks of my servo code has gone through and I have all the data, then it gets output onto a serial port using some avrlib stuff. The code is below. What boggles me is that I’ve used the vTaskSuspend and xTaskResumeFromISR in this manner for a I2C command processing with FreeRTOS V 4.3 and it worked wonderfully and so I did a direct port. When it didn’t work, meaning the DebugServo task never runs after it’s first suspension, I started throwing in toggles on a led to see where the code was going and where it wasn’t and I’ve marked which calls to LED\_TOGGLE( YELLOW ) don’t work (no flashing light). The only other task running is just changes the servo position ever 50 milliseconds. I’m running this at a really high rate of 1ms ticks, but I don’t think that should be the problem…

Any Ideas?

/\*! \file servo\_class.c \brief Interrupt-driven RC Servo function library. \*/  
//\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
//  
// File Name&nbsp;&nbsp;&nbsp; : ‘servo.c’  
// Title&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Interrupt-driven RC Servo function library  
// Author&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Pascal Stang - Copyright (C) 2002  
// Modified&nbsp;&nbsp;&nbsp;&nbsp; : Jesse Welling - Copyright (C) 2008  
// Created&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 7/31/2002  
// Revised&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 4/02/2008  
// Version&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 1.1  
// Target MCU&nbsp;&nbsp; : Atmel AVR Series  
// Editor Tabs&nbsp; : 3 spaces = 1 tab  
//  
// This code is distributed under the GNU Public License  
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; which can be found at [http://www.gnu.org/licenses/gpl.txt](http://www.gnu.org/licenses/gpl.txt)  
//  
//\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

#include \<avr/io.h\>  
#include \<avr/interrupt.h\>

#include "FreeRTOS.h"  
#include "task.h"  
#include "semphr.h"

#include "…/avrlib/global.h"  
#include "…/avrlib/uart.h"&nbsp;&nbsp;&nbsp; // include uart function library  
#include "…/avrlib/rprintf.h" // include printf function library

#include "servo.h"  
#include "…/Robostix.h"

/\*roll over number\*/  
#define TOP&nbsp;&nbsp; ((uint16\_t)40000u)

// handy to think with values  
#define CENTER\_POSITION\_MSX100&nbsp;&nbsp; 1500u  
#define MIN\_POSITION\_MSX100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1000u  
#define MAX\_POSITION\_MSX100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2000u

// actual raw values  
#define CENTER\_POSITION\_RAW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (CENTER\_POSITION\_MSX100 \* 2)&nbsp; // 3000  
#define MIN\_POSITION\_RAW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (MIN\_POSITION\_MSX100 \* 2) // 2000  
#define MAX\_POSITION\_RAW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (MAX\_POSITION\_MSX100 \* 2) // 4000

/\* Note: Since only 500 millisecondsX100 is between center and min, and likewise center to max, when multiplied  
\*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by 2 to get the raw value that gives 1000 which then can be used as a signed percentX10 from center.  
\*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Nifty! But only for 16Mhz clocks  
\*/

// Global variables  
// servo channel registers  
static volatile uint16\_t ServoPosTics;  
static volatile uint8\_t&nbsp; ServoChannel;  
static const uint16\_t ServoPeriodTics = TOP;

xTaskHandle ServoDebugTaskHandle;

typedef struct  
{&nbsp;  
&nbsp;&nbsp; uint8\_t&nbsp; chan;  
&nbsp;&nbsp; uint16\_t inc;  
&nbsp;&nbsp; uint16\_t nxt;  
&nbsp;&nbsp; uint16\_t ocval;  
&nbsp;&nbsp; uint16\_t srvpos;  
}TimerDebug\_T;

TimerDebug\_T ServoTimerDebugBuffer[3];

// functions

static void DebugServo( void \* param);

//! initializes software PWM system  
void servoInit(void)  
{  
&nbsp;&nbsp; uint8\_t channel;  
&nbsp;&nbsp;  
&nbsp;&nbsp; //TODO REMOVE DEBUG  
&nbsp;&nbsp; uartInit();  
&nbsp;&nbsp; uartSetBaudRate(115200);  
&nbsp;&nbsp; rprintfInit(uartSendByte);

&nbsp;&nbsp; // disble the timer3 output compare A interrupt  
&nbsp;&nbsp; cbi(ETIMSK, OCIE3A);

&nbsp;&nbsp; /\* setup timer 3  
&nbsp;&nbsp;&nbsp; \*  
&nbsp;&nbsp;&nbsp; \* TCCR3A Bit 7:6 – COMnA1:0: Compare Output Mode for Channel A  
&nbsp;&nbsp;&nbsp; \* TCCR3A Bit 5:4 – COMnB1:0: Compare Output Mode for Channel B  
&nbsp;&nbsp;&nbsp; \* TCCR3A Bit 3:2 – COMnC1:0: Compare Output Mode for Channel C  
&nbsp;&nbsp;&nbsp; \* TCCR3A Bit 1:0 – WGMn1:0: Waveform Generation Mode  
&nbsp;&nbsp;&nbsp; \*  
&nbsp;&nbsp;&nbsp; \* TCCR3B Bit 4:3 – WGMn3:2: Waveform Generation Mode  
&nbsp;&nbsp;&nbsp; \* TCCR3B Bit 2:0 – CSn2:0: Clock Select  
&nbsp;&nbsp;&nbsp; \*  
&nbsp;&nbsp;&nbsp; \* TCCR3C Bit 7 – FOCnA: Force Output Compare for Channel A  
&nbsp;&nbsp;&nbsp; \* TCCR3C Bit 6 – FOCnB: Force Output Compare for Channel B  
&nbsp;&nbsp;&nbsp; \* TCCR3C Bit 5 – FOCnC: Force Output Compare for Channel C  
&nbsp;&nbsp;&nbsp; \*  
&nbsp;&nbsp;&nbsp; \*/

&nbsp;&nbsp; TCCR3A |= 0x00;  
&nbsp;&nbsp; TCCR3B = 0x02;  
&nbsp;&nbsp; TCCR3C |= 0x00;

&nbsp;&nbsp; // enable and clear channels  
&nbsp;&nbsp; for(channel=0; channel\<NumberOfServoChannels; channel++)  
&nbsp;&nbsp; {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // set minimum position as default  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ServoChannels[channel]-\>duty\_raw = CENTER\_POSITION\_RAW;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // set up DDR for each port.  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \*DDR(ServoChannels[ServoChannel]-\>port) |= ServoChannels[ServoChannel]-\>pin\_mask;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // turn off current channel to break out of tristate. see page 67 of the data sheet  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \*(ServoChannels[ServoChannel]-\>port) &= ~(ServoChannels[ServoChannel]-\>pin\_mask);  
&nbsp;&nbsp; }  
&nbsp;&nbsp; // set PosTics  
&nbsp;&nbsp; ServoPosTics = 0;

&nbsp;&nbsp; // Start at just past the last forcing the intrrupts to start processing the first.  
&nbsp;&nbsp; ServoChannel = NumberOfServoChannels + 1;

&nbsp;&nbsp; // set initial interrupt time  
&nbsp;&nbsp; uint16\_t OCValue = 0;

&nbsp;&nbsp; // read in current value of output compare register OCR3A  
&nbsp;&nbsp; //OCValue = OCR3A;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // read OCR3A  
&nbsp;&nbsp; OCValue =&nbsp; inb(OCR3AL);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // read low byte of OCR3A  
&nbsp;&nbsp; OCValue += inb(OCR3AH)\<\<8;&nbsp;&nbsp; // read high byte of OCR3A

&nbsp;&nbsp; // increment OCR3A value by nextTics  
&nbsp;&nbsp; OCValue += ServoPeriodTics;

&nbsp;&nbsp; ServoTimerDebugBuffer[0].ocval = ServoPeriodTics;  
&nbsp;&nbsp; ServoTimerDebugBuffer[1].ocval = ServoPeriodTics;  
&nbsp;&nbsp; ServoTimerDebugBuffer[2].ocval = ServoPeriodTics;

&nbsp;&nbsp; // set future output compare time to this new value  
&nbsp;&nbsp; //OCR3A = OCValue;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // write 16bit  
&nbsp;&nbsp; outb(OCR3AH, (OCValue\>\>8));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // write high byte  
&nbsp;&nbsp; outb(OCR3AL, (OCValue & 0x00FF));&nbsp;&nbsp; // write low byte

&nbsp;&nbsp; // enable the timer3 output compare A interrupt  
&nbsp;&nbsp; sbi(ETIMSK, OCIE3A);  
}

//! turns off software PWM system  
void servoOff(void)  
{  
&nbsp;&nbsp; // disable the timer3 output compare A interrupt  
&nbsp;&nbsp; cbi(ETIMSK, OCIE3A);  
}

//! set servo position on channel  
void servoSetPosition(ServoChannel\_T\* this, int16\_t percentX10)  
{  
&nbsp;&nbsp; // input should be between 0 and SERVO\_POSITION\_MAX  
&nbsp;&nbsp; uint16\_t pos\_scaled;

&nbsp;&nbsp; percentX10 = MAX(percentX10, -1000);  
&nbsp;&nbsp; percentX10 = MIN(percentX10, 1000);  
&nbsp;&nbsp;  
&nbsp;&nbsp; // calculate scaled position  
&nbsp;&nbsp; pos\_scaled = (uint16\_t)( percentX10 + CENTER\_POSITION\_RAW);

&nbsp;&nbsp; // set position  
&nbsp;&nbsp; servoSetPositionRaw(this, pos\_scaled);  
}

//! get servo position on channel  
int16\_t servoGetPosition(ServoChannel\_T\* this)  
{  
&nbsp;&nbsp; return ( (int16\_t)servoGetPositionRaw(this) - CENTER\_POSITION\_RAW );  
}

//! set servo position on channel (raw unscaled format)  
void servoSetPositionRaw(ServoChannel\_T\* this, uint16\_t position)  
{  
&nbsp;&nbsp; // bind to limits  
&nbsp;&nbsp; position = MAX(position, MIN\_POSITION\_RAW);  
&nbsp;&nbsp; position = MIN(position, MAX\_POSITION\_RAW);

&nbsp;&nbsp; // set position  
&nbsp;&nbsp; this-\>duty\_raw = position;

&nbsp;&nbsp; //TODO REMOVE DEBUG  
&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp; /\*  
&nbsp;&nbsp; rprintfu08(this-\>pin\_mask);  
&nbsp;&nbsp; rprintfChar(’@’);  
&nbsp;&nbsp; rprintfu08(this-\>port);  
&nbsp;&nbsp; rprintfChar(’:’);  
&nbsp;&nbsp; rprintfu16(this-\>duty\_raw);  
&nbsp;&nbsp; rprintfCRLF();  
&nbsp;&nbsp; \*/  
&nbsp;&nbsp;  
}

//! get servo position on channel (raw unscaled format)  
uint16\_t servoGetPositionRaw(ServoChannel\_T\* this)  
{  
&nbsp;&nbsp; return this-\>duty\_raw;  
}

void PrintServoDebug(void)  
{  
&nbsp;&nbsp; {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfu08(ServoTimerDebugBuffer[0].chan);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfChar(’ ‘);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfu16(ServoTimerDebugBuffer[0].inc);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfChar(’ ‘);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfu16(ServoTimerDebugBuffer[0].ocval);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfChar(’ ‘);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfu16(ServoTimerDebugBuffer[0].nxt);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfChar(’ ');  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfu16(ServoTimerDebugBuffer[0].srvpos);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfCRLF();  
&nbsp;&nbsp; }

&nbsp;&nbsp; {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfu08(ServoTimerDebugBuffer[1].chan);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfChar(’ ‘);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfu16(ServoTimerDebugBuffer[1].inc);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfChar(’ ‘);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfu16(ServoTimerDebugBuffer[1].ocval);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfChar(’ ‘);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfu16(ServoTimerDebugBuffer[1].nxt);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfChar(’ ');  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfu16(ServoTimerDebugBuffer[1].srvpos);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfCRLF();  
&nbsp;&nbsp; }

&nbsp;&nbsp; {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfu08(ServoTimerDebugBuffer[2].chan);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfChar(’ ‘);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfu16(ServoTimerDebugBuffer[2].inc);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfChar(’ ‘);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfu16(ServoTimerDebugBuffer[2].ocval);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfChar(’ ‘);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfu16(ServoTimerDebugBuffer[2].nxt);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfChar(’ ');  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfu16(ServoTimerDebugBuffer[2].srvpos);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rprintfCRLF();  
&nbsp;&nbsp; }  
}

void StartDebugServoTask(void)  
{  
&nbsp;&nbsp; xTaskCreate (DebugServo, "DbSrv", configMINIMAL\_STACK\_SIZE, NULL, ( tskIDLE\_PRIORITY + 2), &ServoDebugTaskHandle);  
}

static void DebugServo( void \* param)  
{  
&nbsp;&nbsp; for(;😉  
&nbsp;&nbsp; {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PrintServoDebug();  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vTaskSuspend( NULL );  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //The toggle does not work here  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //LED\_TOGGLE( YELLOW );  
&nbsp;&nbsp; }  
}

ISR(TIMER3\_COMPA\_vect)  
{  
&nbsp;&nbsp; uint16\_t nextTics;

&nbsp;&nbsp; // schedule next interrupt  
&nbsp;&nbsp; uint16\_t OCValue;

&nbsp;&nbsp; if(ServoChannel \< NumberOfServoChannels)  
&nbsp;&nbsp; {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // turn off current channel  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \*(ServoChannels[ServoChannel]-\>port) &= ~(ServoChannels[ServoChannel]-\>pin\_mask);  
&nbsp;&nbsp; }  
&nbsp;&nbsp;  
&nbsp;&nbsp; // next channel  
&nbsp;&nbsp; ServoChannel++;

&nbsp;&nbsp; if(ServoChannel != NumberOfServoChannels)  
&nbsp;&nbsp; {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // loop to channel 0 if needed  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(ServoChannel \> NumberOfServoChannels)&nbsp;&nbsp; ServoChannel = 0;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // turn on new channel  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \*(ServoChannels[ServoChannel]-\>port) |= ServoChannels[ServoChannel]-\>pin\_mask;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // schedule turn off time  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nextTics = ServoChannels[ServoChannel]-\>duty\_raw;  
&nbsp;&nbsp; }  
&nbsp;&nbsp; else //(Channel == NumberOfServoChannels)  
&nbsp;&nbsp; {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // \*\*\*we could save time by precalculating this  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // schedule end-of-period  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nextTics = ServoPeriodTics - ServoPosTics;  
&nbsp;&nbsp; }

&nbsp;&nbsp; // read in current value of output compare register OCR3A,  
&nbsp;&nbsp; // but within an interrupt so this direct access is safe  
&nbsp;&nbsp; OCValue = OCR3A;&nbsp;&nbsp; // read all 16 bits of OCR3A  
&nbsp;&nbsp; //OCValue =&nbsp; inb(OCR3AL);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // read low byte of OCR3A  
&nbsp;&nbsp; //OCValue += inb(OCR3AH)\<\<8;&nbsp;&nbsp; // read high byte of OCR3A

&nbsp;&nbsp; //TODO REMOVE DEBUG  
&nbsp;&nbsp; ServoTimerDebugBuffer[ServoChannel].chan = ServoChannel;  
&nbsp;&nbsp; ServoTimerDebugBuffer[ServoChannel].ocval = OCValue;  
&nbsp;&nbsp; ServoTimerDebugBuffer[ServoChannel].inc++;

&nbsp;&nbsp; // increment OCR3A value by nextTics  
&nbsp;&nbsp; OCValue += nextTics;

&nbsp;&nbsp; //&nbsp;&nbsp; OCR3A+=nextTics; // but must protect the register so byte wise shift it in  
&nbsp;&nbsp; // set future output compare time to this new value  
&nbsp;&nbsp; // but within an interrupt so this direct access is safe  
&nbsp;&nbsp; OCR3A = OCValue;  
&nbsp;&nbsp; //outb(OCR3AH, (OCValue\>\>8));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // write high byte  
&nbsp;&nbsp; //outb(OCR3AL, (OCValue & 0x00FF));&nbsp;&nbsp; // write low byte

&nbsp;&nbsp; // set our new tic position  
&nbsp;&nbsp; ServoPosTics += nextTics;

&nbsp;&nbsp; //TODO REMOVE DEBUG  
&nbsp;&nbsp; ServoTimerDebugBuffer[ServoChannel].nxt = nextTics;  
&nbsp;&nbsp; ServoTimerDebugBuffer[ServoChannel].srvpos = ServoPosTics;

&nbsp;&nbsp; if(ServoPosTics \>= ServoPeriodTics)  
&nbsp;&nbsp; {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ServoPosTics = 0;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //The toggle works here  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LED\_TOGGLE( YELLOW );

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (xTaskResumeFromISR(ServoDebugTaskHandle) == pdTRUE)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //The toggle does not work here  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //LED\_TOGGLE( YELLOW );  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; taskYIELD();  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  
&nbsp;&nbsp; }  
}

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [May 26, 2008, 8:27am UTC](https://forums.freertos.org/t/problem-vtasksuspend-and-xtaskresumefromisr/3805/2 "2008-05-26T08:27:07Z")

</div>

**[woops\_](https://sourceforge.net/u/woops_/)** wrote on [Monday, May 26, 2008](https://sourceforge.net/p/freertos/discussion/382005/thread/a89fc636/#04b8/aca7):

The ResumeFromISR function has the following statement

vTaskResumeFromISR() should not be used to synchronise a task with an interrupt if there is a chance that the interrupt could arrive prior to the task being suspended - as this can lead to interrupts being missed. Use of a semaphore as a synchronisation mechanism would avoid this eventuality.

could that be the problem?

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [May 27, 2008, 7:00am UTC](https://forums.freertos.org/t/problem-vtasksuspend-and-xtaskresumefromisr/3805/3 "2008-05-27T07:00:57Z")

</div>

**[wellingj](https://sourceforge.net/u/wellingj/)** wrote on [Tuesday, May 27, 2008](https://sourceforge.net/p/freertos/discussion/382005/thread/a89fc636/#04b8/aca7/5330):

That was exactly it…

Coincidentally, The example for vTaskResumeFromISR() has a "xSemaphoreCreateBinary()" when it should be a "vSemaphoreCreateBinary()". Had to look at the .h file to figure that one out 😉

Thanks a bunch!

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [May 27, 2008, 7:02am UTC](https://forums.freertos.org/t/problem-vtasksuspend-and-xtaskresumefromisr/3805/4 "2008-05-27T07:02:34Z")

</div>

**[wellingj](https://sourceforge.net/u/wellingj/)** wrote on [Tuesday, May 27, 2008](https://sourceforge.net/p/freertos/discussion/382005/thread/a89fc636/#04b8/38f0):

Correction: The example for xSemaphoreGiveFromISR() had the error…

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [May 27, 2008, 7:34am UTC](https://forums.freertos.org/t/problem-vtasksuspend-and-xtaskresumefromisr/3805/5 "2008-05-27T07:34:13Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Tuesday, May 27, 2008](https://sourceforge.net/p/freertos/discussion/382005/thread/a89fc636/#04b8/38f0/4e3f):

\>Correction: The example for xSemaphoreGiveFromISR() had the error

Fixed - thanks for pointing this out.

Regards.
