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.

RTOS/EK-TM4C129EXL: Please, advise me to add second thread.

Part Number: EK-TM4C129EXL

Tool/software: TI-RTOS

Hello community,

sorry, maybe I did overseen something

What I Didi, I took a UART-DMA echo example.

It has one thread where UART connection is opened, then in endless looping echo is processed.

Just wanted to add second thread..

Simply adding in main following

   Task_Params taskParams1;
    Task_Params_init(&taskParams1);
    taskParams1.stackSize        = TASKSTACKSIZE;
    taskParams1.stack            = &task1Stack;
    taskParams1.instance->name   = "Uart RX Thread";
    Task_construct(&task1Struct, (Task_FuncPtr) UARTRXFxn, &taskParams1, NULL);

    /* Start BIOS */
    BIOS_start();

Unexpectedly, it doesnt work, secon thread was not started at all.

did I miss something?

 

  • Hi Yuliy,

    I'm assuming you have the following globals also.

    Task_Struct task1Struct;
    Char task1Stack[TASKSTACKSIZE];

    If that's the case, it should work. Can you set a breakpoint at BIOS_start and run to it. Then look at Tools->ROV->Task->Detailed in CCS. You should see three tasks (idle and the two that you created in main). You should be able to set breakpoints at the start of each task function also to confirm they are running (e.g. at UARTRXFxn and echoFxn).

    Minor nit, you don't need a second Task_Params structure. You can re-use the same one for both the Task_construct calls. Just make sure to change the needed fields as needed (e.g. stack and instance->name).

    Todd
  • >I'm assuming you have the following globals also. 

    Yes, I have.

    >Then look at Tools->ROV->Task->Detailed in CCS

    I have tools->ROV classic, and I see the following pic. Still second thread is not started.

  •  >Can you set a breakpoint at BIOS_start and run to it. Then look at Tools->ROV->Task->Detailed in CCS. Y

    now I did back sequence first I opened  Tools->ROV classic->Task->Detailed, then I run into  BIOS_start.

    I see following

  • I have the solution.
    Each task MUST have Task_yield(); call.
    Otherwise it doesnt work.

    Now, I have simple, question. Why it is not written in documentation?
    It is not optional, it is a MUST.
    such kind of info must be in documentation..
  • Oh no..

    what if a thread is blocked in, say, UART_read,
    It means that it will not yield..
    and it means that it all other threads will suffocate...

    is it what I call bad design? or I understand something wrong?
  • even worse..

    in this thread

    I read the answer from TI..

    "Coming to your second question. When Task_yield() is called, the currently running task will immediately yield the processor to the next same priority ready task."

    Huh? it means the low prio thread will never get a chance to run.

    Why then to introduce prio mechanism for thread?

    Looks like I am alone in this channel...

  • Yuliy Poluyanov said:
    Looks like I am alone in this channel...

    Probably because not many people here use TI's RTOS (Actually I think that's likely a pretty good general statement). You will have to check the manual on the tasking scheme.

    Robert

  • Hi Robert,

    > You will have to check the manual on the tasking scheme.

    The manual is laconic.. There no single words about Task_yield() command..for example..

    Looks like in presence of 2 thread with same priority, the tread with lower priority will ge no CPU at all.

    it suffocates.. 

    on my opinion iit is a serious design error.

  • Yuliy Poluyanov said:

    Looks like in presence of 2 thread with same priority, the tread with lower priority will ge no CPU at all.

    it suffocates.. 

    on my opinion iit is a serious design error.

    That's a fairly usual design decision, I think the only more common one is to outlaw multiple tasks having the same priority.

    Some RTOSs do have round-robin time slicing among tasks of equal priority but even in that case may default to the more efficient co-operative tasking scheme using as task yield of some sort. And note that in that case waits on semaphores etc.. usually have an implicit yield so you can write w/o adding explicit yields in many cases.

    The manual should have some sort of operating explanation/theory section that is separate from the function call explanations. Or you could just be seeing a reason to choose a less restrictive RTOS.

    Robert

  • You wrote:

    Some RTOSs do have round-robin time slicing among tasks of equal priority but even in that case may default to the more efficient co-operative tasking scheme using as task yield of some sort. And note that in that case waits on semaphores etc.. usually have an implicit yield so you can write w/o adding explicit yields in many cases.

    and nothing in documentation is said what strategy is implemented in TI-RTOS. 

    that is the point, must I test the threads and investigate is TI-RTOS is like "usualy" implemented implicit yield behind semaphore wait, or must i bother myself with yield..?

    Why not to write full and clear document? Maybe somebody from TI will se my complain..

    ok. sorry.. I close the topic.

  • It appears you are early enough in the process, that you could easily switch to a non vendor specific RTOS.

    Robert

    FREE-RTOS and uCOS-II come to mind as possibilities
  • Yuliy,

    TI-RTOS is a preemptive RTOS (much like most RTOS schedulers). The highest priority Task runs until it

    1. A higher priority thread becomes ready to run (e.g. higher priority Task, a Swi or a Hwi).

    2. It hits a blocking condition (e.g. Task_sleep or Semaphore_pend with a non-zero timeout and the semaphore is not available or UART_read and you need to block to wait for the data to come it).

    3. It calls Task_yield and another task of the same priority is ready to run (not a common use case).

    When you design a task, you should not spin on a resource for a long time since it can starve lower priority tasks (just like you should not spin on a resource in an ISR for a long time). Of course, if you have to do it, it's your choice, not the schedulers. It's up to the designer to set the priorities accordingly to the need of their system/application.

    TI-RTOS is actually rather popular in the embedded world. Here is a chart from 

    Unfortunately we've done a confusing job in messaging the name, so many times we get split into two items.

    The round-robin trick you saw is not commonly used. There are a few customers that desired it, so we showed a way it could be done. The much more common approach is to use the normal preemptive scheduler and use different priorities as needed.

    Todd

  • Thank you Todd,

    you message is cooperative and useful.

    You are right, I am at the bigining of my design and somwhere in proof-of-concept phase. It is not too late to change the OS.

    After night sleep, I still think that I adjust my design according to new input from you. I will remain by TI-RTOS.

    the only wish I would like to tell you. Please, put at least a link to the TI documentation so engineer can inform himself with pros and contras of scheduler inTI RTOS.

    Thank you very much.

  • Hi Yuliy,

    I'm glad my response was helpful. Moving forward we are trying to consolidate training in SimpleLink Academy (e.g dev.ti.com/.../ ). There is a lecture of general RTOS concepts and then labs on TI-RTOS. While these do not currently cover the TM4C devices, the concepts are applicable.

    Todd