suspend & resume tasks on LPC1768

Hi, I have a simple blinkLED() task which is working well as long as I don’t try to suspend/resume the running task. If I suspend the task, LEDs turned off but never turning on after calling resume(). Could anyone give me a hint?
task function
void vTask1( void *p)
{
    for( ;; )
    {
        LED_On();
    }
}
FreeRTOSTask class
class FreeRTOSTask {
    [..]
    public:
    xTaskHandle xth;
};
activate method
void FreeRTOSTask::activate(char const* tskname, unsigned portBASE_TYPE prio) {
    [..]
    xTaskCreate(this->pvTaskCode, (const signed char*) this->name, this->stackDepth, (void*)this->name, this->priority, &(this->xth));
}
suspend method
void FreeRTOSTask::suspend(FreeRTOSTask* tsk) {
    [..]
    vTaskSuspend(tsk->xth);
    UARTPuts_(LPC_UART2, debugMessage);
}
continue method
void FreeRTOSTask::con(FreeRTOSTask* tsk) {
    [..]
    vTaskResume(tsk->xth);
    UARTPuts_(LPC_UART2, debugMessage);
}
main function
void main() {
    [..]
    FreeRTOSTask t1(vTask1, 1000);
    t1.activate("Task-1", 1);
    t1.suspend(&t1);
    t1.con(&t1);
    [..]
}

suspend & resume tasks on LPC1768

Obviously there is a problem when I use the task handler within a FreeRTOS function. For example I can call the vTaskPrioritySet() function from my C++ code and I am able to change the priority of a task (only once). After a successful change of the task priority, the program moves into an undefined state.

suspend & resume tasks on LPC1768

FreeRTOS is C code rather than C++ code, although every effort is made to ensure it can be built in a C++ project it is only actually tested in C projects. However there are some contributed C++ frameworks in the FreeRTOS interactive site, and a few people who regularly answer C++ questions in this forum. It might be a an idea to have C++ in the subject of your post so they are more likely to notice your question. Regards.

suspend & resume tasks on LPC1768

You’re right, it is probably because the C/C++ mix up! Back to my C-only demo, the following code snippet works
main function
    [...]
    xTaskHandle xth1;
    xTaskCreate(vTask1, (const signed char*)"Task-1", 1000, NULL, 1, &xth1);
    vTaskPrioritySet(xth1, tskIDLE_PRIORITY + 1);

    xTaskHandle xth2;
    xTaskCreate(vTask2, (const signed char*)"Task-2", 1000, NULL, 1, &xth2);
    [...]
Does anyone know a helpful documentation describing an solution for clean separation of the FreeRTOS C code and the application code in C++ for (FreeRTOS-)beginners? 😉

suspend & resume tasks on LPC1768

I have used C++ with FreeRTOS in the past, (and thought I submitted some basic interface headers to do so). Generally, it is very straight forward to do so. 1) The FreeRTOS files are compiled a C source files in a manner that the C++ complier considers comparable, and also compatible with how the port was written. 2) When passing a function pointer to FreeRTOS, the function needs to be compiled as “C compatable”. One standard way to do this is to declare it as ‘extern “C” ‘, 3) Data passed via queues needs to be “POD”, simple structures/classes without virtual members or non-trivial constructors/destructors (since FreeRTOS will move them with plain memcpy). There is a bit of a funniness with your functions. They are member functions, but DON’T refer to the object they are called with, but take a parameter for who to work on. I also preferred that the constructor of my task object created the task itself. Until you call activate, your class in in an only semi-usable state (as it doesn’t have a handle yet), and activate can be called exactly once on the object (or you don’t have a spot to store the second task handle). The other BIG issue I see, is that main doesn’t show code to start the scheduler, generally main just initializes stuff, creates some tasks (maybe, if constructors create tasks, then they might be created as global objects elsewhere), and then starts the scheduler. Main NEVER has code that runs with the scheduler running.

suspend & resume tasks on LPC1768

Thank you for your hints. I will try to “implement” your comments today. With regard to the BIG issue I just had poorly named the functions, so there was possibly a misunderstanding. The code below works fine, so I suppose that FreeRTOS can work with the C++ functions/tasks.
FreeRTOS main()
int main( void )
{
    prvSetupHardware();

    /* main() function for my C++ code */
    runTask();

    /* Start the scheduler. */
    vTaskStartScheduler();

    // Will only get here if there was insufficient memory to create the idle
    // task.  The idle task is created within vTaskStartScheduler(). */
    for( ;; );
}
runTasks() in C++
void runTask(){

    FreeRTOSTask t1(vTask1, 1000);
    FreeRTOSTask t2(vTask2, 1000);

    t1.activate("Task-1", 1);
    t2.activate("Task-2", 1);

}

suspend & resume tasks on LPC1768

I will give you one big caution about how that code is working. Your FreeRTOSTask object created in runTask are going to go away right after you create your two tasks. This won’t prevent the tasks from running, but you no longer have the objects t1 or t2 to use your task manipulation functions. You can either create the objects as variables in main, AS LONG AS your port doesn’t reuse main stack for use in interrupts, or you need to create the objects as statics or globals or on the heap.

suspend & resume tasks on LPC1768

Ok, I think I understand the runTask() issue and the resulting lost of link to the objects t1 and t2. In the meantime I have revised my code, oriented on your example: http://www.freertos.org/FreeRTOSSupportForumArchive/July2010/freertosIsitpossiblecreatefreertostaskinc_3778071.html But how can I declare both C++ tasks from the runTask() function as global or static to fix my missing link issue? Or in other words how can I access both tasks from the FreeRTOS main()?
FreeRTOSTask.h
#ifndef FREERTOSTASK_H_
#define FREERTOSTASK_H_

