This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/CC1352R: SysBios Event_post()

Part Number: CC1352R
Other Parts Discussed in Thread: SYSBIOS

Tool/software: Code Composer Studio

Hello,

I have some doubts concerning sysbios event module. I'm trying to wake up my project every X seconds using a clock module. Inside clock callback, there is an Event_post in order to "unlock" a fsmThread pending on the relative event-mask. 

This is my example code for Clock:

void *mainClockThread(void *arg0){

    Clock_Params clkParams;

    Clock_Params_init(&clkParams);
    clkParams.period = 60000000/Clock_tickPeriod; 
    clkParams.startFlag = TRUE;

    Clock_construct(&clk0Struct,(Clock_FuncPtr) clkFxn,60000000/Clock_tickPeriod, &clkParams);

}


void clkFxn(UArg arg0){

    x = Seconds_get();

    GPIO_toggle(Board_GPIO_LED0);
    Event_post(myEvent, WAKE_UP_EVENT);
}


While the fsmThread code :

while(1){

        event = Event_pend(myEvent, 0, WAKE_UP_EVENT, BIOS_WAIT_FOREVER);
        if ( event & WAKE_UP_EVENT)
            nextState = FSM_STATE_Toggle;
        else
            nextState = FSM_STATE_Idle;


        switch (nextState) {
            case FSM_STATE_Idle:

                // do nothing
                break;
            case FSM_STATE_Toggle:

                // post the event
                Event_post(myEvent, TOGGLE_EVENT);
                nextState = FSM_STATE_Print;
                break;
            case FSM_STATE_Print:

                // post the event
                Event_post(myEvent, PRINT_EVENT);
                nextState = FSM_STATE_Idle;
                break;
            default:
                break;
        }

        b = false;
        usleep(100);
    }

Where toggleEvent and printEvent awake two different threads that toggle a led and print something on display_uart. 

With Event_post() inside of clkFxn nothing works. Is it possible to use it inside the clockCallback? If I check postedEvents value inside the myEvent struct during the clockCallback I get the correct value but the toggleThread does not start at all. Do you have any idea why? 

