| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409 |
- /*
- * Copyright (c) 2023 HPMicro
- */
- /***************************************************************************//**
- * @file cmsis_os2.c
- * @brief CMSIS-RTOS2 -> MicriumOS Emulation Layer
- ******************************************************************************/
- /***************************************************************************//**
- * # License
- *
- * The licensor of this software is Silicon Laboratories Inc. Your use of this
- * software is governed by the terms of Silicon Labs Master Software License
- * Agreement (MSLA) available at
- * www.silabs.com/about-us/legal/master-software-license-agreement. This
- * software is Third Party Software licensed by Silicon Labs from a third party
- * and is governed by the sections of the MSLA applicable to Third Party
- * Software and the additional terms set forth below.
- *
- ******************************************************************************/
- /***************************************************************************//**
- * Copyright (c) , Arm Limited and affiliates.
- * 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
- *
- * http://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.
- ******************************************************************************/
- /*
- ****************************************************************************************************
- ****************************************************************************************************
- * I N C L U D E S
- ****************************************************************************************************
- ****************************************************************************************************
- */
- #include <string.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #include "sl_cmsis_os2_common.h"
- #include "rtos_utils_priv.h"
- #include "cmsis_os2.h"
- #include "hpm_soc.h"
- #include "hpm_mchtmr_drv.h"
- #include "hpm_clock_drv.h"
- /*
- ****************************************************************************************************
- ****************************************************************************************************
- * F I L E G L O B A L S
- ****************************************************************************************************
- ****************************************************************************************************
- */
- #ifndef RTOS2_DEFAULT_THREAD_STACK_SIZE
- #define RTOS2_DEFAULT_THREAD_STACK_SIZE 1024
- #endif
- #define RTOS_MODULE_CUR RTOS_CFG_MODULE_KERNEL
- #define osMinNumPriority 56
- #if OS_CFG_PRIO_MAX < osMinNumPriority
- #error CMSIS-RTOS2 requires atleast 56 priority levels. OS_CFG_PRIO_MAX must be >= 56.
- #endif
- #if defined CMSIS_RTOS2_TIMER_TASK_EN && (CMSIS_RTOS2_TIMER_TASK_EN == DEF_ENABLED)
- #ifndef CMSIS_RTOS2_TIMER_TASK_STACK_SIZE
- #error CMSIS Timer task stack size not configured
- #endif
- #ifndef CMSIS_RTOS2_TIMER_TASK_PRIO
- #error CMSIS Timer task priority not configured
- #endif
- #ifndef CMSIS_RTOS2_TIMER_TASK_QUEUE_SIZE
- #error CMSIS Timer task queue size not configured
- #endif
- static OS_TCB timer_task_tcb;
- static CPU_STK timer_task_stack[CMSIS_RTOS2_TIMER_TASK_STACK_SIZE];
- static OS_Q timer_msg_queue;
- #endif
- /********************************************************************************************************
- ********************************************************************************************************
- * C O R E F U N C T I O N S
- ********************************************************************************************************
- *******************************************************************************************************/
- /** Allocate storage for PRIMASK or BASEPRI value for use by
- * CORE_ENTER/EXIT_ATOMIC() and CORE_ENTER/EXIT_CRITICAL() macros. */
- #define CORE_DECLARE_IRQ_STATE CPU_SR_ALLOC()
- /** Enter ATOMIC section. Assumes that a @ref CORE_DECLARE_IRQ_STATE exist in
- * scope. */
- #define CORE_ENTER_ATOMIC CPU_CRITICAL_ENTER
- /** Exit ATOMIC section. Assumes that a @ref CORE_DECLARE_IRQ_STATE exist in
- * scope. */
- #define CORE_EXIT_ATOMIC CPU_CRITICAL_EXIT
- /***************************************************************************//**
- * @brief
- * Check whether the current CPU operation mode is handler mode.
- *
- * @return
- * True if the CPU is in handler mode (currently executing an interrupt handler).
- * @n False if the CPU is in thread mode.
- ******************************************************************************/
- static bool CORE_InIrqContext(void)
- {
- return (read_csr(CSR_MSCRATCH) != 0U) ? true : false;
- }
- /********************************************************************************************************
- ********************************************************************************************************
- * L O C A L F U N C T I O N S
- ********************************************************************************************************
- *******************************************************************************************************/
- #if defined CMSIS_RTOS2_TIMER_TASK_EN && (CMSIS_RTOS2_TIMER_TASK_EN == DEF_ENABLED)
- static void sleeptimer_callback(sl_sleeptimer_timer_handle_t *handle, void *data)
- {
- OS_ERR err;
- (void)handle;
- OSQPost(&timer_msg_queue,
- (void *)data,
- sizeof(void *),
- OS_OPT_POST_FIFO,
- &err
- );
- RTOS_ASSERT_CRITICAL((RTOS_ERR_CODE_GET(err) == OS_ERR_NONE), RTOS_ERR_CODE_GET(err),; );
- }
- static void timer_task(void *arg)
- {
- OS_ERR err;
- OS_MSG_SIZE size;
- osTimer_t *p_tmr;
- (void)arg;
- while (1) {
- p_tmr = (osTimer_t *)OSQPend(&timer_msg_queue,
- 0,
- OS_OPT_PEND_BLOCKING,
- &size,
- NULL,
- &err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- continue;
- }
- if (p_tmr != NULL) {
- p_tmr->callback(p_tmr->callback_data);
- }
- }
- }
- #endif
- /********************************************************************************************************
- ********************************************************************************************************
- * G L O B A L F U N C T I O N S
- ********************************************************************************************************
- *******************************************************************************************************/
- /*
- ****************************************************************************************************
- ****************************************************************************************************
- * I N F O R M A T I O N A N D C O N T R O L
- ****************************************************************************************************
- ****************************************************************************************************
- */
- /*
- ****************************************************************************************************
- * osKernelInitialize()
- *
- * Description: The function 'osKernelInitialize()' initializes the RTOS Kernel. Before it is successfully
- * executed, only the functions 'osKernelGetInfo()' and 'osKernelGetState()' may be called.
- *
- * Arguments : None
- *
- * Returns : osOK in case of success.
- * osError if an unspecific error occurred.
- * osErrorISR if called from an Interrupt Service Routine.
- * osErrorNoMemory if no memory could be reserved for the operation.
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- osStatus_t osKernelInitialize(void)
- {
- OS_ERR err;
- CPU_Init();
- if (OSRunning == OS_STATE_OS_RUNNING) {
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- } else {
- return osError;
- }
- }
- OSInit(&err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- return osError;
- }
- #if (OS_CFG_SCHED_ROUND_ROBIN_EN == DEF_ENABLED)
- OSSchedRoundRobinCfg(DEF_TRUE, 0, &err);
- #endif
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- return osError;
- }
- #if defined CMSIS_RTOS2_TIMER_TASK_EN && (CMSIS_RTOS2_TIMER_TASK_EN == DEF_ENABLED)
- OSTaskCreate(&timer_task_tcb,
- "CMSIS RTOS2 Timer Task",
- timer_task,
- (void *)0,
- CMSIS_RTOS2_TIMER_TASK_PRIO,
- &timer_task_stack[0],
- ((CMSIS_RTOS2_TIMER_TASK_STACK_SIZE * 10u) / 100u),
- CMSIS_RTOS2_TIMER_TASK_STACK_SIZE,
- 0,
- 0,
- (void *)0,
- OS_OPT_TASK_STK_CHK + OS_OPT_TASK_STK_CLR,
- &err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- return osError;
- }
- OSQCreate(&timer_msg_queue,
- "CMSIS RTOS2 Timer Queue",
- CMSIS_RTOS2_TIMER_TASK_QUEUE_SIZE,
- &err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- return osError;
- }
- #endif
- return osOK;
- }
- /*
- ****************************************************************************************************
- * osKernelGetInfo()
- *
- * Description: The function 'osKernelGetInfo()' retrieves the API and kernel version of the underlying
- * RTOS kernel and a human readable identifier string for the kernel. It can be safely
- * called before the RTOS is initialized or started (call to 'osKernelInitialize()' or
- * 'osKernelStart()').
- *
- * Arguments : version pointer to a buffer for retrieving the version information.
- * Format (decimal):
- * MMmmmrrrr
- * MM : Major
- * mmm : Minor
- * rrrr: Revision
- *
- * id_buf pointer to the buffer for retrieving kernel identification string.
- *
- * id_size size of the buffer for the kernel identification string
- *
- * Returns : osOK in case of success.
- * osError if an unspecific error occurred.
- *
- * Note(s) : None
- ****************************************************************************************************
- */
- osStatus_t osKernelGetInfo(osVersion_t *version,
- char *id_buf,
- uint32_t id_size)
- {
- CPU_INT16U os_version;
- OS_ERR err;
- uint32_t os_major;
- uint32_t os_minor;
- uint32_t os_revision;
- if (id_buf == (char *)0) {
- return osError;
- }
- if (id_size < 20u) {
- return osError;
- }
- os_version = OSVersion(&err);
- os_major = os_version / 10000u;
- os_minor = (os_version - os_major * 10000u) / 100u;
- os_revision = os_version % 100u;
- version->api = (os_major * 10000000u)
- + (os_minor * 10000u)
- + os_revision;
- version->kernel = version->api;
- strcpy(id_buf, "MicriumOS");
- return osOK;
- }
- /*
- ****************************************************************************************************
- * osKernelGetState()
- *
- * Description: The function 'osKernelGetState()' returns the current state of the kernel and can be
- * safely called before the RTOS is initialized or started (call to 'osKernelInitialize()'
- * or 'osKernelStart()').
- *
- * In case it fails it will return 'osKernelError', otherwise it returns the kernel state
- * (refer to 'osKernelState_t' for the list of kernel states).
- *
- * Arguments : None
- *
- * Returns : osKernelInactive The kernel is not ready yet
- * osKernelReady The kernel is not running yet
- * osKernelRunning The kernel is initialized and running
- * osKernelLocked The kernel was locked by 'OSKernelLock()'
- * osKernelSuspended The kernel was suspended by 'OSKernelSuspend()' (NOT SUPPORTED)
- * osKernelError An error occurred
- * osKernelReserved Prevents enum down-size compiler optimization
- *
- * Note(s) : None
- ****************************************************************************************************
- */
- osKernelState_t osKernelGetState(void)
- {
- if (OSInitialized == DEF_TRUE) {
- if (OSRunning == OS_STATE_OS_RUNNING) {
- if (OSSchedLockNestingCtr > 0u) {
- return osKernelLocked;
- } else {
- return osKernelRunning;
- }
- } else {
- return osKernelReady;
- }
- }
- return osKernelInactive;
- }
- /*
- ****************************************************************************************************
- * osKernelStart()
- *
- * Description: The function 'osKernelStart()' starts the RTOS kernel and begins thread switching.
- * It will not return to its calling function in case of success. Before it is successfully
- * executed, only the functions 'osKernelGetInfo()', 'osKernelGetState()', and object creation
- * functions ('osXxxNew()') may be called.
- *
- * At least one initial thread should be created prior 'osKernelStart()', see 'osThreadNew()'.
- *
- * Arguments : None
- *
- * Returns : osError If an unspecified error occurs
- * osErrorISR If called from an ISR
- *
- * Note(s) : 1) This function cannot be called from Interrupt Service Routines
- *
- * 2) This function should not be called because MicriumOS should already be initialized.
- *
- * 3) CMSIS-RTOS2 requires atleast 56 priority levels. OS_CFG_PRIO_MAX must be >= 56.
- ****************************************************************************************************
- */
- osStatus_t osKernelStart(void)
- {
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- if (OSRunning == OS_STATE_OS_RUNNING) {
- return osError;
- }
- #if OS_CFG_PRIO_MAX >= osMinNumPriority
- OSStart(&err);
- (void)err; // There is no point in checking the error here
- // because the function will not return in case of success
- return osError;
- #else
- (void)err;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osError); // CMSIS-RTOS2 requires atleast 56 priority levels
- return osError;
- #endif
- }
- /*
- ****************************************************************************************************
- * osKernelLock()
- *
- * Description: The function 'osKernelLock()' allows to lock all task switches. It returns the previous
- * value of the lock state (1 if it was locked, 0 if it was unlocked), or a negative number
- * representing an error code otherwise (refer to 'osStatus_t').
- *
- * Arguments : None
- *
- * Returns : osError If an unspecified error occurs
- * osErrorISR If called from an ISR
- *
- * Note(s) : 1) This function cannot be called from Interrupt Service Routines
- *
- * 2) The MicriumOS equivalent function can be called from an ISR.
- ****************************************************************************************************
- */
- int32_t osKernelLock(void)
- {
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- if (OSSchedLockNestingCtr > 0u) {
- return 1u;
- }
- OSSchedLock(&err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- return osError;
- }
- return 0u;
- }
- /*
- ****************************************************************************************************
- * osKernelUnlock()
- *
- * Description: The function 'osKernelUnlock()' resumes from 'osKernelLock()'. It returns the previous
- * value of the lock state (1 if it was locked, 0 if it was unlocked), or a negative number
- * representing an error code otherwise (refer to 'osStatus_t').
- *
- * Arguments : None
- *
- * Returns : osError If an unspecified error occurs
- * osErrorISR If called from an ISR
- *
- * Note(s) : 1) This function cannot be called from Interrupt Service Routines
- *
- * 2) The MicriumOS equivalent function can be called from an ISR.
- *
- * 3) MicriumOS supports multiple lock levels but CMSIS-RTOS doesn't
- ****************************************************************************************************
- */
- int32_t osKernelUnlock(void)
- {
- OS_NESTING_CTR ctr;
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- ctr = OSSchedLockNestingCtr; // Get the current value of the lock counter
- if (ctr > 1u) { // CMSIS-RTOS only supports 1 lock level
- ctr = 1u;
- }
- OSSchedUnlock(&err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- return osError;
- }
- return ctr;
- }
- /*
- ****************************************************************************************************
- * osKernelRestoreLock()
- *
- * Description: The function 'osKernelRestoreLock()' restores the previous lock state after 'osKernelLock()'
- * or 'osKernelUnlock()'.
- *
- * The argument lock specifies the lock state as obtained by 'osKernelLock()' or 'osKernelUnlock()'.
- *
- * The function returns the new value of the lock state (1 if it was locked, 0 if it was unlocked),
- * or a negative number representing an error code otherwise (refer to 'osStatus_t').
- *
- * Arguments : lock new lock state: 1 == locked, 0 == not locked
- *
- * Returns : osError If an unspecified error occurs
- * osErrorISR If called from an ISR
- *
- * Note(s) : 1) This function cannot be called from Interrupt Service Routines
- *
- * 2) There are no MicriumOS equivalent function to emulate this behavior.
- ****************************************************************************************************
- */
- int32_t osKernelRestoreLock(int32_t lock)
- {
- int32_t new_state;
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- if (lock > 0) {
- OSSchedLock(&err);
- new_state = 1u;
- } else {
- OSSchedUnlock(&err);
- new_state = 0u;
- }
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- return osError;
- }
- return new_state;
- }
- /*
- ****************************************************************************************************
- * osKernelSuspend()
- *
- * Description: CMSIS-RTOS provides extension for tick-less operation which is useful for applications
- * that use extensively low-power modes where the SysTick timer is also disabled. To provide
- * a time-tick in such power-saving modes a wake-up timer is used to derive timer intervals.
- * The function 'osKernelSuspend()' suspends the RTX kernel scheduler and thus enables sleep
- * modes.
- *
- * The return value can be used to determine the amount of system ticks until the next
- * tick-based kernel event will occure, i.e. a delayed thread becomed ready again. It is
- * recommended to set up the low power timer to generate a wake-up interrupt based on this
- * return value.
- *
- * Arguments : None
- *
- * Returns : time in 'ticks', for how long the system can sleep or power-down
- *
- * Note(s) : 1) This function cannot be called from Interrupt Service Routines
- *
- * 2) There are no MicriumOS equivalent function to emulate this behavior.
- ****************************************************************************************************
- */
- uint32_t osKernelSuspend(void)
- {
- if (CORE_InIrqContext() == true) {
- return 0u;
- }
- return 0u;
- }
- /*
- ****************************************************************************************************
- * osKernelResume()
- *
- * Description: CMSIS-RTOS provides extension for tick-less operation which is useful for applications
- * that use extensively low-power modes where the SysTick timer is also disabled. To provide
- * a time-tick in such power-saving modes a wake-up timer is used to derive timer intervals.
- * The function 'osKernelSuspend()' suspends the RTX kernel scheduler and thus enables sleep
- * modes.
- *
- * Arguments : time in 'ticks', for how long the system can sleep or power-down
- *
- * Returns : None
- *
- * Note(s) : 1) This function cannot be called from Interrupt Service Routines
- *
- * 2) There are no MicriumOS equivalent function to emulate this behavior.
- ****************************************************************************************************
- */
- void osKernelResume(uint32_t sleep_ticks)
- {
- (void)sleep_ticks;
- if (CORE_InIrqContext() == true) {
- return;
- }
- }
- /*
- ****************************************************************************************************
- * osKernelGetTickCount()
- *
- * Description: The function 'osKernelGetTickCount()' returns the current RTOS kernel tick count.
- *
- * Arguments : None
- *
- * Returns : the kernel current tick count
- *
- * Note(s) : None
- ****************************************************************************************************
- */
- uint32_t osKernelGetTickCount(void)
- {
- #if (OS_CFG_TICK_EN == DEF_ENABLED)
- OS_ERR err;
- OS_TICK ticks;
- ticks = OSTimeGet(&err);
- (void)err; // CMSIS RTOS API does not give us a way to propagate errors here
- return ticks;
- #else
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, 0u);
- return 0u;
- #endif //#if (OS_CFG_TICK_EN == DEF_ENABLED)
- }
- /*
- ****************************************************************************************************
- * osKernelGetTickFreq()
- *
- * Description: The function 'osKernelGetTickFreq()' returns the frequency of the current RTOS kernel tick.
- *
- * Arguments : None
- *
- * Returns : the kernel tick frequency in Hz
- *
- * Note(s) : None
- ****************************************************************************************************
- */
- uint32_t osKernelGetTickFreq(void)
- {
- #if (OS_CFG_TICK_EN == DEF_ENABLED)
- return OS_CFG_TICK_RATE_HZ;
- #else
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, 0u);
- return 0u;
- #endif
- }
- /*
- ****************************************************************************************************
- * osKernelGetSysTimerCount()
- *
- * Description: The function 'osKernelGetSysTimerCount() returns the current RTOS kernel system timer
- * as a 32-bit value. The value is a rolling 32-bit counter that is composed of the kernel
- * system interrupt timer value and the counter that counts these interrupts (RTOS kernel ticks).
- *
- * This function allows the implementation of very short timeout checks below the RTOS tick
- * granularity. Such checks might be required when checking for a busy status in a device
- * or peripheral initialization routine.
- *
- * Arguments : None
- *
- * Returns : the kernel timer tick count
- ****************************************************************************************************
- */
- uint32_t osKernelGetSysTimerCount(void)
- {
- #if (OS_CFG_TICK_EN == DEF_ENABLED)
- return (uint32_t)(mchtmr_get_count(HPM_MCHTMR));
- #else
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, 0u);
- return 0u;
- #endif
- }
- /*
- ****************************************************************************************************
- * osKernelGetSysTimerFreq()
- *
- * Description: The function 'osKernelGetSysTimerFreq()' returns the frequency of the current RTOS
- * kernel system timer.
- *
- * Arguments : None
- *
- * Returns : the kernel system timer frequency in Hz
- ****************************************************************************************************
- */
- uint32_t osKernelGetSysTimerFreq(void)
- {
- #if (OS_CFG_TICK_EN == DEF_ENABLED)
- return (clock_get_frequency(clock_mchtmr0));
- #else
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, 0u);
- return 0u;
- #endif
- }
- /*
- ****************************************************************************************************
- ****************************************************************************************************
- * G E N E R I C W A I T
- ****************************************************************************************************
- ****************************************************************************************************
- */
- /*
- ****************************************************************************************************
- * osDelay()
- *
- * Description: The function 'osDelay()' waits for a time period specified in kernel ticks. For a value
- * of 1 the system waits until the next timer tick occurs. The actual time delay may be up
- * to one timer tick less than specified, i.e. calling 'osDelay(1)' right before the next
- * system tick occurs the thread is rescheduled immediately.
- *
- * The delayed thread is put into the BLOCKED state and a context switch occurs immediately.
- * The thread is automatically put back to the READY state after the given amount of ticks
- * has elapsed. If the thread will have the highest priority in READY state it will being
- * scheduled immediately.
- *
- * Arguments : ticks is the amount of time (in ticks) that the task will be blocked
- *
- * Returns : osOK if the call is successful
- * osErrorISR if called from an ISR
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- osStatus_t osDelay(uint32_t ticks)
- {
- #if (OS_CFG_TICK_EN == DEF_ENABLED)
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- OSTimeDly((OS_TICK)ticks, OS_OPT_TIME_DLY, &err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- return osError;
- }
- return osOK;
- #else
- (void)ticks;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osError);
- return osError;
- #endif // #if (OS_CFG_TICK_EN == DEF_ENABLED)
- }
- /*
- ****************************************************************************************************
- * osDelayUntil()
- *
- * Description: The function 'osDelayUntil()' waits until an absolute time (specified in kernel ticks)
- * is reached.
- *
- * The corner case when the kernel tick counter overflows is handled by 'osDelayUntil()'.
- * Thus it is absolutely legal to provide a value which is lower than the current tick
- * value, i.e. returned by 'osKernelGetTickCount()'. Typically as a user you do not have
- * to take care about the overflow. The only limitation you have to have in mind is that
- * the maximum delay is limited to 0x7FFFFFFF ticks.
- *
- * The delayed thread is put into the BLOCKED state and a context switch occurs immediately.
- * The thread is automatically put back to the READY state when the given time is reached.
- * If the thread will have the highest priority in READY state it will being scheduled immediately.
- *
- * Arguments : ticks is the absolute time (in ticks) at which the task will wake up.
- *
- * Returns : osOK if the call is successful
- * osParameter if time cannot be handled (out of bounds)
- * osErrorISR if called from an ISR
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- osStatus_t osDelayUntil(uint32_t ticks)
- {
- #if (OS_CFG_TICK_EN == DEF_ENABLED)
- OS_ERR err;
- OS_TICK until;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- until = ticks - OSTimeGet(&err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- return osError;
- }
- if (until > 0x7FFFFFF0u) { // Allow for 16 ticks of latency
- until = 0u;
- }
- OSTimeDly((OS_TICK)until, OS_OPT_TIME_DLY, &err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- return osErrorParameter;
- } else {
- return osOK;
- }
- #else
- (void)ticks;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osError);
- return osError;
- #endif // #if (OS_CFG_TICK_EN == DEF_ENABLED)
- }
- /*
- ****************************************************************************************************
- ****************************************************************************************************
- * E V E N T F L A G S
- ****************************************************************************************************
- ****************************************************************************************************
- */
- /*
- ****************************************************************************************************
- * osEventFlagsNew()
- *
- * Description: The function 'osEventFlagsNew()' creates a new event flags object that is used to send
- * events across threads and returns the pointer to the event flags object identifier or
- * NULL in case of an error. It can be safely called before the RTOS is started
- * (call to 'osKernelStart()'), but not before it is initialized (call to 'osKernelInitialize()').
- *
- * The parameter 'attr' sets the event flags attributes (refer to 'osEventFlagsAttr_t').
- * Default attributes will be used if set to NULL, i.e. kernel memory allocation is used for
- * the event control block.
- *
- * Arguments : attr sets the event flags attributes or default values if NULL
- *
- * .name is an ASCII string used to name the mutex
- *
- * .attr_bits Not currently used, MUST be set to 0
- *
- * .cb_mem Pointer to storage area for the event flags control block
- *
- * .cb_size Size of the memory storage for the event flags control block
- *
- * Returns : The event flags ID
- *
- * Note(s) : 1) The event flags control block is assumed to be of type 'osEentFlags_t' which for the
- * CMSIS-RTOS adaptation layer is defined as an OS_FLAG_GRP in MicriumOS.
- ****************************************************************************************************
- */
- osEventFlagsId_t osEventFlagsNew(const osEventFlagsAttr_t *attr)
- {
- #if (OS_CFG_FLAG_EN == DEF_ENABLED)
- osEventFlags_t *p_flags;
- CPU_CHAR *p_name;
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return (osEventFlagsId_t)0;
- }
- p_name = (CPU_CHAR *)"EventFlags";
- if (attr == 0) {
- p_flags = (osEventFlags_t *)malloc(sizeof(osEventFlags_t));
- if (p_flags == (osEventFlags_t *)0) {
- return (osEventFlagsId_t)0;
- }
- p_flags->dyn_alloc = DEF_TRUE;
- } else {
- if (attr->cb_mem == (void *)0) {
- p_flags = (osEventFlags_t *)malloc(sizeof(osEventFlags_t));
- if (p_flags == (osEventFlags_t *)0) {
- return (osEventFlagsId_t)0;
- }
- p_flags->dyn_alloc = DEF_TRUE;
- } else {
- if (attr->cb_size < sizeof(osEventFlags_t) || (uint32_t)attr->cb_mem % sizeof(CPU_ALIGN)) {
- return (osEventFlagsId_t)0;
- }
- p_flags = (osEventFlags_t*)attr->cb_mem;
- p_flags->dyn_alloc = DEF_FALSE;
- }
- if (attr->name != (const char *)0) {
- p_name = (CPU_CHAR *)attr->name;
- }
- }
- p_flags->flags = 0;
- OSFlagCreate(&p_flags->flag_grp, p_name, p_flags->flags, &err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- if (p_flags->dyn_alloc == DEF_TRUE) {
- free(p_flags);
- }
- return (osEventFlagsId_t)0;
- }
- return (osEventFlagsId_t)p_flags;
- #else
- (void)attr;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, (osEventFlagsId_t)0);
- return (osEventFlagsId_t)0;
- #endif
- }
- /*
- ****************************************************************************************************
- * osEventFlagsSet()
- *
- * Description: The function 'osEventFlagsSet()' sets the event flags specified by the parameter 'flags'
- * in an event flags object specified by parameter 'ef_id'. All threads waiting for the
- * flag set will be notified to resume from BLOCKED state.
- *
- * The function returns the event flags stored in the event control block or an error code
- * (highest bit is set, refer to Flags Functions Error Codes).
- *
- * Arguments : ef_id Is the events flags ID
- *
- * flags The flags to set
- *
- * Returns : The new state of the event flags
- * osFlagsErrorUnknown unspecified error.
- * osFlagsErrorParameter parameter ef_id does not identify a valid event flags object or flags has highest bit set.
- * osFlagsErrorResource the event flags object is in an invalid state.
- *
- * Note(s) : None
- ****************************************************************************************************
- */
- uint32_t osEventFlagsSet(osEventFlagsId_t ef_id,
- uint32_t flags)
- {
- #if (OS_CFG_FLAG_EN == DEF_ENABLED)
- osEventFlags_t *p_flags;
- OS_FLAG_GRP *p_grp;
- OS_TCB *p_tcb;
- OS_ERR err;
- uint32_t rdy_flags;
- uint32_t new_flags;
- uint32_t ret_flags;
- CORE_DECLARE_IRQ_STATE;
- p_flags = (osEventFlags_t *)ef_id;
- if (p_flags == (osEventFlags_t *)0) {
- return osFlagsErrorParameter;
- }
- p_grp = &p_flags->flag_grp;
- if ((flags & 0x80000000u) == 0x80000000u) { // MSB cannot be set
- return osFlagsErrorParameter;
- }
- CORE_ENTER_ATOMIC();
- p_flags->flags |= flags;
- new_flags = p_flags->flags; // New flags after set
- p_tcb = p_grp->PendList.HeadPtr; // Loop over pending tasks
- while (p_tcb != DEF_NULL) {
- if (p_tcb->FlagsOpt & OS_OPT_PEND_FLAG_CONSUME) { // Pender might consume the flags?
- switch (p_tcb->FlagsOpt & OS_OPT_PEND_FLAG_MASK) {
- case OS_OPT_PEND_FLAG_SET_ALL: // -> Pender waiting for all flags to be set
- rdy_flags = (new_flags & p_tcb->FlagsPend);
- if (rdy_flags == p_tcb->FlagsPend) { // -> Pender will really consume?
- new_flags &= ~rdy_flags; // -> Simulate the consumption
- }
- break;
- case OS_OPT_PEND_FLAG_SET_ANY: // -> Pender waiting for any flags to be set
- rdy_flags = (new_flags & p_tcb->FlagsPend);
- if (rdy_flags != 0u) { // -> Pender will really consume?
- new_flags &= ~rdy_flags; // -> Simulate the consumption
- }
- break;
- default:
- break;
- }
- }
- p_tcb = p_tcb->PendNextPtr; // Point to next task waiting for event flag(s)
- }
- CORE_EXIT_ATOMIC();
- OSFlagPost(p_grp, flags, OS_OPT_POST_FLAG_SET, &err);
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- ret_flags = new_flags;
- break;
- default:
- ret_flags = osFlagsErrorResource;
- break;
- }
- return ret_flags;
- #else
- (void)ef_id;
- (void)flags;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osFlagsErrorUnknown);
- return osFlagsErrorUnknown;
- #endif
- }
- /*
- ****************************************************************************************************
- * osEventFlagsClear()
- *
- * Description: The function 'osEventFlagsClear()' clears the event flags specified by the parameter 'flags'
- * in an event flags object specified by parameter 'ef_id'.
- *
- * The function returns the event flags stored in the event control block prior to clearing
- * the flags or an error code (highest bit is set, refer to Flags Functions Error Codes).
- *
- * Arguments : ef_id Is the events flags ID
- *
- * flags The flags to clear
- *
- * Returns : osFlagsErrorUnknown unspecified error.
- * osFlagsErrorParameter parameter ef_id does not identify a valid event flags
- * object or flags has highest bit set.
- * osFlagsErrorResource the event flags object is in an invalid state.
- *
- * Note(s) : None
- ****************************************************************************************************
- */
- uint32_t osEventFlagsClear(osEventFlagsId_t ef_id,
- uint32_t flags)
- {
- #if (OS_CFG_FLAG_EN == DEF_ENABLED)
- osEventFlags_t *p_flags;
- OS_ERR err;
- uint32_t old_flags;
- CORE_DECLARE_IRQ_STATE;
- p_flags = (osEventFlags_t *)ef_id;
- if (p_flags == (osEventFlags_t *)0) {
- return osFlagsErrorParameter;
- }
- CORE_ENTER_ATOMIC();
- old_flags = p_flags->flags; // Get previous value of flags
- p_flags->flags &= ~flags;
- CORE_EXIT_ATOMIC();
- OSFlagPost(&p_flags->flag_grp, flags, OS_OPT_POST_FLAG_CLR, &err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- old_flags = osFlagsErrorUnknown;
- }
- return old_flags;
- #else
- (void)ef_id;
- (void)flags;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osFlagsErrorUnknown);
- return osFlagsErrorUnknown;
- #endif
- }
- /*
- ****************************************************************************************************
- * osEventFlagsGet()
- *
- * Description: The function 'osEventFlagsGet()' gets the current state of the event flags in an event
- * flags object specified by parameter 'ef_id'.
- *
- * Arguments : ef_id Is the events flags ID
- *
- * flags The flags to clear
- *
- * Returns : osFlagsErrorUnknown unspecified error.
- * osFlagsErrorParameter parameter ef_id does not identify a valid event flags object or flags has highest bit set.
- * osFlagsErrorResource the event flags object is in an invalid state.
- *
- * Note(s) : None
- ****************************************************************************************************
- */
- uint32_t osEventFlagsGet(osEventFlagsId_t ef_id)
- {
- #if (OS_CFG_FLAG_EN == DEF_ENABLED)
- osEventFlags_t *p_flags;
- uint32_t flags;
- p_flags = (osEventFlags_t *)ef_id;
- if (p_flags == (osEventFlags_t *)0) {
- return 0u;
- }
- flags = (uint32_t)p_flags->flags; // Get current value of flags
- return flags;
- #else
- (void)ef_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osFlagsErrorUnknown);
- return osFlagsErrorUnknown;
- #endif
- }
- /*
- ****************************************************************************************************
- * osEventFlagsWait()
- *
- * Description: The function 'osEventFlagsWait()' suspends the execution of the currently RUNNING thread
- * until any or all event flags specified by the parameter 'flags' in the event object
- * specified by parameter 'ef_id' are set. When these event flags are already set, the
- * function returns instantly. Otherwise, the thread is put into the state BLOCKED.
- *
- * Arguments : ef_id Is the events flags ID
- *
- * flags The desired flag(s) to wait for
- *
- * options
- * osFlagsWaitAny Wait for any flag (default).
- * osFlagsWaitAny | osFlagsNoClear Wait for any flag specified but do not consume
- * osFlagsWaitAll Wait for all flags.
- * osFlagsWaitAll | osFlagsNoClear Wait for all flags specified but do not consume
- *
- * timeout
- * The parameter timeout specifies how long the system waits for event flags.
- * While the system waits, the thread that is calling this function is put into the
- * BLOCKED state. The parameter timeout can have the following values:
- *
- * when timeout is 0, the function returns instantly (i.e. try semantics).
- * when timeout is set to 'osWaitForever' the function will wait for an infinite time until
- * the event flags become available (i.e. wait semantics).
- * all other values specify a time in kernel ticks for a timeout
- * (i.e. timed-wait semantics).
- *
- * Returns : The
- * osFlagsErrorUnknown unspecified error.
- * osFlagsErrorTimeout awaited flags have not been set in the given time.
- * osFlagsErrorResource awaited flags have not been set when no timeout was specified.
- * osFlagsErrorParameter parameter 'ef_id' does not identify a valid event flags object or flags has highest bit set.
- *
- * Note(s) : 1) May be called from Interrupt Service Routines if the parameter timeout is set to 0.
- *
- * 2) MicriumOS does NOT return the flags prior to clearing but instead, the flags that
- * made the task ready-to-run.
- ****************************************************************************************************
- */
- uint32_t osEventFlagsWait(osEventFlagsId_t ef_id,
- uint32_t flags,
- uint32_t options,
- uint32_t timeout)
- {
- #if (OS_CFG_FLAG_EN == DEF_ENABLED)
- osEventFlags_t *p_flags;
- OS_TICK os_timeout;
- OS_OPT opt;
- OS_ERR err;
- CPU_TS ts;
- uint32_t rtn_flags;
- CORE_DECLARE_IRQ_STATE;
- p_flags = (osEventFlags_t *)ef_id;
- if (p_flags == (osEventFlags_t *)0) {
- return osFlagsErrorParameter;
- }
- if ((flags & 0x80000000u) == 0x80000000u) { // MSB cannot be set
- return osFlagsErrorParameter;
- }
- opt = OS_OPT_PEND_BLOCKING;
- if (timeout == osWaitForever) { // Convert CMSIS-RTOS timeout to MicriumOS
- if (CORE_InIrqContext() == true) {
- return osFlagsErrorParameter;
- }
- os_timeout = 0u; // 0 for MicriumOS means forever
- } else if (timeout == 0u) {
- opt = OS_OPT_PEND_NON_BLOCKING; // No timeout, non-blocking
- os_timeout = 0u; // timeout for MicriumOS in non-blocking mode is ignored
- } else {
- if (CORE_InIrqContext() == true) {
- return osFlagsErrorParameter;
- }
- os_timeout = (OS_TICK)timeout;
- }
- if (options & osFlagsWaitAll) {
- opt |= OS_OPT_PEND_FLAG_SET_ALL;
- } else {
- opt |= OS_OPT_PEND_FLAG_SET_ANY;
- }
- if (!(options & osFlagsNoClear)) {
- opt |= OS_OPT_PEND_FLAG_CONSUME;
- }
- OSFlagPend(&p_flags->flag_grp, (OS_FLAGS)flags, os_timeout, opt, &ts, &err);
- CORE_ENTER_ATOMIC();
- rtn_flags = p_flags->flags;
- if (!(options & osFlagsNoClear)) {
- p_flags->flags &= ~flags;
- }
- CORE_EXIT_ATOMIC();
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- return rtn_flags;
- case OS_ERR_TIMEOUT:
- return osFlagsErrorTimeout;
- case OS_ERR_PEND_WOULD_BLOCK:
- if (rtn_flags != (uint32_t)0u) {
- return rtn_flags;
- } else {
- return osFlagsErrorResource;
- }
- default:
- return osFlagsErrorUnknown;
- }
- #else
- (void)ef_id;
- (void)flags;
- (void)options;
- (void)timeout;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osFlagsErrorUnknown);
- return osFlagsErrorUnknown;
- #endif
- }
- /*
- ****************************************************************************************************
- * osEventFlagsDelete()
- *
- * Description: The function 'osEventFlagsDelete()' deletes the event flags object specified by parameter
- * 'ef_id' and releases the internal memory obtained for the event flags handling.
- *
- * After this call, the 'ef_id' is no longer valid and cannot be used. This can cause starvation
- * of threads that are waiting for flags of this event object. The 'ef_id' may be created again
- * using the function 'osEventFlagsNew()'.
- *
- * Arguments : ef_id Is the ID of the events flags to delete
- *
- * Returns : osOK the specified event flags object was deleted
- * osErrorISR the function was called from an ISR
- * osErrorParameter parameter 'ef_id' does not identify a valid event flags object
- * osErrorResource the event flags object is in an invalid state.
- *
- * Note(s) : 1) This function cannot be called from an ISR.
- ****************************************************************************************************
- */
- osStatus_t osEventFlagsDelete(osEventFlagsId_t ef_id)
- {
- #if (OS_CFG_FLAG_EN == DEF_ENABLED)
- osEventFlags_t *p_flags;
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- p_flags = (osEventFlags_t *)ef_id;
- if (p_flags == (osEventFlags_t *)0) {
- return osErrorParameter;
- }
- OSFlagDel(&p_flags->flag_grp, OS_OPT_DEL_ALWAYS, &err);
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- if (p_flags->dyn_alloc == DEF_TRUE) {
- free(p_flags);
- }
- return osOK;
- default:
- return osErrorResource;
- }
- #else
- (void)ef_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osFlagsErrorUnknown);
- return osError;
- #endif
- }
- /*
- ****************************************************************************************************
- * osEventFlagsGetName()
- *
- * Description: The function 'osEventFlagsGetName()' gets the name of the event flags object specified
- * by parameter 'ef_id'.
- *
- * Arguments : ef_id Is the events flags ID
- *
- * Returns : A pointer to the name upon success
- * NULL upon failure
- *
- * Note(s) : 1) This function cannot be called from an ISR
- ****************************************************************************************************
- */
- const char *osEventFlagsGetName(osEventFlagsId_t ef_id)
- {
- #if (OS_CFG_FLAG_EN == DEF_ENABLED) && (OS_CFG_DBG_EN == DEF_ENABLED)
- osEventFlags_t *p_flags;
- CPU_CHAR *p_name;
- p_flags = (osEventFlags_t *)ef_id;
- if (p_flags == (osEventFlags_t *)0) {
- return 0u;
- }
- p_name = p_flags->flag_grp.NamePtr; // Get name of the event flags
- return p_name;
- #else
- (void)ef_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, 0u);
- return 0u;
- #endif
- }
- /*
- ****************************************************************************************************
- ****************************************************************************************************
- * M U T U A L E X C L U S I O N S E M A P H O R E S
- ****************************************************************************************************
- ****************************************************************************************************
- */
- /*
- ****************************************************************************************************
- * osMutexNew()
- *
- * Description: The function 'osMutexNew()' creates and initializes a new mutex object and returns the
- * pointer to the mutex object identifier or NULL in case of an error. It can be safely
- * called before the RTOS is started (call to 'osKernelStart()'), but not before it is
- * initialized (call to 'osKernelInitialize()').
- *
- * The parameter 'attr' sets the mutex object attributes (refer to 'osMutexAttr_t').
- * Default attributes will be used if set to NULL.
- *
- * Arguments : attr sets the mutex attributes or default values if NULL
- *
- * .name is an ASCII string used to name the mutex
- *
- * .attr_bits can have the following attributes:
- *
- * osMutexRecursive
- * osMutexPrioInherit
- * osMutexRobust
- *
- * .cb_mem Pointer to storage area for the mutex control block
- *
- * .cb_size Size of the memory storage for the mutex control block
- *
- * Returns : The mutex ID
- *
- * Note(s) : 1) MicriumOS does NOT support the osMutexRobust attribute. The user must explicitely
- * release ownership of the mutex before deleting a task.
- *
- * 2) MicriumOS mutexes are always recursive and support priority inheritance. Those
- * attributes cannot be disabled.
- *
- * 3) The memory control block is assumed to be of type 'osMutex_t' which for the CMSIS-RTOS
- * adaptation layer is defined as an OS_MUTEX in MicriumOS.
- ****************************************************************************************************
- */
- osMutexId_t osMutexNew(const osMutexAttr_t *attr)
- {
- #if (OS_CFG_MUTEX_EN == DEF_ENABLED)
- osMutex_t *p_mutex;
- CPU_CHAR *p_name;
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return (osMutexId_t)0;
- }
- p_name = (CPU_CHAR *)"Mutex";
- if (attr == 0) {
- p_mutex = (osMutex_t *)malloc(sizeof(osMutex_t));
- if (p_mutex == (osMutex_t *)0) {
- return (osMutexId_t)0;
- }
- p_mutex->dyn_alloc = DEF_TRUE;
- } else {
- if (attr->cb_mem == (void *)0) {
- p_mutex = (osMutex_t*)malloc(sizeof(osMutex_t));
- if (p_mutex == (osMutex_t*)0) {
- return (osMutexId_t)0;
- }
- p_mutex->dyn_alloc = DEF_TRUE;
- } else {
- if (attr->cb_size < sizeof(osMutex_t) || (uint32_t)attr->cb_mem % sizeof(CPU_ALIGN)) {
- return (osMutexId_t)0;
- }
- p_mutex = (osMutex_t *)attr->cb_mem;
- p_mutex->dyn_alloc = DEF_FALSE;
- }
- if (attr->name != (const char *)0) {
- p_name = (CPU_CHAR *)attr->name;
- }
- }
- OSMutexCreate(&p_mutex->mutex, p_name, &err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- if (p_mutex->dyn_alloc == DEF_TRUE) {
- free(p_mutex);
- }
- return (osMutexId_t)0;
- }
- if (attr != NULL && (attr->attr_bits & osMutexRecursive)) {
- p_mutex->recursive = DEF_TRUE;
- } else {
- p_mutex->recursive = DEF_FALSE;
- }
- return (osMutexId_t)p_mutex;
- #else
- (void)attr;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, (osMutexId_t)0);
- return (osMutexId_t)0;
- #endif
- }
- /*
- ****************************************************************************************************
- * osMutexGetName()
- *
- * Description: The function 'osMutexGetName()' returns the pointer to the name string of the mutex
- * identified by parameter 'mutex_id' or NULL in case of an error.
- *
- * Arguments : mutex_id is the mutex ID returned by 'osMutexNew()'
- *
- * Returns : A pointer to the ASCII string containing the name of the mutex.
- * NULL upon error
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- const char *osMutexGetName(osMutexId_t mutex_id)
- {
- #if (OS_CFG_MUTEX_EN == DEF_ENABLED) && (OS_CFG_DBG_EN == DEF_ENABLED)
- osMutex_t *p_mutex;
- if (CORE_InIrqContext() == true) {
- return NULL;
- }
- p_mutex = (osMutex_t *)mutex_id;
- if (p_mutex == (osMutex_t *)0) {
- return NULL;
- }
- return p_mutex->mutex.NamePtr;
- #else
- (void)mutex_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, NULL);
- return NULL;
- #endif
- }
- /*
- ****************************************************************************************************
- * osMutexAcquire()
- *
- * Description: The blocking function 'osMutexAcquire()' waits until a mutex object specified by parameter
- * mutex_id becomes available. If no other thread has obtained the mutex, the function
- * instantly returns and blocks the mutex object.
- *
- * The parameter timeout specifies how long the system waits to acquire the mutex. While
- * the system waits, the thread that is calling this function is put into the BLOCKED state.
- * The parameter timeout can have the following values:
- *
- * Arguments : mutex_id is the mutex ID returned by 'osMutexNew()'
- *
- * timeout when timeout is 0, the function returns instantly (i.e. try semantics).
- * when timeout is set to osWaitForever the function will wait for an infinite
- * time until the mutex becomes available (i.e. wait semantics).
- * all other values specify a time in kernel ticks for a timeout
- * (i.e. timed-wait semantics).Timeout Value or 0 in case of no time-out.
- *
- * Returns : osOK the token has been obtained and the token count decremented.
- * osErrorTimeout the token could not be obtained in the given time.
- * osErrorResource the token could not be obtained when no timeout was specified.
- * osErrorParameter the parameter semaphore_id is NULL or invalid.
- * osErrorISR cannot be called from an ISR
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- osStatus_t osMutexAcquire(osMutexId_t mutex_id,
- uint32_t timeout)
- {
- #if (OS_CFG_MUTEX_EN == DEF_ENABLED)
- OS_OPT opt;
- osMutex_t *p_mutex;
- OS_ERR err;
- CPU_TS ts;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- p_mutex = (osMutex_t *)mutex_id;
- if (p_mutex == (osMutex_t *)0) {
- return osErrorParameter;
- }
- if (timeout == 0u) {
- opt = OS_OPT_PEND_NON_BLOCKING;
- } else {
- opt = OS_OPT_PEND_BLOCKING;
- }
- if (timeout == osWaitForever) {
- timeout = 0u;
- }
- OSMutexPend(&p_mutex->mutex, (OS_TICK)timeout, opt, &ts, &err);
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_MUTEX_OWNER:
- if (p_mutex->recursive == DEF_FALSE) {
- return osErrorResource;
- }
- return osOK;
- case OS_ERR_NONE:
- return osOK;
- case OS_ERR_TIMEOUT:
- return osErrorTimeout;
- default:
- return osErrorResource;
- }
- #else
- (void)mutex_id;
- (void)timeout;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osError);
- return osError;
- #endif
- }
- /*
- ****************************************************************************************************
- * osMutexRelease()
- *
- * Description: The function 'osMutexRelease()' releases a mutex specified by parameter 'mutex_id'.
- * Other threads that currently wait for this mutex will be put into the READY state.
- *
- * Arguments : mutex_id is the mutex ID returned by 'osMutexNew()'
- *
- * Returns : osOK the mutex has been released and the count incremented.
- * osErrorResource the mutex could not be released
- * osErrorParameter the parameter mutex_id is NULL or invalid.
- * osErrorISR if called from an ISR
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- *
- * 2) MicriumOS always allows mutex nesting and thus that feature cannot be disabled.
- ****************************************************************************************************
- */
- osStatus_t osMutexRelease(osMutexId_t mutex_id)
- {
- #if (OS_CFG_MUTEX_EN == DEF_ENABLED)
- osMutex_t *p_mutex;
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- p_mutex = (osMutex_t *)mutex_id;
- if (p_mutex == (osMutex_t *)0) {
- return osErrorParameter;
- }
- OSMutexPost(&p_mutex->mutex, OS_OPT_POST_NONE, &err);
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- case OS_ERR_MUTEX_OWNER:
- return osOK;
- default:
- return osErrorResource;
- }
- #else
- (void)mutex_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osError);
- return osError;
- #endif
- }
- /*
- ****************************************************************************************************
- * osMutexGetOwner()
- *
- * Description: The function 'osMutexGetOwner()' returns the thread ID of the thread that acquired a
- * mutex specified by parameter 'mutex_id'. In case of an error or if the mutex is not
- * blocked by any thread, it returns NULL.
- *
- * Arguments : mutex_id is the mutex ID returned by 'osMutexNew()'
- *
- * Returns : the theard ID of the mutex owner
- *
- * Note(s) : None
- ****************************************************************************************************
- */
- osThreadId_t osMutexGetOwner(osMutexId_t mutex_id)
- {
- #if (OS_CFG_MUTEX_EN == DEF_ENABLED)
- osMutex_t *p_mutex;
- osThread_t *p_thread;
- CORE_DECLARE_IRQ_STATE;
- p_mutex = (osMutex_t *)mutex_id;
- if (p_mutex == (osMutex_t *)0) {
- return 0u;
- }
- CORE_ENTER_ATOMIC();
- p_thread = (osThread_t *)p_mutex->mutex.OwnerTCBPtr;
- CORE_EXIT_ATOMIC();
- return (osThreadId_t)p_thread;
- #else
- (void)mutex_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, 0u);
- return 0u;
- #endif
- }
- /*
- ****************************************************************************************************
- * osMutexDelete()
- *
- * Description: The function 'osMutexDelete()' deletes a mutex object specified by parameter 'mutex_id'.
- * It releases internal memory obtained for mutex handling. After this call, the 'mutex_id'
- * is no longer valid and cannot be used.
- *
- * The mutex may be created again using the function 'osMutexNew()'.
- *
- * Arguments : mutex_id is the mutex ID returned by 'osMutexNew()'
- *
- * Returns : osOK the mutex object has been deleted.
- * osErrorParameter the parameter mutex_id is NULL or invalid.
- * osErrorResource the mutex is in an invalid state.
- * osErrorISR osMutexDelete() cannot be called from interrupt service routines.
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- osStatus_t osMutexDelete(osMutexId_t mutex_id)
- {
- #if (OS_CFG_MUTEX_EN == DEF_ENABLED)
- osMutex_t *p_mutex;
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- p_mutex = (osMutex_t *)mutex_id;
- if (p_mutex == (osMutex_t *)0) {
- return osErrorParameter;
- }
- OSMutexDel(&p_mutex->mutex, OS_OPT_DEL_ALWAYS, &err);
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- if (p_mutex->dyn_alloc == DEF_TRUE) {
- free(p_mutex);
- }
- return osOK;
- default:
- return osErrorResource;
- }
- #else
- (void)mutex_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osError);
- return osError;
- #endif
- }
- /*
- ****************************************************************************************************
- ****************************************************************************************************
- * S E M A P H O R E M A N A G E M E N T
- ****************************************************************************************************
- ****************************************************************************************************
- */
- /*
- ****************************************************************************************************
- * osSemaphoreNew()
- *
- * Description: The function 'osSemaphoreNew()' creates and initializes a semaphore object that is used
- * to manage access to shared resources and returns the pointer to the semaphore object
- * identifier or NULL in case of an error.
- *
- * It can be safely called before the RTOS is started (call to 'osKernelStart()'), but not
- * before it is initialized (call to 'osKernelInitialize()').
- *
- * The parameter 'max_count' specifies the maximum number of available tokens. A 'max_count'
- * value of 1 creates a binary semaphore.
- *
- * The parameter 'initial_count' sets the initial number of available tokens.
- *
- * The parameter 'attr' specifies additional semaphore attributes. Default attributes will
- * be used if set to NULL.
- *
- * Arguments : max_count maximum number of available tokens.
- *
- * initial_count initial number of available tokens.
- *
- * attr semaphore attributes; NULL: default values.
- *
- * Returns : semaphore ID for reference by other functions or NULL in case of error.
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- *
- * 2) MicriumOS does not support a maximum count so the first argument is ignored.
- ****************************************************************************************************
- */
- osSemaphoreId_t osSemaphoreNew(uint32_t max_count,
- uint32_t initial_count,
- const osSemaphoreAttr_t *attr)
- {
- #if (OS_CFG_SEM_EN == DEF_ENABLED)
- osSemaphore_t *p_sem;
- CPU_CHAR *p_name;
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return (osSemaphoreId_t)0;
- }
- if (max_count == 0u) {
- return (osSemaphoreId_t)0; // Cannot specify a 0 value for max count
- }
- p_name = (CPU_CHAR *)"Semaphore";
- if (attr == 0) {
- p_sem = (osSemaphore_t *)malloc(sizeof(osSemaphore_t));
- if (p_sem == (osSemaphore_t *)0) {
- return (osSemaphoreId_t)0;
- }
- p_sem->dyn_alloc = DEF_TRUE;
- } else {
- if (attr->cb_mem == (void *)0) {
- p_sem = (osSemaphore_t *)malloc(sizeof(osSemaphore_t));
- if (p_sem == (osSemaphore_t *)0) {
- return (osSemaphoreId_t)0;
- }
- p_sem->dyn_alloc = DEF_TRUE;
- } else {
- if (attr->cb_size < sizeof(osSemaphore_t) || (uint32_t)attr->cb_mem % sizeof(CPU_ALIGN)) {
- return (osSemaphoreId_t)0;
- }
- p_sem = (osSemaphore_t *)attr->cb_mem;
- p_sem->dyn_alloc = DEF_FALSE;
- }
- if (attr->name != (const char *)0) {
- p_name = (CPU_CHAR *)attr->name;
- }
- }
- OSSemCreate(&p_sem->sem, p_name, initial_count, &err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- if (p_sem->dyn_alloc == DEF_TRUE) {
- free(p_sem);
- }
- return (osSemaphoreId_t)0;
- }
- return (osSemaphoreId_t)p_sem;
- #else
- (void)max_count;
- (void)initial_count;
- (void)attr;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, (osSemaphoreId_t)0);
- return (osSemaphoreId_t)0;
- #endif
- }
- /*
- ****************************************************************************************************
- * osSemaphoreGetName()
- *
- * Description: The function 'osSemaphoreGetName()' returns the pointer to the name string of the semaphore
- * identified by parameter 'semaphore_id' or NULL in case of an error.
- *
- * Arguments : semaphore_id is the semaphore ID returned by 'osSemaphoreNew()'
- *
- * Returns : A pointer to the ASCII string containing the name of the semaphore.
- * NULL upon error
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- const char *osSemaphoreGetName(osSemaphoreId_t semaphore_id)
- {
- #if (OS_CFG_SEM_EN == DEF_ENABLED) && (OS_CFG_DBG_EN == DEF_ENABLED)
- osSemaphore_t *p_sem;
- if (CORE_InIrqContext() == true) {
- return NULL;
- }
- p_sem = (osSemaphore_t *)semaphore_id;
- if (p_sem == (osSemaphore_t *)0) {
- return NULL;
- }
- return p_sem->sem.NamePtr;
- #else
- (void)semaphore_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, NULL);
- return NULL;
- #endif
- }
- /*
- ****************************************************************************************************
- * osSemaphoreAcquire()
- *
- * Description: The blocking function 'osSemaphoreAcquire() waits until a token of the semaphore object
- * specified by parameter 'semaphore_id' becomes available. If a token is available, the
- * function instantly returns and decrements the token count.
- *
- * The parameter timeout specifies how long the system waits to acquire the token. While the
- * system waits, the thread that is calling this function is put into the BLOCKED state.
- * The parameter timeout can have the following values:
- *
- * when timeout is 0, the function returns instantly (i.e. try semantics).
- *
- * when timeout is set to 'osWaitForever' the function will wait for an infinite time until
- * the semaphore becomes available (i.e. wait semantics).
- *
- * all other values specify a time in kernel ticks for a timeout (i.e. timed-wait semantics).
- *
- * Arguments : semaphore_id is the semaphore ID returned by 'osSemaphoreNew()'
- *
- * timeout Timeout Value or 0 in case of no time-out.
- *
- * Returns : osOK the token has been obtained and the token count decremented.
- * osErrorTimeout the token could not be obtained in the given time.
- * osErrorResource the token could not be obtained when no timeout was specified.
- * osErrorParameter the parameter semaphore_id is NULL or invalid.
- *
- * Note(s) : 1) This function CANNOT be called from an ISR if you specify an NON-Zero timeout
- ****************************************************************************************************
- */
- osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id,
- uint32_t timeout)
- {
- #if (OS_CFG_SEM_EN == DEF_ENABLED)
- osSemaphore_t *p_sem;
- OS_ERR err;
- CPU_TS ts;
- p_sem = (osSemaphore_t *)semaphore_id;
- if (p_sem == (osSemaphore_t *)0) {
- return osErrorParameter;
- }
- if (timeout == 0u) {
- OSSemPend(&p_sem->sem, (OS_TICK)0u, OS_OPT_PEND_NON_BLOCKING, &ts, &err);
- } else {
- if (CORE_InIrqContext() == true) {
- return osErrorParameter;
- } else {
- if (timeout == osWaitForever) {
- timeout = 0u;
- }
- OSSemPend(&p_sem->sem, (OS_TICK)timeout, OS_OPT_PEND_BLOCKING, &ts, &err);
- }
- }
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- return osOK;
- case OS_ERR_TIMEOUT:
- return osErrorTimeout;
- default:
- return osErrorResource;
- }
- #else
- (void)semaphore_id;
- (void)timeout;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osError);
- return osError;
- #endif
- }
- /*
- ****************************************************************************************************
- * osSemaphoreRelease()
- *
- * Description: The function 'osSemaphoreRelease()' releases a token of the semaphore object specified
- * by parameter 'semaphore_id'. Tokens can only be released up to the maximum count
- * specified at creation time, see 'osSemaphoreNew()'. Other threads that currently wait
- * for a token of this semaphore object will be put into the READY state.
- *
- * Arguments : semaphore_id is the semaphore ID returned by 'osSemaphoreNew()'
- *
- * Returns : osOK the token has been released and the count incremented.
- * osErrorResource the token could not be released (maximum token count has been reached).
- * osErrorParameter the parameter semaphore_id is NULL or invalid.
- *
- * Note(s) : None
- ****************************************************************************************************
- */
- osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id)
- {
- #if (OS_CFG_SEM_EN == DEF_ENABLED)
- osSemaphore_t *p_sem;
- OS_ERR err;
- p_sem = (osSemaphore_t *)semaphore_id;
- if (p_sem == (osSemaphore_t *)0) {
- return osErrorParameter;
- }
- (void)OSSemPost(&p_sem->sem, OS_OPT_POST_1, &err);
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- return osOK;
- default:
- return osErrorResource;
- }
- #else
- (void)semaphore_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osError);
- return osError;
- #endif
- }
- /*
- ****************************************************************************************************
- * osSemaphoreGetCount()
- *
- * Description: The function 'osSemaphoreGetCount()' returns the number of available tokens of the
- * semaphore object specified by parameter 'semaphore_id'.
- *
- * In case of an error it returns 0.
- *
- * Arguments : semaphore_id is the semaphore ID returned by 'osSemaphoreNew()'
- *
- * Returns : the number of tokens available
- *
- * Note(s) : None
- ****************************************************************************************************
- */
- uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphore_id)
- {
- #if (OS_CFG_SEM_EN == DEF_ENABLED)
- osSemaphore_t *p_sem;
- uint32_t count;
- CORE_DECLARE_IRQ_STATE;
- p_sem = (osSemaphore_t*)semaphore_id;
- if (p_sem == (osSemaphore_t *)0) {
- return 0u;
- }
- CORE_ENTER_ATOMIC();
- count = p_sem->sem.Ctr;
- CORE_EXIT_ATOMIC();
- return count;
- #else
- (void)semaphore_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, 0u);
- return 0u;
- #endif
- }
- /*
- ****************************************************************************************************
- * osSemaphoreDelete()
- *
- * Description: The function 'osSemaphoreDelete()' deletes a semaphore object specified by parameter
- * 'semaphore_id'. It releases internal memory obtained for semaphore handling. After
- * this call, the 'semaphore_id' is no longer valid and cannot be used.
- *
- * The semaphore may be created again using the function 'osSemaphoreNew()'.
- *
- * Arguments : semaphore_id is the semaphore ID returned by 'osSemaphoreNew()'
- *
- * Returns : osOK the semaphore object has been deleted.
- * osErrorParameter the parameter semaphore_id is NULL or invalid.
- * osErrorResource the semaphore is in an invalid state.
- * osErrorISR osSemaphoreDelete() cannot be called from interrupt service routines.
- *
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id)
- {
- #if (OS_CFG_SEM_EN == DEF_ENABLED)
- osSemaphore_t *p_sem;
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- p_sem = (osSemaphore_t *)semaphore_id;
- if (p_sem == (osSemaphore_t *)0) {
- return osErrorParameter;
- }
- OSSemDel(&p_sem->sem, OS_OPT_DEL_ALWAYS, &err);
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- if (p_sem->dyn_alloc == DEF_TRUE) {
- free(p_sem);
- }
- return osOK;
- default:
- return osErrorResource;
- }
- #else
- (void)semaphore_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osError);
- return osError;
- #endif
- }
- /*
- ****************************************************************************************************
- ****************************************************************************************************
- * T A S K M A N A G E M E N T
- ****************************************************************************************************
- ****************************************************************************************************
- */
- /*
- ****************************************************************************************************
- * osThreadNew()
- *
- * Description: The function 'osThreadNew()' starts a thread function by adding it to the list of active
- * threads and sets it to state READY. Arguments for the thread function are passed using
- * the parameter pointer *argument. When the priority of the created thread function is
- * higher than the current RUNNING thread, the created thread function starts instantly
- * and becomes the new RUNNING thread.
- *
- * Thread attributes are defined with the parameter pointer 'attr'. Attributes include
- * settings for thread priority, stack size, or memory allocation.
- *
- * Arguments : func is a pointer to the task code
- *
- * argument is a pointer to an argument that is passed to the task when the task
- * starts execution.
- *
- * attr attribute structure passed to the task creation code.
- * specifying NULL assumes defaults.
- *
- * Thread attributes are:
- *
- * .name name of the thread
- * .attr_bits values:
- * osThreadDetached (default) 0x00000000
- * osThreadJoinable 0x00000001
- * .cb_mem pointer to TCB
- * (allocated dynamically if NULL or not specified)
- * .cb_size size of the TCB (in bytes)
- * .stack_mem pointer to the base address of the stack
- * (allocated dynamically if NULL or not specified)
- * .stack_size size of stack (in bytes)
- * (defaults to RTOS2_DEFAULT_THREAD_STACK_SIZE bytes
- * if 0 specified or not specified)
- * .priority Thread priority (0 = lowest, 55 = highest)
- * .tz_module TrustZone Module Identified
- * .reserved Must be 0
- *
- * Returns : The thread ID upon success
- * NULL upon error
- *
- * Note(s) : 1) '.tz_module' is ignored in this implementation
- *
- * 2) if '.cb_mem' is specified it must point to MicriumOS OS_TCB.
- * also, '.cb_size' MUST be declared as 'sizeof(OS_TCB)'
- *
- * 3) 'attr_bits' are not supported and tasks are always assumed to be 'detached'
- ****************************************************************************************************
- */
- osThreadId_t osThreadNew(osThreadFunc_t func,
- void *argument,
- const osThreadAttr_t *attr)
- {
- osThread_t *p_thread;
- CPU_STK *p_stk_base;
- uint32_t stk_size_in_bytes;
- CPU_CHAR *p_name;
- OS_PRIO prio;
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return (osThreadId_t)0; // Can't create a thread from an ISR
- }
- if (func == (osThreadFunc_t)0) { // Make sure a thread is specified
- return (osThreadId_t)0;
- }
- p_name = (CPU_CHAR *)"TaskName?";
- if (attr == 0) {
- p_thread = (osThread_t *)malloc(sizeof(osThread_t));
- if (p_thread == (osThread_t *)0) {
- return (osThreadId_t)0;
- } else {
- p_thread->obj_dyn_alloc = DEF_TRUE;
- p_stk_base = (CPU_STK *)malloc(RTOS2_DEFAULT_THREAD_STACK_SIZE);
- if (p_stk_base == (CPU_STK *)0) {
- free(p_thread);
- return (osThreadId_t)0;
- }
- p_thread->stack_dyn_alloc = DEF_TRUE;
- stk_size_in_bytes = RTOS2_DEFAULT_THREAD_STACK_SIZE;
- prio = (OS_PRIO)(osPriorityRealtime7 - osPriorityNormal);
- }
- } else {
- if (attr->cb_mem == (void *)0) {
- p_thread = (osThread_t *)malloc(sizeof(osThread_t));
- if (p_thread == (osThread_t *)0) {
- return (osThreadId_t)0;
- }
- p_thread->obj_dyn_alloc = DEF_TRUE;
- } else {
- if (attr->cb_size < sizeof(osThread_t) || (uint32_t)attr->cb_mem % sizeof(CPU_ALIGN)) {
- return (osThreadId_t)0;
- }
- p_thread = attr->cb_mem;
- p_thread->obj_dyn_alloc = DEF_FALSE;
- }
- if (attr->stack_size == 0u) {
- p_stk_base = (CPU_STK *)malloc(RTOS2_DEFAULT_THREAD_STACK_SIZE);
- if (p_stk_base == (CPU_STK *)0) {
- if (p_thread->obj_dyn_alloc == DEF_TRUE) {
- free(p_thread);
- }
- return (osThreadId_t)0;
- }
- stk_size_in_bytes = RTOS2_DEFAULT_THREAD_STACK_SIZE;
- p_thread->stack_dyn_alloc = DEF_TRUE;
- } else if ((attr->stack_size != 0u)
- && (attr->stack_mem == NULL)) {
- stk_size_in_bytes = attr->stack_size;
- p_stk_base = (CPU_STK *)malloc(stk_size_in_bytes);
- if (p_stk_base == (CPU_STK *)0) {
- if (p_thread->obj_dyn_alloc == DEF_TRUE) {
- free(p_thread);
- }
- return (osThreadId_t)0;
- }
- p_thread->stack_dyn_alloc = DEF_TRUE;
- } else {
- if (attr->stack_mem == NULL || ((uint32_t)attr->stack_mem % CPU_CFG_STK_ALIGN_BYTES)) {
- if (p_thread->obj_dyn_alloc == DEF_TRUE) {
- free(p_thread);
- }
- return (osThreadId_t)0;
- }
- p_stk_base = (CPU_STK *)attr->stack_mem;
- stk_size_in_bytes = attr->stack_size;
- p_thread->stack_dyn_alloc = DEF_FALSE;
- }
- if (attr->name != (const char *)0) {
- p_name = (CPU_CHAR *)attr->name;
- }
- if (attr->priority == osPriorityNone) {
- prio = (OS_PRIO)(osPriorityRealtime7 - osPriorityNormal);
- } else {
- if (attr->priority == osPriorityError) {
- prio = (OS_PRIO)(OS_CFG_PRIO_MAX); // Set to an invalid priority level for MicriumOS
- } else {
- if (attr->priority > osPriorityRealtime7) {
- if (p_thread->stack_dyn_alloc == DEF_TRUE) {
- free(p_stk_base);
- }
- if (p_thread->obj_dyn_alloc == DEF_TRUE) {
- free(p_thread);
- }
- return (osThreadId_t)0;
- }
- prio = (OS_PRIO)(osPriorityRealtime7 - attr->priority);
- }
- }
- }
- #if (OS_CFG_FLAG_EN == DEF_ENABLED)
- // Create thread flags
- OSFlagCreate(&p_thread->flag_grp, "ThreadFlags", 0, &err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- if (p_thread->stack_dyn_alloc == DEF_TRUE) {
- free(p_stk_base);
- }
- if (p_thread->obj_dyn_alloc == DEF_TRUE) {
- free(p_thread);
- }
- return (osThreadId_t)0;
- }
- #endif
- // Round down the stack size to a multiple of the cpu stack size
- stk_size_in_bytes -= (stk_size_in_bytes % CPU_CFG_STK_ALIGN_BYTES);
- OSTaskCreate(&p_thread->tcb, p_name, func, argument, prio, p_stk_base, 0,
- stk_size_in_bytes / sizeof(CPU_STK), 0u, 0u, 0u,
- OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR | OS_OPT_TASK_SAVE_FP,
- &err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- if (p_thread->stack_dyn_alloc == DEF_TRUE) {
- free(p_stk_base);
- }
- if (p_thread->obj_dyn_alloc == DEF_TRUE) {
- free(p_thread);
- }
- return (osThreadId_t)0;
- }
- return (osThreadId_t)p_thread;
- }
- /*
- ****************************************************************************************************
- * osThreadGetName()
- *
- * Description: The function osThreadGetName returns the pointer to the name string of the thread
- * identified by parameter 'thread_id' or NULL in case of an error.
- *
- * Arguments : thread_id is the thread ID returned by osThreadNew() when the thread is created
- *
- * Returns : A pointer to the ASCII string containing the name of the thread.
- * NULL upon error
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- const char *osThreadGetName(osThreadId_t thread_id)
- {
- #if (OS_CFG_DBG_EN == DEF_ENABLED)
- osThread_t *p_thread;
- p_thread = (osThread_t *)thread_id;
- if (p_thread == (osThread_t *)0) {
- return NULL;
- } else {
- return p_thread->tcb.NamePtr;
- }
- #else
- (void)thread_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, NULL);
- return NULL;
- #endif
- }
- /*
- ****************************************************************************************************
- * osThreadGetId()
- *
- * Description: The function 'osThreadGetId()' returns the thread object ID of the currently running
- * thread or NULL in case of an error.
- *
- * Arguments : None
- *
- * Returns : The thread ID
- * NULL upon error
- ****************************************************************************************************
- */
- osThreadId_t osThreadGetId(void)
- {
- if (OSRunning == OS_STATE_OS_RUNNING) {
- return (osThreadId_t)OSTCBCurPtr;
- }
- return (osThreadId_t)0;
- }
- /*
- ****************************************************************************************************
- * osThreadGetState()
- *
- * Description: The function osThreadGetState() returns the state of the thread identified by parameter
- * 'thread_id'. In case it fails or if it is called from an ISR, it will return
- * osThreadError, otherwise it returns the thread state (refer to 'osThreadState_t' for
- * the list of thread states).
- *
- * Arguments : thread_id is the ID of the desired thread
- *
- * Returns : The thread state (see below)
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- osThreadState_t osThreadGetState(osThreadId_t thread_id)
- {
- osThread_t *p_thread;
- osThreadState_t state;
- if (CORE_InIrqContext() == true) {
- return osThreadError;
- }
- p_thread = (osThread_t *)thread_id;
- if (p_thread == (osThread_t *)0) {
- return osThreadError;
- }
- if (OSRunning == OS_STATE_OS_RUNNING) {
- switch (p_thread->tcb.TaskState) {
- case OS_TASK_STATE_RDY:
- state = osThreadReady;
- break;
- case OS_TASK_STATE_DEL:
- state = osThreadInactive;
- break;
- case OS_TASK_STATE_DLY:
- case OS_TASK_STATE_PEND:
- case OS_TASK_STATE_PEND_TIMEOUT:
- case OS_TASK_STATE_SUSPENDED:
- case OS_TASK_STATE_DLY_SUSPENDED:
- case OS_TASK_STATE_PEND_SUSPENDED:
- case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
- state = osThreadBlocked;
- break;
- default:
- state = osThreadError;
- break;
- }
- } else {
- state = osThreadError;
- }
- return state;
- }
- /*
- ****************************************************************************************************
- * osThreadSetPriority()
- *
- * Description: The function 'osThreadSetPriority()' changes the priority of an active thread specified
- * by the parameter 'thread_id' to the priority specified by the parameter 'priority'.
- *
- * Arguments : thread_id is the thread ID
- *
- * priority is the desired new priority for the specified thread
- *
- * Returns : osOK the priority of the specified thread has been changed
- * osErrorParameter an invalid parameter was specified
- * osErrorResource the thread is in an invalid state
- * osErrorISR if called from an ISR
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- osStatus_t osThreadSetPriority(osThreadId_t thread_id,
- osPriority_t priority)
- {
- OS_PRIO prio;
- osThread_t *p_thread;
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- if (thread_id == (osThreadId_t)0) {
- return osErrorParameter;
- }
- if (priority == osPriorityError) {
- return osErrorParameter;
- }
- if (priority > osPriorityRealtime7) {
- return osErrorParameter;
- }
- prio = (OS_PRIO)(osPriorityRealtime7 - priority);
- p_thread = (osThread_t *)thread_id;
- OSTaskChangePrio(&p_thread->tcb, prio, &err);
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- return osOK;
- default:
- return osErrorResource;
- }
- }
- /*
- ****************************************************************************************************
- * osThreadGetPriority()
- *
- * Description: The function 'osThreadGetPriority()' returns the priority of an active thread specified
- * by the parameter 'thread_id'.
- *
- * Arguments : None
- *
- * Returns : The thread ID upon success
- * osPriorityError upon error
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- osPriority_t osThreadGetPriority(osThreadId_t thread_id)
- {
- osPriority_t priority;
- osThread_t *p_thread;
- if (OSRunning != OS_STATE_OS_RUNNING) {
- return osPriorityError;
- }
- if (CORE_InIrqContext() == true) {
- return osPriorityError;
- }
- p_thread = (osThread_t *)thread_id;
- if (p_thread == (osThread_t *)0) {
- return osPriorityError;
- }
- priority = (osPriority_t)((OS_PRIO)osPriorityRealtime7 - p_thread->tcb.Prio);
- return priority;
- }
- /*
- ****************************************************************************************************
- * osThreadYield()
- *
- * Description: The function 'osThreadYield()' passes control to the next thread with the same priority
- * that is in the READY state. I f there is no other thread with the same priority in state
- * READY, then the current thread continues execution and no thread switch occurs.
- *
- * 'osThreadYield()' does not set the thread to state BLOCKED. Thus no thread with a lower
- * priority will be scheduled even if threads in state READY are available.
- *
- * Arguments : None
- *
- * Returns : osOK control has passed to the next thread
- * osError an unspecified error occurred
- * osErrorISR if called from an ISR
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- osStatus_t osThreadYield(void)
- {
- #if (OS_CFG_SCHED_ROUND_ROBIN_EN == DEF_ENABLED)
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- OSSchedRoundRobinYield(&err);
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- return osOK;
- default:
- return osError;
- }
- #else
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osError);
- return osError;
- #endif
- }
- /*
- ****************************************************************************************************
- * osThreadSuspend()
- *
- * Description: The function 'osThreadSuspend()' suspends the execution of the thread identified by
- * parameter 'thread_id'. The thread is put into the BLOCKED state (osThreadBlocked).
- * Suspending the running thread will cause a context switch to another thread in READY
- * state immediately. The suspended thread is not executed until explicitly resumed
- * by the function 'osThreadResume()'.
- *
- * Threads that are already BLOCKED are removed from any wait list and become ready when
- * they are resumed. Thus it is not recommended to suspend an already blocked thread.
- *
- * Arguments : thread_id is the ID of the thread
- *
- * Returns : osOK the thread has been suspended successfully.
- * osErrorParameter thread_id is NULL or invalid.
- * osErrorResource the thread is in an invalid state.
- * osErrorISR the function osThreadSuspend cannot be called from interrupt service routines.
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- osStatus_t osThreadSuspend(osThreadId_t thread_id)
- {
- OS_ERR err;
- osThread_t *p_thread;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- p_thread = (osThread_t *)thread_id;
- if (p_thread == (osThread_t *)0) {
- return osErrorParameter;
- }
- OSTaskSuspend(&p_thread->tcb, &err);
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- return osOK;
- default:
- return osErrorResource;
- }
- }
- /*
- ****************************************************************************************************
- * osThreadResume()
- *
- * Description: The function 'osThreadResume()' puts the thread identified by parameter 'thread_id'
- * (which has to be in BLOCKED state) back to the READY state. If the resumed thread
- * has a higher priority than the running thread a context switch occurs immediately.
- *
- * The thread becomes ready regardless of the reason why the thread was blocked. Thus
- * it is not recommended to resume a thread not suspended by 'osThreadSuspend()'.
- *
- * Functions that will put a thread into BLOCKED state are:
- *
- * 'osEventFlagsWait()' and 'osThreadFlagsWait()',
- * 'osDelay()' and 'osDelayUntil()',
- * 'osMutexAcquire()' and 'osSemaphoreAcquire()',
- * 'osMessageQueueGet()'
- * 'osMemoryPoolAlloc(),
- * 'osThreadJoin()' Function NOT supported
- * 'osThreadSuspend()'
- *
- * Arguments : thread_id is the ID of the thread
- *
- * Returns : osOK the thread has been resumed successfully.
- * osErrorParameter thread_id is NULL or invalid.
- * osErrorResource the thread is in an invalid state.
- * osErrorISR the function osThreadSuspend cannot be called from interrupt service routines.
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- *
- * 2) MicriumOS cannot emulate this function exactly as described above. In fact,
- * MicriumOS doesn't cancel pending on an object. The suspension is simply removed if
- * the task was suspended by 'osThreadSuspend()'.
- ****************************************************************************************************
- */
- osStatus_t osThreadResume(osThreadId_t thread_id)
- {
- OS_ERR err;
- osThread_t *p_thread;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- p_thread = (osThread_t *)thread_id;
- if (p_thread == (osThread_t *)0) {
- return osErrorParameter;
- }
- OSTaskResume(&p_thread->tcb, &err);
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- return osOK;
- default:
- return osErrorResource;
- }
- }
- /*
- ****************************************************************************************************
- * osThreadDetach()
- *
- * Description: The function 'osThreadDetach()' changes the attribute of a thread (specified by 'thread_id')
- * to 'osThreadDetached'. Detached threads are not joinable with 'osThreadJoin()'.
- *
- * When a detached thread is terminated, all resources are returned to the system.
- *
- * The behavior of 'osThreadDetach()' on an already detached thread is undefined.
- *
- * Arguments : thread_id is the ID of the thread
- *
- * Returns : osOK the thread has been detached successfully.
- * osErrorParameter thread_id is NULL or invalid.
- * osErrorResource the thread is in an invalid state.
- * osErrorISR the function osThreadSuspend cannot be called from interrupt service routines.
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- *
- * 2) MicriumOS DOES NOT support this functionality
- ****************************************************************************************************
- */
- osStatus_t osThreadDetach(osThreadId_t thread_id)
- {
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- if (thread_id == (osThreadId_t)0) {
- return osErrorParameter;
- }
- (void)thread_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, osError);
- return osError;
- }
- /*
- ****************************************************************************************************
- * osThreadJoin()
- *
- * Description: The function 'osThreadJoin()' waits for the thread specified by 'thread_id' to terminate.
- *
- * If that thread has already terminated, then 'osThreadJoin()' returns immediately.
- *
- * The thread must be joinable. By default threads are created with the attribute 'osThreadDetached'.
- *
- * Arguments : thread_id is the ID of the thread
- *
- * Returns : osOK the thread has been joined successfully.
- * osErrorParameter thread_id is NULL or invalid.
- * osErrorResource the thread is in an invalid state.
- * osErrorISR the function osThreadSuspend cannot be called from interrupt service routines.
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- *
- * 2) MicriumOS DOES NOT support this functionality
- ****************************************************************************************************
- */
- osStatus_t osThreadJoin(osThreadId_t thread_id)
- {
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- if (thread_id == (osThreadId_t)0) {
- return osErrorParameter;
- }
- (void)thread_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, osError);
- return osError;
- }
- /*
- ****************************************************************************************************
- * osThreadExit()
- *
- * Description: The function 'osThreadExit()' terminates the calling thread.
- *
- * This allows the thread to be synchronized with 'osThreadJoin()'.
- *
- * Arguments : None
- *
- * Returns : None
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- void osThreadExit(void)
- {
- OS_ERR err;
- if (CORE_InIrqContext() == false) {
- OSTaskDel((OS_TCB *)0, &err);
- }
- for (;; ) {
- ; // This function cannot return
- }
- }
- /*
- ****************************************************************************************************
- * osThreadTerminate()
- *
- * Description: The function 'osThreadTerminate()' removes the thread specified by parameter 'thread_id'
- * from the list of active threads. If the thread is currently RUNNING, the thread
- * terminates and the execution continues with the next READY thread.
- *
- * If no such thread exists, the function will not terminate the running thread, but return
- * 'osErrorResource'.
- *
- * Arguments : thread_id is the ID of the thread
- *
- * Returns : osOK the thread has been joined successfully.
- * osErrorParameter thread_id is NULL or invalid.
- * osErrorResource the thread is in an invalid state.
- * osErrorISR the function osThreadSuspend cannot be called from interrupt service routines.
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- osStatus_t osThreadTerminate(osThreadId_t thread_id)
- {
- osThread_t *p_thread;
- CPU_STK *p_stk_base;
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- p_thread = (osThread_t *)thread_id;
- if (p_thread == (osThread_t *)0) {
- return osErrorParameter;
- }
- p_stk_base = p_thread->tcb.StkBasePtr;
- OSTaskDel(&p_thread->tcb, &err);
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- if (p_thread->stack_dyn_alloc == DEF_TRUE) {
- free(p_stk_base);
- }
- if (p_thread->obj_dyn_alloc == DEF_TRUE) {
- free(p_thread);
- }
- return osOK;
- default:
- return osErrorResource;
- }
- }
- /*
- ****************************************************************************************************
- * osThreadGetStackSize()
- *
- * Description: The function 'osThreadGetStackSize()' returns the stack size of the thread specified
- * by parameter 'thread_id'. In case of an error, it returns 0.
- *
- * Arguments : thread_id is the ID of the thread
- *
- * Returns : The stack size (in bytes)
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- uint32_t osThreadGetStackSize(osThreadId_t thread_id)
- {
- osThread_t *p_thread;
- uint32_t stk_size;
- CORE_DECLARE_IRQ_STATE;
- if (CORE_InIrqContext() == true) {
- return 0u;
- }
- p_thread = (osThread_t *)thread_id;
- if (p_thread == (osThread_t *)0) {
- return 0u;
- }
- CORE_ENTER_ATOMIC();
- stk_size = (uint32_t)p_thread->tcb.StkSize * sizeof(CPU_STK);
- CORE_EXIT_ATOMIC();
- return stk_size;
- }
- /*
- ****************************************************************************************************
- * osThreadGetStackSpace()
- *
- * Description: The function 'osThreadGetStackSize()' returns the unused stack space still available
- * for the thread specified by parameter 'thread_id'. In case of an error, it returns 0.
- *
- * Arguments : thread_id is the ID of the thread
- *
- * Returns : The stack size (in bytes)
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- * 2) This function will likely return an incorrect value if called for the currently running task
- ****************************************************************************************************
- */
- uint32_t osThreadGetStackSpace(osThreadId_t thread_id)
- {
- #if (OS_CFG_STAT_TASK_STK_CHK_EN == DEF_ENABLED)
- osThread_t *p_thread;
- uint32_t free_space;
- CORE_DECLARE_IRQ_STATE;
- if (CORE_InIrqContext() == true) {
- return 0u;
- }
- p_thread = (osThread_t *)thread_id;
- if (p_thread == (osThread_t *)0) {
- return 0u;
- }
- CORE_ENTER_ATOMIC();
- free_space = (uint32_t)(p_thread->tcb.StkSize - p_thread->tcb.StkUsed) * sizeof(CPU_STK);
- CORE_EXIT_ATOMIC();
- return free_space;
- #else
- (void)thread_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, 0u);
- return 0u;
- #endif
- }
- /*
- ****************************************************************************************************
- * osThreadGetCount()
- *
- * Description: The function 'osThreadGetCount()' returns the number of active threads or 0 in case of an error.
- *
- * Arguments : None
- *
- * Returns : The number of active tasks
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- uint32_t osThreadGetCount(void)
- {
- if (CORE_InIrqContext() == true) {
- return 0u;
- }
- return (uint32_t)OSTaskQty;
- }
- /*
- ****************************************************************************************************
- * osThreadEnumerate()
- *
- * Description: The function 'osThreadEnumerate()' returns the number of enumerated threads or 0 in case
- * of an error.
- *
- * Arguments : thread_array pointer to array for retrieving thread IDs.
- * array_items maximum number of items in array for retrieving thread IDs.
- *
- * Returns : The number of active tasks
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- * 2) This feature require OS_CFG_DBG_EN
- ****************************************************************************************************
- */
- uint32_t osThreadEnumerate(osThreadId_t *thread_array,
- uint32_t array_items)
- {
- #if (OS_CFG_DBG_EN == DEF_ENABLED)
- OS_TCB *p_tcb;
- uint32_t items;
- if (CORE_InIrqContext() == true) {
- return 0u;
- }
- items = 0u;
- CORE_DECLARE_IRQ_STATE;
- CORE_ENTER_CRITICAL();
- p_tcb = OSTaskDbgListPtr;
- while ((p_tcb != (OS_TCB *)0) && (items < array_items)) {
- *thread_array = p_tcb;
- thread_array++;
- p_tcb = p_tcb->DbgNextPtr;
- items++;
- }
- CORE_EXIT_CRITICAL();
- return items;
- #else
- (void)thread_array;
- (void)array_items;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, 0u);
- return 0u;
- #endif
- }
- /*
- ****************************************************************************************************
- ****************************************************************************************************
- * T H R E A D F L A G S
- ****************************************************************************************************
- ****************************************************************************************************
- */
- /*
- ****************************************************************************************************
- * osThreadFlagsSet()
- *
- * Description: Thread Flags are a more specialized version of the Event Flags. See Event Flags.
- * While Event Flags can be used to globally signal a number of threads, thread flags are
- * only sent to a single specific thread. Every thread instance can receive thread flags
- * without any additional allocation of a thread flags object.
- *
- * Arguments : thread_id is the desired theard ID
- *
- * flags are the flags to set
- * the upper bit (i.e. bit 31, is not allowed to be set)
- *
- * Returns : osFlagsErrorUnknown unspecified error.
- * osFlagsErrorParameter parameter 'thread_id' is not a valid thread or flags has highest bit set.
- * osFlagsErrorResource the thread is in invalid state.
- *
- * Note(s) : None
- ****************************************************************************************************
- */
- uint32_t osThreadFlagsSet(osThreadId_t thread_id,
- uint32_t flags)
- {
- #if (OS_CFG_FLAG_EN == DEF_ENABLED)
- OS_ERR err;
- osThread_t *p_thread;
- OS_FLAG_GRP *p_grp;
- OS_TCB *p_tcb;
- uint32_t rdy_flags;
- uint32_t new_flags;
- uint32_t ret_flags;
- CORE_DECLARE_IRQ_STATE;
- p_thread = (osThread_t*)thread_id;
- if (p_thread == (osThread_t *)0) {
- return osFlagsErrorParameter;
- }
- p_grp = &p_thread->flag_grp;
- if ((flags & 0x80000000u) == 0x80000000u) { // Upper bit is not allowed to be set
- return osFlagsErrorParameter;
- }
- CORE_ENTER_ATOMIC();
- new_flags = p_grp->Flags |= flags; // New flags after set
- p_tcb = p_grp->PendList.HeadPtr; // Loop over pending tasks
- while (p_tcb != DEF_NULL) {
- if (p_tcb->FlagsOpt & OS_OPT_PEND_FLAG_CONSUME) { // Pender might consume the flags?
- switch (p_tcb->FlagsOpt & OS_OPT_PEND_FLAG_MASK) {
- case OS_OPT_PEND_FLAG_SET_ALL: // -> Pender waiting for all flags to be set
- rdy_flags = (new_flags & p_tcb->FlagsPend);
- if (rdy_flags == p_tcb->FlagsPend) { // -> Pender will really consume?
- new_flags &= ~rdy_flags; // -> Simulate the consumption
- }
- break;
- case OS_OPT_PEND_FLAG_SET_ANY: // -> Pender waiting for any flags to be set
- rdy_flags = (new_flags & p_tcb->FlagsPend);
- if (rdy_flags != 0u) { // -> Pender will really consume?
- new_flags &= ~rdy_flags; // -> Simulate the consumption
- }
- break;
- default:
- break;
- }
- }
- p_tcb = p_tcb->PendNextPtr; // Point to next task waiting for event flag(s)
- }
- CORE_EXIT_ATOMIC();
- OSFlagPost(p_grp, (OS_FLAGS)flags, OS_OPT_POST_FLAG_SET, &err);
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- ret_flags = new_flags;
- break;
- default:
- ret_flags = osFlagsErrorResource;
- break;
- }
- return ret_flags;
- #else
- (void)thread_id;
- (void)flags;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osFlagsErrorUnknown);
- return osFlagsErrorUnknown;
- #endif
- }
- /*
- ****************************************************************************************************
- * osThreadFlagsClear()
- *
- * Description: The function 'osThreadFlagsClear()' clears the specified flags for the currently running
- * thread. It returns the flags before clearing, or an error code if highest bit is set
- * (refer to Flags Functions Error Codes).
- *
- * Arguments : flags are the flags to clear
- *
- * Returns : osFlagsErrorUnknown unspecified error, i.e. not called from a running threads context.
- * osFlagsErrorParameter parameter flags has highest bit set.
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- uint32_t osThreadFlagsClear(uint32_t flags)
- {
- #if (OS_CFG_FLAG_EN == DEF_ENABLED)
- osThread_t *p_thread;
- OS_FLAG_GRP *p_grp;
- OS_ERR err;
- uint32_t old_flags;
- if (CORE_InIrqContext() == true) {
- return (uint32_t)osErrorISR;
- }
- if ((flags & 0x80000000u) == 0x80000000u) { // Upper bit is not allowed to be set
- return osFlagsErrorParameter;
- }
- p_thread = (osThread_t*)OSTCBCurPtr;
- p_grp = &p_thread->flag_grp;
- old_flags = p_grp->Flags;
- (void)OSFlagPost(p_grp, (OS_FLAGS)flags, OS_OPT_POST_FLAG_CLR, &err);
- return old_flags;
- #else
- (void)flags;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osFlagsErrorUnknown);
- return osFlagsErrorUnknown;
- #endif
- }
- /*
- ****************************************************************************************************
- * osThreadFlagsGet()
- *
- * Description: The function 'osThreadFlagsGet()' returns the flags currently set for the currently
- * running thread. If called without a active and currently running thread
- * 'osThreadFlagsGet()' return zero.
- *
- * Arguments : None
- *
- * Returns : the flags
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- uint32_t osThreadFlagsGet(void)
- {
- #if (OS_CFG_FLAG_EN == DEF_ENABLED)
- osThread_t *p_thread;
- OS_FLAG_GRP *p_grp;
- uint32_t flags;
- if (CORE_InIrqContext() == true) {
- return (uint32_t)osErrorISR;
- }
- p_thread = (osThread_t*)OSTCBCurPtr;
- p_grp = &p_thread->flag_grp;
- flags = p_grp->Flags;
- return flags;
- #else
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osFlagsErrorUnknown);
- return osFlagsErrorUnknown;
- #endif
- }
- /*
- ****************************************************************************************************
- * osThreadFlagsWait()
- *
- * Description: The function 'osThreadFlagsWait()' suspends the execution of the currently RUNNING
- * thread until any or all of the thread flags specified with the parameter flags are set.
- *
- * When these thread flags are already set, the function returns instantly. Otherwise the
- * thread is put into the state BLOCKED.
- *
- * Arguments : flags are the flags to wait for
- *
- * options wait for:
- * osFlagsWaitAny
- * osFlagsWaitAnyNoClear
- * osFlagsWaitAll
- * osFlagsWaitAllNoClear
- *
- * timeout the amount of time to wait for the desired flags
- *
- * Returns : osFlagsErrorUnknown unspecified error, i.e. not called from a running threads context.
- * osFlagsErrorTimeout awaited flags have not been set in the given time.
- * osFlagsErrorResource awaited flags have not been set when no timeout was specified.
- * osFlagsErrorParameter Parameter flags has highest bit set.
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- uint32_t osThreadFlagsWait(uint32_t flags,
- uint32_t options,
- uint32_t timeout)
- {
- #if (OS_CFG_FLAG_EN == DEF_ENABLED)
- osThread_t *p_thread;
- OS_FLAG_GRP *p_grp;
- OS_ERR err;
- OS_TICK os_timeout;
- OS_OPT opt;
- CPU_TS ts;
- uint32_t old_flags;
- uint32_t rdy_flags;
- uint32_t rtn_flags;
- if (CORE_InIrqContext() == true) {
- return (uint32_t)osErrorISR;
- }
- if ((flags & 0x80000000u) == 0x80000000u) { // Upper bit is not
- // allowed to be set
- return osFlagsErrorParameter;
- }
- if (timeout == osWaitForever) {
- opt = OS_OPT_PEND_BLOCKING;
- os_timeout = 0u; // Specifying 0 in MicriumOS
- // means wait forever w/ blocking
- } else if (timeout == 0u) {
- opt = OS_OPT_PEND_NON_BLOCKING;
- os_timeout = 0u; // The timeout parameter is
- // ignored by MicriumOS in
- // non-blocking mode
- } else {
- opt = OS_OPT_PEND_BLOCKING;
- os_timeout = timeout;
- }
- if (options & osFlagsWaitAll) {
- opt |= OS_OPT_PEND_FLAG_SET_ALL;
- } else {
- opt |= OS_OPT_PEND_FLAG_SET_ANY;
- }
- if (!(options & osFlagsNoClear)) {
- opt |= OS_OPT_PEND_FLAG_CONSUME;
- }
- p_thread = (osThread_t *)OSTCBCurPtr;
- p_grp = &p_thread->flag_grp;
- old_flags = p_grp->Flags; // Get flags
- rdy_flags = (uint32_t)OSFlagPend(p_grp, (OS_FLAGS)flags, os_timeout, opt, &ts, &err);
- rtn_flags = rdy_flags | old_flags;
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_TIMEOUT:
- return osFlagsErrorTimeout;
- case OS_ERR_NONE:
- return rtn_flags;
- case OS_ERR_PEND_WOULD_BLOCK:
- if (rdy_flags != (uint32_t)0u) {
- return rtn_flags;
- } else {
- return osFlagsErrorResource;
- }
- default:
- return osFlagsErrorResource;
- }
- #else
- (void)flags;
- (void)options;
- (void)timeout;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osFlagsErrorUnknown);
- return osFlagsErrorUnknown;
- #endif
- }
- /*
- ****************************************************************************************************
- ****************************************************************************************************
- * T I M E R M A N A G E M E N T
- ***************************************************************************************************/
- /****************************************************************************************************
- * osTimerNew()
- *
- * Description: The function 'osTimerNew()' creates an one-shot or periodic timer and associates it with
- * a callback function with argument. The timer is in stopped state until it is started
- * with 'osTimerStart()'. The function can be safely called before the RTOS is started
- * (call to 'osKernelStart()'), but not before it is initialized (call to 'osKernelInitialize()').
- *
- * The function 'osTimerNew()' returns the pointer to the timer object identifier or NULL
- * in case of an error.
- *
- * Arguments : func pointer to function that will be called when the timer expires
- *
- * type the type of timer created:
- * osTimerOnce A one-shot timer
- * osTimerPeriodic A periodic timer
- *
- * argument a pointer to arguments passed to the callback function (func) when the
- * timer expires.
- *
- * attr timer attributes or NULL to use default values
- *
- * Returns : timer ID for reference by other functions or NULL in case of error.
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- osTimerId_t osTimerNew(osTimerFunc_t func,
- osTimerType_t type,
- void *argument,
- const osTimerAttr_t *attr)
- {
- #if defined CMSIS_RTOS2_TIMER_TASK_EN && (CMSIS_RTOS2_TIMER_TASK_EN == DEF_ENABLED)
- osTimer_t *p_tmr;
- const char *p_name;
- if (CORE_InIrqContext() == true) {
- return (osTimerId_t)0;
- }
- if (func == (osTimerFunc_t)0) { // Caller must specify a callback
- return (osTimerId_t)0;
- }
- p_name = "Timer";
- if (attr == NULL) {
- p_tmr = (osTimer_t *)malloc(sizeof(osTimer_t));
- if (p_tmr == (osTimer_t *)0) {
- return (osTimerId_t)0;
- }
- p_tmr->dyn_alloc = DEF_TRUE;
- } else {
- if (attr->cb_mem == (void *)0) {
- p_tmr = (osTimer_t *)malloc(sizeof(osTimer_t));
- if (p_tmr == (osTimer_t *)0) {
- return (osTimerId_t)0;
- }
- p_tmr->dyn_alloc = DEF_TRUE;
- } else {
- if (attr->cb_size < sizeof(osTimer_t) || (uint32_t)attr->cb_mem % sizeof(CPU_ALIGN)) {
- return (osTimerId_t)0;
- }
- p_tmr = (osTimer_t *)attr->cb_mem;
- p_tmr->dyn_alloc = DEF_FALSE;
- }
- if (attr->name != (const char *)0) {
- p_name = attr->name;
- }
- }
- p_tmr->type = type;
- p_tmr->name = p_name;
- p_tmr->callback = func;
- p_tmr->callback_data = argument;
- return (osTimerId_t)p_tmr;
- #else
- (void)func;
- (void)type;
- (void)argument;
- (void)attr;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, (osTimerId_t)0);
- return (osTimerId_t)0;
- #endif
- }
- /*
- ****************************************************************************************************
- * osTimerGetName()
- *
- * Description: The function 'osTimerGetName()' returns the pointer to the name string of the timer
- * identified by parameter 'timer_id' or NULL in case of an error.
- *
- * Arguments : timer_id is the timer ID returned by 'osTimerNew()'
- *
- * Returns : A pointer to the ASCII string containing the name of the timer.
- * NULL upon error
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- const char *osTimerGetName(osTimerId_t timer_id)
- {
- #if defined CMSIS_RTOS2_TIMER_TASK_EN && (CMSIS_RTOS2_TIMER_TASK_EN == DEF_ENABLED) && (OS_CFG_DBG_EN == DEF_ENABLED)
- osTimer_t *p_tmr;
- if (CORE_InIrqContext() == true) {
- return NULL;
- }
- p_tmr = (osTimer_t *)timer_id;
- if (p_tmr == (osTimer_t *)0) {
- return NULL;
- }
- return p_tmr->name;
- #else
- (void)timer_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, NULL);
- return NULL;
- #endif
- }
- /*
- ****************************************************************************************************
- * osTimerStart()
- *
- * Description: The function 'osTimerStart()' starts or restarts a timer specified by the parameter
- * 'timer_id'. The parameter ticks specifies the value of the timer in time ticks.
- *
- * Arguments : timer_id is the timer ID returned by 'osTimerNew()'
- *
- * ticks is the one shot delay (osTimerOnce) or
- * the period of timer repeat (osTimerPeriodic)
- *
- * Returns : osOK the specified timer has been started or restarted.
- * osErrorISR osTimerStart() cannot be called from interrupt service routines.
- * osErrorParameter parameter 'timer_id' is either NULL or invalid or ticks is incorrect.
- * osErrorResource the timer is in an invalid state.
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- osStatus_t osTimerStart(osTimerId_t timer_id,
- uint32_t ticks)
- {
- #if defined CMSIS_RTOS2_TIMER_TASK_EN && (CMSIS_RTOS2_TIMER_TASK_EN == DEF_ENABLED)
- osTimer_t *p_tmr;
- sl_status_t status;
- uint32_t delay;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- if (ticks == 0u) { // Cannot be 0 ticks
- return osErrorParameter;
- }
- p_tmr = (osTimer_t *)timer_id;
- if (p_tmr == (osTimer_t *)0) {
- return osErrorParameter;
- }
- // Convert from OS tick to sleeptimer ticks
- delay = (uint64_t)(((uint64_t)ticks * (uint64_t)sl_sleeptimer_get_timer_frequency()) + ((uint64_t)OSCfg_TickRate_Hz - 1u)) / OSCfg_TickRate_Hz;
- if (p_tmr->type == osTimerOnce) {
- status = sl_sleeptimer_start_timer(&p_tmr->handle, delay, sleeptimer_callback, (void *)p_tmr, 0, 0);
- } else {
- status = sl_sleeptimer_start_periodic_timer(&p_tmr->handle, delay, sleeptimer_callback, (void *)p_tmr, 0, 0);
- }
- if (status == SL_STATUS_OK) {
- return osOK;
- } else {
- return osErrorResource;
- }
- #else
- (void)timer_id;
- (void)ticks;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osError);
- return osError;
- #endif
- }
- /*
- ****************************************************************************************************
- * osTimerStop()
- *
- * Description: The function 'osTimerStop()' stops the timer specified by the parameter 'timer_id'.
- *
- * Arguments : timer_id is the timer ID returned by 'osTimerNew()'
- *
- * Returns : osOK the specified timer has been stopped
- * osErrorISR osTimerStop() cannot be called from interrupt service routines.
- * osErrorParameter parameter 'timer_id' is either NULL or invalid or ticks is incorrect.
- * osErrorResource the timer is in an invalid state.
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- osStatus_t osTimerStop(osTimerId_t timer_id)
- {
- #if defined CMSIS_RTOS2_TIMER_TASK_EN && (CMSIS_RTOS2_TIMER_TASK_EN == DEF_ENABLED)
- osTimer_t *p_tmr;
- sl_status_t status;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- p_tmr = (osTimer_t *)timer_id;
- if (p_tmr == (osTimer_t *)0) {
- return osErrorParameter;
- }
- status = sl_sleeptimer_stop_timer(&p_tmr->handle);
- if (status == SL_STATUS_OK) {
- return osOK;
- } else {
- return osErrorResource;
- }
- #else
- (void)timer_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osError);
- return osError;
- #endif
- }
- /*
- ****************************************************************************************************
- * osTimerIsRunning()
- *
- * Description: The function 'osTimerIsRunning()' checks whether a timer specified by parameter 'timer_id'
- * is running.
- *
- * Arguments : timer_id is the timer ID returned by 'osTimerNew()'
- *
- * Returns : 1 if the timer is running
- * 0 if stopped or an error occurs
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- uint32_t osTimerIsRunning(osTimerId_t timer_id)
- {
- #if defined CMSIS_RTOS2_TIMER_TASK_EN && (CMSIS_RTOS2_TIMER_TASK_EN == DEF_ENABLED)
- osTimer_t *p_tmr;
- sl_status_t status;
- bool running;
- if (CORE_InIrqContext() == true) {
- return 0u;
- }
- p_tmr = (osTimer_t*)timer_id;
- if (p_tmr == (osTimer_t*)0) {
- return 0u;
- }
- status = sl_sleeptimer_is_timer_running(&p_tmr->handle, &running);
- if (status != SL_STATUS_OK) {
- return 0u;
- }
- return (uint32_t)running;
- #else
- (void)timer_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, 0u);
- return 0u;
- #endif
- }
- /*
- ****************************************************************************************************
- * osTimerDelete()
- *
- * Description: The function 'osTimerDelete()' deletes the timer object specified by parameter 'timer_id'.
- *
- * Arguments : timer_id is the timer ID returned by 'osTimerNew()'
- *
- * Returns : osOK the timer object has been deleted.
- * osErrorParameter the parameter timer_id is NULL or invalid.
- * osErrorResource the timer is in an invalid state.
- * osErrorISR osTimerDelete() cannot be called from interrupt service routines.
- *
- *
- * Note(s) : 1) This function CANNOT be called from an ISR
- ****************************************************************************************************
- */
- osStatus_t osTimerDelete(osTimerId_t timer_id)
- {
- #if defined CMSIS_RTOS2_TIMER_TASK_EN && (CMSIS_RTOS2_TIMER_TASK_EN == DEF_ENABLED)
- osTimer_t *p_tmr;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- p_tmr = (osTimer_t *)timer_id;
- if (p_tmr == (osTimer_t *)0) {
- return osErrorParameter;
- }
- sl_sleeptimer_stop_timer(&p_tmr->handle);
- if (p_tmr->dyn_alloc == DEF_TRUE) {
- free(p_tmr);
- }
- return osOK;
- #else
- (void)timer_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, osError);
- return osError;
- #endif
- }
- /*
- ****************************************************************************************************
- ****************************************************************************************************
- * M E M O R Y P O O L M A N A G E M E N T
- ****************************************************************************************************
- ****************************************************************************************************
- */
- /*
- ****************************************************************************************************
- * osMemoryPoolNew()
- *
- * Description: The function 'osMemoryPoolNew()' creates and initializes a memory pool object and returns
- * the pointer to the memory pool object identifier or NULL in case of an error.
- *
- * It can be safely called before the RTOS is started (call to 'osKernelStart()'), but not
- * before it is initialized (call to 'osKernelInitialize()').
- *
- * Arguments : block_count maximum number of memory blocks in memory pool.
- * block_size memory block size in bytes.
- * attr memory pool attributes. If NULL, use default values.
- *
- * Returns : Memory Pool ID for reference by other functions or NULL in case of error.
- *
- * Note(s) : 1) MicriumOS DOES NOT support this functionality
- ****************************************************************************************************
- */
- osMemoryPoolId_t osMemoryPoolNew(uint32_t block_count,
- uint32_t block_size,
- const osMemoryPoolAttr_t *attr)
- {
- (void)block_count;
- (void)block_size;
- (void)attr;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, NULL);
- return NULL;
- }
- /*
- ****************************************************************************************************
- * osMemoryPoolGetName()
- *
- * Description: The function 'osMemoryPoolName()' returns the pointer to the name string of the memory
- * pool identified by parameter 'mp_id' or NULL in case of an error.
- *
- * Arguments : mp_id is the memory pool ID returned by 'osMemoryPoolNew()'
- *
- * Returns : A pointer to the ASCII string containing the name of the memory pool.
- * NULL upon error
- *
- * Note(s) : 1) MicriumOS DOES NOT support this functionality
- ****************************************************************************************************
- */
- const char * osMemoryPoolGetName(osMemoryPoolId_t mp_id)
- {
- (void)mp_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, NULL);
- return NULL;
- }
- /*
- ****************************************************************************************************
- * osMemoryPoolAlloc()
- *
- * Description: The blocking function 'osMemoryPoolAlloc()' allocates the memory pool parameter 'mp_id'
- * and returns a pointer to the address of the allocated memory or 0 in case of an error.
- *
- * The parameter 'timeout' specifies how long the system waits to allocate the memory.
- * While the system waits, the thread that is calling this function is put into the
- * BLOCKED state. The thread will become READY as soon as at least one block of memory
- * gets available.
- *
- * Arguments : mp_id is the memory pool ID returned by 'osMemoryPoolNew()'
- *
- * timeout when timeout is 0, the function returns instantly (i.e. try semantics).
- * when timeout is set to 'osWaitForever' the function will wait for an infinite
- * time until the memory is allocated (i.e. wait semantics).
- * all other values specify a time in kernel ticks for a timeout
- * (i.e. timed-wait semantics).
- *
- * Returns : The result is the pointer to the memory block allocated, or NULL if no memory is available.
- *
- * Note(s) : 1) MicriumOS DOES NOT support this functionality
- ****************************************************************************************************
- */
- void * osMemoryPoolAlloc(osMemoryPoolId_t mp_id,
- uint32_t timeout)
- {
- (void)mp_id;
- (void)timeout;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, NULL);
- return NULL;
- }
- /*
- ****************************************************************************************************
- * osMemoryPoolFree()
- *
- * Description: The function 'osMemoryPoolFree()' frees the memory pool block specified by the parameter
- * 'block' in the memory pool object specified by the parameter 'mp_id'. The memory block
- * is put back to the list of available blocks.
- *
- * If another thread is waiting for memory to become available the thread is put to READY state.
- *
- * Arguments : mp_id is the memory pool ID returned by 'osMemoryPoolNew()'
- *
- * block address of the allocated memory block to be returned to the memory pool.
- *
- * Returns : osOK the memory has been freed.
- * osErrorParameter parameter mp_id is NULL or invalid, block points to invalid memory.
- * osErrorResource the memory pool is in an invalid state.
- *
- * Note(s) : 1) MicriumOS DOES NOT support this functionality
- ****************************************************************************************************
- */
- osStatus_t osMemoryPoolFree(osMemoryPoolId_t mp_id,
- void *block)
- {
- (void)mp_id;
- (void)block;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, NULL);
- return osError;
- }
- /*
- ****************************************************************************************************
- * osMemoryPoolGetCapacity()
- *
- * Description: The function 'osMemoryPoolGetCapacity()' returns the maximum number of memory blocks
- * in the memory pool object specified by parameter 'mp_id' or 0 in case of an error.
- *
- * Arguments : mp_id is the memory pool ID returned by 'osMemoryPoolNew()'
- *
- * Returns : Maximum number of memory blocks
- *
- * Note(s) : 1) MicriumOS DOES NOT support this functionality
- ****************************************************************************************************
- */
- uint32_t osMemoryPoolGetCapacity(osMemoryPoolId_t mp_id)
- {
- (void)mp_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, 0);
- return 0;
- }
- /*
- ****************************************************************************************************
- * osMemoryPoolGetBlockSize()
- *
- * Description: The function 'osMemoryPoolGetBlockSize()' returns the memory block size in bytes in
- * the memory pool object specified by parameter 'mp_id' or 0 in case of an error.
- *
- * Arguments : mp_id is the memory pool ID returned by 'osMemoryPoolNew()'
- *
- * Returns : Size (in bytes) of each block
- * 0 upon error
- *
- * Note(s) : 1) MicriumOS DOES NOT support this functionality
- ****************************************************************************************************
- */
- uint32_t osMemoryPoolGetBlockSize(osMemoryPoolId_t mp_id)
- {
- (void)mp_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, 0);
- return 0;
- }
- /*
- ****************************************************************************************************
- * osMemoryPoolGetCount()
- *
- * Description: The function 'osMemoryPoolGetCount()' returns the number of memory blocks used in the
- * memory pool object specified by parameter 'mp_id' or 0 in case of an error.
- *
- * Arguments : mp_id is the memory pool ID returned by 'osMemoryPoolNew()'
- *
- * Returns : number of memory blocks used.
- * 0 upon error
- *
- * Note(s) : 1) MicriumOS DOES NOT support this functionality
- ****************************************************************************************************
- */
- uint32_t osMemoryPoolGetCount(osMemoryPoolId_t mp_id)
- {
- (void)mp_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, 0);
- return 0;
- }
- /*
- ****************************************************************************************************
- * osMemoryPoolGetSpace()
- *
- * Description: The function 'osMemoryPoolGetSpace()' returns the number of memory blocks available
- * in the memory pool object specified by parameter 'mp_id' or 0 in case of an error.
- *
- * Arguments : mp_id is the memory pool ID returned by 'osMemoryPoolNew()'
- *
- * Returns : number of memory blocks available.
- * 0 upon error
- *
- * Note(s) : 1) MicriumOS DOES NOT support this functionality
- ****************************************************************************************************
- */
- uint32_t osMemoryPoolGetSpace(osMemoryPoolId_t mp_id)
- {
- (void)mp_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, 0);
- return 0;
- }
- /*
- ****************************************************************************************************
- * osMemoryPoolDelete()
- *
- * Description: The function 'osMemoryPoolDelete()' deletes a memory pool object specified by parameter
- * 'mp_id'. It releases internal memory obtained for memory pool handling.
- *
- * After this call, the 'mp_id' is no longer valid and cannot be used. The memory pool
- * may be created again using the function 'osMemoryPoolNew()'.
- *
- * Arguments : mp_id is the memory pool ID returned by 'osMemoryPoolNew()'
- *
- * Returns : osOK the memory pool object has been deleted.
- * osErrorParameter parameter mp_id is NULL or invalid.
- * osErrorResource the memory pool is in an invalid state.
- * osErrorISR 'osMemoryPoolDelete()' cannot be called from an ISR
- *
- * Note(s) : 1) MicriumOS DOES NOT support this functionality
- ****************************************************************************************************
- */
- osStatus_t osMemoryPoolDelete(osMemoryPoolId_t mp_id)
- {
- (void)mp_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, osError);
- return osError;
- }
- /*
- ****************************************************************************************************
- ****************************************************************************************************
- * M E S S A G E Q U E U E M A N A G E M E N T
- ****************************************************************************************************
- ****************************************************************************************************
- */
- /*
- ****************************************************************************************************
- * osMessageQueueNew()
- *
- * Description: The function 'osMessageQueueNew()' creates and initializes a message queue object.
- * The function returns a message queue object identifier or NULL in case of an error.
- *
- * The function can be called after kernel initialization with 'osKernelInitialize()'.
- * It is possible to create message queue objects before the RTOS kernel is started with
- * 'osKernelStart()'.
- *
- * The total amount of memory required for the message queue data is at least 'msg_count * msg_size'.
- * The 'msg_size' is rounded up to a double even number to ensure 32-bit alignment of the memory blocks.
- *
- * The memory blocks allocated from the message queue have a fixed size defined with the parameter 'msg_size'.
- *
- * Arguments : msg_count is the maximum number of messages in the queue
- *
- * msg_size maximum message size (in bytes)
- *
- * attr attribute structure passed to the message queue creation code.
- * specifying NULL assumes defaults.
- *
- * Message queue attributes are:
- *
- * .name name of the message queue
- * .attr_bits reserved (should be 0)
- * .cb_mem pointer to message queue control block
- * (allocated dynamically if NULL or not specified)
- * .cb_size size of the message queue control block (in bytes)
- * .mq_mem pointer to storage of messages
- * (allocated dynamically if NULL or not specified)
- * .mq_size size of each message (in bytes)
- * (the minimum is 'msg_count' * 'msg_size')
- *
- * Returns : The message queue ID upon success
- * NULL upon error
- ****************************************************************************************************
- */
- osMessageQueueId_t osMessageQueueNew(uint32_t msg_count,
- uint32_t msg_size,
- const osMessageQueueAttr_t *attr)
- {
- #if (OS_CFG_SEM_EN == DEF_ENABLED)
- osMessageQueue_t *p_msgqueue;
- CPU_CHAR *p_name;
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return (osMessageQueueId_t)0; // Can't create a msgqueue from an ISR
- }
- if (msg_count == 0) { // Validate msg_count
- return (osMessageQueueId_t)0;
- }
- if (msg_size == 0) { // Validate msg_size
- return (osMessageQueueId_t)0;
- } else {
- msg_size = (msg_size + sizeof(CPU_ALIGN) - 1) & ~(sizeof(CPU_ALIGN) - 1); // Align to 4 bytes
- }
- p_name = (CPU_CHAR *)"QueueName?";
- if (attr == 0) {
- p_msgqueue = (osMessageQueue_t *)malloc(sizeof(osMessageQueue_t));
- if (p_msgqueue == (osMessageQueue_t *)0) {
- return (osMessageQueueId_t)0;
- } else {
- p_msgqueue->obj_dyn_alloc = DEF_TRUE;
- p_msgqueue->buf = (uint8_t *) malloc(msg_size * msg_count);
- if (p_msgqueue->buf == (uint8_t *)0) {
- free(p_msgqueue);
- return (osMessageQueueId_t)0;
- }
- p_msgqueue->buf_dyn_alloc = DEF_TRUE;
- }
- } else {
- if (attr->cb_mem == (void *)0) {
- p_msgqueue = (osMessageQueue_t *)malloc(sizeof(osMessageQueue_t));
- if (p_msgqueue == (osMessageQueue_t *)0) {
- return (osMessageQueueId_t)0;
- }
- p_msgqueue->obj_dyn_alloc = DEF_TRUE;
- } else {
- if (attr->cb_size < sizeof(osMessageQueue_t) || (uint32_t)attr->cb_mem % sizeof(CPU_ALIGN)) {
- return (osMessageQueueId_t)0;
- }
- p_msgqueue = attr->cb_mem;
- p_msgqueue->obj_dyn_alloc = DEF_FALSE;
- }
- if (attr->mq_size == 0u) {
- p_msgqueue->buf = (uint8_t *)malloc(msg_size * msg_count);
- if (p_msgqueue->buf == (uint8_t *)0) {
- if (p_msgqueue->obj_dyn_alloc == DEF_TRUE) {
- free(p_msgqueue);
- }
- return (osMessageQueueId_t)0;
- }
- p_msgqueue->buf_dyn_alloc = DEF_TRUE;
- } else if ((attr->mq_size != 0u) && (attr->mq_mem == NULL)) {
- if (attr->mq_size < msg_size * msg_count) {
- if (p_msgqueue->obj_dyn_alloc == DEF_TRUE) {
- free(p_msgqueue);
- }
- return (osMessageQueueId_t)0;
- }
- p_msgqueue->buf = (uint8_t *)malloc(attr->mq_size);
- if (p_msgqueue->buf == (uint8_t *)0) {
- if (p_msgqueue->obj_dyn_alloc == DEF_TRUE) {
- free(p_msgqueue);
- }
- return (osMessageQueueId_t)0;
- }
- p_msgqueue->buf_dyn_alloc = DEF_TRUE;
- } else {
- if (attr->mq_mem == NULL
- || attr->mq_size < msg_size * msg_count
- || (uint32_t)attr->mq_mem % sizeof(CPU_ALIGN)) {
- if (p_msgqueue->obj_dyn_alloc == DEF_TRUE) {
- free(p_msgqueue);
- }
- return (osMessageQueueId_t)0;
- }
- p_msgqueue->buf = (uint8_t *)attr->mq_mem;
- p_msgqueue->buf_dyn_alloc = DEF_FALSE;
- }
- if (attr->name != (const char *)0) {
- p_name = (CPU_CHAR *)attr->name;
- }
- }
- p_msgqueue->msg_count = msg_count;
- p_msgqueue->msg_size = msg_size;
- p_msgqueue->msg_queued = 0;
- p_msgqueue->msg_head = 0;
- p_msgqueue->msg_tail = 0;
- OSSemCreate(&p_msgqueue->sem_put, p_name, msg_count, &err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- if (p_msgqueue->buf_dyn_alloc == DEF_TRUE) {
- free(p_msgqueue->buf);
- }
- if (p_msgqueue->obj_dyn_alloc == DEF_TRUE) {
- free(p_msgqueue);
- }
- return (osMessageQueueId_t)0;
- }
- OSSemCreate(&p_msgqueue->sem_get, p_name, 0, &err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- if (p_msgqueue->buf_dyn_alloc == DEF_TRUE) {
- free(p_msgqueue->buf);
- }
- if (p_msgqueue->obj_dyn_alloc == DEF_TRUE) {
- free(p_msgqueue);
- }
- return (osMessageQueueId_t)0;
- }
- return (osMessageQueueId_t)p_msgqueue;
- #else
- (void) msg_count;
- (void) msg_size;
- (void) attr;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_AVAIL, (osMessageQueueId_t)0);
- return (osMessageQueueId_t)0;
- #endif
- }
- /*
- ****************************************************************************************************
- * osMessageQueueGetName()
- *
- * Description: The function 'osMessageQueueGetName()' returns the pointer to the name string of the
- * message queue identified by parameter 'mq_id' or NULL in case of an error.
- *
- * Arguments : mq_id is the message queue ID returned by 'osMessageQueueNew()'
- *
- * Returns : A pointer to the ASCII string containing the name of the mutex.
- * NULL upon error
- ****************************************************************************************************
- */
- const char * osMessageQueueGetName(osMessageQueueId_t mq_id)
- {
- #if (OS_CFG_SEM_EN == DEF_ENABLED) && (OS_CFG_DBG_EN == DEF_ENABLED)
- osMessageQueue_t *p_msgqueue;
- if (CORE_InIrqContext() == true) {
- return NULL;
- }
- p_msgqueue = (osMessageQueue_t *)mq_id;
- if (p_msgqueue == (osMessageQueue_t *)0) {
- return NULL;
- }
- return p_msgqueue->sem_put.NamePtr;
- #else
- (void)mq_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, NULL);
- return NULL;
- #endif
- }
- /*
- ****************************************************************************************************
- * osMessageQueuePut()
- *
- * Description: The blocking function 'osMessageQueuePut()' puts the message pointed to by 'msg_ptr'
- * into the message queue specified by parameter 'mq_id'.
- *
- * The parameter 'msg_prio' is used to sort message according their priority
- * (higher numbers indicate a higher priority) on insertion.
- *
- * The parameter 'timeout' specifies how long the system waits to put the message into
- * the queue. While the system waits, the thread that is calling this function is put
- * into the BLOCKED state. The parameter timeout can have the following values:
- *
- * when timeout is 0, the function returns instantly (i.e. try semantics).
- * when timeout is set to osWaitForever the function will wait for an infinite time
- * until the message is delivered (i.e. wait semantics).
- * all other values specify a time in kernel ticks for a timeout (i.e. timed-wait semantics).
- *
- * Arguments : mq_id is the message queue ID returned by 'osMessageQueueNew()'
- *
- * msg_ptr pointer to message to send
- *
- * msg_prio priority of message sent
- *
- * timeout when timeout is 0, the function returns instantly (i.e. try semantics).
- * when timeout is set to 'osWaitForever()' the function will wait for an
- * infinite time until the message is delivered (i.e. wait semantics).
- * all other values specify a time in kernel ticks for a timeout
- * (i.e. timed-wait semantics).
- *
- * Returns : osOK the message has been put in the queue
- * osErrorTimeout the message could not be put into the queue within the timeout specified
- * osErrorParameter the parameter 'mq_id' is NULL or invalid.
- * osErrorResource not enough space in the queue
- ****************************************************************************************************
- */
- osStatus_t osMessageQueuePut(osMessageQueueId_t mq_id,
- const void *msg_ptr,
- uint8_t msg_prio,
- uint32_t timeout)
- {
- #if (OS_CFG_SEM_EN == DEF_ENABLED)
- osMessageQueue_t *p_msgqueue;
- CPU_TS ts;
- OS_ERR err;
- uint32_t msg_id, msg_size;
- CORE_DECLARE_IRQ_STATE;
- (void) msg_prio;
- p_msgqueue = (osMessageQueue_t *)mq_id;
- if (p_msgqueue == (osMessageQueue_t *)0) {
- return osErrorParameter;
- }
- if (timeout == 0u) {
- OSSemPend(&p_msgqueue->sem_put, (OS_TICK)0u, OS_OPT_PEND_NON_BLOCKING, &ts, &err);
- } else {
- if (CORE_InIrqContext() == true) {
- return osErrorParameter;
- } else {
- OSSemPend(&p_msgqueue->sem_put, (OS_TICK)timeout, OS_OPT_PEND_BLOCKING, &ts, &err);
- }
- }
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- break;
- case OS_ERR_TIMEOUT:
- return osErrorTimeout;
- default:
- return osErrorResource;
- }
- CORE_ENTER_ATOMIC();
- msg_id = p_msgqueue->msg_head;
- msg_size = p_msgqueue->msg_size;
- p_msgqueue->msg_head = (p_msgqueue->msg_head + 1) % p_msgqueue->msg_count;
- memcpy(&p_msgqueue->buf[msg_id * msg_size], msg_ptr, msg_size);
- p_msgqueue->msg_queued++;
- CORE_EXIT_ATOMIC();
- OSSemPost(&p_msgqueue->sem_get, OS_OPT_POST_1, &err);
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- return osOK;
- default:
- return osErrorResource;
- }
- #else
- (void)mq_id;
- (void)msg_ptr;
- (void)msg_prio;
- (void)timeout;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, osError);
- return osError;
- #endif
- }
- /*
- ****************************************************************************************************
- * osMessageQueueGet()
- *
- * Description: The function 'osMessageQueueGet()' retrieves a message from the message queue specified
- * by the parameter 'mq_id' and saves it to the buffer pointed to by the parameter 'msg_ptr'.
- *
- * The message priority is stored to parameter 'msg_prio' if not token{NULL}.
- *
- * The parameter 'timeout' specifies how long the system waits to retrieve the message from
- * the queue. While the system waits, the thread that is calling this function is put into
- * the BLOCKED state. The parameter 'timeout' can have the following values:
- *
- *
- *
- *
- * Arguments : mq_id the message queue ID
- *
- * msg_ptr a pointer to where the message will be placed
- *
- * msg_prio a pointer to where the message priority will be deposited to.
- *
- * timeout when timeout is 0, the function returns instantly (i.e. try semantics).
- *
- * when timeout is set to 'osWaitForever' the function will wait for an infinite
- * time until the message is retrieved (i.e. wait semantics).
- *
- * all other values specify a time in kernel ticks for a timeout
- * (i.e. timed-wait semantics).
- *
- * Returns : osOK the message has been retrieved from the queue.
- * osErrorTimeout the message could not be retrieved from the queue in the given time
- * (timed-wait semantics).
- * osErrorResource nothing to get from the queue (try semantics).
- * osErrorParameter parameter 'mq_id' is NULL or invalid, non-zero timeout specified in an ISR.
- ****************************************************************************************************
- */
- osStatus_t osMessageQueueGet(osMessageQueueId_t mq_id,
- void *msg_ptr,
- uint8_t *msg_prio,
- uint32_t timeout)
- {
- #if (OS_CFG_SEM_EN == DEF_ENABLED)
- osMessageQueue_t *p_msgqueue;
- CPU_TS ts;
- OS_ERR err;
- uint32_t msg_id, msg_size;
- CORE_DECLARE_IRQ_STATE;
- (void) msg_prio;
- p_msgqueue = (osMessageQueue_t *)mq_id;
- if (p_msgqueue == (osMessageQueue_t *)0) {
- return osErrorParameter;
- }
- if (timeout == 0u) {
- OSSemPend(&p_msgqueue->sem_get, (OS_TICK)0u, OS_OPT_PEND_NON_BLOCKING, &ts, &err);
- } else {
- if (CORE_InIrqContext() == true) {
- return osErrorParameter;
- } else {
- OSSemPend(&p_msgqueue->sem_get, (OS_TICK)timeout, OS_OPT_PEND_BLOCKING, &ts, &err);
- }
- }
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- break;
- case OS_ERR_TIMEOUT:
- return osErrorTimeout;
- default:
- return osErrorResource;
- }
- CORE_ENTER_ATOMIC();
- msg_id = p_msgqueue->msg_tail;
- msg_size = p_msgqueue->msg_size;
- p_msgqueue->msg_tail = (p_msgqueue->msg_tail + 1) % p_msgqueue->msg_count;
- memcpy(msg_ptr, &p_msgqueue->buf[msg_id * msg_size], msg_size);
- p_msgqueue->msg_queued--;
- if (msg_prio != NULL) {
- *msg_prio = 0;
- }
- CORE_EXIT_ATOMIC();
- OSSemPost(&p_msgqueue->sem_put, OS_OPT_POST_1, &err);
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- return osOK;
- default:
- return osErrorResource;
- }
- #else
- (void)mq_id;
- (void)msg_ptr;
- (void)msg_prio;
- (void)timeout;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, osError);
- return osError;
- #endif
- }
- /*
- ****************************************************************************************************
- * osMessageQueueGetCapacity()
- *
- * Description: The function 'osMessageQueueGetCapacity()' returns the maximum number of messages in
- * the message queue object specified by parameter 'mq_id' or 0 in case of an error.
- *
- * Arguments : mq_id is the message queue ID returned by 'osMessageQueueNew()'
- *
- * Returns : The maximum number of messages
- * 0 upon error
- ****************************************************************************************************
- */
- uint32_t osMessageQueueGetCapacity(osMessageQueueId_t mq_id)
- {
- #if (OS_CFG_SEM_EN == DEF_ENABLED)
- osMessageQueue_t *p_msgqueue;
- p_msgqueue = (osMessageQueue_t *)mq_id;
- if (p_msgqueue == (osMessageQueue_t *)0) {
- return 0;
- }
- return p_msgqueue->msg_count;
- #else
- (void)mq_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, 0);
- return 0;
- #endif
- }
- /*
- ****************************************************************************************************
- * osMessageQueueGetMsgSize()
- *
- * Description: The function 'osMessageQueueGetMsgSize()' returns the maximum message size in bytes
- * for the message queue object specified by parameter 'mq_id' or 0 in case of an error.
- *
- * Arguments : mq_id is the message queue ID returned by 'osMessageQueueNew()'
- *
- * Returns : The maximum message size (in bytes)
- * 0 upon error
- ****************************************************************************************************
- */
- uint32_t osMessageQueueGetMsgSize(osMessageQueueId_t mq_id)
- {
- #if (OS_CFG_SEM_EN == DEF_ENABLED)
- osMessageQueue_t *p_msgqueue;
- p_msgqueue = (osMessageQueue_t *)mq_id;
- if (p_msgqueue == (osMessageQueue_t *)0) {
- return 0;
- }
- return p_msgqueue->msg_size;
- #else
- (void)mq_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, 0);
- return 0;
- #endif
- }
- /*
- ****************************************************************************************************
- * osMessageQueueGetCount()
- *
- * Description: The function 'osMessageQueueGetCount()' returns the number of queued messages in the
- * message queue object specified by parameter 'mq_id' or 0 in case of an error.
- *
- * Arguments : mq_id is the message queue ID returned by 'osMessageQueueNew()'
- *
- * Returns : The number of messages in the queue
- * 0 upon error
- ****************************************************************************************************
- */
- uint32_t osMessageQueueGetCount(osMessageQueueId_t mq_id)
- {
- #if (OS_CFG_SEM_EN == DEF_ENABLED)
- osMessageQueue_t *p_msgqueue;
- p_msgqueue = (osMessageQueue_t *)mq_id;
- if (p_msgqueue == (osMessageQueue_t *)0) {
- return 0;
- }
- return p_msgqueue->msg_queued;
- #else
- (void)mq_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, 0);
- return 0;
- #endif
- }
- /*
- ****************************************************************************************************
- * osMessageQueueGetSpace()
- *
- * Description: The function 'osMessageQueueGetSpace()' returns the number available slots for messages
- * in the message queue object specified by parameter 'mq_id' or 0 in case of an error.
- *
- * Arguments : mq_id is the message queue ID returned by 'osMessageQueueNew()'
- *
- * Returns : The number of available slots in the queue
- * 0 upon error
- ****************************************************************************************************
- */
- uint32_t osMessageQueueGetSpace(osMessageQueueId_t mq_id)
- {
- #if (OS_CFG_SEM_EN == DEF_ENABLED)
- osMessageQueue_t *p_msgqueue;
- p_msgqueue = (osMessageQueue_t *)mq_id;
- if (p_msgqueue == (osMessageQueue_t *)0) {
- return 0;
- }
- return p_msgqueue->msg_count - p_msgqueue->msg_queued;
- #else
- (void)mq_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, 0);
- return 0;
- #endif
- }
- /*
- ****************************************************************************************************
- * osMessageQueueReset()
- *
- * Description: The function 'osMessageQueueReset()' resets the message queue specified by the parameter
- * 'mq_id'.
- *
- * Arguments : mq_id is the message queue ID returned by 'osMessageQueueNew()'
- *
- * Returns : osOK the queue has been reset
- * osErrorParameter parameter 'mq_id' is NULL or invalid.
- * osErrorResource the message queue is in an invalid state.
- * osErrorISR 'osMessageQueueReset()' cannot be called from interrupt service routines.
- ****************************************************************************************************
- */
- osStatus_t osMessageQueueReset(osMessageQueueId_t mq_id)
- {
- #if (OS_CFG_SEM_EN == DEF_ENABLED)
- osMessageQueue_t *p_msgqueue;
- CPU_TS ts;
- OS_ERR err;
- CORE_DECLARE_IRQ_STATE;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- p_msgqueue = (osMessageQueue_t *)mq_id;
- if (p_msgqueue == (osMessageQueue_t *)0) {
- return osErrorParameter;
- }
- while (p_msgqueue->msg_queued != 0) {
- OSSemPend(&p_msgqueue->sem_get, (OS_TICK)0u, OS_OPT_PEND_BLOCKING, &ts, &err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- break;
- }
- CORE_ENTER_ATOMIC();
- p_msgqueue->msg_queued--;
- p_msgqueue->msg_tail = (p_msgqueue->msg_tail + 1) % p_msgqueue->msg_count;
- CORE_EXIT_ATOMIC();
- OSSemPost(&p_msgqueue->sem_put, OS_OPT_POST_1, &err);
- if (RTOS_ERR_CODE_GET(err) != OS_ERR_NONE) {
- break;
- }
- }
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- return osOK;
- default:
- return osErrorResource;
- }
- #else
- (void)mq_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, osError);
- return osError;
- #endif
- }
- /*
- ****************************************************************************************************
- * osMessageQueueDelete()
- *
- * Description: The function 'osMessageQueueDelete() deletes a message queue object specified by
- * parameter 'mq_id'. It releases internal memory obtained for message queue handling.
- *
- * After this call, the 'mq_id' is no longer valid and cannot be used.
- *
- * The message queue may be created again using the function 'osMessageQueueNew()'.
- *
- * Arguments : mq_id is the message queue ID returned by 'osMessageQueueNew()'
- *
- * Returns : osOK the message queue object has been deleted.
- * osErrorParameter parameter 'mq_id' is NULL or invalid.
- * osErrorResource the message queue is in an invalid state.
- * osErrorISR 'osMessageQueueDelete()' cannot be called from interrupt service routines.
- ****************************************************************************************************
- */
- osStatus_t osMessageQueueDelete(osMessageQueueId_t mq_id)
- {
- #if (OS_CFG_SEM_EN == DEF_ENABLED)
- osMessageQueue_t *p_msgqueue;
- OS_ERR err;
- if (CORE_InIrqContext() == true) {
- return osErrorISR;
- }
- p_msgqueue = (osMessageQueue_t *)mq_id;
- if (p_msgqueue == (osMessageQueue_t *)0) {
- return osErrorParameter;
- }
- OSSemDel(&p_msgqueue->sem_put, OS_OPT_DEL_ALWAYS, &err);
- OSSemDel(&p_msgqueue->sem_get, OS_OPT_DEL_ALWAYS, &err);
- switch (RTOS_ERR_CODE_GET(err)) {
- case OS_ERR_NONE:
- if (p_msgqueue->buf_dyn_alloc == DEF_TRUE) {
- free(p_msgqueue->buf);
- }
- if (p_msgqueue->obj_dyn_alloc == DEF_TRUE) {
- free(p_msgqueue);
- }
- return osOK;
- default:
- return osErrorResource;
- }
- #else
- (void)mq_id;
- RTOS_ASSERT_CRITICAL(DEF_FALSE, RTOS_ERR_NOT_SUPPORTED, osError);
- return osError;
- #endif
- }
|