Global ThreadX objects

Objects as event flags, mutexes etc. can be defined per thread in the configurator. But their purpose is thread sychronization so there is a need for shared objects which should be visible from all threads and mainly initialized before any thread starts.

There is  tx_application_define_user() function which could be used for this purpose but it is called AFTER all threads starts (which makes no sense to me). So how to perform a, I believe, common task i.e. call initialization code which needs to be called before any thread starts? I could make every thread wait on an event flag set after all initialization is done. Fine but it needs global object and it has to be initialized BEFORE any thread starts.

Well, I can define such an object in the first thread and because threads are started in defined order and objects are created before thread really starts it should work. But it is ugly and probably depends on an undocumented behavior. Is there a supported and more elegant way how to do it?

  • Hi Michal-
    Have you tried creating an object like a semaphore to see if it is made available to other threads? Make sure you include the header file for the thread you created the semaphore in the other thread entry files.

    I just did it for a project with multiple threads and it compiles fine. blinky_thread is the thread I created g_new_semaphore0 in...

    ++++++++
    #include "new_thread2.h"
    #include "blinky_thread.h"

    /* Little Thread C entry function */
    void new_thread2_entry(void)
    {
    /* TODO: add your own code here */
    while (1)
    {
    tx_thread_sleep (4);
    tx_semaphore_get(&g_new_semaphore0, TX_WAIT_FOREVER);
    tx_thread_sleep (20);
    tx_semaphore_put(&g_new_semaphore0);
    }
    }
    ++++

    Let me know if you want me to upload the full project...
  • In reply to WarrenM:

    Warren, that's not a problem, I can see objects from different threads. The problem is initialization order. If I create an object in one thread, the other thread can try to use it before it is created. That's why objects should be created before threads are started. Sleeps aren't way to sychronize.

    Well, the way Synergy configurator uses objects doesn't make sense to me. Objects are used for threads synchronization so why they can be created only in a context of some speficic thread?
  • In reply to Michal:

    if you look at the initialisation code for threadx in the file tx_initialize_kernel_enter.c (you will need to add threadx source code to the project) you can see the initialisation flow for threadx. The Threads and thread objects added in the Synergy configurator are created in the call to tx_application_define(); (which will also call tx_application_define_user() if added by the user to the project) :-

    However the threads are not actually executed until the scheduling loop is entered :-

     

  • In reply to Jeremy:

    Good, thank you :) So I can do all the global initialization inside tx_application_define_user() call and don't have to worry about threads running.

    Still I believe generated code is suboptimal. Is there any good reason why NOT call this function before creating threads? It would be apparent with no doubts and with no need to examine ThreadX implementation details.

    Also, I believe configurator should allow to create global synchronization objects. They're more important than ones created in thread context and in turn current way is just misleading.
  • In reply to Michal:

    Well, it was a bit more complicated. I've found some modules as crypto can't be initialized from tx_application_define_user() because their lower part isn't initialized, yet. So I had to divide initialization to the two parts. The first is called from tx_application_define_user() and creates global objects and the second is called at the start of one thread and all other threads wait until it is done using global event flags created in the first phase. Rather messy but works.