Regards,
Vincenzo

  • Vincenzo,

    Can you confirm the Clock function is running. You can look at it in Tools->Runtime Object View->Clock->Basic. Note: the params.period and timeout argument are in Clock ticks. So 60000000/Clock_tickPeriod = 6,000,000 Clock ticks which is 60,000,000 us so 60 seconds.

    What do the other calls to Event_pend look like? Could they be the one receiving the event? Also, what are the values of WAKE_UP_EVENT, et.al.

    Todd

  • Hi Todd,

    ToddMullanix said:

    Can you confirm the Clock function is running. You can look at it in Tools->Runtime Object View->Clock->Basic. 

    This is what I get:


    Otherwise, if I comment the Event_post API inside clockCallbak ROV shows me clkFxn(the callback), all the threads and also the Event pending.


    ToddMullanix said:

    What do the other calls to Event_pend look like? Could they be the one receiving the event? Also, what are the values of WAKE_UP_EVENT, et.al.



    The other calls are all the same as the fsmThread one. For example the one for the printer:

    // printerThread
    while (1) {
    
            event02 = Event_pend(myEvent, 0, PRINT_EVENT, BIOS_WAIT_FOREVER);
    
            /*sleep(time);*/
            time += 1;
            Display_printf(hSerial, 0, 0, "hello:%d\r\n", time);
    
        }

    Event value are :

    #define ALL_EVENT               (uint32_t)( 0xFF )
    #define WAKE_UP_EVENT           (uint32_t)(1 << 0)
    #define TOGGLE_EVENT            (uint32_t)(1 << 1)
    #define PRINT_EVENT             (uint32_t)(1 << 2)


    Regards,

    Vincenzo 




  • Vincenzo,

    It looks like your mainClockThread function is not being called since the Clock is not in ROV. Can you confirm this?

    Is mainClockThread a task (or pThread). If so, does it do anything else? You could construct the Clock in main() instead and save a task if this is the only thing it does.

    Todd

  • Todd,

    sorry, this was my very first using ROV, maybe I did something wrong before. I tried again, refreshing also the tab in ROV, and I found my clkFxn (callback) inside the Clocks. Nevertheless, it did not post any pending threads.

    ToddMullanix said:

    If so, does it do anything else? You could construct the Clock in main() instead and save a task if this is the only thing it does.


     

    However, the mainClockThread does also a GPIOToggle and this feature works fine.  I just tried also the main() solution that you suggest ... without success. 

    Note: If I remove the Event_post API from the clockCallback and use a simple boolean to start my fsmThread everything works fine, also the other Event_post/pend used to unlock/lock toggleThread and printerThread works. Why only the clockCallback do this?  

  • Vincenzo Cristiano said:
    However, the mainClockThread does also a GPIOToggle and this feature works fine.  I

    mainClockThread or clkFxn? Does a breakpoint in clkFxn get hit at the expected rate (i.e. 60 seconds).

  • Todd,


    ClockFxn.
    Yes, a breakpoint in clkFxn gets hit at the expected rate (now just 10 seconds).

    I also noticed (picture below) that the posted Event shown in ROV table is correct but the pending Thread does not start consequently. 



    Regards, 
    Vincenzo

  • Hello,

    I tried to remove thread by thread in order to simplify the whole script. Suddenly, It works. Right now there are 3 different threads pending on different events that will be posted by the clkFxn every x seconds. These threads are really simple (toggle led, display_printf). But, if I put the fsmThread that I wrote in the previous posts nothing goes ahead, even if the clkFxn hit every x seconds.

    Could it be an issue related to threads nature or stack_size?

    Moreover, in these conditions, what will be the power consumption when every thread will be blocked on their events? The CPU will be in standby or idle power modes?

    Best Regards,

    Vincenzo 

  • Vincenzo,

    Can you make a simple example project that has the issue and post it please. It rather hard to debug this when I told have the source code and the task names you are saying don't make up with what ROV is showing (e.g. there is no fsmThread in the ROV view).

    Todd

  • Todd,

    you are right, trying to solve my issue I did some changes in the previous posts making the issues a little unclear.

    This is what I get NOW:

    main() => Clock with a period of x seconds; clkFxn (callback) there is an Event_post for the fsmThraed. I debugged it and every x seconds a breakpoint is hit.

    Clock_Params clkParams;
    
    Clock_Params_init(&clkParams);
    clkParams.startFlag = TRUE;
    
    Clock_construct(&clk0Struct,(Clock_FuncPtr) clkFxn,3000000/Clock_tickPeriod, &clkParams);
    
    /* pthread_create() for all the threads */
    
    
    void clkFxn(UArg arg0){
    
    //    GPIO_toggle(Board_GPIO_LED0);
        Event_post(myEvent, WAKE_UP_EVENT);
    }

    fsmThread => A finite state machine used to activate other threads.

    fsmState nextState;
    fsmState currState = FSM_STATE_Idle;
    void *mainfsmThread(void *arg0)
    {
        /* 1 second delay */
        uint32_t time = 3;
    
        /* Call driver init functions */
        GPIO_init();
    
    
        while(1){
    
            event = Event_pend(myEvent, 0, ALL_EVENT, BIOS_WAIT_FOREVER);
            if (event & WAKE_UP_EVENT){
                currState = nextState;
            }else {
                currState = FSM_STATE_Idle;
            }
    
            switch (currState) {
                case FSM_STATE_Idle:
    
                    // do nothing
                    nextState = FSM_STATE_Toggle;
                    break;
                case FSM_STATE_Toggle:
    
                    // post the event
                    Event_post(myEvent, TOGGLE_EVENT);
                    nextState = FSM_STATE_Print;
                    break;
                case FSM_STATE_Print:
    
                    // post the event
                    Event_post(myEvent, PRINT_EVENT);
                    nextState = FSM_STATE_Idle;
                    break;
                default:
                    break;
            }
    
            b = false;
            usleep(100);
        }

    serviceThread => Toggle a led;

     while (1) {
    
            event01 = Event_pend(myEvent, 0, TOGGLE_EVENT, BIOS_WAIT_FOREVER);
    
            /*sleep(time);*/
            GPIO_toggle(Board_GPIO_LED1);
    
        }

    printerThread => Print something on display uart.

    cfg = 0xAA;
    
        while (1) {
    
            event02 = Event_pend(myEvent, 0, PRINT_EVENT, BIOS_WAIT_FOREVER);
    
            /*sleep(time);*/
            if (event02 & PRINT_EVENT ){
                time += 1;
                Display_printf(hSerial, 0, 0, "<cfg:%x>hello:%d\r\n", cfg, time);
            }
    
        }

    ROV view:


    What I expect to see is an Event_post directed to fsmThread every 3 seconds that change the FSM currentState. This happens only the first time and not every 3 seconds. Is it something related to the fsm logic? 
    If I remove the fsmThread from the main(), and so change the clkFxn to post directly serviceThread and printerThread, it works fine with a post every 3 seconds as I expect. 

    P.S. I hope this is clearer than before.

    Regards,
    Vincenzo

  • Hi Vincenzo,

    Thanks. Sorry, I should have noticed this sooner, but per the Event API Reference "Unlike Semaphores, only a single task can pend on an Event object.". So your design is invalid. You need to make three different Event instances. So the fsmThread will pend as you have, but then it will Event_post either the printThread Event instance or the serviceThread Event instance. Those task will then Event_pend on their respective Event instances.

    Todd

  • Todd,

    Thanks for your help, it has been very precious!

    Just another simple question: when all the threads are blocked waiting for an event_pend in which state is the CPU in?


    Thank you,
    Vincenzo

  • Vincenzo,

    If all tasks are blocked (and no Swi or Hwi is running), the Idle task will run. The Power module adds in an Idle function. 

    The Idle task just loops through all the Idle functions. If the power policy is enabled (see below) the Power_idleFunc() function will go into the lowest power mode based on the current constraints. Please refer to the docs\tidrivers\Power_Management.pdf for more details.

      

    Todd

  • Todd,

    Thank you! Everything is clear! 

    Wish you all the best in your work.


    Best regards,
    Vincenzo