- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
when I make three tasks synchronized by semaphores (the tasks do nothing, they only make a Post and then a Pend to pass the control each other), after a number of iterations (this number is ever the same) the program is blocked. If I put a delay after the Pend, the number of iterations grew, but after this number of iterations the program crash. Why?? ThanksLink Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Nobody had the same problem? I don't understand why the program crashes, it make nothing, there are only three tasks and each launches the other between semaphores: task A launches task B that launches task C that launches task A, and so on. After 107 iterations, the program crashes!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
could you post your code?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for the interesting.
The code is: #include "includes.h" #include <iostream> using namespace std; #define OS_TASK_STAT_EN 1 #define OS_MAX_TASKS 8 #define TASK_STK_SIZE 1024 OS_STK TaskStartStk[TASK_STK_SIZE]; OS_STK TaskStartStk1[TASK_STK_SIZE]; OS_STK TaskStartStk2[TASK_STK_SIZE]; OS_STK TaskStartStk3[TASK_STK_SIZE]; OS_EVENT* sem_sync0; OS_EVENT* sem_sync1; OS_EVENT* sem_sync2; OS_EVENT* sem_sync3; void handle_sync(void* pdata) { INT8U err_sync3; pdata = pdata; for(;;) { cout << "I'm in handle_sync" << endl; fflush(0); OSSemPost(sem_sync1); OSSemPend(sem_sync3, 0, &err_sync3); } } void processing(void* pdata) { INT8U err_sync1; pdata = pdata; for(;;) { cout << "I'm in processing" << endl; fflush(0); OSSemPost(sem_sync2); OSSemPend(sem_sync1, 0, &err_sync1); } } void monitoring(void* pdata) { INT8U err_sync2; pdata = pdata; for(;;) { cout << "I'm in monitoring" << endl; fflush(0); OSSemPost(sem_sync3); OSSemPend(sem_sync2, 0, &err_sync2); } } static void TaskStartCreateTask(void) { cout << "I'm in TaskStartCreateTask" << endl; fflush(0); OSTaskCreate(handle_sync, (void*) 0, &TaskStartStk1 [TASK_STK_SIZE - 1], 11); OSTaskCreate(processing, (void*) 0, &TaskStartStk2[TASK_STK_SIZE - 1], 12); OSTaskCreate(monitoring, (void*) 0, &TaskStartStk3[TASK_STK_SIZE - 1], 15); } void TaskStart(void* pdata) { INT8U err_sync0; cout << "I'm in TaskStart" << endl; fflush(0); pdata = pdata; OSStatInit(); OSTaskCreate(handle_sync, (void*) 0, &TaskStartStk1[TASK_STK_SIZE - 1], 11); OSTaskCreate(processing, (void*) 0, &TaskStartStk2[TASK_STK_SIZE - 1], 6); OSTaskCreate(monitoring, (void*) 0, &TaskStartStk3[TASK_STK_SIZE - 1], 15); for(;;) { OSSemPost(sem_sync3); OSSemPend(sem_sync0, 0, &err_sync0); } } int main() { OSInit(); sem_sync0 = OSSemCreate(0); sem_sync1 = OSSemCreate(0); sem_sync2 = OSSemCreate(0); sem_sync3 = OSSemCreate(0); cout << "I'm in the main" << endl; fflush(0); OSTaskCreate(TaskStart, (void*) 0, &TaskStartStk[TASK_STK_SIZE - 1], 18); OSStart(); }- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm pretty sure the standard output drivers aren't thread safe, so if you write from several threads at the same time you can crash. It's better either to only print out from one task, or use something else, such as leds, to monitor the threads activities.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the answer, but now, because hardware's problems, I can't verify if your idea is right.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If I put the semaphore in this way:
OSSemPend(sem); cout << "Hello world" << endl; OSSemPost(sem, 0, err); does it become thread safe? Thanks- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, as long as you do that in every thread that uses the standard output, and that you use the same semaphore on each, obviously.
I re-read your code and I'm wondering something... where do you post your semaphore sem_sync0 ? What are you trying to achieve in this code?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't post sem_sync0 because I want that TaskStart creates the other tasks and stops: sem_sync0 never becomes 1, then TaskStart never runs, only at the beginning. But I don' think that this is the problem, because the same problem is verified when the three tasks are created in the main and not in TaskStart, i.e. when there isn't the thread TaskStart.
Thanks- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A task can kill itself with OsTaskDel(OS_PRIO_SELF);
After this call the task will be deleted. Did you see any improvement by using this semaphore to make the standard output thread safe?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Unfortunately now I've not the hardware, and then I can't try if it runs. According to you, with the semaphores to make the cout thread safe, must it function?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It should work, yes
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Italian,
I know that this post is a bit old, but if you didn't already solved your problem I have a suggest for you. I took a look to your code and I saw the call to OSInit() function: :evil: you don't have to call it because it is already called within alt_main() function that is called before your main()! If you do it, that function initialize os structure, included semaphre, mailbox, queue, etc... If you call it a second time after one in alt_main() you will re-assign all previously initialized semaphore (e.g. uart one, jtag one, etc)!!! Ciao- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Hi Italian, I know that this post is a bit old, but if you didn't already solved your problem I have a suggest for you. I took a look to your code and I saw the call to OSInit() function: :evil: you don't have to call it because it is already called within alt_main() function that is called before your main()! If you do it, that function initialize os structure, included semaphre, mailbox, queue, etc... If you call it a second time after one in alt_main() you will re-assign all previously initialized semaphore (e.g. uart one, jtag one, etc)!!! Ciao --- Quote End --- Ho letto solo ora il tuo post, grazie per la risposta. Il problema l'ho risolto cambiando strategia di programmazione: un solo loop infinito senza sistema operativo. Però mi interessa capire il perché del malfunzionamento. Ho chiamato OSInit() perché ho seguito le indicazioni del libro su MicroC/OS-II. Dici che è già chiamata dentro alt_main()? Ma cos'è questa alt_main()? Grazie Ciao
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
alt_main() is the first C code called from the assembler startup code, it initialises things like stdin and stdout, then calls the uses's main().
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Moreover alt_sys_init() also instantiate and init all device you foreseen in your pld (e.g. ALTERA_AVALON_UART_INSTANCE and ALTERA_AVALON_UART_INIT); this has the consequence that isr function for uart is anyway linked and included in your firmware also if you provide another one written by yourself.
alt_sys_init() function is in your source file named as alt_sys_init().c and you can find it within syslib folder or bsp folder. Ciao
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page