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.

TI-RTOS multiple clock instances

Other Parts Discussed in Thread: SYSBIOS

Hi,

 I am trying to send periodic BLE messages using a clock module that came with simpleBLEperipheral example. I would like to expand that concept and use multiple clocks where I could send different measurements with each having its own timing interval. Basically each measurement would have it's own timer.  

Ideally I would like to be able to create/destroy timers based on received messages. But it seems like I have to create predetermined number of clock instances first and then decide if I want to use them based on the need.

Is  creating multiple clock instances my only option here for sending messages at different timing intervals?

I read in another post about an event object that might work better but I didn't find any examples.

e2e.ti.com/.../1925760

Thanks

  • Please note there is a difference between Clock instances and Timer instances. TI-RTOS by default uses the RTC timer to drive it's internal timing (e.g. if you call Semaphore_pend with a timeout). The Clock module allows users to create additional Clock functions that will be called at the specified time (note you can have a one-shot or periodic Clock function). Creating new Clock instances does not use more timers.

    The RTC timer is used by the kernel because it allows the kernel to better manage low-power modes.

    You can use different timers if the kernel's Clock module is not sufficient but it does not seem like you need to.

    The Event module is basically like the select() function. It allows you to block waiting on multiple things (e.g. multiple semaphores or/and mailboxes).

    Todd
  • Thanks Todd,
    I'll use Clock module, it seems like it might work.
    What happens when I call Clock_destruct()? Do I have to stop the clock before I call it? I have an array of clock structs and I'd like to construct clocks and have them fire at different time intervals and then at some point I'd like to stop them. But I'm not sure if calling Clock_destruct() is the best way to do that or if I should just stop the clock and reschedule it later, or if I should call Clock_desctruct() and then construct new instance when I need it.

    Thanks
  • There are several strategies that you could use.

    These are the things to consider when designing your solution:
    1- There is dynamic and static ways to instanciate your clocks.
    Clock_create/Clock_delete dynamically assigns memory from the heap.
    Clock_construct/Clock_destruct do it statically (you need to have declared a Clock_Struct in your code)

    2 - You can use the following function to change the handler function and parameters (after the clock has been constructed/created).
    Void Clock_setFunc(Clock_Handle handle, Clock_FuncPtr fxn, UArg arg);

    3- You can use the following function to change the period (after the clock has been constructed/created).
    Void Clock_setPeriod(Clock_Handle handle, UInt32 period);

    So the one important element that you need to consider is whether you could have several clocks running at the same time.

    If there is only one clock at a time, you can use the functions above to modify the parameters as you need.

    Otherwise, you can have a predetermined number of clocks where each will serve its purpose, or you dynamically create and delete your clocks.
    If you don't know how many clocks you need (or that number could change), you can always use Clock_create (which will instanciate a new clock every time you call it).

    That means that you could have different events generating a new clock every time an event occurs.
    But you would also need to delete each instance otherwise you will quickly run out of memory. In order to delete the clock, you need a handle to the newly created clock. You first create your clock and then call Clock_setFunc to pass its own Clock_Handle as a parameter. (You would have to check whether you can delete a Clock from within its own handler function. I don't know the mechanics of the clock so it could potentially crash your system because the clock would no longer exist. You would have to ask someone from TI to answer that question)

    So you choose what suits your needs.
  • Thank you for your very informative answer!

    I could have a maximum of 16 clocks and many could run at the same time. I think that's the limitation of the callback argument that's 16bits long. Is that a correct assumption?

    Since I have an array of clock structs then it makes sense that I don't dynamically create a clock instance.

    Here's what my array of strucks looks like:

    typedef struct
    {
       bool                 isActive;
       Clock_Struct  periodicClock;
    uint8_t command; uint16_t interval; } event_t; event_t Sessions[16];

    So I will construct a clock instance in each array element. From your reply when I don't need a clock I can destruct it. And then I have to create it again?

    Also, is there a limit to the amount of concurrent clocks that can be created? 

    Thanks

  • The argument type given to the clock handler function is a UArg, which means 32 bits. If your MCU is also 32 bits, that means you could even pass a pointer to whatever you want (a large struct for example)

    As for your event_t struct, you wouldn't need the bool isActive since Sysbios already provides this function:
    Bool Clock_isActive(Clock_Handle handle);
    You would simply need to use the function Clock_handle (notice the small h in handle instead of Handle) to convert your Clock_Struct to a Clock_Handle.

    For the construction and destruction of your clocks, I don't see any reason why you would want to create and destroy them every time. The memory for all your clocks is already reserved when you declare your array of structs that contain the clocks. If memory is of importance, then you could use Clock_Handle (it's a pointer so 32 bits only) instead of your Clock_Struct. You would create and delete them as you need. The memory space would be taken from the heap.

    If memory is not an issue, then construct them all before your app starts running. Then all you have to worry about is starting and stopping them as you need. I don't believe there would be a big impact on performance if all your clocks are sitting idle. (I would ask TI the impact of having many idle clocks). Even if you assign your clocks to different messages (or sessions), use Clock_setFunc to change the parameters of your clock. This will be more efficient than constructing and destroying your clocks each time.
  • When you create/construct a Clock instance, you can have it not start by setting params.startFlag = false. There is no overhead for having the clock function not be started (other than some memory). When you want to start it, simply call Clock_start. If you don't want it to run, you can call Clock_stop.

    Please note, having N Clock instances does not result in N timers. All the Clock functions are called in the context of the single Timer used by the kernel to drive the Clock module.

    Todd
  • There was a suggested answer and since there has been no active on this thread for more than a week, the suggested answer was marked as verify. Please feel free to select the "Reject Answer" button and reply with more details.