#include <stdio.h>
#include <stdlib.h>
#include <LPC1768Function.h>


#ifdef __cplusplus
extern "C" {
#endif

#include <FreeRTOS.h>
#include <task.h>

#ifdef __cplusplus
}
#endif

#ifdef __cplusplus

// BaseTask ---------------------------------------------------------

class FreeRTOSBaseTask {

    public:
    xTaskHandle xth;
};

// TaskClass ---------------------------------------------------------

class FreeRTOSTask : public FreeRTOSBaseTask {

    public:
    FreeRTOSTask(char const* name,
                    unsigned portBASE_TYPE priority,
                    unsigned portSHORT stackDepth);

virtual void task() = 0;
static void tskfunc(void* parm);
};

// Task 1 ---------------------------------------------------------

class Task1 : public FreeRTOSTask {

    public:
    Task1(char const* name,
    unsigned portBASE_TYPE priority,
    unsigned portSHORT stackDepth);

void task();
};

// Task 2 ---------------------------------------------------------


class Task2 : public FreeRTOSTask {

public:
    Task2(char const* name,
    unsigned portBASE_TYPE priority,
    unsigned portSHORT stackDepth);

void task();
};


#endif


// ------------------------------------------------------------------

#ifdef __cplusplus
extern "C" {
#endif

void runTask();


#ifdef __cplusplus
}
#endif

// -------------------------------------------------------------------

#endif /* FREERTOSTASK_H_ */
FreeRTOSTask.cc
#include <FreeRTOSTask.h>

// -------------------------------------------------------------------


FreeRTOSTask::FreeRTOSTask(char const* name,
                            unsigned portBASE_TYPE priority,
                            unsigned portSHORT stackDepth) {

xTaskCreate(&tskfunc, (signed char*) name, stackDepth, this, priority, &xth);

}

void FreeRTOSTask::tskfunc(void* param) {

    static_cast<FreeRTOSTask *>(param)->task();
}


// Task-1---------------------------------------------------------------

Task1::Task1(char const* name,
                unsigned portBASE_TYPE priority,
                unsigned portSHORT stackDepth) : 
                           FreeRTOSTask(name, priority, stackDepth) {

}

void Task1::task() {

    volatile unsigned long ul;

    for( ;; )
    {
        for( ul = 0; ul < 0xffffff; ul++)
        {
            UARTPuts_(LPC_UART2, "rnFreeRTOS Task1 is runningrn");
            LED_On(7);
            LED_On(5);
            LED_On(3);
            LED_On(1);
        }
    }
}


// Task-2 -------------------------------------------------------------

Task2::Task2(char const* name,
                unsigned portBASE_TYPE priority,
                unsigned portSHORT stackDepth) : 
                            FreeRTOSTask(name, priority, stackDepth) {

}

void Task2::task() {

volatile unsigned long ul;

    for( ;; )
    {
        for( ul = 0; ul < 0xffffff; ul++)
        {
            UARTPuts_(LPC_UART2, "rnTask2 runningrn");
            LED_Off(7);
            LED_Off(5);
            LED_Off(3);
            LED_Off(1);
        }
    }
}



// ----------------------------------------------------------------


void runTask(){

    Task1 *tsk1;
    tsk1 = new Task1("Task1",1,1000);
    tsk1->task();

    Task2 *tsk2;
    tsk2 = new Task2("Task2",1,1000);
    tsk2->task();
}
FreeRTOS main()
/*-----------------------------------------------------------*/
int main( void )
{
    prvSetupHardware();
    runTask();

    /* Start the scheduler. */
    vTaskStartScheduler();
    // Will only get here if there was insufficient memory to create the idle
    // task.  The idle task is created within vTaskStartScheduler(). */

    for( ;; );
}
/*-----------------------------------------------------------*/

suspend & resume tasks on LPC1768

I have not seen the forest for the trees. But the question how to define the tasks as global/static to access the task objects is still open.
FreeRTOSTask.h
/* Add 2 new lines (export functions) */ 

[...]    
/* remove runTask() */
//void runTask();

xTaskHandle runTask1();
xTaskHandle runTask2();

[...]
FreeRTOSTask.cc
/* Add 2 new functions */

xTaskHandle runTask1(){

    Task1 *tsk1;
    tsk1 = new Task1("Task1",1,1000);
    return tsk1->xth;
}

xTaskHandle runTask2(){

    Task2 *tsk2;
    tsk2 = new Task2("Task2",1,1000);
    return tsk2->xth;
}
FreeRTOS main()
int main( void )
{
    /* remove runTask() */

    prvSetupHardware();
    xTaskHandle xtsk1;
    xtsk1 = runTask1();
    xTaskHandle xtsk2;
    xtsk2 = runTask2();

    vTaskPrioritySet(xtsk2, 10);

    /* Start the scheduler. */
    vTaskStartScheduler();
    [...]

}

suspend & resume tasks on LPC1768

That will work, but you are leaking the memory from your FreeRTOSTask objects, and you have lost the object to operate on with your member functions. In my wrappers, as I said, the constructors created the tasks and stored the handle. The destructor (rarely used) deleted the task. My program would look something more like: // These lines might be in different files Task task1(…parameters to create the task…); Task task2(…parameters to create the 2nd task …); int main(void){ prvSetupHardware(); // This might be omitted if global objects do this vTaskStartScheduler(); while(1); }

suspend & resume tasks on LPC1768

For the beginning I will be satisfied with a running program, memory optimization is more optional for the moment 😉 But you’re right, it is suboptimal and I have to fix it! By the way, do you think it is a good idea to store the object references in a array/map/vector?