0
\$\begingroup\$

As you know event flags are very useful (e.g. let task running),but unfortunately their control functions (os_evt_clr/set/wait) does not work outside of tasks bodies correctly(e.g. in interrupt handling functions). For alternative I used a variable ,I initialized it in Interrupt handler when needed ,then used it on another task to running a os_evt_set() function for let MCU entering a task.

    bool Instance_Variable;

    Interrupt_Handler()
    {
    if(xxxx)
    Instance_Variable=1
    }
//--------------------------        
    Secondary_Task()
    {
    //This is frequently run task
    if(Instance_Variable==1)
    {
    os_evt_set (0x0001, Primary_Task_ID);
    Instance_Variable=0;
    }
    }
//--------------------------    
    Primary_Task()
    {
    Result = os_evt_wait_or (0x0001, 0xFFFF);
    //Task's body 
    os_evt_clr (0x0001, Primary_Task_ID);
    }

Any better approach?WBR.

\$\endgroup\$
2
  • \$\begingroup\$ This is just a guess: Try setting your bool Instance_Variable as Volatile. \$\endgroup\$
    – Dejvid_no1
    Jan 16, 2016 at 21:48
  • \$\begingroup\$ Could the os_evt_xxx function be interrupt? If that's the case, what you do here is the easiest way to solve it. \$\endgroup\$
    – Anke Ge
    Jan 16, 2016 at 22:11

1 Answer 1

3
\$\begingroup\$

What I've done in these situations is use a message or mail queue depending on how much and the type of information you want to log. When used in the ISR the timeout values must be zero. Below is an example of how I'm handling an ISR from a FTM that is being used to measure an incoming PWM signal.

void FTM0_IRQHandler(void){ 
    toMail = (FTM_data*) osMailAlloc(FTM_mail,0);

    if( toMail == NULL ){
        FTM0_STATUS = 0x00;
        return;
    }

    toMail->status = FTM0_STATUS;
    toMail->c0v = FTM0_C0V;
    toMail->c1v = FTM0_C1V;
    toMail->c2v = FTM0_C2V;
    toMail->c3v = FTM0_C3V;

    osMailPut(FTM_mail,toMail);
    FTM0_STATUS = 0x00;
}

Now since I am using a mail queue here I have to make sure that a block of memory was alloc'ed for use, if the mail queue is full is will return NULL.

Now when you want to check for data in mail queue you can do the following. osWaitForever can be replaced with a number and then it will wait that number of milliseconds before returning a timeout error.

osEvent FTM_evt;
// Wait for FTM data
FTM_evt = osMailGet(FTM_mail,osWaitForever);        


if(FTM_evt.status == osEventMail){
    // Mail was present

    // Get data struct
    FTM_info = (FTM_data*) FTM_evt.value.p;

    // Free memory when done
    osMailFree(FTM_mail,FTM_info);

}else if(FTM_evt.status == osEventTimeout){
    // Time limit reached, no data present
}

There are two other errors as well. One for no mail in queue when you had no timeout specified and one for a parameter error.

Now if you only need to send a single number you can use a message queue. These are simpler because you do not need to alloc memory for them. The two calls are just osMessagePut with the name of the mail queue, the number, and the timeout. osMessageGet works the same way osMailGet does by either returning the first object in the queue or another code so say data was not available or the timeout was reached ect.

Now also know you have to initialize these queues with the ID's of the queues in the proper scope (global in most cases). Examples below.

// Mail system, FTM_mail is the ID used to access data, 15 is the size of the queue
// and FTM_data a structure type of the items that will be stored in the queue
osMailQDef(FTM_mail,15,FTM_data);
osMailQId FTM_mail;

int Init_Thread_RxPPM (void) {

    //Init mail
    FTM_mail = osMailCreate(osMailQ(FTM_mail),NULL);            

    //Start Thread
    tid_Thread_RxPPM = osThreadCreate (osThread(Thread_RxPPM), NULL);
    if(!tid_Thread_RxPPM) return(-1);  
    return(0);
}

Message queue initialization is nearly identical, just a few differences in parameters.

There is also a tutorial for RTX that includes more information about these topics as well as how to use a message queue to store pointers so you can have dynamic items in the queue

https://www.keil.com/pack/doc/CMSIS/RTX/CMSIS_RTOS_Tutorial.pdf

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.