| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795 |
- /*
- * Copyright (c) 2013-2023 Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the License); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * -----------------------------------------------------------------------------
- *
- * Project: CMSIS-RTOS RTX
- * Title: Thread functions
- *
- * -----------------------------------------------------------------------------
- */
- #include "rtx_lib.h"
- // OS Runtime Object Memory Usage
- #ifdef RTX_OBJ_MEM_USAGE
- osRtxObjectMemUsage_t osRtxThreadMemUsage \
- __attribute__((section(".data.os.thread.obj"))) =
- { 0U, 0U, 0U };
- #endif
- // Runtime Class/Zone assignment table
- #if defined(RTX_EXECUTION_ZONE) && defined(RTX_SAFETY_CLASS)
- static uint8_t ThreadClassTable[64] __attribute__((section(".data.os"))) = { 0U };
- #endif
- // Watchdog Alarm Flag
- #if defined(RTX_THREAD_WATCHDOG) && defined(RTX_EXECUTION_ZONE)
- static uint8_t WatchdogAlarmFlag __attribute__((section(".data.os"))) = 0U;
- #endif
- // ==== Helper functions ====
- /// Set Thread Flags.
- /// \param[in] thread thread object.
- /// \param[in] flags specifies the flags to set.
- /// \return thread flags after setting.
- static uint32_t ThreadFlagsSet (os_thread_t *thread, uint32_t flags) {
- #if (EXCLUSIVE_ACCESS == 0)
- uint32_t primask = __get_PRIMASK();
- #endif
- uint32_t thread_flags;
- #if (EXCLUSIVE_ACCESS == 0)
- __disable_irq();
- thread->thread_flags |= flags;
- thread_flags = thread->thread_flags;
- if (primask == 0U) {
- __enable_irq();
- }
- #else
- thread_flags = atomic_set32(&thread->thread_flags, flags);
- #endif
- return thread_flags;
- }
- /// Clear Thread Flags.
- /// \param[in] thread thread object.
- /// \param[in] flags specifies the flags to clear.
- /// \return thread flags before clearing.
- static uint32_t ThreadFlagsClear (os_thread_t *thread, uint32_t flags) {
- #if (EXCLUSIVE_ACCESS == 0)
- uint32_t primask = __get_PRIMASK();
- #endif
- uint32_t thread_flags;
- #if (EXCLUSIVE_ACCESS == 0)
- __disable_irq();
- thread_flags = thread->thread_flags;
- thread->thread_flags &= ~flags;
- if (primask == 0U) {
- __enable_irq();
- }
- #else
- thread_flags = atomic_clr32(&thread->thread_flags, flags);
- #endif
- return thread_flags;
- }
- /// Check Thread Flags.
- /// \param[in] thread thread object.
- /// \param[in] flags specifies the flags to check.
- /// \param[in] options specifies flags options (osFlagsXxxx).
- /// \return thread flags before clearing or 0 if specified flags have not been set.
- static uint32_t ThreadFlagsCheck (os_thread_t *thread, uint32_t flags, uint32_t options) {
- #if (EXCLUSIVE_ACCESS == 0)
- uint32_t primask;
- #endif
- uint32_t thread_flags;
- if ((options & osFlagsNoClear) == 0U) {
- #if (EXCLUSIVE_ACCESS == 0)
- primask = __get_PRIMASK();
- __disable_irq();
- thread_flags = thread->thread_flags;
- if ((((options & osFlagsWaitAll) != 0U) && ((thread_flags & flags) != flags)) ||
- (((options & osFlagsWaitAll) == 0U) && ((thread_flags & flags) == 0U))) {
- thread_flags = 0U;
- } else {
- thread->thread_flags &= ~flags;
- }
- if (primask == 0U) {
- __enable_irq();
- }
- #else
- if ((options & osFlagsWaitAll) != 0U) {
- thread_flags = atomic_chk32_all(&thread->thread_flags, flags);
- } else {
- thread_flags = atomic_chk32_any(&thread->thread_flags, flags);
- }
- #endif
- } else {
- thread_flags = thread->thread_flags;
- if ((((options & osFlagsWaitAll) != 0U) && ((thread_flags & flags) != flags)) ||
- (((options & osFlagsWaitAll) == 0U) && ((thread_flags & flags) == 0U))) {
- thread_flags = 0U;
- }
- }
- return thread_flags;
- }
- /// Verify that Thread object pointer is valid.
- /// \param[in] thread thread object.
- /// \return true - valid, false - invalid.
- static bool_t IsThreadPtrValid (const os_thread_t *thread) {
- #ifdef RTX_OBJ_PTR_CHECK
- //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
- uint32_t cb_start = (uint32_t)&__os_thread_cb_start__;
- uint32_t cb_length = (uint32_t)&__os_thread_cb_length__;
- // Check the section boundaries
- if (((uint32_t)thread - cb_start) >= cb_length) {
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return FALSE;
- }
- // Check the object alignment
- if ((((uint32_t)thread - cb_start) % sizeof(os_thread_t)) != 0U) {
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return FALSE;
- }
- #else
- // Check NULL pointer
- if (thread == NULL) {
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return FALSE;
- }
- #endif
- return TRUE;
- }
- #if defined(RTX_EXECUTION_ZONE) && defined(RTX_SAFETY_CLASS)
- /// Check if Thread Zone to Safety Class mapping is valid.
- /// \param[in] attr_bits thread attributes.
- /// \param[in] thread running thread.
- /// \return true - valid, false - not valid.
- static bool_t IsClassMappingValid (uint32_t attr_bits, const os_thread_t *thread) {
- uint32_t safety_class;
- uint32_t zone;
- if ((attr_bits & osThreadZone_Valid) != 0U) {
- zone = (attr_bits & osThreadZone_Msk) >> osThreadZone_Pos;
- } else if (thread != NULL) {
- zone = thread->zone;
- } else {
- zone = 0U;
- }
- if ((attr_bits & osSafetyClass_Valid) != 0U) {
- safety_class = (attr_bits & osSafetyClass_Msk) >> osSafetyClass_Pos;
- } else if (thread != NULL) {
- safety_class = (uint32_t)thread->attr >> osRtxAttrClass_Pos;
- } else {
- safety_class = 0U;
- }
- // Check if zone is free or assigned to class
- if ((ThreadClassTable[zone] == 0U) ||
- (ThreadClassTable[zone] == (0x80U | safety_class))) {
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return TRUE;
- }
- // Invalid class to zone mapping
- return FALSE;
- }
- #endif
- // ==== Library functions ====
- /// Put a Thread into specified Object list sorted by Priority (Highest at Head).
- /// \param[in] object generic object.
- /// \param[in] thread thread object.
- void osRtxThreadListPut (os_object_t *object, os_thread_t *thread) {
- os_thread_t *prev, *next;
- int32_t priority;
- priority = thread->priority;
- prev = osRtxThreadObject(object);
- next = prev->thread_next;
- while ((next != NULL) && (next->priority >= priority)) {
- prev = next;
- next = next->thread_next;
- }
- thread->thread_prev = prev;
- thread->thread_next = next;
- prev->thread_next = thread;
- if (next != NULL) {
- next->thread_prev = thread;
- }
- }
- /// Get a Thread with Highest Priority from specified Object list and remove it.
- /// \param[in] object generic object.
- /// \return thread object.
- os_thread_t *osRtxThreadListGet (os_object_t *object) {
- os_thread_t *thread;
- thread = object->thread_list;
- object->thread_list = thread->thread_next;
- if (thread->thread_next != NULL) {
- thread->thread_next->thread_prev = osRtxThreadObject(object);
- }
- thread->thread_prev = NULL;
- return thread;
- }
- /// Retrieve Thread list root object.
- /// \param[in] thread thread object.
- /// \return root object.
- static void *osRtxThreadListRoot (os_thread_t *thread) {
- os_thread_t *thread0;
- thread0 = thread;
- while (thread0->id == osRtxIdThread) {
- thread0 = thread0->thread_prev;
- }
- return thread0;
- }
- /// Re-sort a Thread in linked Object list by Priority (Highest at Head).
- /// \param[in] thread thread object.
- void osRtxThreadListSort (os_thread_t *thread) {
- os_object_t *object;
- os_thread_t *thread0;
- // Search for object
- thread0 = thread;
- while ((thread0 != NULL) && (thread0->id == osRtxIdThread)) {
- thread0 = thread0->thread_prev;
- }
- object = osRtxObject(thread0);
- if (object != NULL) {
- osRtxThreadListRemove(thread);
- osRtxThreadListPut(object, thread);
- }
- }
- /// Remove a Thread from linked Object list.
- /// \param[in] thread thread object.
- void osRtxThreadListRemove (os_thread_t *thread) {
- if (thread->thread_prev != NULL) {
- thread->thread_prev->thread_next = thread->thread_next;
- if (thread->thread_next != NULL) {
- thread->thread_next->thread_prev = thread->thread_prev;
- }
- thread->thread_prev = NULL;
- }
- }
- /// Unlink a Thread from specified linked list.
- /// \param[in] thread thread object.
- static void osRtxThreadListUnlink (os_thread_t **thread_list, os_thread_t *thread) {
- if (thread->thread_next != NULL) {
- thread->thread_next->thread_prev = thread->thread_prev;
- }
- if (thread->thread_prev != NULL) {
- thread->thread_prev->thread_next = thread->thread_next;
- thread->thread_prev = NULL;
- } else {
- *thread_list = thread->thread_next;
- }
- }
- /// Mark a Thread as Ready and put it into Ready list (sorted by Priority).
- /// \param[in] thread thread object.
- void osRtxThreadReadyPut (os_thread_t *thread) {
- thread->state = osRtxThreadReady;
- osRtxThreadListPut(&osRtxInfo.thread.ready, thread);
- }
- /// Insert a Thread into the Delay list sorted by Delay (Lowest at Head).
- /// \param[in] thread thread object.
- /// \param[in] delay delay value.
- static void osRtxThreadDelayInsert (os_thread_t *thread, uint32_t delay) {
- os_thread_t *prev, *next;
- if (delay == osWaitForever) {
- prev = NULL;
- next = osRtxInfo.thread.wait_list;
- while (next != NULL) {
- prev = next;
- next = next->delay_next;
- }
- thread->delay = delay;
- thread->delay_prev = prev;
- thread->delay_next = NULL;
- if (prev != NULL) {
- prev->delay_next = thread;
- } else {
- osRtxInfo.thread.wait_list = thread;
- }
- } else {
- prev = NULL;
- next = osRtxInfo.thread.delay_list;
- while ((next != NULL) && (next->delay <= delay)) {
- delay -= next->delay;
- prev = next;
- next = next->delay_next;
- }
- thread->delay = delay;
- thread->delay_prev = prev;
- thread->delay_next = next;
- if (prev != NULL) {
- prev->delay_next = thread;
- } else {
- osRtxInfo.thread.delay_list = thread;
- }
- if (next != NULL) {
- next->delay -= delay;
- next->delay_prev = thread;
- }
- }
- }
- /// Remove a Thread from the Delay list.
- /// \param[in] thread thread object.
- void osRtxThreadDelayRemove (os_thread_t *thread) {
- if (thread->delay == osWaitForever) {
- if (thread->delay_next != NULL) {
- thread->delay_next->delay_prev = thread->delay_prev;
- }
- if (thread->delay_prev != NULL) {
- thread->delay_prev->delay_next = thread->delay_next;
- thread->delay_prev = NULL;
- } else {
- osRtxInfo.thread.wait_list = thread->delay_next;
- }
- } else {
- if (thread->delay_next != NULL) {
- thread->delay_next->delay += thread->delay;
- thread->delay_next->delay_prev = thread->delay_prev;
- }
- if (thread->delay_prev != NULL) {
- thread->delay_prev->delay_next = thread->delay_next;
- thread->delay_prev = NULL;
- } else {
- osRtxInfo.thread.delay_list = thread->delay_next;
- }
- }
- thread->delay = 0U;
- }
- /// Process Thread Delay Tick (executed each System Tick).
- void osRtxThreadDelayTick (void) {
- os_thread_t *thread;
- os_object_t *object;
- thread = osRtxInfo.thread.delay_list;
- if (thread == NULL) {
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return;
- }
- thread->delay--;
- if (thread->delay == 0U) {
- do {
- switch (thread->state) {
- case osRtxThreadWaitingDelay:
- EvrRtxDelayCompleted(thread);
- break;
- case osRtxThreadWaitingThreadFlags:
- EvrRtxThreadFlagsWaitTimeout(thread);
- break;
- case osRtxThreadWaitingEventFlags:
- EvrRtxEventFlagsWaitTimeout((osEventFlagsId_t)osRtxThreadListRoot(thread));
- break;
- case osRtxThreadWaitingMutex:
- object = osRtxObject(osRtxThreadListRoot(thread));
- osRtxMutexOwnerRestore(osRtxMutexObject(object), thread);
- EvrRtxMutexAcquireTimeout(osRtxMutexObject(object));
- break;
- case osRtxThreadWaitingSemaphore:
- EvrRtxSemaphoreAcquireTimeout((osSemaphoreId_t)osRtxThreadListRoot(thread));
- break;
- case osRtxThreadWaitingMemoryPool:
- EvrRtxMemoryPoolAllocTimeout((osMemoryPoolId_t)osRtxThreadListRoot(thread));
- break;
- case osRtxThreadWaitingMessageGet:
- EvrRtxMessageQueueGetTimeout((osMessageQueueId_t)osRtxThreadListRoot(thread));
- break;
- case osRtxThreadWaitingMessagePut:
- EvrRtxMessageQueuePutTimeout((osMessageQueueId_t)osRtxThreadListRoot(thread));
- break;
- default:
- // Invalid
- break;
- }
- EvrRtxThreadUnblocked(thread, (osRtxThreadRegPtr(thread))[0]);
- osRtxThreadListRemove(thread);
- osRtxThreadReadyPut(thread);
- thread = thread->delay_next;
- } while ((thread != NULL) && (thread->delay == 0U));
- if (thread != NULL) {
- thread->delay_prev = NULL;
- }
- osRtxInfo.thread.delay_list = thread;
- }
- }
- /// Get pointer to Thread registers (R0..R3)
- /// \param[in] thread thread object.
- /// \return pointer to registers R0-R3.
- uint32_t *osRtxThreadRegPtr (const os_thread_t *thread) {
- uint32_t addr = thread->sp + StackOffsetR0(thread->stack_frame);
- //lint -e{923} -e{9078} "cast from unsigned int to pointer"
- return ((uint32_t *)addr);
- }
- /// Block running Thread execution and register it as Ready to Run.
- /// \param[in] thread running thread object.
- static void osRtxThreadBlock (os_thread_t *thread) {
- os_thread_t *prev, *next;
- int32_t priority;
- thread->state = osRtxThreadReady;
- priority = thread->priority;
- prev = osRtxThreadObject(&osRtxInfo.thread.ready);
- next = prev->thread_next;
- while ((next != NULL) && (next->priority > priority)) {
- prev = next;
- next = next->thread_next;
- }
- thread->thread_prev = prev;
- thread->thread_next = next;
- prev->thread_next = thread;
- if (next != NULL) {
- next->thread_prev = thread;
- }
- EvrRtxThreadPreempted(thread);
- }
- /// Switch to specified Thread.
- /// \param[in] thread thread object.
- void osRtxThreadSwitch (os_thread_t *thread) {
- thread->state = osRtxThreadRunning;
- SetPrivileged((bool_t)((thread->attr & osThreadPrivileged) != 0U));
- osRtxInfo.thread.run.next = thread;
- EvrRtxThreadSwitched(thread);
- }
- /// Dispatch specified Thread or Ready Thread with Highest Priority.
- /// \param[in] thread thread object or NULL.
- void osRtxThreadDispatch (os_thread_t *thread) {
- uint8_t kernel_state;
- os_thread_t *thread_running;
- os_thread_t *thread_ready;
- kernel_state = osRtxKernelGetState();
- thread_running = osRtxThreadGetRunning();
- if (thread == NULL) {
- thread_ready = osRtxInfo.thread.ready.thread_list;
- if ((kernel_state == osRtxKernelRunning) &&
- (thread_ready != NULL) &&
- (thread_ready->priority > thread_running->priority)) {
- // Preempt running Thread
- osRtxThreadListRemove(thread_ready);
- osRtxThreadBlock(thread_running);
- osRtxThreadSwitch(thread_ready);
- }
- } else {
- if ((kernel_state == osRtxKernelRunning) &&
- (thread->priority > thread_running->priority)) {
- // Preempt running Thread
- osRtxThreadBlock(thread_running);
- osRtxThreadSwitch(thread);
- } else {
- // Put Thread into Ready list
- osRtxThreadReadyPut(thread);
- }
- }
- }
- /// Exit Thread wait state.
- /// \param[in] thread thread object.
- /// \param[in] ret_val return value.
- /// \param[in] dispatch dispatch flag.
- void osRtxThreadWaitExit (os_thread_t *thread, uint32_t ret_val, bool_t dispatch) {
- uint32_t *reg;
- EvrRtxThreadUnblocked(thread, ret_val);
- reg = osRtxThreadRegPtr(thread);
- reg[0] = ret_val;
- osRtxThreadDelayRemove(thread);
- if (dispatch) {
- osRtxThreadDispatch(thread);
- } else {
- osRtxThreadReadyPut(thread);
- }
- }
- /// Enter Thread wait state.
- /// \param[in] state new thread state.
- /// \param[in] timeout timeout.
- /// \return true - success, false - failure.
- bool_t osRtxThreadWaitEnter (uint8_t state, uint32_t timeout) {
- os_thread_t *thread;
- // Check if Kernel is running
- if (osRtxKernelGetState() != osRtxKernelRunning) {
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return FALSE;
- }
- // Check if any thread is ready
- if (osRtxInfo.thread.ready.thread_list == NULL) {
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return FALSE;
- }
- // Get running thread
- thread = osRtxThreadGetRunning();
- EvrRtxThreadBlocked(thread, timeout);
- thread->state = state;
- osRtxThreadDelayInsert(thread, timeout);
- thread = osRtxThreadListGet(&osRtxInfo.thread.ready);
- osRtxThreadSwitch(thread);
- return TRUE;
- }
- #ifdef RTX_STACK_CHECK
- /// Check current running Thread Stack.
- /// \param[in] thread running thread.
- /// \return true - success, false - failure.
- //lint -esym(714,osRtxThreadStackCheck) "Referenced by Exception handlers"
- //lint -esym(759,osRtxThreadStackCheck) "Prototype in header"
- //lint -esym(765,osRtxThreadStackCheck) "Global scope"
- bool_t osRtxThreadStackCheck (const os_thread_t *thread) {
- //lint -e{923} "cast from pointer to unsigned int"
- //lint -e{9079} -e{9087} "cast between pointers to different object types"
- if ((thread->sp <= (uint32_t)thread->stack_mem) ||
- (*((uint32_t *)thread->stack_mem) != osRtxStackMagicWord)) {
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return FALSE;
- }
- return TRUE;
- }
- #endif
- #ifdef RTX_THREAD_WATCHDOG
- /// Insert a Thread into the Watchdog list, sorted by tick (lowest at Head).
- /// \param[in] thread thread object.
- /// \param[in] ticks watchdog timeout.
- static void osRtxThreadWatchdogInsert (os_thread_t *thread, uint32_t ticks) {
- os_thread_t *prev, *next;
- if (ticks == 0U) {
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return;
- }
- prev = NULL;
- next = osRtxInfo.thread.wdog_list;
- while ((next != NULL) && ((next->wdog_tick <= ticks))) {
- ticks -= next->wdog_tick;
- prev = next;
- next = next->wdog_next;
- }
- thread->wdog_tick = ticks;
- thread->wdog_next = next;
- if (next != NULL) {
- next->wdog_tick -= ticks;
- }
- if (prev != NULL) {
- prev->wdog_next = thread;
- } else {
- osRtxInfo.thread.wdog_list = thread;
- }
- }
- /// Remove a Thread from the Watchdog list.
- /// \param[in] thread thread object.
- void osRtxThreadWatchdogRemove (const os_thread_t *thread) {
- os_thread_t *prev, *next;
- prev = NULL;
- next = osRtxInfo.thread.wdog_list;
- while ((next != NULL) && (next != thread)) {
- prev = next;
- next = next->wdog_next;
- }
- if (next == NULL) {
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return;
- }
- if (thread->wdog_next != NULL) {
- thread->wdog_next->wdog_tick += thread->wdog_tick;
- }
- if (prev != NULL) {
- prev->wdog_next = thread->wdog_next;
- } else {
- osRtxInfo.thread.wdog_list = thread->wdog_next;
- }
- }
- /// Process Watchdog Tick (executed each System Tick).
- void osRtxThreadWatchdogTick (void) {
- os_thread_t *thread_running;
- os_thread_t *thread;
- #ifdef RTX_SAFETY_CLASS
- os_thread_t *next;
- #endif
- uint32_t ticks;
- thread = osRtxInfo.thread.wdog_list;
- if (thread == NULL) {
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return;
- }
- thread->wdog_tick--;
- if (thread->wdog_tick == 0U) {
- // Call watchdog handler for all expired threads
- thread_running = osRtxThreadGetRunning();
- do {
- osRtxThreadSetRunning(osRtxInfo.thread.run.next);
- #ifdef RTX_SAFETY_CLASS
- // First the highest safety thread (sorted by Safety Class)
- next = thread->wdog_next;
- while ((next != NULL) && (next->wdog_tick == 0U)) {
- if ((next->attr & osRtxAttrClass_Msk) > (thread->attr & osRtxAttrClass_Msk)) {
- thread = next;
- }
- next = next->wdog_next;
- }
- #endif
- osRtxThreadWatchdogRemove(thread);
- EvrRtxThreadWatchdogExpired(thread);
- #ifdef RTX_EXECUTION_ZONE
- WatchdogAlarmFlag = 1U;
- #endif
- ticks = osWatchdogAlarm_Handler(thread);
- #ifdef RTX_EXECUTION_ZONE
- WatchdogAlarmFlag = 0U;
- #endif
- osRtxThreadWatchdogInsert(thread, ticks);
- thread = osRtxInfo.thread.wdog_list;
- } while ((thread != NULL) && (thread->wdog_tick == 0U));
- osRtxThreadSetRunning(thread_running);
- }
- }
- #endif
- static __NO_RETURN void osThreadEntry (void *argument, osThreadFunc_t func) {
- func(argument);
- osThreadExit();
- }
- // ==== Post ISR processing ====
- /// Thread post ISR processing.
- /// \param[in] thread thread object.
- static void osRtxThreadPostProcess (os_thread_t *thread) {
- uint32_t thread_flags;
- // Check if Thread is waiting for Thread Flags
- if (thread->state == osRtxThreadWaitingThreadFlags) {
- thread_flags = ThreadFlagsCheck(thread, thread->wait_flags, thread->flags_options);
- if (thread_flags != 0U) {
- osRtxThreadWaitExit(thread, thread_flags, FALSE);
- EvrRtxThreadFlagsWaitCompleted(thread->wait_flags, thread->flags_options, thread_flags, thread);
- }
- }
- }
- // ==== Service Calls ====
- /// Create a thread and add it to Active Threads.
- /// \note API identical to osThreadNew
- static osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) {
- os_thread_t *thread;
- #if defined(RTX_SAFETY_CLASS) || defined(RTX_EXECUTION_ZONE)
- const os_thread_t *thread_running = osRtxThreadGetRunning();
- #endif
- uint32_t attr_bits;
- void *stack_mem;
- uint32_t stack_size;
- osPriority_t priority;
- uint8_t flags;
- const char *name;
- uint32_t *ptr;
- uint32_t n;
- #ifdef RTX_TZ_CONTEXT
- TZ_ModuleId_t tz_module;
- TZ_MemoryId_t tz_memory;
- #endif
- // Check parameters
- if (func == NULL) {
- EvrRtxThreadError(NULL, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return NULL;
- }
- // Process attributes
- if (attr != NULL) {
- name = attr->name;
- attr_bits = attr->attr_bits;
- //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
- thread = attr->cb_mem;
- //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
- stack_mem = attr->stack_mem;
- stack_size = attr->stack_size;
- priority = attr->priority;
- #ifdef RTX_TZ_CONTEXT
- tz_module = attr->tz_module;
- #endif
- if (((attr_bits & osThreadPrivileged) != 0U) && ((attr_bits & osThreadUnprivileged) != 0U)) {
- EvrRtxThreadError(NULL, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return NULL;
- }
- #ifdef RTX_SAFETY_CLASS
- if ((attr_bits & osSafetyClass_Valid) != 0U) {
- if ((thread_running != NULL) &&
- ((thread_running->attr >> osRtxAttrClass_Pos) <
- (uint8_t)((attr_bits & osSafetyClass_Msk) >> osSafetyClass_Pos))) {
- EvrRtxThreadError(NULL, (int32_t)osErrorSafetyClass);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return NULL;
- }
- }
- #endif
- if (thread != NULL) {
- if (!IsThreadPtrValid(thread) || (attr->cb_size != sizeof(os_thread_t))) {
- EvrRtxThreadError(NULL, osRtxErrorInvalidControlBlock);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return NULL;
- }
- } else {
- if (attr->cb_size != 0U) {
- EvrRtxThreadError(NULL, osRtxErrorInvalidControlBlock);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return NULL;
- }
- }
- if (stack_mem != NULL) {
- //lint -e{923} "cast from pointer to unsigned int" [MISRA Note 7]
- if ((((uint32_t)stack_mem & 7U) != 0U) || (stack_size == 0U)) {
- EvrRtxThreadError(NULL, osRtxErrorInvalidThreadStack);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return NULL;
- }
- }
- if (priority == osPriorityNone) {
- priority = osPriorityNormal;
- } else {
- if ((priority < osPriorityIdle) || (priority > osPriorityISR)) {
- EvrRtxThreadError(NULL, osRtxErrorInvalidPriority);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return NULL;
- }
- }
- } else {
- name = NULL;
- attr_bits = 0U;
- thread = NULL;
- stack_mem = NULL;
- stack_size = 0U;
- priority = osPriorityNormal;
- #ifdef RTX_TZ_CONTEXT
- tz_module = 0U;
- #endif
- }
- // Set default privilege if not specified
- if ((attr_bits & (osThreadPrivileged | osThreadUnprivileged)) == 0U) {
- if ((osRtxConfig.flags & osRtxConfigPrivilegedMode) != 0U) {
- attr_bits |= osThreadPrivileged;
- } else {
- attr_bits |= osThreadUnprivileged;
- }
- }
- #ifdef RTX_SAFETY_FEATURES
- // Check privilege protection
- if ((attr_bits & osThreadPrivileged) != 0U) {
- if ((osRtxInfo.kernel.protect & osRtxKernelProtectPrivileged) != 0U) {
- EvrRtxThreadError(NULL, osRtxErrorInvalidPrivilegedMode);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return NULL;
- }
- }
- #endif
- #if defined(RTX_EXECUTION_ZONE) && defined(RTX_SAFETY_CLASS)
- // Check class to zone mapping
- if (!IsClassMappingValid(attr_bits, thread_running)) {
- EvrRtxThreadError(NULL, (int32_t)osErrorSafetyClass);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return NULL;
- }
- #endif
- // Check stack size
- if (stack_size != 0U) {
- if (((stack_size & 7U) != 0U) || (stack_size < (64U + 8U)) || (stack_size > 0x7FFFFFFFU)) {
- EvrRtxThreadError(NULL, osRtxErrorInvalidThreadStack);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return NULL;
- }
- }
- // Allocate object memory if not provided
- if (thread == NULL) {
- if (osRtxInfo.mpi.thread != NULL) {
- //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
- thread = osRtxMemoryPoolAlloc(osRtxInfo.mpi.thread);
- #ifndef RTX_OBJ_PTR_CHECK
- } else {
- //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
- thread = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_thread_t), 1U);
- #endif
- }
- #ifdef RTX_OBJ_MEM_USAGE
- if (thread != NULL) {
- uint32_t used;
- osRtxThreadMemUsage.cnt_alloc++;
- used = osRtxThreadMemUsage.cnt_alloc - osRtxThreadMemUsage.cnt_free;
- if (osRtxThreadMemUsage.max_used < used) {
- osRtxThreadMemUsage.max_used = used;
- }
- }
- #endif
- flags = osRtxFlagSystemObject;
- } else {
- flags = 0U;
- }
- // Allocate stack memory if not provided
- if ((thread != NULL) && (stack_mem == NULL)) {
- if (stack_size == 0U) {
- stack_size = osRtxConfig.thread_stack_size;
- if (osRtxInfo.mpi.stack != NULL) {
- //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
- stack_mem = osRtxMemoryPoolAlloc(osRtxInfo.mpi.stack);
- if (stack_mem != NULL) {
- flags |= osRtxThreadFlagDefStack;
- }
- } else {
- //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
- stack_mem = osRtxMemoryAlloc(osRtxInfo.mem.stack, stack_size, 0U);
- }
- } else {
- //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
- stack_mem = osRtxMemoryAlloc(osRtxInfo.mem.stack, stack_size, 0U);
- }
- if (stack_mem == NULL) {
- if ((flags & osRtxFlagSystemObject) != 0U) {
- #ifdef RTX_OBJ_PTR_CHECK
- (void)osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread);
- #else
- if (osRtxInfo.mpi.thread != NULL) {
- (void)osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread);
- } else {
- (void)osRtxMemoryFree(osRtxInfo.mem.common, thread);
- }
- #endif
- #ifdef RTX_OBJ_MEM_USAGE
- osRtxThreadMemUsage.cnt_free++;
- #endif
- }
- thread = NULL;
- }
- flags |= osRtxFlagSystemMemory;
- }
- #ifdef RTX_TZ_CONTEXT
- // Allocate secure process stack
- if ((thread != NULL) && (tz_module != 0U)) {
- tz_memory = TZ_AllocModuleContext_S(tz_module);
- if (tz_memory == 0U) {
- EvrRtxThreadError(NULL, osRtxErrorTZ_AllocContext_S);
- if ((flags & osRtxFlagSystemMemory) != 0U) {
- if ((flags & osRtxThreadFlagDefStack) != 0U) {
- (void)osRtxMemoryPoolFree(osRtxInfo.mpi.stack, thread->stack_mem);
- } else {
- (void)osRtxMemoryFree(osRtxInfo.mem.stack, thread->stack_mem);
- }
- }
- if ((flags & osRtxFlagSystemObject) != 0U) {
- #ifdef RTX_OBJ_PTR_CHECK
- (void)osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread);
- #else
- if (osRtxInfo.mpi.thread != NULL) {
- (void)osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread);
- } else {
- (void)osRtxMemoryFree(osRtxInfo.mem.common, thread);
- }
- #endif
- #ifdef RTX_OBJ_MEM_USAGE
- osRtxThreadMemUsage.cnt_free++;
- #endif
- }
- thread = NULL;
- }
- } else {
- tz_memory = 0U;
- }
- #endif
- if (thread != NULL) {
- // Initialize control block
- //lint --e{923} --e{9078} "cast between pointers and unsigned int"
- //lint --e{9079} --e{9087} "cast between pointers to different object types"
- //lint --e{9074} "conversion between a pointer to function and another type"
- thread->id = osRtxIdThread;
- thread->state = osRtxThreadReady;
- thread->flags = flags;
- thread->attr = (uint8_t)(attr_bits & ~osRtxAttrClass_Msk);
- thread->name = name;
- thread->thread_next = NULL;
- thread->thread_prev = NULL;
- thread->delay_next = NULL;
- thread->delay_prev = NULL;
- thread->thread_join = NULL;
- thread->delay = 0U;
- thread->priority = (int8_t)priority;
- thread->priority_base = (int8_t)priority;
- thread->stack_frame = STACK_FRAME_INIT_VAL;
- thread->flags_options = 0U;
- thread->wait_flags = 0U;
- thread->thread_flags = 0U;
- thread->mutex_list = NULL;
- thread->stack_mem = stack_mem;
- thread->stack_size = stack_size;
- thread->sp = (uint32_t)stack_mem + stack_size - 64U;
- thread->thread_addr = (uint32_t)func;
- #ifdef RTX_TZ_CONTEXT
- thread->tz_memory = tz_memory;
- #endif
- #ifdef RTX_SAFETY_CLASS
- if ((attr_bits & osSafetyClass_Valid) != 0U) {
- thread->attr |= (uint8_t)((attr_bits & osSafetyClass_Msk) >>
- (osSafetyClass_Pos - osRtxAttrClass_Pos));
- } else {
- // Inherit safety class from the running thread
- if (thread_running != NULL) {
- thread->attr |= (uint8_t)(thread_running->attr & osRtxAttrClass_Msk);
- }
- }
- #endif
- #ifdef RTX_EXECUTION_ZONE
- if ((attr_bits & osThreadZone_Valid) != 0U) {
- thread->zone = (uint8_t)((attr_bits & osThreadZone_Msk) >> osThreadZone_Pos);
- } else {
- // Inherit zone from the running thread
- if (thread_running != NULL) {
- thread->zone = thread_running->zone;
- } else {
- thread->zone = 0U;
- }
- }
- #endif
- #if defined(RTX_EXECUTION_ZONE) && defined(RTX_SAFETY_CLASS)
- // Update class to zone assignment table
- if (ThreadClassTable[thread->zone] == 0U) {
- ThreadClassTable[thread->zone] = (uint8_t)(0x80U | (thread->attr >> osRtxAttrClass_Pos));
- }
- #endif
- #ifdef RTX_THREAD_WATCHDOG
- thread->wdog_next = NULL;
- thread->wdog_tick = 0U;
- #endif
- // Initialize stack
- //lint --e{613} false detection: "Possible use of null pointer"
- ptr = (uint32_t *)stack_mem;
- ptr[0] = osRtxStackMagicWord;
- if ((osRtxConfig.flags & osRtxConfigStackWatermark) != 0U) {
- for (n = (stack_size/4U) - (16U + 1U); n != 0U; n--) {
- ptr++;
- *ptr = osRtxStackFillPattern;
- }
- }
- ptr = (uint32_t *)thread->sp;
- for (n = 0U; n != 14U; n++) {
- ptr[n] = 0U; // R4..R11, R0..R3, R12, LR
- }
- ptr[14] = (uint32_t)osThreadEntry; // PC
- ptr[15] = xPSR_InitVal(
- (bool_t)((attr_bits & osThreadPrivileged) != 0U),
- (bool_t)(((uint32_t)func & 1U) != 0U)
- ); // xPSR
- ptr[8] = (uint32_t)argument; // R0
- ptr[9] = (uint32_t)func; // R1
- // Register post ISR processing function
- osRtxInfo.post_process.thread = osRtxThreadPostProcess;
- EvrRtxThreadCreated(thread, thread->thread_addr, thread->name);
- } else {
- EvrRtxThreadError(NULL, (int32_t)osErrorNoMemory);
- }
- if (thread != NULL) {
- osRtxThreadDispatch(thread);
- }
- return thread;
- }
- /// Get name of a thread.
- /// \note API identical to osThreadGetName
- static const char *svcRtxThreadGetName (osThreadId_t thread_id) {
- os_thread_t *thread = osRtxThreadId(thread_id);
- // Check parameters
- if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
- EvrRtxThreadGetName(thread, NULL);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return NULL;
- }
- EvrRtxThreadGetName(thread, thread->name);
- return thread->name;
- }
- #ifdef RTX_SAFETY_CLASS
- /// Get safety class of a thread.
- /// \note API identical to osThreadGetClass
- static uint32_t svcRtxThreadGetClass (osThreadId_t thread_id) {
- os_thread_t *thread = osRtxThreadId(thread_id);
- // Check parameters
- if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
- EvrRtxThreadGetClass(thread, osErrorId);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorId;
- }
- EvrRtxThreadGetClass(thread, (uint32_t)thread->attr >> osRtxAttrClass_Pos);
- return ((uint32_t)thread->attr >> osRtxAttrClass_Pos);
- }
- #endif
- #ifdef RTX_EXECUTION_ZONE
- /// Get zone of a thread.
- /// \note API identical to osThreadGetZone
- static uint32_t svcRtxThreadGetZone (osThreadId_t thread_id) {
- os_thread_t *thread = osRtxThreadId(thread_id);
- // Check parameters
- if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
- EvrRtxThreadGetZone(thread, osErrorId);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorId;
- }
- EvrRtxThreadGetZone(thread, thread->zone);
- return thread->zone;
- }
- #endif
- /// Return the thread ID of the current running thread.
- /// \note API identical to osThreadGetId
- static osThreadId_t svcRtxThreadGetId (void) {
- os_thread_t *thread;
- thread = osRtxThreadGetRunning();
- EvrRtxThreadGetId(thread);
- return thread;
- }
- /// Get current thread state of a thread.
- /// \note API identical to osThreadGetState
- static osThreadState_t svcRtxThreadGetState (osThreadId_t thread_id) {
- os_thread_t *thread = osRtxThreadId(thread_id);
- osThreadState_t state;
- // Check parameters
- if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
- EvrRtxThreadGetState(thread, osThreadError);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osThreadError;
- }
- state = osRtxThreadState(thread);
- EvrRtxThreadGetState(thread, state);
- return state;
- }
- /// Get stack size of a thread.
- /// \note API identical to osThreadGetStackSize
- static uint32_t svcRtxThreadGetStackSize (osThreadId_t thread_id) {
- os_thread_t *thread = osRtxThreadId(thread_id);
- // Check parameters
- if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
- EvrRtxThreadGetStackSize(thread, 0U);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return 0U;
- }
- EvrRtxThreadGetStackSize(thread, thread->stack_size);
- return thread->stack_size;
- }
- /// Get available stack space of a thread based on stack watermark recording during execution.
- /// \note API identical to osThreadGetStackSpace
- static uint32_t svcRtxThreadGetStackSpace (osThreadId_t thread_id) {
- os_thread_t *thread = osRtxThreadId(thread_id);
- const uint32_t *stack;
- uint32_t space;
- // Check parameters
- if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
- EvrRtxThreadGetStackSpace(thread, 0U);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return 0U;
- }
- // Check if stack watermark is not enabled
- if ((osRtxConfig.flags & osRtxConfigStackWatermark) == 0U) {
- EvrRtxThreadGetStackSpace(thread, 0U);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return 0U;
- }
- //lint -e{9079} "conversion from pointer to void to pointer to other type"
- stack = thread->stack_mem;
- if (*stack++ == osRtxStackMagicWord) {
- for (space = 4U; space < thread->stack_size; space += 4U) {
- if (*stack++ != osRtxStackFillPattern) {
- break;
- }
- }
- } else {
- space = 0U;
- }
- EvrRtxThreadGetStackSpace(thread, space);
- return space;
- }
- /// Change priority of a thread.
- /// \note API identical to osThreadSetPriority
- static osStatus_t svcRtxThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) {
- os_thread_t *thread = osRtxThreadId(thread_id);
- #ifdef RTX_SAFETY_CLASS
- const os_thread_t *thread_running;
- #endif
- // Check parameters
- if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread) ||
- (priority < osPriorityIdle) || (priority > osPriorityISR)) {
- EvrRtxThreadError(thread, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorParameter;
- }
- #ifdef RTX_SAFETY_CLASS
- // Check running thread safety class
- thread_running = osRtxThreadGetRunning();
- if ((thread_running != NULL) &&
- ((thread_running->attr >> osRtxAttrClass_Pos) < (thread->attr >> osRtxAttrClass_Pos))) {
- EvrRtxThreadError(thread, (int32_t)osErrorSafetyClass);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorSafetyClass;
- }
- #endif
- // Check object state
- if (thread->state == osRtxThreadTerminated) {
- EvrRtxThreadError(thread, (int32_t)osErrorResource);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorResource;
- }
- if (thread->priority != (int8_t)priority) {
- thread->priority = (int8_t)priority;
- thread->priority_base = (int8_t)priority;
- EvrRtxThreadPriorityUpdated(thread, priority);
- osRtxThreadListSort(thread);
- osRtxThreadDispatch(NULL);
- }
- return osOK;
- }
- /// Get current priority of a thread.
- /// \note API identical to osThreadGetPriority
- static osPriority_t svcRtxThreadGetPriority (osThreadId_t thread_id) {
- os_thread_t *thread = osRtxThreadId(thread_id);
- osPriority_t priority;
- // Check parameters
- if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
- EvrRtxThreadGetPriority(thread, osPriorityError);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osPriorityError;
- }
- // Check object state
- if (thread->state == osRtxThreadTerminated) {
- EvrRtxThreadGetPriority(thread, osPriorityError);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osPriorityError;
- }
- priority = osRtxThreadPriority(thread);
- EvrRtxThreadGetPriority(thread, priority);
- return priority;
- }
- /// Pass control to next thread that is in state READY.
- /// \note API identical to osThreadYield
- static osStatus_t svcRtxThreadYield (void) {
- os_thread_t *thread_running;
- os_thread_t *thread_ready;
- if (osRtxKernelGetState() == osRtxKernelRunning) {
- thread_running = osRtxThreadGetRunning();
- thread_ready = osRtxInfo.thread.ready.thread_list;
- if ((thread_ready != NULL) &&
- (thread_ready->priority == thread_running->priority)) {
- osRtxThreadListRemove(thread_ready);
- osRtxThreadReadyPut(thread_running);
- EvrRtxThreadPreempted(thread_running);
- osRtxThreadSwitch(thread_ready);
- }
- }
- return osOK;
- }
- /// Suspend execution of a thread.
- /// \note API identical to osThreadSuspend
- static osStatus_t svcRtxThreadSuspend (osThreadId_t thread_id) {
- os_thread_t *thread = osRtxThreadId(thread_id);
- #ifdef RTX_SAFETY_CLASS
- const os_thread_t *thread_running;
- #endif
- osStatus_t status;
- // Check parameters
- if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
- EvrRtxThreadError(thread, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorParameter;
- }
- #ifdef RTX_SAFETY_CLASS
- // Check running thread safety class
- thread_running = osRtxThreadGetRunning();
- if ((thread_running != NULL) &&
- ((thread_running->attr >> osRtxAttrClass_Pos) < (thread->attr >> osRtxAttrClass_Pos))) {
- EvrRtxThreadError(thread, (int32_t)osErrorSafetyClass);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorSafetyClass;
- }
- #endif
- // Check object state
- switch (thread->state & osRtxThreadStateMask) {
- case osRtxThreadRunning:
- if ((osRtxKernelGetState() != osRtxKernelRunning) ||
- (osRtxInfo.thread.ready.thread_list == NULL)) {
- EvrRtxThreadError(thread, (int32_t)osErrorResource);
- status = osErrorResource;
- } else {
- status = osOK;
- }
- break;
- case osRtxThreadReady:
- osRtxThreadListRemove(thread);
- status = osOK;
- break;
- case osRtxThreadBlocked:
- osRtxThreadListRemove(thread);
- osRtxThreadDelayRemove(thread);
- status = osOK;
- break;
- case osRtxThreadInactive:
- case osRtxThreadTerminated:
- default:
- EvrRtxThreadError(thread, (int32_t)osErrorResource);
- status = osErrorResource;
- break;
- }
- if (status == osOK) {
- EvrRtxThreadSuspended(thread);
- if (thread->state == osRtxThreadRunning) {
- osRtxThreadSwitch(osRtxThreadListGet(&osRtxInfo.thread.ready));
- }
- // Update Thread State and put it into Delay list
- thread->state = osRtxThreadBlocked;
- osRtxThreadDelayInsert(thread, osWaitForever);
- }
- return status;
- }
- /// Resume execution of a thread.
- /// \note API identical to osThreadResume
- static osStatus_t svcRtxThreadResume (osThreadId_t thread_id) {
- os_thread_t *thread = osRtxThreadId(thread_id);
- #ifdef RTX_SAFETY_CLASS
- const os_thread_t *thread_running;
- #endif
- // Check parameters
- if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
- EvrRtxThreadError(thread, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorParameter;
- }
- #ifdef RTX_SAFETY_CLASS
- // Check running thread safety class
- thread_running = osRtxThreadGetRunning();
- if ((thread_running != NULL) &&
- ((thread_running->attr >> osRtxAttrClass_Pos) < (thread->attr >> osRtxAttrClass_Pos))) {
- EvrRtxThreadError(thread, (int32_t)osErrorSafetyClass);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorSafetyClass;
- }
- #endif
- // Check object state
- if ((thread->state & osRtxThreadStateMask) != osRtxThreadBlocked) {
- EvrRtxThreadError(thread, (int32_t)osErrorResource);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorResource;
- }
- EvrRtxThreadResumed(thread);
- // Wakeup Thread
- osRtxThreadListRemove(thread);
- osRtxThreadDelayRemove(thread);
- osRtxThreadDispatch(thread);
- return osOK;
- }
- /// Wakeup a thread waiting to join.
- /// \param[in] thread thread object.
- void osRtxThreadJoinWakeup (const os_thread_t *thread) {
- if (thread->thread_join != NULL) {
- osRtxThreadWaitExit(thread->thread_join, (uint32_t)osOK, FALSE);
- EvrRtxThreadJoined(thread->thread_join);
- }
- if (thread->state == osRtxThreadWaitingJoin) {
- thread->thread_next->thread_join = NULL;
- }
- }
- /// Free Thread resources.
- /// \param[in] thread thread object.
- static void osRtxThreadFree (os_thread_t *thread) {
- osRtxThreadBeforeFree(thread);
- // Mark object as inactive and invalid
- thread->state = osRtxThreadInactive;
- thread->id = osRtxIdInvalid;
- #ifdef RTX_TZ_CONTEXT
- // Free secure process stack
- if (thread->tz_memory != 0U) {
- (void)TZ_FreeModuleContext_S(thread->tz_memory);
- }
- #endif
- // Free stack memory
- if ((thread->flags & osRtxFlagSystemMemory) != 0U) {
- if ((thread->flags & osRtxThreadFlagDefStack) != 0U) {
- (void)osRtxMemoryPoolFree(osRtxInfo.mpi.stack, thread->stack_mem);
- } else {
- (void)osRtxMemoryFree(osRtxInfo.mem.stack, thread->stack_mem);
- }
- }
- // Free object memory
- if ((thread->flags & osRtxFlagSystemObject) != 0U) {
- #ifdef RTX_OBJ_PTR_CHECK
- (void)osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread);
- #else
- if (osRtxInfo.mpi.thread != NULL) {
- (void)osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread);
- } else {
- (void)osRtxMemoryFree(osRtxInfo.mem.common, thread);
- }
- #endif
- #ifdef RTX_OBJ_MEM_USAGE
- osRtxThreadMemUsage.cnt_free++;
- #endif
- }
- }
- /// Destroy a Thread.
- /// \param[in] thread thread object.
- void osRtxThreadDestroy (os_thread_t *thread) {
- if ((thread->attr & osThreadJoinable) == 0U) {
- osRtxThreadFree(thread);
- } else {
- // Update Thread State and put it into Terminate Thread list
- thread->state = osRtxThreadTerminated;
- thread->thread_prev = NULL;
- thread->thread_next = osRtxInfo.thread.terminate_list;
- if (osRtxInfo.thread.terminate_list != NULL) {
- osRtxInfo.thread.terminate_list->thread_prev = thread;
- }
- osRtxInfo.thread.terminate_list = thread;
- }
- EvrRtxThreadDestroyed(thread);
- }
- /// Detach a thread (thread storage can be reclaimed when thread terminates).
- /// \note API identical to osThreadDetach
- static osStatus_t svcRtxThreadDetach (osThreadId_t thread_id) {
- os_thread_t *thread = osRtxThreadId(thread_id);
- #ifdef RTX_SAFETY_CLASS
- const os_thread_t *thread_running;
- #endif
- // Check parameters
- if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
- EvrRtxThreadError(thread, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorParameter;
- }
- #ifdef RTX_SAFETY_CLASS
- // Check running thread safety class
- thread_running = osRtxThreadGetRunning();
- if ((thread_running != NULL) &&
- ((thread_running->attr >> osRtxAttrClass_Pos) < (thread->attr >> osRtxAttrClass_Pos))) {
- EvrRtxThreadError(thread, (int32_t)osErrorSafetyClass);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorSafetyClass;
- }
- #endif
- // Check object attributes
- if ((thread->attr & osThreadJoinable) == 0U) {
- EvrRtxThreadError(thread, osRtxErrorThreadNotJoinable);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorResource;
- }
- if (thread->state == osRtxThreadTerminated) {
- osRtxThreadListUnlink(&osRtxInfo.thread.terminate_list, thread);
- osRtxThreadFree(thread);
- } else {
- thread->attr &= ~osThreadJoinable;
- }
- EvrRtxThreadDetached(thread);
- return osOK;
- }
- /// Wait for specified thread to terminate.
- /// \note API identical to osThreadJoin
- static osStatus_t svcRtxThreadJoin (osThreadId_t thread_id) {
- os_thread_t *thread = osRtxThreadId(thread_id);
- os_thread_t *thread_running;
- osStatus_t status;
- // Check parameters
- if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
- EvrRtxThreadError(thread, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorParameter;
- }
- #ifdef RTX_SAFETY_CLASS
- // Check running thread safety class
- thread_running = osRtxThreadGetRunning();
- if ((thread_running != NULL) &&
- ((thread_running->attr >> osRtxAttrClass_Pos) < (thread->attr >> osRtxAttrClass_Pos))) {
- EvrRtxThreadError(thread, (int32_t)osErrorSafetyClass);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorSafetyClass;
- }
- #endif
- // Check object attributes
- if ((thread->attr & osThreadJoinable) == 0U) {
- EvrRtxThreadError(thread, osRtxErrorThreadNotJoinable);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorResource;
- }
- // Check object state
- if (thread->state == osRtxThreadRunning) {
- EvrRtxThreadError(thread, (int32_t)osErrorResource);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorResource;
- }
- if (thread->state == osRtxThreadTerminated) {
- osRtxThreadListUnlink(&osRtxInfo.thread.terminate_list, thread);
- osRtxThreadFree(thread);
- EvrRtxThreadJoined(thread);
- status = osOK;
- } else {
- // Suspend current Thread
- if (osRtxThreadWaitEnter(osRtxThreadWaitingJoin, osWaitForever)) {
- thread_running = osRtxThreadGetRunning();
- thread_running->thread_next = thread;
- thread->thread_join = thread_running;
- thread->attr &= ~osThreadJoinable;
- EvrRtxThreadJoinPending(thread);
- } else {
- EvrRtxThreadError(thread, (int32_t)osErrorResource);
- }
- status = osErrorResource;
- }
- return status;
- }
- /// Terminate execution of current running thread.
- /// \note API identical to osThreadExit
- static void svcRtxThreadExit (void) {
- os_thread_t *thread;
- // Check if switch to next Ready Thread is possible
- if ((osRtxKernelGetState() != osRtxKernelRunning) ||
- (osRtxInfo.thread.ready.thread_list == NULL)) {
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return;
- }
- // Get running thread
- thread = osRtxThreadGetRunning();
- #ifdef RTX_THREAD_WATCHDOG
- // Remove Thread from the Watchdog list
- osRtxThreadWatchdogRemove(thread);
- #endif
- // Release owned Mutexes
- osRtxMutexOwnerRelease(thread->mutex_list);
- // Wakeup Thread waiting to Join
- osRtxThreadJoinWakeup(thread);
- // Switch to next Ready Thread
- osRtxThreadSwitch(osRtxThreadListGet(&osRtxInfo.thread.ready));
- // Update Stack Pointer
- thread->sp = __get_PSP();
- #ifdef RTX_STACK_CHECK
- // Check Stack usage
- if (!osRtxThreadStackCheck(thread)) {
- osRtxThreadSetRunning(osRtxInfo.thread.run.next);
- (void)osRtxKernelErrorNotify(osRtxErrorStackOverflow, thread);
- }
- #endif
- // Mark running thread as deleted
- osRtxThreadSetRunning(NULL);
- // Destroy Thread
- osRtxThreadDestroy(thread);
- }
- /// Terminate execution of a thread.
- /// \note API identical to osThreadTerminate
- static osStatus_t svcRtxThreadTerminate (osThreadId_t thread_id) {
- os_thread_t *thread = osRtxThreadId(thread_id);
- #ifdef RTX_SAFETY_CLASS
- const os_thread_t *thread_running;
- #endif
- osStatus_t status;
- // Check parameters
- if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread)) {
- EvrRtxThreadError(thread, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorParameter;
- }
- #ifdef RTX_SAFETY_CLASS
- // Check running thread safety class
- thread_running = osRtxThreadGetRunning();
- if ((thread_running != NULL) &&
- ((thread_running->attr >> osRtxAttrClass_Pos) < (thread->attr >> osRtxAttrClass_Pos))) {
- EvrRtxThreadError(thread, (int32_t)osErrorSafetyClass);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorSafetyClass;
- }
- #endif
- // Check object state
- switch (thread->state & osRtxThreadStateMask) {
- case osRtxThreadRunning:
- if ((osRtxKernelGetState() != osRtxKernelRunning) ||
- (osRtxInfo.thread.ready.thread_list == NULL)) {
- EvrRtxThreadError(thread, (int32_t)osErrorResource);
- status = osErrorResource;
- } else {
- status = osOK;
- }
- break;
- case osRtxThreadReady:
- osRtxThreadListRemove(thread);
- status = osOK;
- break;
- case osRtxThreadBlocked:
- osRtxThreadListRemove(thread);
- osRtxThreadDelayRemove(thread);
- status = osOK;
- break;
- case osRtxThreadInactive:
- case osRtxThreadTerminated:
- default:
- EvrRtxThreadError(thread, (int32_t)osErrorResource);
- status = osErrorResource;
- break;
- }
- if (status == osOK) {
- #ifdef RTX_THREAD_WATCHDOG
- // Remove Thread from the Watchdog list
- osRtxThreadWatchdogRemove(thread);
- #endif
- // Release owned Mutexes
- osRtxMutexOwnerRelease(thread->mutex_list);
- // Wakeup Thread waiting to Join
- osRtxThreadJoinWakeup(thread);
- // Switch to next Ready Thread when terminating running Thread
- if (thread->state == osRtxThreadRunning) {
- osRtxThreadSwitch(osRtxThreadListGet(&osRtxInfo.thread.ready));
- // Update Stack Pointer
- thread->sp = __get_PSP();
- #ifdef RTX_STACK_CHECK
- // Check Stack usage
- if (!osRtxThreadStackCheck(thread)) {
- osRtxThreadSetRunning(osRtxInfo.thread.run.next);
- (void)osRtxKernelErrorNotify(osRtxErrorStackOverflow, thread);
- }
- #endif
- // Mark running thread as deleted
- osRtxThreadSetRunning(NULL);
- } else {
- osRtxThreadDispatch(NULL);
- }
- // Destroy Thread
- osRtxThreadDestroy(thread);
- }
- return status;
- }
- #ifdef RTX_THREAD_WATCHDOG
- /// Feed watchdog of the current running thread.
- /// \note API identical to osThreadFeedWatchdog
- static osStatus_t svcRtxThreadFeedWatchdog (uint32_t ticks) {
- os_thread_t *thread;
- // Check running thread
- thread = osRtxThreadGetRunning();
- if (thread == NULL) {
- EvrRtxThreadError(NULL, osRtxErrorKernelNotRunning);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osError;
- }
- osRtxThreadWatchdogRemove(thread);
- osRtxThreadWatchdogInsert(thread, ticks);
- EvrRtxThreadFeedWatchdogDone();
- return osOK;
- }
- #endif
- #ifdef RTX_SAFETY_FEATURES
- /// Protect the creation of privileged threads.
- /// \note API identical to osThreadProtectPrivileged
- static osStatus_t svcRtxThreadProtectPrivileged (void) {
- // Check that Kernel is initialized
- if (osRtxKernelGetState() == osRtxKernelInactive) {
- EvrRtxThreadError(NULL, osRtxErrorKernelNotReady);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osError;
- }
- osRtxInfo.kernel.protect |= osRtxKernelProtectPrivileged;
- EvrRtxThreadPrivilegedProtected();
- return osOK;
- }
- #endif
- #ifdef RTX_SAFETY_CLASS
- /// Suspend execution of threads for specified safety classes.
- /// \note API identical to osThreadSuspendClass
- static osStatus_t svcRtxThreadSuspendClass (uint32_t safety_class, uint32_t mode) {
- os_thread_t *thread;
- os_thread_t *thread_next;
- // Check parameters
- if (safety_class > 0x0FU) {
- EvrRtxThreadError(NULL, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorParameter;
- }
- // Check running thread safety class (when called from thread)
- thread = osRtxThreadGetRunning();
- if ((thread != NULL) && IsSVCallIrq()) {
- if ((((mode & osSafetyWithSameClass) != 0U) &&
- ((thread->attr >> osRtxAttrClass_Pos) < (uint8_t)safety_class)) ||
- (((mode & osSafetyWithLowerClass) != 0U) &&
- (((thread->attr >> osRtxAttrClass_Pos) + 1U) < (uint8_t)safety_class))) {
- EvrRtxThreadError(NULL, (int32_t)osErrorSafetyClass);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorSafetyClass;
- }
- }
- // Threads in Wait List
- thread = osRtxInfo.thread.wait_list;
- while (thread != NULL) {
- thread_next = thread->delay_next;
- if ((((mode & osSafetyWithSameClass) != 0U) &&
- ((thread->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
- (((mode & osSafetyWithLowerClass) != 0U) &&
- ((thread->attr >> osRtxAttrClass_Pos) < (uint8_t)safety_class))) {
- osRtxThreadListRemove(thread);
- thread->state = osRtxThreadBlocked;
- EvrRtxThreadSuspended(thread);
- }
- thread = thread_next;
- }
- // Threads in Delay List
- thread = osRtxInfo.thread.delay_list;
- while (thread != NULL) {
- thread_next = thread->delay_next;
- if ((((mode & osSafetyWithSameClass) != 0U) &&
- ((thread->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
- (((mode & osSafetyWithLowerClass) != 0U) &&
- ((thread->attr >> osRtxAttrClass_Pos) < (uint8_t)safety_class))) {
- osRtxThreadListRemove(thread);
- osRtxThreadDelayRemove(thread);
- thread->state = osRtxThreadBlocked;
- osRtxThreadDelayInsert(thread, osWaitForever);
- EvrRtxThreadSuspended(thread);
- }
- thread = thread_next;
- }
- // Threads in Ready List
- thread = osRtxInfo.thread.ready.thread_list;
- while (thread != NULL) {
- thread_next = thread->thread_next;
- if ((((mode & osSafetyWithSameClass) != 0U) &&
- ((thread->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
- (((mode & osSafetyWithLowerClass) != 0U) &&
- ((thread->attr >> osRtxAttrClass_Pos) < (uint8_t)safety_class))) {
- osRtxThreadListRemove(thread);
- thread->state = osRtxThreadBlocked;
- osRtxThreadDelayInsert(thread, osWaitForever);
- EvrRtxThreadSuspended(thread);
- }
- thread = thread_next;
- }
- // Running Thread
- thread = osRtxThreadGetRunning();
- if ((thread != NULL) &&
- ((((mode & osSafetyWithSameClass) != 0U) &&
- ((thread->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
- (((mode & osSafetyWithLowerClass) != 0U) &&
- ((thread->attr >> osRtxAttrClass_Pos) < (uint8_t)safety_class)))) {
- if ((osRtxKernelGetState() == osRtxKernelRunning) &&
- (osRtxInfo.thread.ready.thread_list != NULL)) {
- thread->state = osRtxThreadBlocked;
- osRtxThreadDelayInsert(thread, osWaitForever);
- EvrRtxThreadSuspended(thread);
- osRtxThreadSwitch(osRtxThreadListGet(&osRtxInfo.thread.ready));
- } else {
- EvrRtxThreadError(thread, (int32_t)osErrorResource);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorResource;
- }
- }
- return osOK;
- }
- /// Resume execution of threads for specified safety classes.
- /// \note API identical to osThreadResumeClass
- static osStatus_t svcRtxThreadResumeClass (uint32_t safety_class, uint32_t mode) {
- os_thread_t *thread;
- os_thread_t *thread_next;
- // Check parameters
- if (safety_class > 0x0FU) {
- EvrRtxThreadError(NULL, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorParameter;
- }
- // Check running thread safety class (when called from thread)
- thread = osRtxThreadGetRunning();
- if ((thread != NULL) && IsSVCallIrq()) {
- if ((((mode & osSafetyWithSameClass) != 0U) &&
- ((thread->attr >> osRtxAttrClass_Pos) < (uint8_t)safety_class)) ||
- (((mode & osSafetyWithLowerClass) != 0U) &&
- (((thread->attr >> osRtxAttrClass_Pos) + 1U) < (uint8_t)safety_class))) {
- EvrRtxThreadError(NULL, (int32_t)osErrorSafetyClass);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorSafetyClass;
- }
- }
- // Threads in Wait List
- thread = osRtxInfo.thread.wait_list;
- while (thread != NULL) {
- thread_next = thread->delay_next;
- if ((((mode & osSafetyWithSameClass) != 0U) &&
- ((thread->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
- (((mode & osSafetyWithLowerClass) != 0U) &&
- ((thread->attr >> osRtxAttrClass_Pos) < (uint8_t)safety_class))) {
- // Wakeup Thread
- osRtxThreadListRemove(thread);
- osRtxThreadDelayRemove(thread);
- osRtxThreadReadyPut(thread);
- EvrRtxThreadResumed(thread);
- }
- thread = thread_next;
- }
- // Threads in Delay List
- thread = osRtxInfo.thread.delay_list;
- while (thread != NULL) {
- thread_next = thread->delay_next;
- if ((((mode & osSafetyWithSameClass) != 0U) &&
- ((thread->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
- (((mode & osSafetyWithLowerClass) != 0U) &&
- ((thread->attr >> osRtxAttrClass_Pos) < (uint8_t)safety_class))) {
- // Wakeup Thread
- osRtxThreadListRemove(thread);
- osRtxThreadDelayRemove(thread);
- osRtxThreadReadyPut(thread);
- EvrRtxThreadResumed(thread);
- }
- thread = thread_next;
- }
- osRtxThreadDispatch(NULL);
- return osOK;
- }
- #endif
- #ifdef RTX_EXECUTION_ZONE
- /// Terminate execution of threads assigned to a specified MPU protected zone.
- /// \note API identical to osThreadTerminateZone
- static osStatus_t svcRtxThreadTerminateZone (uint32_t zone) {
- os_thread_t *thread;
- os_thread_t *thread_next;
- #ifdef RTX_THREAD_WATCHDOG
- // Check Watchdog Alarm Flag
- if (WatchdogAlarmFlag != 0U) {
- EvrRtxThreadError(NULL, (int32_t)osErrorISR);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorISR;
- }
- #endif
- // Check parameters
- if (zone > 0x3FU) {
- EvrRtxThreadError(NULL, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorParameter;
- }
- // Threads in Wait List
- thread = osRtxInfo.thread.wait_list;
- while (thread != NULL) {
- thread_next = thread->delay_next;
- if (thread->zone == zone) {
- osRtxThreadListRemove(thread);
- osRtxThreadDelayRemove(thread);
- #ifdef RTX_THREAD_WATCHDOG
- osRtxThreadWatchdogRemove(thread);
- #endif
- osRtxMutexOwnerRelease(thread->mutex_list);
- osRtxThreadJoinWakeup(thread);
- osRtxThreadDestroy(thread);
- }
- thread = thread_next;
- }
- // Threads in Delay List
- thread = osRtxInfo.thread.delay_list;
- while (thread != NULL) {
- thread_next = thread->delay_next;
- if (thread->zone == zone) {
- osRtxThreadListRemove(thread);
- osRtxThreadDelayRemove(thread);
- #ifdef RTX_THREAD_WATCHDOG
- osRtxThreadWatchdogRemove(thread);
- #endif
- osRtxMutexOwnerRelease(thread->mutex_list);
- osRtxThreadJoinWakeup(thread);
- osRtxThreadDestroy(thread);
- }
- thread = thread_next;
- }
- // Threads in Ready List
- thread = osRtxInfo.thread.ready.thread_list;
- while (thread != NULL) {
- thread_next = thread->thread_next;
- if (thread->zone == zone) {
- osRtxThreadListRemove(thread);
- #ifdef RTX_THREAD_WATCHDOG
- osRtxThreadWatchdogRemove(thread);
- #endif
- osRtxMutexOwnerRelease(thread->mutex_list);
- osRtxThreadJoinWakeup(thread);
- osRtxThreadDestroy(thread);
- }
- thread = thread_next;
- }
- // Running Thread
- thread = osRtxThreadGetRunning();
- if ((thread != NULL) && (thread->zone == zone)) {
- if ((osRtxKernelGetState() != osRtxKernelRunning) ||
- (osRtxInfo.thread.ready.thread_list == NULL)) {
- osRtxThreadDispatch(NULL);
- EvrRtxThreadError(thread, (int32_t)osErrorResource);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorResource;
- }
- #ifdef RTX_THREAD_WATCHDOG
- osRtxThreadWatchdogRemove(thread);
- #endif
- osRtxMutexOwnerRelease(thread->mutex_list);
- osRtxThreadJoinWakeup(thread);
- // Switch to next Ready Thread
- osRtxThreadSwitch(osRtxThreadListGet(&osRtxInfo.thread.ready));
- // Update Stack Pointer
- thread->sp = __get_PSP();
- #ifdef RTX_STACK_CHECK
- // Check Stack usage
- if (!osRtxThreadStackCheck(thread)) {
- osRtxThreadSetRunning(osRtxInfo.thread.run.next);
- (void)osRtxKernelErrorNotify(osRtxErrorStackOverflow, thread);
- }
- #endif
- // Mark running thread as deleted
- osRtxThreadSetRunning(NULL);
- // Destroy Thread
- osRtxThreadDestroy(thread);
- } else {
- osRtxThreadDispatch(NULL);
- }
- return osOK;
- }
- #endif
- /// Get number of active threads.
- /// \note API identical to osThreadGetCount
- static uint32_t svcRtxThreadGetCount (void) {
- const os_thread_t *thread;
- uint32_t count;
- // Running Thread
- count = 1U;
- // Ready List
- for (thread = osRtxInfo.thread.ready.thread_list;
- thread != NULL; thread = thread->thread_next) {
- count++;
- }
- // Delay List
- for (thread = osRtxInfo.thread.delay_list;
- thread != NULL; thread = thread->delay_next) {
- count++;
- }
- // Wait List
- for (thread = osRtxInfo.thread.wait_list;
- thread != NULL; thread = thread->delay_next) {
- count++;
- }
- EvrRtxThreadGetCount(count);
- return count;
- }
- /// Enumerate active threads.
- /// \note API identical to osThreadEnumerate
- static uint32_t svcRtxThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items) {
- os_thread_t *thread;
- uint32_t count;
- // Check parameters
- if ((thread_array == NULL) || (array_items == 0U)) {
- EvrRtxThreadEnumerate(thread_array, array_items, 0U);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return 0U;
- }
- // Running Thread
- *thread_array = osRtxThreadGetRunning();
- thread_array++;
- count = 1U;
- // Ready List
- for (thread = osRtxInfo.thread.ready.thread_list;
- (thread != NULL) && (count < array_items); thread = thread->thread_next) {
- *thread_array = thread;
- thread_array++;
- count++;
- }
- // Delay List
- for (thread = osRtxInfo.thread.delay_list;
- (thread != NULL) && (count < array_items); thread = thread->delay_next) {
- *thread_array = thread;
- thread_array++;
- count++;
- }
- // Wait List
- for (thread = osRtxInfo.thread.wait_list;
- (thread != NULL) && (count < array_items); thread = thread->delay_next) {
- *thread_array = thread;
- thread_array++;
- count++;
- }
- EvrRtxThreadEnumerate(thread_array - count, array_items, count);
- return count;
- }
- /// Set the specified Thread Flags of a thread.
- /// \note API identical to osThreadFlagsSet
- static uint32_t svcRtxThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) {
- os_thread_t *thread = osRtxThreadId(thread_id);
- #ifdef RTX_SAFETY_CLASS
- const os_thread_t *thread_running;
- #endif
- uint32_t thread_flags;
- uint32_t thread_flags0;
- // Check parameters
- if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread) ||
- ((flags & ~(((uint32_t)1U << osRtxThreadFlagsLimit) - 1U)) != 0U)) {
- EvrRtxThreadFlagsError(thread, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return ((uint32_t)osErrorParameter);
- }
- // Check object state
- if (thread->state == osRtxThreadTerminated) {
- EvrRtxThreadFlagsError(thread, (int32_t)osErrorResource);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return ((uint32_t)osErrorResource);
- }
- #ifdef RTX_SAFETY_CLASS
- // Check running thread safety class
- thread_running = osRtxThreadGetRunning();
- if ((thread_running != NULL) &&
- ((thread_running->attr >> osRtxAttrClass_Pos) < (thread->attr >> osRtxAttrClass_Pos))) {
- EvrRtxThreadFlagsError(thread, (int32_t)osErrorSafetyClass);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return ((uint32_t)osErrorSafetyClass);
- }
- #endif
- // Set Thread Flags
- thread_flags = ThreadFlagsSet(thread, flags);
- // Check if Thread is waiting for Thread Flags
- if (thread->state == osRtxThreadWaitingThreadFlags) {
- thread_flags0 = ThreadFlagsCheck(thread, thread->wait_flags, thread->flags_options);
- if (thread_flags0 != 0U) {
- if ((thread->flags_options & osFlagsNoClear) == 0U) {
- thread_flags = thread_flags0 & ~thread->wait_flags;
- } else {
- thread_flags = thread_flags0;
- }
- osRtxThreadWaitExit(thread, thread_flags0, TRUE);
- EvrRtxThreadFlagsWaitCompleted(thread->wait_flags, thread->flags_options, thread_flags0, thread);
- }
- }
- EvrRtxThreadFlagsSetDone(thread, thread_flags);
- return thread_flags;
- }
- /// Clear the specified Thread Flags of current running thread.
- /// \note API identical to osThreadFlagsClear
- static uint32_t svcRtxThreadFlagsClear (uint32_t flags) {
- os_thread_t *thread;
- uint32_t thread_flags;
- // Check running thread
- thread = osRtxThreadGetRunning();
- if (thread == NULL) {
- EvrRtxThreadFlagsError(NULL, osRtxErrorKernelNotRunning);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return ((uint32_t)osError);
- }
- // Check parameters
- if ((flags & ~(((uint32_t)1U << osRtxThreadFlagsLimit) - 1U)) != 0U) {
- EvrRtxThreadFlagsError(thread, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return ((uint32_t)osErrorParameter);
- }
- // Clear Thread Flags
- thread_flags = ThreadFlagsClear(thread, flags);
- EvrRtxThreadFlagsClearDone(thread_flags);
- return thread_flags;
- }
- /// Get the current Thread Flags of current running thread.
- /// \note API identical to osThreadFlagsGet
- static uint32_t svcRtxThreadFlagsGet (void) {
- const os_thread_t *thread;
- // Check running thread
- thread = osRtxThreadGetRunning();
- if (thread == NULL) {
- EvrRtxThreadFlagsGet(0U);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return 0U;
- }
- EvrRtxThreadFlagsGet(thread->thread_flags);
- return thread->thread_flags;
- }
- /// Wait for one or more Thread Flags of the current running thread to become signaled.
- /// \note API identical to osThreadFlagsWait
- static uint32_t svcRtxThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout) {
- os_thread_t *thread;
- uint32_t thread_flags;
- // Check running thread
- thread = osRtxThreadGetRunning();
- if (thread == NULL) {
- EvrRtxThreadFlagsError(NULL, osRtxErrorKernelNotRunning);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return ((uint32_t)osError);
- }
- // Check parameters
- if ((flags & ~(((uint32_t)1U << osRtxThreadFlagsLimit) - 1U)) != 0U) {
- EvrRtxThreadFlagsError(thread, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return ((uint32_t)osErrorParameter);
- }
- // Check Thread Flags
- thread_flags = ThreadFlagsCheck(thread, flags, options);
- if (thread_flags != 0U) {
- EvrRtxThreadFlagsWaitCompleted(flags, options, thread_flags, thread);
- } else {
- // Check if timeout is specified
- if (timeout != 0U) {
- // Store waiting flags and options
- EvrRtxThreadFlagsWaitPending(flags, options, timeout);
- thread->wait_flags = flags;
- thread->flags_options = (uint8_t)options;
- // Suspend current Thread
- if (!osRtxThreadWaitEnter(osRtxThreadWaitingThreadFlags, timeout)) {
- EvrRtxThreadFlagsWaitTimeout(thread);
- }
- thread_flags = (uint32_t)osErrorTimeout;
- } else {
- EvrRtxThreadFlagsWaitNotCompleted(flags, options);
- thread_flags = (uint32_t)osErrorResource;
- }
- }
- return thread_flags;
- }
- // Service Calls definitions
- //lint ++flb "Library Begin" [MISRA Note 11]
- SVC0_3 (ThreadNew, osThreadId_t, osThreadFunc_t, void *, const osThreadAttr_t *)
- SVC0_1 (ThreadGetName, const char *, osThreadId_t)
- #ifdef RTX_SAFETY_CLASS
- SVC0_1 (ThreadGetClass, uint32_t, osThreadId_t)
- #endif
- #ifdef RTX_EXECUTION_ZONE
- SVC0_1 (ThreadGetZone, uint32_t, osThreadId_t)
- #endif
- SVC0_0 (ThreadGetId, osThreadId_t)
- SVC0_1 (ThreadGetState, osThreadState_t, osThreadId_t)
- SVC0_1 (ThreadGetStackSize, uint32_t, osThreadId_t)
- SVC0_1 (ThreadGetStackSpace, uint32_t, osThreadId_t)
- SVC0_2 (ThreadSetPriority, osStatus_t, osThreadId_t, osPriority_t)
- SVC0_1 (ThreadGetPriority, osPriority_t, osThreadId_t)
- SVC0_0 (ThreadYield, osStatus_t)
- SVC0_1 (ThreadSuspend, osStatus_t, osThreadId_t)
- SVC0_1 (ThreadResume, osStatus_t, osThreadId_t)
- SVC0_1 (ThreadDetach, osStatus_t, osThreadId_t)
- SVC0_1 (ThreadJoin, osStatus_t, osThreadId_t)
- SVC0_0N(ThreadExit, void)
- SVC0_1 (ThreadTerminate, osStatus_t, osThreadId_t)
- #ifdef RTX_THREAD_WATCHDOG
- SVC0_1 (ThreadFeedWatchdog, osStatus_t, uint32_t)
- #endif
- #ifdef RTX_SAFETY_FEATURES
- SVC0_0 (ThreadProtectPrivileged, osStatus_t)
- #endif
- #ifdef RTX_SAFETY_CLASS
- SVC0_2 (ThreadSuspendClass, osStatus_t, uint32_t, uint32_t)
- SVC0_2 (ThreadResumeClass, osStatus_t, uint32_t, uint32_t)
- #endif
- SVC0_0 (ThreadGetCount, uint32_t)
- SVC0_2 (ThreadEnumerate, uint32_t, osThreadId_t *, uint32_t)
- SVC0_2 (ThreadFlagsSet, uint32_t, osThreadId_t, uint32_t)
- SVC0_1 (ThreadFlagsClear, uint32_t, uint32_t)
- SVC0_0 (ThreadFlagsGet, uint32_t)
- SVC0_3 (ThreadFlagsWait, uint32_t, uint32_t, uint32_t, uint32_t)
- //lint --flb "Library End"
- // ==== ISR Calls ====
- /// Set the specified Thread Flags of a thread.
- /// \note API identical to osThreadFlagsSet
- __STATIC_INLINE
- uint32_t isrRtxThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) {
- os_thread_t *thread = osRtxThreadId(thread_id);
- uint32_t thread_flags;
- // Check parameters
- if (!IsThreadPtrValid(thread) || (thread->id != osRtxIdThread) ||
- ((flags & ~(((uint32_t)1U << osRtxThreadFlagsLimit) - 1U)) != 0U)) {
- EvrRtxThreadFlagsError(thread, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return ((uint32_t)osErrorParameter);
- }
- // Check object state
- if (thread->state == osRtxThreadTerminated) {
- EvrRtxThreadFlagsError(thread, (int32_t)osErrorResource);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return ((uint32_t)osErrorResource);
- }
- // Set Thread Flags
- thread_flags = ThreadFlagsSet(thread, flags);
- // Register post ISR processing
- osRtxPostProcess(osRtxObject(thread));
- EvrRtxThreadFlagsSetDone(thread, thread_flags);
- return thread_flags;
- }
- // ==== Library functions ====
- /// RTOS Thread Before Free Hook.
- //lint -esym(759,osRtxThreadBeforeFree) "Prototype in header"
- //lint -esym(765,osRtxThreadBeforeFree) "Global scope (can be overridden)"
- __WEAK void osRtxThreadBeforeFree (os_thread_t *thread) {
- (void)thread;
- }
- /// Thread startup (Idle and Timer Thread).
- /// \return true - success, false - failure.
- bool_t osRtxThreadStartup (void) {
- bool_t ret = FALSE;
- // Create Idle Thread
- osRtxInfo.thread.idle = osRtxThreadId(
- svcRtxThreadNew(osRtxIdleThread, NULL, osRtxConfig.idle_thread_attr)
- );
- // Create Timer Thread
- if (osRtxConfig.timer_setup != NULL) {
- if (osRtxConfig.timer_setup() == 0) {
- osRtxInfo.timer.thread = osRtxThreadId(
- svcRtxThreadNew(osRtxConfig.timer_thread, osRtxInfo.timer.mq, osRtxConfig.timer_thread_attr)
- );
- if (osRtxInfo.timer.thread != NULL) {
- ret = TRUE;
- }
- }
- } else {
- ret = TRUE;
- }
- return ret;
- }
- // ==== Public API ====
- /// Create a thread and add it to Active Threads.
- osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) {
- osThreadId_t thread_id;
- EvrRtxThreadNew(func, argument, attr);
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadError(NULL, (int32_t)osErrorISR);
- thread_id = NULL;
- } else {
- thread_id = __svcThreadNew(func, argument, attr);
- }
- return thread_id;
- }
- /// Get name of a thread.
- const char *osThreadGetName (osThreadId_t thread_id) {
- const char *name;
- if (IsException() || IsIrqMasked()) {
- name = svcRtxThreadGetName(thread_id);
- } else {
- name = __svcThreadGetName(thread_id);
- }
- return name;
- }
- #ifdef RTX_SAFETY_CLASS
- /// Get safety class of a thread.
- uint32_t osThreadGetClass (osThreadId_t thread_id) {
- uint32_t safety_class;
- if (IsException() || IsIrqMasked()) {
- safety_class = svcRtxThreadGetClass(thread_id);
- } else {
- safety_class = __svcThreadGetClass(thread_id);
- }
- return safety_class;
- }
- #endif
- #ifdef RTX_EXECUTION_ZONE
- /// Get zone of a thread.
- uint32_t osThreadGetZone (osThreadId_t thread_id) {
- uint32_t zone;
- if (IsException() || IsIrqMasked()) {
- zone = svcRtxThreadGetZone(thread_id);
- } else {
- zone = __svcThreadGetZone(thread_id);
- }
- return zone;
- }
- #endif
- /// Return the thread ID of the current running thread.
- osThreadId_t osThreadGetId (void) {
- osThreadId_t thread_id;
- if (IsException() || IsIrqMasked()) {
- thread_id = svcRtxThreadGetId();
- } else {
- thread_id = __svcThreadGetId();
- }
- return thread_id;
- }
- /// Get current thread state of a thread.
- osThreadState_t osThreadGetState (osThreadId_t thread_id) {
- osThreadState_t state;
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadGetState(thread_id, osThreadError);
- state = osThreadError;
- } else {
- state = __svcThreadGetState(thread_id);
- }
- return state;
- }
- /// Get stack size of a thread.
- uint32_t osThreadGetStackSize (osThreadId_t thread_id) {
- uint32_t stack_size;
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadGetStackSize(thread_id, 0U);
- stack_size = 0U;
- } else {
- stack_size = __svcThreadGetStackSize(thread_id);
- }
- return stack_size;
- }
- /// Get available stack space of a thread based on stack watermark recording during execution.
- uint32_t osThreadGetStackSpace (osThreadId_t thread_id) {
- uint32_t stack_space;
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadGetStackSpace(thread_id, 0U);
- stack_space = 0U;
- } else {
- stack_space = __svcThreadGetStackSpace(thread_id);
- }
- return stack_space;
- }
- /// Change priority of a thread.
- osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) {
- osStatus_t status;
- EvrRtxThreadSetPriority(thread_id, priority);
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadError(thread_id, (int32_t)osErrorISR);
- status = osErrorISR;
- } else {
- status = __svcThreadSetPriority(thread_id, priority);
- }
- return status;
- }
- /// Get current priority of a thread.
- osPriority_t osThreadGetPriority (osThreadId_t thread_id) {
- osPriority_t priority;
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadGetPriority(thread_id, osPriorityError);
- priority = osPriorityError;
- } else {
- priority = __svcThreadGetPriority(thread_id);
- }
- return priority;
- }
- /// Pass control to next thread that is in state READY.
- osStatus_t osThreadYield (void) {
- osStatus_t status;
- EvrRtxThreadYield();
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadError(NULL, (int32_t)osErrorISR);
- status = osErrorISR;
- } else {
- status = __svcThreadYield();
- }
- return status;
- }
- /// Suspend execution of a thread.
- osStatus_t osThreadSuspend (osThreadId_t thread_id) {
- osStatus_t status;
- EvrRtxThreadSuspend(thread_id);
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadError(thread_id, (int32_t)osErrorISR);
- status = osErrorISR;
- } else {
- status = __svcThreadSuspend(thread_id);
- }
- return status;
- }
- /// Resume execution of a thread.
- osStatus_t osThreadResume (osThreadId_t thread_id) {
- osStatus_t status;
- EvrRtxThreadResume(thread_id);
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadError(thread_id, (int32_t)osErrorISR);
- status = osErrorISR;
- } else {
- status = __svcThreadResume(thread_id);
- }
- return status;
- }
- /// Detach a thread (thread storage can be reclaimed when thread terminates).
- osStatus_t osThreadDetach (osThreadId_t thread_id) {
- osStatus_t status;
- EvrRtxThreadDetach(thread_id);
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadError(thread_id, (int32_t)osErrorISR);
- status = osErrorISR;
- } else {
- status = __svcThreadDetach(thread_id);
- }
- return status;
- }
- /// Wait for specified thread to terminate.
- osStatus_t osThreadJoin (osThreadId_t thread_id) {
- osStatus_t status;
- EvrRtxThreadJoin(thread_id);
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadError(thread_id, (int32_t)osErrorISR);
- status = osErrorISR;
- } else {
- status = __svcThreadJoin(thread_id);
- }
- return status;
- }
- /// Terminate execution of current running thread.
- __NO_RETURN void osThreadExit (void) {
- EvrRtxThreadExit();
- __svcThreadExit();
- EvrRtxThreadError(NULL, (int32_t)osError);
- for (;;) {}
- }
- /// Terminate execution of a thread.
- osStatus_t osThreadTerminate (osThreadId_t thread_id) {
- osStatus_t status;
- EvrRtxThreadTerminate(thread_id);
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadError(thread_id, (int32_t)osErrorISR);
- status = osErrorISR;
- } else {
- status = __svcThreadTerminate(thread_id);
- }
- return status;
- }
- #ifdef RTX_THREAD_WATCHDOG
- /// Feed watchdog of the current running thread.
- osStatus_t osThreadFeedWatchdog (uint32_t ticks) {
- osStatus_t status;
- EvrRtxThreadFeedWatchdog(ticks);
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadError(NULL, (int32_t)osErrorISR);
- status = osErrorISR;
- } else {
- status = __svcThreadFeedWatchdog(ticks);
- }
- return status;
- }
- #endif
- #ifdef RTX_SAFETY_FEATURES
- /// Protect the creation of privileged threads.
- osStatus_t osThreadProtectPrivileged (void) {
- osStatus_t status;
- EvrRtxThreadProtectPrivileged();
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadError(NULL, (int32_t)osErrorISR);
- status = osErrorISR;
- } else {
- status = __svcThreadProtectPrivileged();
- }
- return status;
- }
- #endif
- #ifdef RTX_SAFETY_CLASS
- /// Suspend execution of threads for specified safety classes.
- osStatus_t osThreadSuspendClass (uint32_t safety_class, uint32_t mode) {
- osStatus_t status;
- EvrRtxThreadSuspendClass(safety_class, mode);
- if (IsException() || IsIrqMasked()) {
- if (IsTickIrq(osRtxInfo.tick_irqn)) {
- status = svcRtxThreadSuspendClass(safety_class, mode);
- } else {
- EvrRtxThreadError(NULL, (int32_t)osErrorISR);
- status = osErrorISR;
- }
- } else {
- status = __svcThreadSuspendClass(safety_class, mode);
- }
- return status;
- }
- /// Resume execution of threads for specified safety classes.
- osStatus_t osThreadResumeClass (uint32_t safety_class, uint32_t mode) {
- osStatus_t status;
- EvrRtxThreadResumeClass(safety_class, mode);
- if (IsException() || IsIrqMasked()) {
- if (IsTickIrq(osRtxInfo.tick_irqn)) {
- status = svcRtxThreadResumeClass(safety_class, mode);
- } else {
- EvrRtxThreadError(NULL, (int32_t)osErrorISR);
- status = osErrorISR;
- }
- } else {
- status = __svcThreadResumeClass(safety_class, mode);
- }
- return status;
- }
- #endif
- #ifdef RTX_EXECUTION_ZONE
- /// Terminate execution of threads assigned to a specified MPU protected zone.
- osStatus_t osThreadTerminateZone (uint32_t zone) {
- osStatus_t status;
- EvrRtxThreadTerminateZone(zone);
- if (IsException() || IsIrqMasked()) {
- if (IsFault() || IsSVCallIrq() || IsPendSvIrq() || IsTickIrq(osRtxInfo.tick_irqn)) {
- status = svcRtxThreadTerminateZone(zone);
- } else {
- EvrRtxThreadError(NULL, (int32_t)osErrorISR);
- status = osErrorISR;
- }
- } else {
- EvrRtxThreadError(osRtxThreadGetRunning(), (int32_t)osError);
- status = osError;
- }
- return status;
- }
- #endif
- /// Get number of active threads.
- uint32_t osThreadGetCount (void) {
- uint32_t count;
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadGetCount(0U);
- count = 0U;
- } else {
- count = __svcThreadGetCount();
- }
- return count;
- }
- /// Enumerate active threads.
- uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items) {
- uint32_t count;
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadEnumerate(thread_array, array_items, 0U);
- count = 0U;
- } else {
- count = __svcThreadEnumerate(thread_array, array_items);
- }
- return count;
- }
- /// Set the specified Thread Flags of a thread.
- uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) {
- uint32_t thread_flags;
- EvrRtxThreadFlagsSet(thread_id, flags);
- if (IsException() || IsIrqMasked()) {
- thread_flags = isrRtxThreadFlagsSet(thread_id, flags);
- } else {
- thread_flags = __svcThreadFlagsSet(thread_id, flags);
- }
- return thread_flags;
- }
- /// Clear the specified Thread Flags of current running thread.
- uint32_t osThreadFlagsClear (uint32_t flags) {
- uint32_t thread_flags;
- EvrRtxThreadFlagsClear(flags);
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadFlagsError(NULL, (int32_t)osErrorISR);
- thread_flags = (uint32_t)osErrorISR;
- } else {
- thread_flags = __svcThreadFlagsClear(flags);
- }
- return thread_flags;
- }
- /// Get the current Thread Flags of current running thread.
- uint32_t osThreadFlagsGet (void) {
- uint32_t thread_flags;
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadFlagsGet(0U);
- thread_flags = 0U;
- } else {
- thread_flags = __svcThreadFlagsGet();
- }
- return thread_flags;
- }
- /// Wait for one or more Thread Flags of the current running thread to become signaled.
- uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout) {
- uint32_t thread_flags;
- EvrRtxThreadFlagsWait(flags, options, timeout);
- if (IsException() || IsIrqMasked()) {
- EvrRtxThreadFlagsError(NULL, (int32_t)osErrorISR);
- thread_flags = (uint32_t)osErrorISR;
- } else {
- thread_flags = __svcThreadFlagsWait(flags, options, timeout);
- }
- return thread_flags;
- }
|