/** \brief Test case: TC_MutexOwnership \details - Create a mutex object - Create a child thread and wait until acquires mutex - Create a child thread that trys to release a mutex - Only thread that obtains a mutex can release it. */ void TC_MutexOwnership (void) { osThreadId ctrl_id, id[2]; /* Ensure that priority of the control thread is set to normal */ ctrl_id = osThreadGetId(); ASSERT_TRUE (osThreadSetPriority (ctrl_id, osPriorityNormal) == osOK); /* - Create a mutex object */ G_MutexId = osMutexCreate (osMutex (Mutex_Ownership)); ASSERT_TRUE (G_MutexId != NULL); if (G_MutexId != NULL) { /* - Create a child thread and wait until acquires mutex */ id[0] = osThreadCreate (osThread (Th_MutexAcqLow), NULL); ASSERT_TRUE (id[0] != NULL); if (id[0] != NULL) { osDelay(10); /* - Create a child thread that trys to release a mutex */ id[1] = osThreadCreate (osThread (Th_MutexRelHigh), NULL); ASSERT_TRUE (id[1] != NULL); /* Terminate both threads */ if (id[1] != NULL) { ASSERT_TRUE (osThreadTerminate (id[1]) == osOK); } ASSERT_TRUE (osThreadTerminate (id[0]) == osOK); } } /* - Delete a mutex object */ ASSERT_TRUE (osMutexDelete (G_MutexId) == osOK); }
/*..........................................................................*/ void QF_setRtxPrio(QActive *act, osPriority prio) { if (act->thread == (osThreadId)0) { /* thread not started yet? */ act->osObject = (uint32_t)prio; /* store the RTX prio, see NOTE1 */ } else { osThreadSetPriority(act->thread, prio); } }
osStatus Thread::set_priority(osPriority priority) { osStatus ret; _mutex.lock(); ret = osThreadSetPriority(_tid, priority); _mutex.unlock(); return ret; }
/*---------------------------------------------------------------------------- * Main Thread *---------------------------------------------------------------------------*/ int main (void) { /* program execution starts here */ /* Set higher priority of main thread to preempt job2 */ osThreadSetPriority(osThreadGetId(), osPriorityAboveNormal); thread1_id = osThreadCreate(osThread(job1),NULL); /* create thread1 */ thread2_id = osThreadCreate(osThread(job2),NULL); /* create thread2 */ thread3_id = osThreadCreate(osThread(job3),NULL); /* create thread3 */ while (1) { /* endless loop */ counter++; /* increment counter */ osDelay(5); /* wait for timeout: 5ms */ } }
// Main program int main (void) { DAP_Setup(); // DAP Setup USBD_Initialize(0U); // USB Device Initialization USBD_Connect(0U); // USB Device Connect while (!USBD_Configured(0U)); // Wait for USB Device to configure LED_CONNECTED_OUT(1U); // Turn on Debugger Connected LED LED_RUNNING_OUT(1U); // Turn on Target Running LED Delayms(500U); // Wait for 500ms LED_RUNNING_OUT(0U); // Turn off Target Running LED LED_CONNECTED_OUT(0U); // Turn off Debugger Connected LED // Create HID Thread HID0_ThreadId = osThreadCreate(osThread(HID0_Thread), NULL); osThreadSetPriority(osThreadGetId(), osPriorityIdle); for (;;); // Endless Loop }
/*..........................................................................*/ void QF_setRtxTicker(uint32_t period, osPriority prio) { l_tickerPeriod = period; osThreadSetPriority(l_tickerThreadId, (prio != 0 ? prio : osPriorityNormal)); }
osStatus Thread::set_priority(osPriority priority) { return osThreadSetPriority(_tid, priority); }
/** \brief Test case: TC_MutexPriorityInversion \details - Set priority of the control thread to normal - Create low priority thread, which will acquire mutex - Wait until low priority thread acquires mutex - Raise priority of the control thread - Create high priority thread, which will wait for a mutex - Allow high priority job to wait for mutex - Create medium priority thread - Set priority of the control thread to be the lowest of all - Wait until all jobs finish - Verify thread execution order - Thread execution order must be: Low, High, Medium */ void TC_MutexPriorityInversion (void) { osThreadId ctrl_id, id[3]; osStatus stat; osEvent evt; uint32_t i; /* Init execution array */ for (i = 0; i < 3; i++) { G_ExecArr[i] = 0; } /* Get id of the control thread */ ctrl_id = osThreadGetId(); /* - Set priority of the control thread to normal */ stat = osThreadSetPriority (ctrl_id, osPriorityNormal); ASSERT_TRUE (stat == osOK); if (stat == osOK) { /* Create a mutex object */ G_MutexId = osMutexCreate (osMutex (Mutex_PrioInv)); ASSERT_TRUE (G_MutexId != NULL); if (G_MutexId != NULL) { /* - Create low priority thread, which will acquire mutex */ id[0] = osThreadCreate (osThread (Th_LowPrioJob), &ctrl_id); ASSERT_TRUE (id[0] != NULL); if (id[0] != NULL) { /* - Wait until low priority thread acquires mutex */ evt = osSignalWait (0x01, 100); ASSERT_TRUE (evt.status == osEventSignal); if (evt.status == osEventSignal) { /* - Raise priority of the control thread */ stat = osThreadSetPriority (ctrl_id, osPriorityAboveNormal); ASSERT_TRUE (stat == osOK); if (stat == osOK) { /* - Create high priority thread, which will wait for a mutex */ id[1] = osThreadCreate (osThread (Th_HighPrioJob), &ctrl_id); ASSERT_TRUE (id[1] != NULL); if (id[1] != NULL) { /* - Allow high priority job to wait for mutex */ osSignalWait (0x01, 100); /* - Create medium priority thread */ id[2] = osThreadCreate (osThread (Th_MediumPrioJob), &ctrl_id); ASSERT_TRUE (id[2] != NULL); if (id[2] != NULL) { /* - Set priority of the control thread to be the lowest of all */ stat = osThreadSetPriority (ctrl_id, osPriorityLow); ASSERT_TRUE (stat == osOK); if (stat == osOK) { /* Wait until all jobs finish */ evt = osSignalWait (0x0E, 100); ASSERT_TRUE (evt.status == osEventSignal); if (evt.status == osEventSignal) { /* - Verify thread execution order */ ASSERT_TRUE (G_ExecArr[0] == 'L'); ASSERT_TRUE (G_ExecArr[1] == 'H'); ASSERT_TRUE (G_ExecArr[2] == 'M'); } } } } } } } } /* - Delete mutex object */ ASSERT_TRUE (osMutexDelete (G_MutexId) == osOK); /* - Restore priority of the control thread to normal */ stat = osThreadSetPriority (ctrl_id, osPriorityNormal); ASSERT_TRUE (stat == osOK); } }
/** * Initializes the console */ void Task_SerialConsole(void const* args) { const osThreadId mainID = (const osThreadId)args; // Store the thread's ID const osThreadId threadID = Thread::gettid(); ASSERT(threadID != nullptr); // Store our priority so we know what to reset it to after running a command const osPriority threadPriority = osThreadGetPriority(threadID); // Initalize the console buffer and save the char buffer's starting address std::shared_ptr<Console> console = Console::Instance(); // Set the console username to whoever the git author is console->changeUser(git_head_author); // Let everyone know we're ok LOG(INIT, "Serial console ready!\r\n" " Thread ID: %u, Priority: %d", threadID, threadPriority); // Signal back to main and wait until we're signaled to continue osSignalSet(mainID, MAIN_TASK_CONTINUE); Thread::signal_wait(SUB_TASK_CONTINUE, osWaitForever); // Display RoboJackets if we're up and running at this point during startup console->ShowLogo(); // Print out the header to show the user we're ready for input console->PrintHeader(); // Set the title of the terminal window console->SetTitle("RoboJackets"); while (true) { // Execute any active iterative command execute_iterative_command(); // If there is a new command to handle, parse and process it if (console->CommandReady() == true) { // Increase the thread's priority first so we can make sure the // scheduler will select it to run osStatus tState = osThreadSetPriority(threadID, osPriorityAboveNormal); ASSERT(tState == osOK); // Execute the command NVIC_DisableIRQ(UART0_IRQn); size_t rxLen = console->rxBuffer().size() + 1; char rx[rxLen]; memcpy(rx, console->rxBuffer().c_str(), rxLen - 1); rx[rxLen - 1] = '\0'; execute_line(rx); NVIC_EnableIRQ(UART0_IRQn); // Now, reset the priority of the thread to its idle state tState = osThreadSetPriority(threadID, threadPriority); ASSERT(tState == osOK); console->CommandHandled(); } // Check if a system stop is requested if (console->IsSystemStopRequested() == true) break; // Yield to other threads when not needing to execute anything Thread::yield(); } }
/*! \fn void thread0 (void const *argument) \brief Thread definition for thread 0. \param argument A pointer to the list of arguments. */ void thread0 (void const *argument) { if (addTraceProtected("thread0 start run") != TRACE_OK) { stop_cpu; } while (1) { if (addTraceProtected("thread0 take sem0 attempt") != TRACE_OK) { stop_cpu; } if ( osSemaphoreWait (sid_Semaphore0, 0) != -1 ) // no wait { if (addTraceProtected("thread0 take sem0 success") != TRACE_OK) { stop_cpu; } task0(); // thread code count1Sec(); task0(); if (addTraceProtected("thread0 set priority to osPriorityLow") != TRACE_OK) { stop_cpu; } osThreadSetPriority(osThreadGetId(), osPriorityLow); if (addTraceProtected("thread0 yields") != TRACE_OK) { stop_cpu; } osThreadYield(); // suspend thread if (addTraceProtected("thread0 release sem0 attempt") != TRACE_OK) { stop_cpu; } if (osSemaphoreRelease (sid_Semaphore0) != osOK) { if (addTraceProtected("thread0 release sem0 fail") != TRACE_OK) { stop_cpu; } } else { if (addTraceProtected("thread0 release sem0 success") != TRACE_OK) { stop_cpu; } } } else { if (addTraceProtected("thread0 take sem0 fail") != TRACE_OK) { stop_cpu; } } if (addTraceProtected("thread0 set priority to osPriorityLow") != TRACE_OK) { stop_cpu; } osThreadSetPriority(osThreadGetId(), osPriorityLow); if (addTraceProtected("thread0 yields") != TRACE_OK) { stop_cpu; } osThreadYield(); // suspend thread if (addTraceProtected("thread0 back from yield") != TRACE_OK) { stop_cpu; } if (addTraceProtected("thread0 delete sem0") != TRACE_OK) { stop_cpu; } if (Delete_Semaphore0() != 0) { stop_cpu; } // This should terminate the current thread0 thread if (Terminate_thread0() != 0) { stop_cpu; } } }
/*! \brief Thread definition for thread 2. \param argument A pointer to the list of arguments. */ void thread2 (void const *argument) { if (addTraceProtected("thread2 start run") != TRACE_OK) { stop_cpu; } while (1) { if (addTraceProtected("thread2 take sem0 attempt") != TRACE_OK) { stop_cpu; } if ( osSemaphoreWait (sid_Semaphore0, osWaitForever) != -1 ) // wait forever { if (addTraceProtected("thread2 take sem0 success") != TRACE_OK) { stop_cpu; } task2(); // thread code count1Sec(); task2(); if (addTraceProtected("thread2 release sem0 attempt") != TRACE_OK) { stop_cpu; } if (osSemaphoreRelease (sid_Semaphore0) != osOK) { if (addTraceProtected("thread2 release sem0 fail") != TRACE_OK) { stop_cpu; } } } else { if (addTraceProtected("thread2 take sem0 fail") != TRACE_OK) { stop_cpu; } } if (addTraceProtected("thread2 set priority to osPriorityBelowNormal") != TRACE_OK) { stop_cpu; } osThreadSetPriority(osThreadGetId(), osPriorityBelowNormal); if (addTraceProtected("thread2 yields") != TRACE_OK) { stop_cpu; } osThreadYield(); // suspend thread if (addTraceProtected("thread2 back from yield") != TRACE_OK) { stop_cpu; } // This should terminate the current thread2 thread if (Terminate_thread2() != 0) { stop_cpu; } } }