| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319 | 
							- /*
 
-     FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
 
-     All rights reserved
 
-     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 
-     This file is part of the FreeRTOS distribution.
 
-     FreeRTOS is free software; you can redistribute it and/or modify it under
 
-     the terms of the GNU General Public License (version 2) as published by the
 
-     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
 
- 	***************************************************************************
 
-     >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 
-     >>!   distribute a combined work that includes FreeRTOS without being   !<<
 
-     >>!   obliged to provide the source code for proprietary components     !<<
 
-     >>!   outside of the FreeRTOS kernel.                                   !<<
 
- 	***************************************************************************
 
-     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 
-     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
-     FOR A PARTICULAR PURPOSE.  Full license text is available on the following
 
-     link: http://www.freertos.org/a00114.html
 
-     ***************************************************************************
 
-      *                                                                       *
 
-      *    FreeRTOS provides completely free yet professionally developed,    *
 
-      *    robust, strictly quality controlled, supported, and cross          *
 
-      *    platform software that is more than just the market leader, it     *
 
-      *    is the industry's de facto standard.                               *
 
-      *                                                                       *
 
-      *    Help yourself get started quickly while simultaneously helping     *
 
-      *    to support the FreeRTOS project by purchasing a FreeRTOS           *
 
-      *    tutorial book, reference manual, or both:                          *
 
-      *    http://www.FreeRTOS.org/Documentation                              *
 
-      *                                                                       *
 
-     ***************************************************************************
 
-     http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
 
- 	the FAQ page "My application does not run, what could be wrong?".  Have you
 
- 	defined configASSERT()?
 
- 	http://www.FreeRTOS.org/support - In return for receiving this top quality
 
- 	embedded software for free we request you assist our global community by
 
- 	participating in the support forum.
 
- 	http://www.FreeRTOS.org/training - Investing in training allows your team to
 
- 	be as productive as possible as early as possible.  Now you can receive
 
- 	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
 
- 	Ltd, and the world's leading authority on the world's leading RTOS.
 
-     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 
-     including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 
-     compatible FAT file system, and our tiny thread aware UDP/IP stack.
 
-     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
 
-     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
 
-     http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
 
-     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
 
-     licenses offer ticketed support, indemnification and commercial middleware.
 
-     http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 
-     engineered and independently SIL3 certified version for use in safety and
 
-     mission critical applications that require provable dependability.
 
-     1 tab == 4 spaces!
 
- */
 
- /* Standard includes. */
 
- #include <stdlib.h>
 
- #include <string.h>
 
- /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
 
- all the API functions to use the MPU wrappers.  That should only be done when
 
- task.h is included from an application file. */
 
- #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 
- /* FreeRTOS includes. */
 
- #include "FreeRTOS.h"
 
- #include "task.h"
 
- #include "fr_timers.h"
 
- #include "StackMacros.h"
 
- /* Lint e961 and e750 are suppressed as a MISRA exception justified because the
 
- MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
 
- header files above, but not in this file, in order to generate the correct
 
- privileged Vs unprivileged linkage and placement. */
 
- #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
 
- /* Set configUSE_STATS_FORMATTING_FUNCTIONS to 2 to include the stats formatting
 
- functions but without including stdio.h here. */
 
- #if ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 )
 
- 	/* At the bottom of this file are two optional functions that can be used
 
- 	to generate human readable text from the raw data generated by the
 
- 	uxTaskGetSystemState() function.  Note the formatting functions are provided
 
- 	for convenience only, and are NOT considered part of the kernel. */
 
- 	#include <stdio.h>
 
- #endif /* configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) */
 
- /* Sanity check the configuration. */
 
- #if configUSE_TICKLESS_IDLE != 0
 
- 	#if INCLUDE_vTaskSuspend != 1
 
- 		#error INCLUDE_vTaskSuspend must be set to 1 if configUSE_TICKLESS_IDLE is not set to 0
 
- 	#endif /* INCLUDE_vTaskSuspend */
 
- #endif /* configUSE_TICKLESS_IDLE */
 
- /*
 
-  * Defines the size, in words, of the stack allocated to the idle task.
 
-  */
 
- #define tskIDLE_STACK_SIZE	configMINIMAL_STACK_SIZE
 
- #if( configUSE_PREEMPTION == 0 )
 
- 	/* If the cooperative scheduler is being used then a yield should not be
 
- 	performed just because a higher priority task has been woken. */
 
- 	#define taskYIELD_IF_USING_PREEMPTION()
 
- #else
 
- 	#define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API()
 
- #endif
 
- /* Value that can be assigned to the eNotifyState member of the TCB. */
 
- typedef enum
 
- {
 
- 	eNotWaitingNotification = 0,
 
- 	eWaitingNotification,
 
- 	eNotified
 
- } eNotifyValue;
 
- /*
 
-  * Task control block.  A task control block (TCB) is allocated for each task,
 
-  * and stores task state information, including a pointer to the task's context
 
-  * (the task's run time environment, including register values)
 
-  */
 
- typedef struct tskTaskControlBlock
 
- {
 
- 	volatile StackType_t	*pxTopOfStack;	/*< Points to the location of the last item placed on the tasks stack.  THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */
 
- 	#if ( portUSING_MPU_WRAPPERS == 1 )
 
- 		xMPU_SETTINGS	xMPUSettings;		/*< The MPU settings are defined as part of the port layer.  THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */
 
- 		BaseType_t		xUsingStaticallyAllocatedStack; /* Set to pdTRUE if the stack is a statically allocated array, and pdFALSE if the stack is dynamically allocated. */
 
- 	#endif
 
- 	ListItem_t			xGenericListItem;	/*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */
 
- 	ListItem_t			xEventListItem;		/*< Used to reference a task from an event list. */
 
- 	UBaseType_t			uxPriority;			/*< The priority of the task.  0 is the lowest priority. */
 
- 	StackType_t			*pxStack;			/*< Points to the start of the stack. */
 
- 	char				pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created.  Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
 
- 	#if ( portSTACK_GROWTH > 0 )
 
- 		StackType_t		*pxEndOfStack;		/*< Points to the end of the stack on architectures where the stack grows up from low memory. */
 
- 	#endif
 
- 	#if ( portCRITICAL_NESTING_IN_TCB == 1 )
 
- 		UBaseType_t 	uxCriticalNesting; 	/*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */
 
- 	#endif
 
- 	#if ( configUSE_TRACE_FACILITY == 1 )
 
- 		UBaseType_t		uxTCBNumber;		/*< Stores a number that increments each time a TCB is created.  It allows debuggers to determine when a task has been deleted and then recreated. */
 
- 		UBaseType_t  	uxTaskNumber;		/*< Stores a number specifically for use by third party trace code. */
 
- 	#endif
 
- 	#if ( configUSE_MUTEXES == 1 )
 
- 		UBaseType_t 	uxBasePriority;		/*< The priority last assigned to the task - used by the priority inheritance mechanism. */
 
- 		UBaseType_t 	uxMutexesHeld;
 
- 	#endif
 
- 	#if ( configUSE_APPLICATION_TASK_TAG == 1 )
 
- 		TaskHookFunction_t pxTaskTag;
 
- 	#endif
 
- 	#if ( configGENERATE_RUN_TIME_STATS == 1 )
 
- 		uint32_t		ulRunTimeCounter;	/*< Stores the amount of time the task has spent in the Running state. */
 
- 	#endif
 
- 	#if ( configUSE_NEWLIB_REENTRANT == 1 )
 
- 		/* Allocate a Newlib reent structure that is specific to this task.
 
- 		Note Newlib support has been included by popular demand, but is not
 
- 		used by the FreeRTOS maintainers themselves.  FreeRTOS is not
 
- 		responsible for resulting newlib operation.  User must be familiar with
 
- 		newlib and must provide system-wide implementations of the necessary
 
- 		stubs. Be warned that (at the time of writing) the current newlib design
 
- 		implements a system-wide malloc() that must be provided with locks. */
 
- 		struct 	_reent xNewLib_reent;
 
- 	#endif
 
- 	#if ( configUSE_TASK_NOTIFICATIONS == 1 )
 
- 		volatile uint32_t ulNotifiedValue;
 
- 		volatile eNotifyValue eNotifyState;
 
- 	#endif
 
- } tskTCB;
 
- /* The old tskTCB name is maintained above then typedefed to the new TCB_t name
 
- below to enable the use of older kernel aware debuggers. */
 
- typedef tskTCB TCB_t;
 
- /*
 
-  * Some kernel aware debuggers require the data the debugger needs access to to
 
-  * be global, rather than file scope.
 
-  */
 
- #ifdef portREMOVE_STATIC_QUALIFIER
 
- 	#define static
 
- #endif
 
- /*lint -e956 A manual analysis and inspection has been used to determine which
 
- static variables must be declared volatile. */
 
- PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL;
 
- /* Lists for ready and blocked tasks. --------------------*/
 
- PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ];/*< Prioritised ready tasks. */
 
- PRIVILEGED_DATA static List_t xDelayedTaskList1;						/*< Delayed tasks. */
 
- PRIVILEGED_DATA static List_t xDelayedTaskList2;						/*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */
 
- PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList;				/*< Points to the delayed task list currently being used. */
 
- PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList;		/*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */
 
- PRIVILEGED_DATA static List_t xPendingReadyList;						/*< Tasks that have been readied while the scheduler was suspended.  They will be moved to the ready list when the scheduler is resumed. */
 
- #if ( INCLUDE_vTaskDelete == 1 )
 
- 	PRIVILEGED_DATA static List_t xTasksWaitingTermination;				/*< Tasks that have been deleted - but their memory not yet freed. */
 
- 	PRIVILEGED_DATA static volatile UBaseType_t uxTasksDeleted = ( UBaseType_t ) 0U;
 
- #endif
 
- #if ( INCLUDE_vTaskSuspend == 1 )
 
- 	PRIVILEGED_DATA static List_t xSuspendedTaskList;					/*< Tasks that are currently suspended. */
 
- #endif
 
- #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
 
- 	PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandle = NULL;			/*< Holds the handle of the idle task.  The idle task is created automatically when the scheduler is started. */
 
- #endif
 
- /* Other file private variables. --------------------------------*/
 
- PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks 	= ( UBaseType_t ) 0U;
 
- PRIVILEGED_DATA static volatile TickType_t xTickCount 				= ( TickType_t ) 0U;
 
- PRIVILEGED_DATA static volatile UBaseType_t uxTopReadyPriority 		= tskIDLE_PRIORITY;
 
- PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning 		= pdFALSE;
 
- PRIVILEGED_DATA static volatile UBaseType_t uxPendedTicks 			= ( UBaseType_t ) 0U;
 
- PRIVILEGED_DATA static volatile BaseType_t xYieldPending 			= pdFALSE;
 
- PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows 			= ( BaseType_t ) 0;
 
- PRIVILEGED_DATA static UBaseType_t uxTaskNumber 					= ( UBaseType_t ) 0U;
 
- PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime		= portMAX_DELAY;
 
- /* Context switches are held pending while the scheduler is suspended.  Also,
 
- interrupts must not manipulate the xGenericListItem of a TCB, or any of the
 
- lists the xGenericListItem can be referenced from, if the scheduler is suspended.
 
- If an interrupt needs to unblock a task while the scheduler is suspended then it
 
- moves the task's event list item into the xPendingReadyList, ready for the
 
- kernel to move the task from the pending ready list into the real ready list
 
- when the scheduler is unsuspended.  The pending ready list itself can only be
 
- accessed from a critical section. */
 
- PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended	= ( UBaseType_t ) pdFALSE;
 
- #if ( configGENERATE_RUN_TIME_STATS == 1 )
 
- 	PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime = 0UL;	/*< Holds the value of a timer/counter the last time a task was switched in. */
 
- 	PRIVILEGED_DATA static uint32_t ulTotalRunTime = 0UL;		/*< Holds the total amount of execution time as defined by the run time counter clock. */
 
- #endif
 
- /*lint +e956 */
 
- /* Debugging and trace facilities private variables and macros. ------------*/
 
- /*
 
-  * The value used to fill the stack of a task when the task is created.  This
 
-  * is used purely for checking the high water mark for tasks.
 
-  */
 
- #define tskSTACK_FILL_BYTE	( 0xa5U )
 
- /*
 
-  * Macros used by vListTask to indicate which state a task is in.
 
-  */
 
- #define tskBLOCKED_CHAR		( 'B' )
 
- #define tskREADY_CHAR		( 'R' )
 
- #define tskDELETED_CHAR		( 'D' )
 
- #define tskSUSPENDED_CHAR	( 'S' )
 
- /*-----------------------------------------------------------*/
 
- #if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 )
 
- 	/* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is
 
- 	performed in a generic way that is not optimised to any particular
 
- 	microcontroller architecture. */
 
- 	/* uxTopReadyPriority holds the priority of the highest priority ready
 
- 	state task. */
 
- 	#define taskRECORD_READY_PRIORITY( uxPriority )														\
 
- 	{																									\
 
- 		if( ( uxPriority ) > uxTopReadyPriority )														\
 
- 		{																								\
 
- 			uxTopReadyPriority = ( uxPriority );														\
 
- 		}																								\
 
- 	} /* taskRECORD_READY_PRIORITY */
 
- 	/*-----------------------------------------------------------*/
 
- 	#define taskSELECT_HIGHEST_PRIORITY_TASK()															\
 
- 	{																									\
 
- 		/* Find the highest priority queue that contains ready tasks. */								\
 
- 		while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )						\
 
- 		{																								\
 
- 			configASSERT( uxTopReadyPriority );															\
 
- 			--uxTopReadyPriority;																		\
 
- 		}																								\
 
- 																										\
 
- 		/* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of						\
 
- 		the	same priority get an equal share of the processor time. */									\
 
- 		listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) );		\
 
- 	} /* taskSELECT_HIGHEST_PRIORITY_TASK */
 
- 	/*-----------------------------------------------------------*/
 
- 	/* Define away taskRESET_READY_PRIORITY() and portRESET_READY_PRIORITY() as
 
- 	they are only required when a port optimised method of task selection is
 
- 	being used. */
 
- 	#define taskRESET_READY_PRIORITY( uxPriority )
 
- 	#define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority )
 
- #else /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
 
- 	/* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 1 then task selection is
 
- 	performed in a way that is tailored to the particular microcontroller
 
- 	architecture being used. */
 
- 	/* A port optimised version is provided.  Call the port defined macros. */
 
- 	#define taskRECORD_READY_PRIORITY( uxPriority )	portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority )
 
- 	/*-----------------------------------------------------------*/
 
- 	#define taskSELECT_HIGHEST_PRIORITY_TASK()														\
 
- 	{																								\
 
- 	UBaseType_t uxTopPriority;																		\
 
- 																									\
 
- 		/* Find the highest priority queue that contains ready tasks. */							\
 
- 		portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority );								\
 
- 		configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 );		\
 
- 		listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) );		\
 
- 	} /* taskSELECT_HIGHEST_PRIORITY_TASK() */
 
- 	/*-----------------------------------------------------------*/
 
- 	/* A port optimised version is provided, call it only if the TCB being reset
 
- 	is being referenced from a ready list.  If it is referenced from a delayed
 
- 	or suspended list then it won't be in a ready list. */
 
- 	#define taskRESET_READY_PRIORITY( uxPriority )														\
 
- 	{																									\
 
- 		if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == ( UBaseType_t ) 0 )	\
 
- 		{																								\
 
- 			portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) );							\
 
- 		}																								\
 
- 	}
 
- #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
 
- /*-----------------------------------------------------------*/
 
- /* pxDelayedTaskList and pxOverflowDelayedTaskList are switched when the tick
 
- count overflows. */
 
- #define taskSWITCH_DELAYED_LISTS()																	\
 
- {																									\
 
- 	List_t *pxTemp;																					\
 
- 																									\
 
- 	/* The delayed tasks list should be empty when the lists are switched. */						\
 
- 	configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) );										\
 
- 																									\
 
- 	pxTemp = pxDelayedTaskList;																		\
 
- 	pxDelayedTaskList = pxOverflowDelayedTaskList;													\
 
- 	pxOverflowDelayedTaskList = pxTemp;																\
 
- 	xNumOfOverflows++;																				\
 
- 	prvResetNextTaskUnblockTime();																	\
 
- }
 
- /*-----------------------------------------------------------*/
 
- /*
 
-  * Place the task represented by pxTCB into the appropriate ready list for
 
-  * the task.  It is inserted at the end of the list.
 
-  */
 
- #define prvAddTaskToReadyList( pxTCB )																\
 
- 	traceMOVED_TASK_TO_READY_STATE( pxTCB )															\
 
- 	taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority );												\
 
- 	vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) )
 
- /*-----------------------------------------------------------*/
 
- /*
 
-  * Several functions take an TaskHandle_t parameter that can optionally be NULL,
 
-  * where NULL is used to indicate that the handle of the currently executing
 
-  * task should be used in place of the parameter.  This macro simply checks to
 
-  * see if the parameter is NULL and returns a pointer to the appropriate TCB.
 
-  */
 
- #define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? ( TCB_t * ) pxCurrentTCB : ( TCB_t * ) ( pxHandle ) )
 
- /* The item value of the event list item is normally used to hold the priority
 
- of the task to which it belongs (coded to allow it to be held in reverse
 
- priority order).  However, it is occasionally borrowed for other purposes.  It
 
- is important its value is not updated due to a task priority change while it is
 
- being used for another purpose.  The following bit definition is used to inform
 
- the scheduler that the value should not be changed - in which case it is the
 
- responsibility of whichever module is using the value to ensure it gets set back
 
- to its original value when it is released. */
 
- #if configUSE_16_BIT_TICKS == 1
 
- 	#define taskEVENT_LIST_ITEM_VALUE_IN_USE	0x8000U
 
- #else
 
- 	#define taskEVENT_LIST_ITEM_VALUE_IN_USE	0x80000000UL
 
- #endif
 
- /* Callback function prototypes. --------------------------*/
 
- #if configCHECK_FOR_STACK_OVERFLOW > 0
 
- 	extern void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName );
 
- #endif
 
- #if configUSE_TICK_HOOK > 0
 
- 	extern void vApplicationTickHook( void );
 
- #endif
 
- /* File private functions. --------------------------------*/
 
- /*
 
-  * Utility to ready a TCB for a given task.  Mainly just copies the parameters
 
-  * into the TCB structure.
 
-  */
 
- static void prvInitialiseTCBVariables( TCB_t * const pxTCB, const char * const pcName, UBaseType_t uxPriority, const MemoryRegion_t * const xRegions, const uint16_t usStackDepth ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
 
- /**
 
-  * Utility task that simply returns pdTRUE if the task referenced by xTask is
 
-  * currently in the Suspended state, or pdFALSE if the task referenced by xTask
 
-  * is in any other state.
 
-  */
 
- #if ( INCLUDE_vTaskSuspend == 1 )
 
- 	static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
 
- #endif /* INCLUDE_vTaskSuspend */
 
- /*
 
-  * Utility to ready all the lists used by the scheduler.  This is called
 
-  * automatically upon the creation of the first task.
 
-  */
 
- static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION;
 
- /*
 
-  * The idle task, which as all tasks is implemented as a never ending loop.
 
-  * The idle task is automatically created and added to the ready lists upon
 
-  * creation of the first user task.
 
-  *
 
-  * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific
 
-  * language extensions.  The equivalent prototype for this function is:
 
-  *
 
-  * void prvIdleTask( void *pvParameters );
 
-  *
 
-  */
 
- static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters );
 
- /*
 
-  * Utility to free all memory allocated by the scheduler to hold a TCB,
 
-  * including the stack pointed to by the TCB.
 
-  *
 
-  * This does not free memory allocated by the task itself (i.e. memory
 
-  * allocated by calls to pvPortMalloc from within the tasks application code).
 
-  */
 
- #if ( INCLUDE_vTaskDelete == 1 )
 
- 	static void prvDeleteTCB( TCB_t *pxTCB ) PRIVILEGED_FUNCTION;
 
- #endif
 
- /*
 
-  * Used only by the idle task.  This checks to see if anything has been placed
 
-  * in the list of tasks waiting to be deleted.  If so the task is cleaned up
 
-  * and its TCB deleted.
 
-  */
 
- static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION;
 
- /*
 
-  * The currently executing task is entering the Blocked state.  Add the task to
 
-  * either the current or the overflow delayed task list.
 
-  */
 
- static void prvAddCurrentTaskToDelayedList( const TickType_t xTimeToWake ) PRIVILEGED_FUNCTION;
 
- /*
 
-  * Allocates memory from the heap for a TCB and associated stack.  Checks the
 
-  * allocation was successful.
 
-  */
 
- static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer ) PRIVILEGED_FUNCTION;
 
- /*
 
-  * Fills an TaskStatus_t structure with information on each task that is
 
-  * referenced from the pxList list (which may be a ready list, a delayed list,
 
-  * a suspended list, etc.).
 
-  *
 
-  * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM
 
-  * NORMAL APPLICATION CODE.
 
-  */
 
- #if ( configUSE_TRACE_FACILITY == 1 )
 
- 	static UBaseType_t prvListTaskWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState ) PRIVILEGED_FUNCTION;
 
- #endif
 
- /*
 
-  * When a task is created, the stack of the task is filled with a known value.
 
-  * This function determines the 'high water mark' of the task stack by
 
-  * determining how much of the stack remains at the original preset value.
 
-  */
 
- #if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
 
- 	static uint16_t prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) PRIVILEGED_FUNCTION;
 
- #endif
 
- /*
 
-  * Return the amount of time, in ticks, that will pass before the kernel will
 
-  * next move a task from the Blocked state to the Running state.
 
-  *
 
-  * This conditional compilation should use inequality to 0, not equality to 1.
 
-  * This is to ensure portSUPPRESS_TICKS_AND_SLEEP() can be called when user
 
-  * defined low power mode implementations require configUSE_TICKLESS_IDLE to be
 
-  * set to a value other than 1.
 
-  */
 
- #if ( configUSE_TICKLESS_IDLE != 0 )
 
- 	static TickType_t prvGetExpectedIdleTime( void ) PRIVILEGED_FUNCTION;
 
- #endif
 
- /*
 
-  * Set xNextTaskUnblockTime to the time at which the next Blocked state task
 
-  * will exit the Blocked state.
 
-  */
 
- static void prvResetNextTaskUnblockTime( void );
 
- #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
 
- 	/*
 
- 	 * Helper function used to pad task names with spaces when printing out
 
- 	 * human readable tables of task information.
 
- 	 */
 
- 	static char *prvWriteNameToBuffer( char *pcBuffer, const char *pcTaskName );
 
- #endif
 
- /*-----------------------------------------------------------*/
 
- BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
 
- {
 
- BaseType_t xReturn;
 
- TCB_t * pxNewTCB;
 
- StackType_t *pxTopOfStack;
 
- 	configASSERT( pxTaskCode );
 
- 	configASSERT( ( ( uxPriority & ( ~portPRIVILEGE_BIT ) ) < configMAX_PRIORITIES ) );
 
- 	/* Allocate the memory required by the TCB and stack for the new task,
 
- 	checking that the allocation was successful. */
 
- 	pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer );
 
- 	if( pxNewTCB != NULL )
 
- 	{
 
- 		#if( portUSING_MPU_WRAPPERS == 1 )
 
- 			/* Should the task be created in privileged mode? */
 
- 			BaseType_t xRunPrivileged;
 
- 			if( ( uxPriority & portPRIVILEGE_BIT ) != 0U )
 
- 			{
 
- 				xRunPrivileged = pdTRUE;
 
- 			}
 
- 			else
 
- 			{
 
- 				xRunPrivileged = pdFALSE;
 
- 			}
 
- 			uxPriority &= ~portPRIVILEGE_BIT;
 
- 			if( puxStackBuffer != NULL )
 
- 			{
 
- 				/* The application provided its own stack.  Note this so no
 
- 				attempt is made to delete the stack should that task be
 
- 				deleted. */
 
- 				pxNewTCB->xUsingStaticallyAllocatedStack = pdTRUE;
 
- 			}
 
- 			else
 
- 			{
 
- 				/* The stack was allocated dynamically.  Note this so it can be
 
- 				deleted again if the task is deleted. */
 
- 				pxNewTCB->xUsingStaticallyAllocatedStack = pdFALSE;
 
- 			}
 
- 		#endif /* portUSING_MPU_WRAPPERS == 1 */
 
- 		/* Calculate the top of stack address.  This depends on whether the
 
- 		stack grows from high memory to low (as per the 80x86) or vice versa.
 
- 		portSTACK_GROWTH is used to make the result positive or negative as
 
- 		required by the port. */
 
- 		#if( portSTACK_GROWTH < 0 )
 
- 		{
 
- 			pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - ( uint16_t ) 1 );
 
- 			pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK  ) ); /*lint !e923 MISRA exception.  Avoiding casts between pointers and integers is not practical.  Size differences accounted for using portPOINTER_SIZE_TYPE type. */
 
- 			/* Check the alignment of the calculated top of stack is correct. */
 
- 			configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
 
- 		}
 
- 		#else /* portSTACK_GROWTH */
 
- 		{
 
- 			pxTopOfStack = pxNewTCB->pxStack;
 
- 			/* Check the alignment of the stack buffer is correct. */
 
- 			configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxNewTCB->pxStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
 
- 			/* If we want to use stack checking on architectures that use
 
- 			a positive stack growth direction then we also need to store the
 
- 			other extreme of the stack space. */
 
- 			pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );
 
- 		}
 
- 		#endif /* portSTACK_GROWTH */
 
- 		/* Setup the newly allocated TCB with the initial state of the task. */
 
- 		prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority, xRegions, usStackDepth );
 
- 		/* Initialize the TCB stack to look as if the task was already running,
 
- 		but had been interrupted by the scheduler.  The return address is set
 
- 		to the start of the task function. Once the stack has been initialised
 
- 		the	top of stack variable is updated. */
 
- 		#if( portUSING_MPU_WRAPPERS == 1 )
 
- 		{
 
- 			pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged );
 
- 		}
 
- 		#else /* portUSING_MPU_WRAPPERS */
 
- 		{
 
- 			pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );
 
- 		}
 
- 		#endif /* portUSING_MPU_WRAPPERS */
 
- 		if( ( void * ) pxCreatedTask != NULL )
 
- 		{
 
- 			/* Pass the TCB out - in an anonymous way.  The calling function/
 
- 			task can use this as a handle to delete the task later if
 
- 			required.*/
 
- 			*pxCreatedTask = ( TaskHandle_t ) pxNewTCB;
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 		/* Ensure interrupts don't access the task lists while they are being
 
- 		updated. */
 
- 		taskENTER_CRITICAL();
 
- 		{
 
- 			uxCurrentNumberOfTasks++;
 
- 			if( pxCurrentTCB == NULL )
 
- 			{
 
- 				/* There are no other tasks, or all the other tasks are in
 
- 				the suspended state - make this the current task. */
 
- 				pxCurrentTCB =  pxNewTCB;
 
- 				if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 )
 
- 				{
 
- 					/* This is the first task to be created so do the preliminary
 
- 					initialisation required.  We will not recover if this call
 
- 					fails, but we will report the failure. */
 
- 					prvInitialiseTaskLists();
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 			}
 
- 			else
 
- 			{
 
- 				/* If the scheduler is not already running, make this task the
 
- 				current task if it is the highest priority task to be created
 
- 				so far. */
 
- 				if( xSchedulerRunning == pdFALSE )
 
- 				{
 
- 					if( pxCurrentTCB->uxPriority <= uxPriority )
 
- 					{
 
- 						pxCurrentTCB = pxNewTCB;
 
- 					}
 
- 					else
 
- 					{
 
- 						mtCOVERAGE_TEST_MARKER();
 
- 					}
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 			}
 
- 			uxTaskNumber++;
 
- 			#if ( configUSE_TRACE_FACILITY == 1 )
 
- 			{
 
- 				/* Add a counter into the TCB for tracing only. */
 
- 				pxNewTCB->uxTCBNumber = uxTaskNumber;
 
- 			}
 
- 			#endif /* configUSE_TRACE_FACILITY */
 
- 			traceTASK_CREATE( pxNewTCB );
 
- 			prvAddTaskToReadyList( pxNewTCB );
 
- 			xReturn = pdPASS;
 
- 			portSETUP_TCB( pxNewTCB );
 
- 		}
 
- 		taskEXIT_CRITICAL();
 
- 	}
 
- 	else
 
- 	{
 
- 		xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
 
- 		traceTASK_CREATE_FAILED();
 
- 	}
 
- 	if( xReturn == pdPASS )
 
- 	{
 
- 		if( xSchedulerRunning != pdFALSE )
 
- 		{
 
- 			/* If the created task is of a higher priority than the current task
 
- 			then it should run now. */
 
- 			if( pxCurrentTCB->uxPriority < uxPriority )
 
- 			{
 
- 				taskYIELD_IF_USING_PREEMPTION();
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 	}
 
- 	return xReturn;
 
- }
 
- /*-----------------------------------------------------------*/
 
- #if ( INCLUDE_vTaskDelete == 1 )
 
- 	void vTaskDelete( TaskHandle_t xTaskToDelete )
 
- 	{
 
- 	TCB_t *pxTCB;
 
- 		taskENTER_CRITICAL();
 
- 		{
 
- 			/* If null is passed in here then it is the calling task that is
 
- 			being deleted. */
 
- 			pxTCB = prvGetTCBFromHandle( xTaskToDelete );
 
- 			/* Remove task from the ready list and place in the	termination list.
 
- 			This will stop the task from be scheduled.  The idle task will check
 
- 			the termination list and free up any memory allocated by the
 
- 			scheduler for the TCB and stack. */
 
- 			if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
 
- 			{
 
- 				taskRESET_READY_PRIORITY( pxTCB->uxPriority );
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 			/* Is the task waiting on an event also? */
 
- 			if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
 
- 			{
 
- 				( void ) uxListRemove( &( pxTCB->xEventListItem ) );
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 			vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xGenericListItem ) );
 
- 			/* Increment the ucTasksDeleted variable so the idle task knows
 
- 			there is a task that has been deleted and that it should therefore
 
- 			check the xTasksWaitingTermination list. */
 
- 			++uxTasksDeleted;
 
- 			/* Increment the uxTaskNumberVariable also so kernel aware debuggers
 
- 			can detect that the task lists need re-generating. */
 
- 			uxTaskNumber++;
 
- 			traceTASK_DELETE( pxTCB );
 
- 		}
 
- 		taskEXIT_CRITICAL();
 
- 		/* Force a reschedule if it is the currently running task that has just
 
- 		been deleted. */
 
- 		if( xSchedulerRunning != pdFALSE )
 
- 		{
 
- 			if( pxTCB == pxCurrentTCB )
 
- 			{
 
- 				configASSERT( uxSchedulerSuspended == 0 );
 
- 				/* The pre-delete hook is primarily for the Windows simulator,
 
- 				in which Windows specific clean up operations are performed,
 
- 				after which it is not possible to yield away from this task -
 
- 				hence xYieldPending is used to latch that a context switch is
 
- 				required. */
 
- 				portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending );
 
- 				portYIELD_WITHIN_API();
 
- 			}
 
- 			else
 
- 			{
 
- 				/* Reset the next expected unblock time in case it referred to
 
- 				the task that has just been deleted. */
 
- 				taskENTER_CRITICAL();
 
- 				{
 
- 					prvResetNextTaskUnblockTime();
 
- 				}
 
- 				taskEXIT_CRITICAL();
 
- 			}
 
- 		}
 
- 	}
 
- #endif /* INCLUDE_vTaskDelete */
 
- /*-----------------------------------------------------------*/
 
- #if ( INCLUDE_vTaskDelayUntil == 1 )
 
- 	void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement )
 
- 	{
 
- 	TickType_t xTimeToWake;
 
- 	BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE;
 
- 		configASSERT( pxPreviousWakeTime );
 
- 		configASSERT( ( xTimeIncrement > 0U ) );
 
- 		configASSERT( uxSchedulerSuspended == 0 );
 
- 		vTaskSuspendAll();
 
- 		{
 
- 			/* Minor optimisation.  The tick count cannot change in this
 
- 			block. */
 
- 			const TickType_t xConstTickCount = xTickCount;
 
- 			/* Generate the tick time at which the task wants to wake. */
 
- 			xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;
 
- 			if( xConstTickCount < *pxPreviousWakeTime )
 
- 			{
 
- 				/* The tick count has overflowed since this function was
 
- 				lasted called.  In this case the only time we should ever
 
- 				actually delay is if the wake time has also	overflowed,
 
- 				and the wake time is greater than the tick time.  When this
 
- 				is the case it is as if neither time had overflowed. */
 
- 				if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) )
 
- 				{
 
- 					xShouldDelay = pdTRUE;
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 			}
 
- 			else
 
- 			{
 
- 				/* The tick time has not overflowed.  In this case we will
 
- 				delay if either the wake time has overflowed, and/or the
 
- 				tick time is less than the wake time. */
 
- 				if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) )
 
- 				{
 
- 					xShouldDelay = pdTRUE;
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 			}
 
- 			/* Update the wake time ready for the next call. */
 
- 			*pxPreviousWakeTime = xTimeToWake;
 
- 			if( xShouldDelay != pdFALSE )
 
- 			{
 
- 				traceTASK_DELAY_UNTIL();
 
- 				/* Remove the task from the ready list before adding it to the
 
- 				blocked list as the same list item is used for both lists. */
 
- 				if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
 
- 				{
 
- 					/* The current task must be in a ready list, so there is
 
- 					no need to check, and the port reset macro can be called
 
- 					directly. */
 
- 					portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 				prvAddCurrentTaskToDelayedList( xTimeToWake );
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 		}
 
- 		xAlreadyYielded = xTaskResumeAll();
 
- 		/* Force a reschedule if xTaskResumeAll has not already done so, we may
 
- 		have put ourselves to sleep. */
 
- 		if( xAlreadyYielded == pdFALSE )
 
- 		{
 
- 			portYIELD_WITHIN_API();
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 	}
 
- #endif /* INCLUDE_vTaskDelayUntil */
 
- /*-----------------------------------------------------------*/
 
- #if ( INCLUDE_vTaskDelay == 1 )
 
- 	void vTaskDelay( const TickType_t xTicksToDelay )
 
- 	{
 
- 	TickType_t xTimeToWake;
 
- 	BaseType_t xAlreadyYielded = pdFALSE;
 
- 		/* A delay time of zero just forces a reschedule. */
 
- 		if( xTicksToDelay > ( TickType_t ) 0U )
 
- 		{
 
- 			configASSERT( uxSchedulerSuspended == 0 );
 
- 			vTaskSuspendAll();
 
- 			{
 
- 				traceTASK_DELAY();
 
- 				/* A task that is removed from the event list while the
 
- 				scheduler is suspended will not get placed in the ready
 
- 				list or removed from the blocked list until the scheduler
 
- 				is resumed.
 
- 				This task cannot be in an event list as it is the currently
 
- 				executing task. */
 
- 				/* Calculate the time to wake - this may overflow but this is
 
- 				not a problem. */
 
- 				xTimeToWake = xTickCount + xTicksToDelay;
 
- 				/* We must remove ourselves from the ready list before adding
 
- 				ourselves to the blocked list as the same list item is used for
 
- 				both lists. */
 
- 				if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
 
- 				{
 
- 					/* The current task must be in a ready list, so there is
 
- 					no need to check, and the port reset macro can be called
 
- 					directly. */
 
- 					portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 				prvAddCurrentTaskToDelayedList( xTimeToWake );
 
- 			}
 
- 			xAlreadyYielded = xTaskResumeAll();
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 		/* Force a reschedule if xTaskResumeAll has not already done so, we may
 
- 		have put ourselves to sleep. */
 
- 		if( xAlreadyYielded == pdFALSE )
 
- 		{
 
- 			portYIELD_WITHIN_API();
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 	}
 
- #endif /* INCLUDE_vTaskDelay */
 
- /*-----------------------------------------------------------*/
 
- #if ( INCLUDE_eTaskGetState == 1 )
 
- 	eTaskState eTaskGetState( TaskHandle_t xTask )
 
- 	{
 
- 	eTaskState eReturn;
 
- 	List_t *pxStateList;
 
- 	const TCB_t * const pxTCB = ( TCB_t * ) xTask;
 
- 		configASSERT( pxTCB );
 
- 		if( pxTCB == pxCurrentTCB )
 
- 		{
 
- 			/* The task calling this function is querying its own state. */
 
- 			eReturn = eRunning;
 
- 		}
 
- 		else
 
- 		{
 
- 			taskENTER_CRITICAL();
 
- 			{
 
- 				pxStateList = ( List_t * ) listLIST_ITEM_CONTAINER( &( pxTCB->xGenericListItem ) );
 
- 			}
 
- 			taskEXIT_CRITICAL();
 
- 			if( ( pxStateList == pxDelayedTaskList ) || ( pxStateList == pxOverflowDelayedTaskList ) )
 
- 			{
 
- 				/* The task being queried is referenced from one of the Blocked
 
- 				lists. */
 
- 				eReturn = eBlocked;
 
- 			}
 
- 			#if ( INCLUDE_vTaskSuspend == 1 )
 
- 				else if( pxStateList == &xSuspendedTaskList )
 
- 				{
 
- 					/* The task being queried is referenced from the suspended
 
- 					list.  Is it genuinely suspended or is it block
 
- 					indefinitely? */
 
- 					if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL )
 
- 					{
 
- 						eReturn = eSuspended;
 
- 					}
 
- 					else
 
- 					{
 
- 						eReturn = eBlocked;
 
- 					}
 
- 				}
 
- 			#endif
 
- 			#if ( INCLUDE_vTaskDelete == 1 )
 
- 				else if( pxStateList == &xTasksWaitingTermination )
 
- 				{
 
- 					/* The task being queried is referenced from the deleted
 
- 					tasks list. */
 
- 					eReturn = eDeleted;
 
- 				}
 
- 			#endif
 
- 			else /*lint !e525 Negative indentation is intended to make use of pre-processor clearer. */
 
- 			{
 
- 				/* If the task is not in any other state, it must be in the
 
- 				Ready (including pending ready) state. */
 
- 				eReturn = eReady;
 
- 			}
 
- 		}
 
- 		return eReturn;
 
- 	} /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */
 
- #endif /* INCLUDE_eTaskGetState */
 
- /*-----------------------------------------------------------*/
 
- #if ( INCLUDE_uxTaskPriorityGet == 1 )
 
- 	UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask )
 
- 	{
 
- 	TCB_t *pxTCB;
 
- 	UBaseType_t uxReturn;
 
- 		taskENTER_CRITICAL();
 
- 		{
 
- 			/* If null is passed in here then we are changing the
 
- 			priority of the calling function. */
 
- 			pxTCB = prvGetTCBFromHandle( xTask );
 
- 			uxReturn = pxTCB->uxPriority;
 
- 		}
 
- 		taskEXIT_CRITICAL();
 
- 		return uxReturn;
 
- 	}
 
- #endif /* INCLUDE_uxTaskPriorityGet */
 
- /*-----------------------------------------------------------*/
 
- #if ( INCLUDE_uxTaskPriorityGet == 1 )
 
- 	UBaseType_t uxTaskPriorityGetFromISR( TaskHandle_t xTask )
 
- 	{
 
- 	TCB_t *pxTCB;
 
- 	UBaseType_t uxReturn, uxSavedInterruptState;
 
- 		/* RTOS ports that support interrupt nesting have the concept of a
 
- 		maximum	system call (or maximum API call) interrupt priority.
 
- 		Interrupts that are	above the maximum system call priority are keep
 
- 		permanently enabled, even when the RTOS kernel is in a critical section,
 
- 		but cannot make any calls to FreeRTOS API functions.  If configASSERT()
 
- 		is defined in FreeRTOSConfig.h then
 
- 		portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
 
- 		failure if a FreeRTOS API function is called from an interrupt that has
 
- 		been assigned a priority above the configured maximum system call
 
- 		priority.  Only FreeRTOS functions that end in FromISR can be called
 
- 		from interrupts	that have been assigned a priority at or (logically)
 
- 		below the maximum system call interrupt priority.  FreeRTOS maintains a
 
- 		separate interrupt safe API to ensure interrupt entry is as fast and as
 
- 		simple as possible.  More information (albeit Cortex-M specific) is
 
- 		provided on the following link:
 
- 		http://www.freertos.org/RTOS-Cortex-M3-M4.html */
 
- 		portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
 
- 		uxSavedInterruptState = portSET_INTERRUPT_MASK_FROM_ISR();
 
- 		{
 
- 			/* If null is passed in here then it is the priority of the calling
 
- 			task that is being queried. */
 
- 			pxTCB = prvGetTCBFromHandle( xTask );
 
- 			uxReturn = pxTCB->uxPriority;
 
- 		}
 
- 		portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptState );
 
- 		return uxReturn;
 
- 	}
 
- #endif /* INCLUDE_uxTaskPriorityGet */
 
- /*-----------------------------------------------------------*/
 
- #if ( INCLUDE_vTaskPrioritySet == 1 )
 
- 	void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority )
 
- 	{
 
- 	TCB_t *pxTCB;
 
- 	UBaseType_t uxCurrentBasePriority, uxPriorityUsedOnEntry;
 
- 	BaseType_t xYieldRequired = pdFALSE;
 
- 		configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) );
 
- 		/* Ensure the new priority is valid. */
 
- 		if( uxNewPriority >= ( UBaseType_t ) configMAX_PRIORITIES )
 
- 		{
 
- 			uxNewPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U;
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 		taskENTER_CRITICAL();
 
- 		{
 
- 			/* If null is passed in here then it is the priority of the calling
 
- 			task that is being changed. */
 
- 			pxTCB = prvGetTCBFromHandle( xTask );
 
- 			traceTASK_PRIORITY_SET( pxTCB, uxNewPriority );
 
- 			#if ( configUSE_MUTEXES == 1 )
 
- 			{
 
- 				uxCurrentBasePriority = pxTCB->uxBasePriority;
 
- 			}
 
- 			#else
 
- 			{
 
- 				uxCurrentBasePriority = pxTCB->uxPriority;
 
- 			}
 
- 			#endif
 
- 			if( uxCurrentBasePriority != uxNewPriority )
 
- 			{
 
- 				/* The priority change may have readied a task of higher
 
- 				priority than the calling task. */
 
- 				if( uxNewPriority > uxCurrentBasePriority )
 
- 				{
 
- 					if( pxTCB != pxCurrentTCB )
 
- 					{
 
- 						/* The priority of a task other than the currently
 
- 						running task is being raised.  Is the priority being
 
- 						raised above that of the running task? */
 
- 						if( uxNewPriority >= pxCurrentTCB->uxPriority )
 
- 						{
 
- 							xYieldRequired = pdTRUE;
 
- 						}
 
- 						else
 
- 						{
 
- 							mtCOVERAGE_TEST_MARKER();
 
- 						}
 
- 					}
 
- 					else
 
- 					{
 
- 						/* The priority of the running task is being raised,
 
- 						but the running task must already be the highest
 
- 						priority task able to run so no yield is required. */
 
- 					}
 
- 				}
 
- 				else if( pxTCB == pxCurrentTCB )
 
- 				{
 
- 					/* Setting the priority of the running task down means
 
- 					there may now be another task of higher priority that
 
- 					is ready to execute. */
 
- 					xYieldRequired = pdTRUE;
 
- 				}
 
- 				else
 
- 				{
 
- 					/* Setting the priority of any other task down does not
 
- 					require a yield as the running task must be above the
 
- 					new priority of the task being modified. */
 
- 				}
 
- 				/* Remember the ready list the task might be referenced from
 
- 				before its uxPriority member is changed so the
 
- 				taskRESET_READY_PRIORITY() macro can function correctly. */
 
- 				uxPriorityUsedOnEntry = pxTCB->uxPriority;
 
- 				#if ( configUSE_MUTEXES == 1 )
 
- 				{
 
- 					/* Only change the priority being used if the task is not
 
- 					currently using an inherited priority. */
 
- 					if( pxTCB->uxBasePriority == pxTCB->uxPriority )
 
- 					{
 
- 						pxTCB->uxPriority = uxNewPriority;
 
- 					}
 
- 					else
 
- 					{
 
- 						mtCOVERAGE_TEST_MARKER();
 
- 					}
 
- 					/* The base priority gets set whatever. */
 
- 					pxTCB->uxBasePriority = uxNewPriority;
 
- 				}
 
- 				#else
 
- 				{
 
- 					pxTCB->uxPriority = uxNewPriority;
 
- 				}
 
- 				#endif
 
- 				/* Only reset the event list item value if the value is not
 
- 				being used for anything else. */
 
- 				if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL )
 
- 				{
 
- 					listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxNewPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 				/* If the task is in the blocked or suspended list we need do
 
- 				nothing more than change it's priority variable. However, if
 
- 				the task is in a ready list it needs to be removed and placed
 
- 				in the list appropriate to its new priority. */
 
- 				if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )
 
- 				{
 
- 					/* The task is currently in its ready list - remove before adding
 
- 					it to it's new ready list.  As we are in a critical section we
 
- 					can do this even if the scheduler is suspended. */
 
- 					if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
 
- 					{
 
- 						/* It is known that the task is in its ready list so
 
- 						there is no need to check again and the port level
 
- 						reset macro can be called directly. */
 
- 						portRESET_READY_PRIORITY( uxPriorityUsedOnEntry, uxTopReadyPriority );
 
- 					}
 
- 					else
 
- 					{
 
- 						mtCOVERAGE_TEST_MARKER();
 
- 					}
 
- 					prvAddTaskToReadyList( pxTCB );
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 				if( xYieldRequired == pdTRUE )
 
- 				{
 
- 					taskYIELD_IF_USING_PREEMPTION();
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 				/* Remove compiler warning about unused variables when the port
 
- 				optimised task selection is not being used. */
 
- 				( void ) uxPriorityUsedOnEntry;
 
- 			}
 
- 		}
 
- 		taskEXIT_CRITICAL();
 
- 	}
 
- #endif /* INCLUDE_vTaskPrioritySet */
 
- /*-----------------------------------------------------------*/
 
- #if ( INCLUDE_vTaskSuspend == 1 )
 
- 	void vTaskSuspend( TaskHandle_t xTaskToSuspend )
 
- 	{
 
- 	TCB_t *pxTCB;
 
- 		taskENTER_CRITICAL();
 
- 		{
 
- 			/* If null is passed in here then it is the running task that is
 
- 			being suspended. */
 
- 			pxTCB = prvGetTCBFromHandle( xTaskToSuspend );
 
- 			traceTASK_SUSPEND( pxTCB );
 
- 			/* Remove task from the ready/delayed list and place in the
 
- 			suspended list. */
 
- 			if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
 
- 			{
 
- 				taskRESET_READY_PRIORITY( pxTCB->uxPriority );
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 			/* Is the task waiting on an event also? */
 
- 			if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
 
- 			{
 
- 				( void ) uxListRemove( &( pxTCB->xEventListItem ) );
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 			vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) );
 
- 		}
 
- 		taskEXIT_CRITICAL();
 
- 		if( pxTCB == pxCurrentTCB )
 
- 		{
 
- 			if( xSchedulerRunning != pdFALSE )
 
- 			{
 
- 				/* The current task has just been suspended. */
 
- 				configASSERT( uxSchedulerSuspended == 0 );
 
- 				portYIELD_WITHIN_API();
 
- 			}
 
- 			else
 
- 			{
 
- 				/* The scheduler is not running, but the task that was pointed
 
- 				to by pxCurrentTCB has just been suspended and pxCurrentTCB
 
- 				must be adjusted to point to a different task. */
 
- 				if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks )
 
- 				{
 
- 					/* No other tasks are ready, so set pxCurrentTCB back to
 
- 					NULL so when the next task is created pxCurrentTCB will
 
- 					be set to point to it no matter what its relative priority
 
- 					is. */
 
- 					pxCurrentTCB = NULL;
 
- 				}
 
- 				else
 
- 				{
 
- 					vTaskSwitchContext();
 
- 				}
 
- 			}
 
- 		}
 
- 		else
 
- 		{
 
- 			if( xSchedulerRunning != pdFALSE )
 
- 			{
 
- 				/* A task other than the currently running task was suspended,
 
- 				reset the next expected unblock time in case it referred to the
 
- 				task that is now in the Suspended state. */
 
- 				taskENTER_CRITICAL();
 
- 				{
 
- 					prvResetNextTaskUnblockTime();
 
- 				}
 
- 				taskEXIT_CRITICAL();
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 		}
 
- 	}
 
- #endif /* INCLUDE_vTaskSuspend */
 
- /*-----------------------------------------------------------*/
 
- #if ( INCLUDE_vTaskSuspend == 1 )
 
- 	static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask )
 
- 	{
 
- 	BaseType_t xReturn = pdFALSE;
 
- 	const TCB_t * const pxTCB = ( TCB_t * ) xTask;
 
- 		/* Accesses xPendingReadyList so must be called from a critical
 
- 		section. */
 
- 		/* It does not make sense to check if the calling task is suspended. */
 
- 		configASSERT( xTask );
 
- 		/* Is the task being resumed actually in the suspended list? */
 
- 		if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )
 
- 		{
 
- 			/* Has the task already been resumed from within an ISR? */
 
- 			if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) == pdFALSE )
 
- 			{
 
- 				/* Is it in the suspended list because it is in the	Suspended
 
- 				state, or because is is blocked with no timeout? */
 
- 				if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) != pdFALSE )
 
- 				{
 
- 					xReturn = pdTRUE;
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 		return xReturn;
 
- 	} /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */
 
- #endif /* INCLUDE_vTaskSuspend */
 
- /*-----------------------------------------------------------*/
 
- #if ( INCLUDE_vTaskSuspend == 1 )
 
- 	void vTaskResume( TaskHandle_t xTaskToResume )
 
- 	{
 
- 	TCB_t * const pxTCB = ( TCB_t * ) xTaskToResume;
 
- 		/* It does not make sense to resume the calling task. */
 
- 		configASSERT( xTaskToResume );
 
- 		/* The parameter cannot be NULL as it is impossible to resume the
 
- 		currently executing task. */
 
- 		if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) )
 
- 		{
 
- 			taskENTER_CRITICAL();
 
- 			{
 
- 				if( prvTaskIsTaskSuspended( pxTCB ) == pdTRUE )
 
- 				{
 
- 					traceTASK_RESUME( pxTCB );
 
- 					/* As we are in a critical section we can access the ready
 
- 					lists even if the scheduler is suspended. */
 
- 					( void ) uxListRemove(  &( pxTCB->xGenericListItem ) );
 
- 					prvAddTaskToReadyList( pxTCB );
 
- 					/* We may have just resumed a higher priority task. */
 
- 					if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
 
- 					{
 
- 						/* This yield may not cause the task just resumed to run,
 
- 						but will leave the lists in the correct state for the
 
- 						next yield. */
 
- 						taskYIELD_IF_USING_PREEMPTION();
 
- 					}
 
- 					else
 
- 					{
 
- 						mtCOVERAGE_TEST_MARKER();
 
- 					}
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 			}
 
- 			taskEXIT_CRITICAL();
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 	}
 
- #endif /* INCLUDE_vTaskSuspend */
 
- /*-----------------------------------------------------------*/
 
- #if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )
 
- 	BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )
 
- 	{
 
- 	BaseType_t xYieldRequired = pdFALSE;
 
- 	TCB_t * const pxTCB = ( TCB_t * ) xTaskToResume;
 
- 	UBaseType_t uxSavedInterruptStatus;
 
- 		configASSERT( xTaskToResume );
 
- 		/* RTOS ports that support interrupt nesting have the concept of a
 
- 		maximum	system call (or maximum API call) interrupt priority.
 
- 		Interrupts that are	above the maximum system call priority are keep
 
- 		permanently enabled, even when the RTOS kernel is in a critical section,
 
- 		but cannot make any calls to FreeRTOS API functions.  If configASSERT()
 
- 		is defined in FreeRTOSConfig.h then
 
- 		portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
 
- 		failure if a FreeRTOS API function is called from an interrupt that has
 
- 		been assigned a priority above the configured maximum system call
 
- 		priority.  Only FreeRTOS functions that end in FromISR can be called
 
- 		from interrupts	that have been assigned a priority at or (logically)
 
- 		below the maximum system call interrupt priority.  FreeRTOS maintains a
 
- 		separate interrupt safe API to ensure interrupt entry is as fast and as
 
- 		simple as possible.  More information (albeit Cortex-M specific) is
 
- 		provided on the following link:
 
- 		http://www.freertos.org/RTOS-Cortex-M3-M4.html */
 
- 		portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
 
- 		uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
 
- 		{
 
- 			if( prvTaskIsTaskSuspended( pxTCB ) == pdTRUE )
 
- 			{
 
- 				traceTASK_RESUME_FROM_ISR( pxTCB );
 
- 				/* Check the ready lists can be accessed. */
 
- 				if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
 
- 				{
 
- 					/* Ready lists can be accessed so move the task from the
 
- 					suspended list to the ready list directly. */
 
- 					if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
 
- 					{
 
- 						xYieldRequired = pdTRUE;
 
- 					}
 
- 					else
 
- 					{
 
- 						mtCOVERAGE_TEST_MARKER();
 
- 					}
 
- 					( void ) uxListRemove(  &( pxTCB->xGenericListItem ) );
 
- 					prvAddTaskToReadyList( pxTCB );
 
- 				}
 
- 				else
 
- 				{
 
- 					/* The delayed or ready lists cannot be accessed so the task
 
- 					is held in the pending ready list until the scheduler is
 
- 					unsuspended. */
 
- 					vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
 
- 				}
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 		}
 
- 		portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
 
- 		return xYieldRequired;
 
- 	}
 
- #endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */
 
- /*-----------------------------------------------------------*/
 
- void vTaskStartScheduler( void )
 
- {
 
- BaseType_t xReturn;
 
- 	/* Add the idle task at the lowest priority. */
 
- 	#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
 
- 	{
 
- 		/* Create the idle task, storing its handle in xIdleTaskHandle so it can
 
- 		be returned by the xTaskGetIdleTaskHandle() function. */
 
- 		xReturn = xTaskCreate( prvIdleTask, "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), &xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
 
- 	}
 
- 	#else
 
- 	{
 
- 		/* Create the idle task without storing its handle. */
 
- 		xReturn = xTaskCreate( prvIdleTask, "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), NULL );  /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
 
- 	}
 
- 	#endif /* INCLUDE_xTaskGetIdleTaskHandle */
 
- 	#if ( configUSE_TIMERS == 1 )
 
- 	{
 
- 		if( xReturn == pdPASS )
 
- 		{
 
- 			xReturn = xTimerCreateTimerTask();
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 	}
 
- 	#endif /* configUSE_TIMERS */
 
- 	if( xReturn == pdPASS )
 
- 	{
 
- 		/* Interrupts are turned off here, to ensure a tick does not occur
 
- 		before or during the call to xPortStartScheduler().  The stacks of
 
- 		the created tasks contain a status word with interrupts switched on
 
- 		so interrupts will automatically get re-enabled when the first task
 
- 		starts to run. */
 
- 		portDISABLE_INTERRUPTS();
 
- 		#if ( configUSE_NEWLIB_REENTRANT == 1 )
 
- 		{
 
- 			/* Switch Newlib's _impure_ptr variable to point to the _reent
 
- 			structure specific to the task that will run first. */
 
- 			_impure_ptr = &( pxCurrentTCB->xNewLib_reent );
 
- 		}
 
- 		#endif /* configUSE_NEWLIB_REENTRANT */
 
- 		xSchedulerRunning = pdTRUE;
 
- 		xTickCount = ( TickType_t ) 0U;
 
- 		/* If configGENERATE_RUN_TIME_STATS is defined then the following
 
- 		macro must be defined to configure the timer/counter used to generate
 
- 		the run time counter time base. */
 
- 		portCONFIGURE_TIMER_FOR_RUN_TIME_STATS();
 
- 		/* Setting up the timer tick is hardware specific and thus in the
 
- 		portable interface. */
 
- 		if( xPortStartScheduler() != pdFALSE )
 
- 		{
 
- 			/* Should not reach here as if the scheduler is running the
 
- 			function will not return. */
 
- 		}
 
- 		else
 
- 		{
 
- 			/* Should only reach here if a task calls xTaskEndScheduler(). */
 
- 		}
 
- 	}
 
- 	else
 
- 	{
 
- 		/* This line will only be reached if the kernel could not be started,
 
- 		because there was not enough FreeRTOS heap to create the idle task
 
- 		or the timer task. */
 
- 		configASSERT( xReturn );
 
- 	}
 
- }
 
- /*-----------------------------------------------------------*/
 
- void vTaskEndScheduler( void )
 
- {
 
- 	/* Stop the scheduler interrupts and call the portable scheduler end
 
- 	routine so the original ISRs can be restored if necessary.  The port
 
- 	layer must ensure interrupts enable	bit is left in the correct state. */
 
- 	portDISABLE_INTERRUPTS();
 
- 	xSchedulerRunning = pdFALSE;
 
- 	vPortEndScheduler();
 
- }
 
- /*----------------------------------------------------------*/
 
- void vTaskSuspendAll( void )
 
- {
 
- 	/* A critical section is not required as the variable is of type
 
- 	BaseType_t.  Please read Richard Barry's reply in the following link to a
 
- 	post in the FreeRTOS support forum before reporting this as a bug! -
 
- 	http://goo.gl/wu4acr */
 
- 	++uxSchedulerSuspended;
 
- }
 
- /*----------------------------------------------------------*/
 
- #if ( configUSE_TICKLESS_IDLE != 0 )
 
- 	static TickType_t prvGetExpectedIdleTime( void )
 
- 	{
 
- 	TickType_t xReturn;
 
- 		if( pxCurrentTCB->uxPriority > tskIDLE_PRIORITY )
 
- 		{
 
- 			xReturn = 0;
 
- 		}
 
- 		else if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > 1 )
 
- 		{
 
- 			/* There are other idle priority tasks in the ready state.  If
 
- 			time slicing is used then the very next tick interrupt must be
 
- 			processed. */
 
- 			xReturn = 0;
 
- 		}
 
- 		else
 
- 		{
 
- 			xReturn = xNextTaskUnblockTime - xTickCount;
 
- 		}
 
- 		return xReturn;
 
- 	}
 
- #endif /* configUSE_TICKLESS_IDLE */
 
- /*----------------------------------------------------------*/
 
- BaseType_t xTaskResumeAll( void )
 
- {
 
- TCB_t *pxTCB;
 
- BaseType_t xAlreadyYielded = pdFALSE;
 
- 	/* If uxSchedulerSuspended is zero then this function does not match a
 
- 	previous call to vTaskSuspendAll(). */
 
- 	configASSERT( uxSchedulerSuspended );
 
- 	/* It is possible that an ISR caused a task to be removed from an event
 
- 	list while the scheduler was suspended.  If this was the case then the
 
- 	removed task will have been added to the xPendingReadyList.  Once the
 
- 	scheduler has been resumed it is safe to move all the pending ready
 
- 	tasks from this list into their appropriate ready list. */
 
- 	taskENTER_CRITICAL();
 
- 	{
 
- 		--uxSchedulerSuspended;
 
- 		if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
 
- 		{
 
- 			if( uxCurrentNumberOfTasks > ( UBaseType_t ) 0U )
 
- 			{
 
- 				/* Move any readied tasks from the pending list into the
 
- 				appropriate ready list. */
 
- 				while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE )
 
- 				{
 
- 					pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) );
 
- 					( void ) uxListRemove( &( pxTCB->xEventListItem ) );
 
- 					( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
 
- 					prvAddTaskToReadyList( pxTCB );
 
- 					/* If the moved task has a priority higher than the current
 
- 					task then a yield must be performed. */
 
- 					if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
 
- 					{
 
- 						xYieldPending = pdTRUE;
 
- 					}
 
- 					else
 
- 					{
 
- 						mtCOVERAGE_TEST_MARKER();
 
- 					}
 
- 				}
 
- 				/* If any ticks occurred while the scheduler was suspended then
 
- 				they should be processed now.  This ensures the tick count does
 
- 				not	slip, and that any delayed tasks are resumed at the correct
 
- 				time. */
 
- 				if( uxPendedTicks > ( UBaseType_t ) 0U )
 
- 				{
 
- 					while( uxPendedTicks > ( UBaseType_t ) 0U )
 
- 					{
 
- 						if( xTaskIncrementTick() != pdFALSE )
 
- 						{
 
- 							xYieldPending = pdTRUE;
 
- 						}
 
- 						else
 
- 						{
 
- 							mtCOVERAGE_TEST_MARKER();
 
- 						}
 
- 						--uxPendedTicks;
 
- 					}
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 				if( xYieldPending == pdTRUE )
 
- 				{
 
- 					#if( configUSE_PREEMPTION != 0 )
 
- 					{
 
- 						xAlreadyYielded = pdTRUE;
 
- 					}
 
- 					#endif
 
- 					taskYIELD_IF_USING_PREEMPTION();
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 			}
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 	}
 
- 	taskEXIT_CRITICAL();
 
- 	return xAlreadyYielded;
 
- }
 
- /*-----------------------------------------------------------*/
 
- TickType_t xTaskGetTickCount( void )
 
- {
 
- TickType_t xTicks;
 
- 	/* Critical section required if running on a 16 bit processor. */
 
- 	portTICK_TYPE_ENTER_CRITICAL();
 
- 	{
 
- 		xTicks = xTickCount;
 
- 	}
 
- 	portTICK_TYPE_EXIT_CRITICAL();
 
- 	return xTicks;
 
- }
 
- /*-----------------------------------------------------------*/
 
- TickType_t xTaskGetTickCountFromISR( void )
 
- {
 
- TickType_t xReturn;
 
- UBaseType_t uxSavedInterruptStatus;
 
- 	/* RTOS ports that support interrupt nesting have the concept of a maximum
 
- 	system call (or maximum API call) interrupt priority.  Interrupts that are
 
- 	above the maximum system call priority are kept permanently enabled, even
 
- 	when the RTOS kernel is in a critical section, but cannot make any calls to
 
- 	FreeRTOS API functions.  If configASSERT() is defined in FreeRTOSConfig.h
 
- 	then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
 
- 	failure if a FreeRTOS API function is called from an interrupt that has been
 
- 	assigned a priority above the configured maximum system call priority.
 
- 	Only FreeRTOS functions that end in FromISR can be called from interrupts
 
- 	that have been assigned a priority at or (logically) below the maximum
 
- 	system call	interrupt priority.  FreeRTOS maintains a separate interrupt
 
- 	safe API to ensure interrupt entry is as fast and as simple as possible.
 
- 	More information (albeit Cortex-M specific) is provided on the following
 
- 	link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */
 
- 	portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
 
- 	uxSavedInterruptStatus = portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR();
 
- 	{
 
- 		xReturn = xTickCount;
 
- 	}
 
- 	portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
 
- 	return xReturn;
 
- }
 
- /*-----------------------------------------------------------*/
 
- UBaseType_t uxTaskGetNumberOfTasks( void )
 
- {
 
- 	/* A critical section is not required because the variables are of type
 
- 	BaseType_t. */
 
- 	return uxCurrentNumberOfTasks;
 
- }
 
- /*-----------------------------------------------------------*/
 
- #if ( INCLUDE_pcTaskGetTaskName == 1 )
 
- 	char *pcTaskGetTaskName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
 
- 	{
 
- 	TCB_t *pxTCB;
 
- 		/* If null is passed in here then the name of the calling task is being queried. */
 
- 		pxTCB = prvGetTCBFromHandle( xTaskToQuery );
 
- 		configASSERT( pxTCB );
 
- 		return &( pxTCB->pcTaskName[ 0 ] );
 
- 	}
 
- #endif /* INCLUDE_pcTaskGetTaskName */
 
- /*-----------------------------------------------------------*/
 
- #if ( configUSE_TRACE_FACILITY == 1 )
 
- 	UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime )
 
- 	{
 
- 	UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES;
 
- 		vTaskSuspendAll();
 
- 		{
 
- 			/* Is there a space in the array for each task in the system? */
 
- 			if( uxArraySize >= uxCurrentNumberOfTasks )
 
- 			{
 
- 				/* Fill in an TaskStatus_t structure with information on each
 
- 				task in the Ready state. */
 
- 				do
 
- 				{
 
- 					uxQueue--;
 
- 					uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &( pxReadyTasksLists[ uxQueue ] ), eReady );
 
- 				} while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
 
- 				/* Fill in an TaskStatus_t structure with information on each
 
- 				task in the Blocked state. */
 
- 				uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxDelayedTaskList, eBlocked );
 
- 				uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxOverflowDelayedTaskList, eBlocked );
 
- 				#if( INCLUDE_vTaskDelete == 1 )
 
- 				{
 
- 					/* Fill in an TaskStatus_t structure with information on
 
- 					each task that has been deleted but not yet cleaned up. */
 
- 					uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xTasksWaitingTermination, eDeleted );
 
- 				}
 
- 				#endif
 
- 				#if ( INCLUDE_vTaskSuspend == 1 )
 
- 				{
 
- 					/* Fill in an TaskStatus_t structure with information on
 
- 					each task in the Suspended state. */
 
- 					uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xSuspendedTaskList, eSuspended );
 
- 				}
 
- 				#endif
 
- 				#if ( configGENERATE_RUN_TIME_STATS == 1)
 
- 				{
 
- 					if( pulTotalRunTime != NULL )
 
- 					{
 
- 						#ifdef portALT_GET_RUN_TIME_COUNTER_VALUE
 
- 							portALT_GET_RUN_TIME_COUNTER_VALUE( ( *pulTotalRunTime ) );
 
- 						#else
 
- 							*pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();
 
- 						#endif
 
- 					}
 
- 				}
 
- 				#else
 
- 				{
 
- 					if( pulTotalRunTime != NULL )
 
- 					{
 
- 						*pulTotalRunTime = 0;
 
- 					}
 
- 				}
 
- 				#endif
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 		}
 
- 		( void ) xTaskResumeAll();
 
- 		return uxTask;
 
- 	}
 
- #endif /* configUSE_TRACE_FACILITY */
 
- /*----------------------------------------------------------*/
 
- #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
 
- 	TaskHandle_t xTaskGetIdleTaskHandle( void )
 
- 	{
 
- 		/* If xTaskGetIdleTaskHandle() is called before the scheduler has been
 
- 		started, then xIdleTaskHandle will be NULL. */
 
- 		configASSERT( ( xIdleTaskHandle != NULL ) );
 
- 		return xIdleTaskHandle;
 
- 	}
 
- #endif /* INCLUDE_xTaskGetIdleTaskHandle */
 
- /*----------------------------------------------------------*/
 
- /* This conditional compilation should use inequality to 0, not equality to 1.
 
- This is to ensure vTaskStepTick() is available when user defined low power mode
 
- implementations require configUSE_TICKLESS_IDLE to be set to a value other than
 
- 1. */
 
- #if ( configUSE_TICKLESS_IDLE != 0 )
 
- 	void vTaskStepTick( const TickType_t xTicksToJump )
 
- 	{
 
- 		/* Correct the tick count value after a period during which the tick
 
- 		was suppressed.  Note this does *not* call the tick hook function for
 
- 		each stepped tick. */
 
- 		configASSERT( ( xTickCount + xTicksToJump ) <= xNextTaskUnblockTime );
 
- 		xTickCount += xTicksToJump;
 
- 		traceINCREASE_TICK_COUNT( xTicksToJump );
 
- 	}
 
- #endif /* configUSE_TICKLESS_IDLE */
 
- /*----------------------------------------------------------*/
 
- BaseType_t xTaskIncrementTick( void )
 
- {
 
- TCB_t * pxTCB;
 
- TickType_t xItemValue;
 
- BaseType_t xSwitchRequired = pdFALSE;
 
- 	/* Called by the portable layer each time a tick interrupt occurs.
 
- 	Increments the tick then checks to see if the new tick value will cause any
 
- 	tasks to be unblocked. */
 
- 	traceTASK_INCREMENT_TICK( xTickCount );
 
- 	if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
 
- 	{
 
- 		/* Increment the RTOS tick, switching the delayed and overflowed
 
- 		delayed lists if it wraps to 0. */
 
- 		++xTickCount;
 
- 		{
 
- 			/* Minor optimisation.  The tick count cannot change in this
 
- 			block. */
 
- 			const TickType_t xConstTickCount = xTickCount;
 
- 			if( xConstTickCount == ( TickType_t ) 0U )
 
- 			{
 
- 				taskSWITCH_DELAYED_LISTS();
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 			/* See if this tick has made a timeout expire.  Tasks are stored in
 
- 			the	queue in the order of their wake time - meaning once one task
 
- 			has been found whose block time has not expired there is no need to
 
- 			look any further down the list. */
 
- 			if( xConstTickCount >= xNextTaskUnblockTime )
 
- 			{
 
- 				for( ;; )
 
- 				{
 
- 					if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )
 
- 					{
 
- 						/* The delayed list is empty.  Set xNextTaskUnblockTime
 
- 						to the maximum possible value so it is extremely
 
- 						unlikely that the
 
- 						if( xTickCount >= xNextTaskUnblockTime ) test will pass
 
- 						next time through. */
 
- 						xNextTaskUnblockTime = portMAX_DELAY;
 
- 						break;
 
- 					}
 
- 					else
 
- 					{
 
- 						/* The delayed list is not empty, get the value of the
 
- 						item at the head of the delayed list.  This is the time
 
- 						at which the task at the head of the delayed list must
 
- 						be removed from the Blocked state. */
 
- 						pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
 
- 						xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );
 
- 						if( xConstTickCount < xItemValue )
 
- 						{
 
- 							/* It is not time to unblock this item yet, but the
 
- 							item value is the time at which the task at the head
 
- 							of the blocked list must be removed from the Blocked
 
- 							state -	so record the item value in
 
- 							xNextTaskUnblockTime. */
 
- 							xNextTaskUnblockTime = xItemValue;
 
- 							break;
 
- 						}
 
- 						else
 
- 						{
 
- 							mtCOVERAGE_TEST_MARKER();
 
- 						}
 
- 						/* It is time to remove the item from the Blocked state. */
 
- 						( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
 
- 						/* Is the task waiting on an event also?  If so remove
 
- 						it from the event list. */
 
- 						if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
 
- 						{
 
- 							( void ) uxListRemove( &( pxTCB->xEventListItem ) );
 
- 						}
 
- 						else
 
- 						{
 
- 							mtCOVERAGE_TEST_MARKER();
 
- 						}
 
- 						/* Place the unblocked task into the appropriate ready
 
- 						list. */
 
- 						prvAddTaskToReadyList( pxTCB );
 
- 						/* A task being unblocked cannot cause an immediate
 
- 						context switch if preemption is turned off. */
 
- 						#if (  configUSE_PREEMPTION == 1 )
 
- 						{
 
- 							/* Preemption is on, but a context switch should
 
- 							only be performed if the unblocked task has a
 
- 							priority that is equal to or higher than the
 
- 							currently executing task. */
 
- 							if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
 
- 							{
 
- 								xSwitchRequired = pdTRUE;
 
- 							}
 
- 							else
 
- 							{
 
- 								mtCOVERAGE_TEST_MARKER();
 
- 							}
 
- 						}
 
- 						#endif /* configUSE_PREEMPTION */
 
- 					}
 
- 				}
 
- 			}
 
- 		}
 
- 		/* Tasks of equal priority to the currently running task will share
 
- 		processing time (time slice) if preemption is on, and the application
 
- 		writer has not explicitly turned time slicing off. */
 
- 		#if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) )
 
- 		{
 
- 			if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > ( UBaseType_t ) 1 )
 
- 			{
 
- 				xSwitchRequired = pdTRUE;
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 		}
 
- 		#endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */
 
- 		#if ( configUSE_TICK_HOOK == 1 )
 
- 		{
 
- 			/* Guard against the tick hook being called when the pended tick
 
- 			count is being unwound (when the scheduler is being unlocked). */
 
- 			if( uxPendedTicks == ( UBaseType_t ) 0U )
 
- 			{
 
- 				vApplicationTickHook();
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 		}
 
- 		#endif /* configUSE_TICK_HOOK */
 
- 	}
 
- 	else
 
- 	{
 
- 		++uxPendedTicks;
 
- 		/* The tick hook gets called at regular intervals, even if the
 
- 		scheduler is locked. */
 
- 		#if ( configUSE_TICK_HOOK == 1 )
 
- 		{
 
- 			vApplicationTickHook();
 
- 		}
 
- 		#endif
 
- 	}
 
- 	#if ( configUSE_PREEMPTION == 1 )
 
- 	{
 
- 		if( xYieldPending != pdFALSE )
 
- 		{
 
- 			xSwitchRequired = pdTRUE;
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 	}
 
- 	#endif /* configUSE_PREEMPTION */
 
- 	return xSwitchRequired;
 
- }
 
- /*-----------------------------------------------------------*/
 
- #if ( configUSE_APPLICATION_TASK_TAG == 1 )
 
- 	void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction )
 
- 	{
 
- 	TCB_t *xTCB;
 
- 		/* If xTask is NULL then it is the task hook of the calling task that is
 
- 		getting set. */
 
- 		if( xTask == NULL )
 
- 		{
 
- 			xTCB = ( TCB_t * ) pxCurrentTCB;
 
- 		}
 
- 		else
 
- 		{
 
- 			xTCB = ( TCB_t * ) xTask;
 
- 		}
 
- 		/* Save the hook function in the TCB.  A critical section is required as
 
- 		the value can be accessed from an interrupt. */
 
- 		taskENTER_CRITICAL();
 
- 			xTCB->pxTaskTag = pxHookFunction;
 
- 		taskEXIT_CRITICAL();
 
- 	}
 
- #endif /* configUSE_APPLICATION_TASK_TAG */
 
- /*-----------------------------------------------------------*/
 
- #if ( configUSE_APPLICATION_TASK_TAG == 1 )
 
- 	TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask )
 
- 	{
 
- 	TCB_t *xTCB;
 
- 	TaskHookFunction_t xReturn;
 
- 		/* If xTask is NULL then we are setting our own task hook. */
 
- 		if( xTask == NULL )
 
- 		{
 
- 			xTCB = ( TCB_t * ) pxCurrentTCB;
 
- 		}
 
- 		else
 
- 		{
 
- 			xTCB = ( TCB_t * ) xTask;
 
- 		}
 
- 		/* Save the hook function in the TCB.  A critical section is required as
 
- 		the value can be accessed from an interrupt. */
 
- 		taskENTER_CRITICAL();
 
- 		{
 
- 			xReturn = xTCB->pxTaskTag;
 
- 		}
 
- 		taskEXIT_CRITICAL();
 
- 		return xReturn;
 
- 	}
 
- #endif /* configUSE_APPLICATION_TASK_TAG */
 
- /*-----------------------------------------------------------*/
 
- #if ( configUSE_APPLICATION_TASK_TAG == 1 )
 
- 	BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter )
 
- 	{
 
- 	TCB_t *xTCB;
 
- 	BaseType_t xReturn;
 
- 		/* If xTask is NULL then we are calling our own task hook. */
 
- 		if( xTask == NULL )
 
- 		{
 
- 			xTCB = ( TCB_t * ) pxCurrentTCB;
 
- 		}
 
- 		else
 
- 		{
 
- 			xTCB = ( TCB_t * ) xTask;
 
- 		}
 
- 		if( xTCB->pxTaskTag != NULL )
 
- 		{
 
- 			xReturn = xTCB->pxTaskTag( pvParameter );
 
- 		}
 
- 		else
 
- 		{
 
- 			xReturn = pdFAIL;
 
- 		}
 
- 		return xReturn;
 
- 	}
 
- #endif /* configUSE_APPLICATION_TASK_TAG */
 
- /*-----------------------------------------------------------*/
 
- void vTaskSwitchContext( void )
 
- {
 
- 	if( uxSchedulerSuspended != ( UBaseType_t ) pdFALSE )
 
- 	{
 
- 		/* The scheduler is currently suspended - do not allow a context
 
- 		switch. */
 
- 		xYieldPending = pdTRUE;
 
- 	}
 
- 	else
 
- 	{
 
- 		xYieldPending = pdFALSE;
 
- 		traceTASK_SWITCHED_OUT();
 
- 		#if ( configGENERATE_RUN_TIME_STATS == 1 )
 
- 		{
 
- 				#ifdef portALT_GET_RUN_TIME_COUNTER_VALUE
 
- 					portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime );
 
- 				#else
 
- 					ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();
 
- 				#endif
 
- 				/* Add the amount of time the task has been running to the
 
- 				accumulated	time so far.  The time the task started running was
 
- 				stored in ulTaskSwitchedInTime.  Note that there is no overflow
 
- 				protection here	so count values are only valid until the timer
 
- 				overflows.  The guard against negative values is to protect
 
- 				against suspect run time stat counter implementations - which
 
- 				are provided by the application, not the kernel. */
 
- 				if( ulTotalRunTime > ulTaskSwitchedInTime )
 
- 				{
 
- 					pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime );
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 				ulTaskSwitchedInTime = ulTotalRunTime;
 
- 		}
 
- 		#endif /* configGENERATE_RUN_TIME_STATS */
 
- 		/* Check for stack overflow, if configured. */
 
- 		taskFIRST_CHECK_FOR_STACK_OVERFLOW();
 
- 		taskSECOND_CHECK_FOR_STACK_OVERFLOW();
 
- 		/* Select a new task to run using either the generic C or port
 
- 		optimised asm code. */
 
- 		taskSELECT_HIGHEST_PRIORITY_TASK();
 
- 		traceTASK_SWITCHED_IN();
 
- 		#if ( configUSE_NEWLIB_REENTRANT == 1 )
 
- 		{
 
- 			/* Switch Newlib's _impure_ptr variable to point to the _reent
 
- 			structure specific to this task. */
 
- 			_impure_ptr = &( pxCurrentTCB->xNewLib_reent );
 
- 		}
 
- 		#endif /* configUSE_NEWLIB_REENTRANT */
 
- 	}
 
- }
 
- /*-----------------------------------------------------------*/
 
- void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait )
 
- {
 
- TickType_t xTimeToWake;
 
- 	configASSERT( pxEventList );
 
- 	/* THIS FUNCTION MUST BE CALLED WITH EITHER INTERRUPTS DISABLED OR THE
 
- 	SCHEDULER SUSPENDED AND THE QUEUE BEING ACCESSED LOCKED. */
 
- 	/* Place the event list item of the TCB in the appropriate event list.
 
- 	This is placed in the list in priority order so the highest priority task
 
- 	is the first to be woken by the event.  The queue that contains the event
 
- 	list is locked, preventing simultaneous access from interrupts. */
 
- 	vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) );
 
- 	/* The task must be removed from from the ready list before it is added to
 
- 	the blocked list as the same list item is used for both lists.  Exclusive
 
- 	access to the ready lists guaranteed because the scheduler is locked. */
 
- 	if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
 
- 	{
 
- 		/* The current task must be in a ready list, so there is no need to
 
- 		check, and the port reset macro can be called directly. */
 
- 		portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
 
- 	}
 
- 	else
 
- 	{
 
- 		mtCOVERAGE_TEST_MARKER();
 
- 	}
 
- 	#if ( INCLUDE_vTaskSuspend == 1 )
 
- 	{
 
- 		if( xTicksToWait == portMAX_DELAY )
 
- 		{
 
- 			/* Add the task to the suspended task list instead of a delayed task
 
- 			list to ensure the task is not woken by a timing event.  It will
 
- 			block indefinitely. */
 
- 			vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
 
- 		}
 
- 		else
 
- 		{
 
- 			/* Calculate the time at which the task should be woken if the event
 
- 			does not occur.  This may overflow but this doesn't matter, the
 
- 			scheduler will handle it. */
 
- 			xTimeToWake = xTickCount + xTicksToWait;
 
- 			prvAddCurrentTaskToDelayedList( xTimeToWake );
 
- 		}
 
- 	}
 
- 	#else /* INCLUDE_vTaskSuspend */
 
- 	{
 
- 			/* Calculate the time at which the task should be woken if the event does
 
- 			not occur.  This may overflow but this doesn't matter, the scheduler
 
- 			will handle it. */
 
- 			xTimeToWake = xTickCount + xTicksToWait;
 
- 			prvAddCurrentTaskToDelayedList( xTimeToWake );
 
- 	}
 
- 	#endif /* INCLUDE_vTaskSuspend */
 
- }
 
- /*-----------------------------------------------------------*/
 
- void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait )
 
- {
 
- TickType_t xTimeToWake;
 
- 	configASSERT( pxEventList );
 
- 	/* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED.  It is used by
 
- 	the event groups implementation. */
 
- 	configASSERT( uxSchedulerSuspended != 0 );
 
- 	/* Store the item value in the event list item.  It is safe to access the
 
- 	event list item here as interrupts won't access the event list item of a
 
- 	task that is not in the Blocked state. */
 
- 	listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE );
 
- 	/* Place the event list item of the TCB at the end of the appropriate event
 
- 	list.  It is safe to access the event list here because it is part of an
 
- 	event group implementation - and interrupts don't access event groups
 
- 	directly (instead they access them indirectly by pending function calls to
 
- 	the task level). */
 
- 	vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) );
 
- 	/* The task must be removed from the ready list before it is added to the
 
- 	blocked list.  Exclusive access can be assured to the ready list as the
 
- 	scheduler is locked. */
 
- 	if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
 
- 	{
 
- 		/* The current task must be in a ready list, so there is no need to
 
- 		check, and the port reset macro can be called directly. */
 
- 		portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
 
- 	}
 
- 	else
 
- 	{
 
- 		mtCOVERAGE_TEST_MARKER();
 
- 	}
 
- 	#if ( INCLUDE_vTaskSuspend == 1 )
 
- 	{
 
- 		if( xTicksToWait == portMAX_DELAY )
 
- 		{
 
- 			/* Add the task to the suspended task list instead of a delayed task
 
- 			list to ensure it is not woken by a timing event.  It will block
 
- 			indefinitely. */
 
- 			vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
 
- 		}
 
- 		else
 
- 		{
 
- 			/* Calculate the time at which the task should be woken if the event
 
- 			does not occur.  This may overflow but this doesn't matter, the
 
- 			kernel will manage it correctly. */
 
- 			xTimeToWake = xTickCount + xTicksToWait;
 
- 			prvAddCurrentTaskToDelayedList( xTimeToWake );
 
- 		}
 
- 	}
 
- 	#else /* INCLUDE_vTaskSuspend */
 
- 	{
 
- 			/* Calculate the time at which the task should be woken if the event does
 
- 			not occur.  This may overflow but this doesn't matter, the kernel
 
- 			will manage it correctly. */
 
- 			xTimeToWake = xTickCount + xTicksToWait;
 
- 			prvAddCurrentTaskToDelayedList( xTimeToWake );
 
- 	}
 
- 	#endif /* INCLUDE_vTaskSuspend */
 
- }
 
- /*-----------------------------------------------------------*/
 
- #if configUSE_TIMERS == 1
 
- 	void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, const TickType_t xTicksToWait )
 
- 	{
 
- 	TickType_t xTimeToWake;
 
- 		configASSERT( pxEventList );
 
- 		/* This function should not be called by application code hence the
 
- 		'Restricted' in its name.  It is not part of the public API.  It is
 
- 		designed for use by kernel code, and has special calling requirements -
 
- 		it should be called from a critical section. */
 
- 		/* Place the event list item of the TCB in the appropriate event list.
 
- 		In this case it is assume that this is the only task that is going to
 
- 		be waiting on this event list, so the faster vListInsertEnd() function
 
- 		can be used in place of vListInsert. */
 
- 		vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) );
 
- 		/* We must remove this task from the ready list before adding it to the
 
- 		blocked list as the same list item is used for both lists.  This
 
- 		function is called form a critical section. */
 
- 		if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
 
- 		{
 
- 			/* The current task must be in a ready list, so there is no need to
 
- 			check, and the port reset macro can be called directly. */
 
- 			portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 		/* Calculate the time at which the task should be woken if the event does
 
- 		not occur.  This may overflow but this doesn't matter. */
 
- 		xTimeToWake = xTickCount + xTicksToWait;
 
- 		traceTASK_DELAY_UNTIL();
 
- 		prvAddCurrentTaskToDelayedList( xTimeToWake );
 
- 	}
 
- #endif /* configUSE_TIMERS */
 
- /*-----------------------------------------------------------*/
 
- BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList )
 
- {
 
- TCB_t *pxUnblockedTCB;
 
- BaseType_t xReturn;
 
- 	/* THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION.  It can also be
 
- 	called from a critical section within an ISR. */
 
- 	/* The event list is sorted in priority order, so the first in the list can
 
- 	be removed as it is known to be the highest priority.  Remove the TCB from
 
- 	the delayed list, and add it to the ready list.
 
- 	If an event is for a queue that is locked then this function will never
 
- 	get called - the lock count on the queue will get modified instead.  This
 
- 	means exclusive access to the event list is guaranteed here.
 
- 	This function assumes that a check has already been made to ensure that
 
- 	pxEventList is not empty. */
 
- 	pxUnblockedTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
 
- 	configASSERT( pxUnblockedTCB );
 
- 	( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) );
 
- 	if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
 
- 	{
 
- 		( void ) uxListRemove( &( pxUnblockedTCB->xGenericListItem ) );
 
- 		prvAddTaskToReadyList( pxUnblockedTCB );
 
- 	}
 
- 	else
 
- 	{
 
- 		/* The delayed and ready lists cannot be accessed, so hold this task
 
- 		pending until the scheduler is resumed. */
 
- 		vListInsertEnd( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) );
 
- 	}
 
- 	if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority )
 
- 	{
 
- 		/* Return true if the task removed from the event list has a higher
 
- 		priority than the calling task.  This allows the calling task to know if
 
- 		it should force a context switch now. */
 
- 		xReturn = pdTRUE;
 
- 		/* Mark that a yield is pending in case the user is not using the
 
- 		"xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */
 
- 		xYieldPending = pdTRUE;
 
- 	}
 
- 	else
 
- 	{
 
- 		xReturn = pdFALSE;
 
- 	}
 
- 	#if( configUSE_TICKLESS_IDLE == 1 )
 
- 	{
 
- 		/* If a task is blocked on a kernel object then xNextTaskUnblockTime
 
- 		might be set to the blocked task's time out time.  If the task is
 
- 		unblocked for a reason other than a timeout xNextTaskUnblockTime is
 
- 		normally left unchanged, because it is automatically get reset to a new
 
- 		value when the tick count equals xNextTaskUnblockTime.  However if
 
- 		tickless idling is used it might be more important to enter sleep mode
 
- 		at the earliest possible time - so reset xNextTaskUnblockTime here to
 
- 		ensure it is updated at the earliest possible time. */
 
- 		prvResetNextTaskUnblockTime();
 
- 	}
 
- 	#endif
 
- 	return xReturn;
 
- }
 
- /*-----------------------------------------------------------*/
 
- BaseType_t xTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue )
 
- {
 
- TCB_t *pxUnblockedTCB;
 
- BaseType_t xReturn;
 
- 	/* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED.  It is used by
 
- 	the event flags implementation. */
 
- 	configASSERT( uxSchedulerSuspended != pdFALSE );
 
- 	/* Store the new item value in the event list. */
 
- 	listSET_LIST_ITEM_VALUE( pxEventListItem, xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE );
 
- 	/* Remove the event list form the event flag.  Interrupts do not access
 
- 	event flags. */
 
- 	pxUnblockedTCB = ( TCB_t * ) listGET_LIST_ITEM_OWNER( pxEventListItem );
 
- 	configASSERT( pxUnblockedTCB );
 
- 	( void ) uxListRemove( pxEventListItem );
 
- 	/* Remove the task from the delayed list and add it to the ready list.  The
 
- 	scheduler is suspended so interrupts will not be accessing the ready
 
- 	lists. */
 
- 	( void ) uxListRemove( &( pxUnblockedTCB->xGenericListItem ) );
 
- 	prvAddTaskToReadyList( pxUnblockedTCB );
 
- 	if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority )
 
- 	{
 
- 		/* Return true if the task removed from the event list has
 
- 		a higher priority than the calling task.  This allows
 
- 		the calling task to know if it should force a context
 
- 		switch now. */
 
- 		xReturn = pdTRUE;
 
- 		/* Mark that a yield is pending in case the user is not using the
 
- 		"xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */
 
- 		xYieldPending = pdTRUE;
 
- 	}
 
- 	else
 
- 	{
 
- 		xReturn = pdFALSE;
 
- 	}
 
- 	return xReturn;
 
- }
 
- /*-----------------------------------------------------------*/
 
- void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut )
 
- {
 
- 	configASSERT( pxTimeOut );
 
- 	pxTimeOut->xOverflowCount = xNumOfOverflows;
 
- 	pxTimeOut->xTimeOnEntering = xTickCount;
 
- }
 
- /*-----------------------------------------------------------*/
 
- BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait )
 
- {
 
- BaseType_t xReturn;
 
- 	configASSERT( pxTimeOut );
 
- 	configASSERT( pxTicksToWait );
 
- 	taskENTER_CRITICAL();
 
- 	{
 
- 		/* Minor optimisation.  The tick count cannot change in this block. */
 
- 		const TickType_t xConstTickCount = xTickCount;
 
- 		#if ( INCLUDE_vTaskSuspend == 1 )
 
- 			/* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is
 
- 			the maximum block time then the task should block indefinitely, and
 
- 			therefore never time out. */
 
- 			if( *pxTicksToWait == portMAX_DELAY )
 
- 			{
 
- 				xReturn = pdFALSE;
 
- 			}
 
- 			else /* We are not blocking indefinitely, perform the checks below. */
 
- 		#endif
 
- 		if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xConstTickCount >= pxTimeOut->xTimeOnEntering ) ) /*lint !e525 Indentation preferred as is to make code within pre-processor directives clearer. */
 
- 		{
 
- 			/* The tick count is greater than the time at which vTaskSetTimeout()
 
- 			was called, but has also overflowed since vTaskSetTimeOut() was called.
 
- 			It must have wrapped all the way around and gone past us again. This
 
- 			passed since vTaskSetTimeout() was called. */
 
- 			xReturn = pdTRUE;
 
- 		}
 
- 		else if( ( xConstTickCount - pxTimeOut->xTimeOnEntering ) < *pxTicksToWait )
 
- 		{
 
- 			/* Not a genuine timeout. Adjust parameters for time remaining. */
 
- 			*pxTicksToWait -= ( xConstTickCount -  pxTimeOut->xTimeOnEntering );
 
- 			vTaskSetTimeOutState( pxTimeOut );
 
- 			xReturn = pdFALSE;
 
- 		}
 
- 		else
 
- 		{
 
- 			xReturn = pdTRUE;
 
- 		}
 
- 	}
 
- 	taskEXIT_CRITICAL();
 
- 	return xReturn;
 
- }
 
- /*-----------------------------------------------------------*/
 
- void vTaskMissedYield( void )
 
- {
 
- 	xYieldPending = pdTRUE;
 
- }
 
- /*-----------------------------------------------------------*/
 
- #if ( configUSE_TRACE_FACILITY == 1 )
 
- 	UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask )
 
- 	{
 
- 	UBaseType_t uxReturn;
 
- 	TCB_t *pxTCB;
 
- 		if( xTask != NULL )
 
- 		{
 
- 			pxTCB = ( TCB_t * ) xTask;
 
- 			uxReturn = pxTCB->uxTaskNumber;
 
- 		}
 
- 		else
 
- 		{
 
- 			uxReturn = 0U;
 
- 		}
 
- 		return uxReturn;
 
- 	}
 
- #endif /* configUSE_TRACE_FACILITY */
 
- /*-----------------------------------------------------------*/
 
- #if ( configUSE_TRACE_FACILITY == 1 )
 
- 	void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle )
 
- 	{
 
- 	TCB_t *pxTCB;
 
- 		if( xTask != NULL )
 
- 		{
 
- 			pxTCB = ( TCB_t * ) xTask;
 
- 			pxTCB->uxTaskNumber = uxHandle;
 
- 		}
 
- 	}
 
- #endif /* configUSE_TRACE_FACILITY */
 
- /*
 
-  * -----------------------------------------------------------
 
-  * The Idle task.
 
-  * ----------------------------------------------------------
 
-  *
 
-  * The portTASK_FUNCTION() macro is used to allow port/compiler specific
 
-  * language extensions.  The equivalent prototype for this function is:
 
-  *
 
-  * void prvIdleTask( void *pvParameters );
 
-  *
 
-  */
 
- static portTASK_FUNCTION( prvIdleTask, pvParameters )
 
- {
 
- 	/* Stop warnings. */
 
- 	( void ) pvParameters;
 
- 	for( ;; )
 
- 	{
 
- 		/* See if any tasks have been deleted. */
 
- 		prvCheckTasksWaitingTermination();
 
- 		#if ( configUSE_PREEMPTION == 0 )
 
- 		{
 
- 			/* If we are not using preemption we keep forcing a task switch to
 
- 			see if any other task has become available.  If we are using
 
- 			preemption we don't need to do this as any task becoming available
 
- 			will automatically get the processor anyway. */
 
- 			taskYIELD();
 
- 		}
 
- 		#endif /* configUSE_PREEMPTION */
 
- 		#if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )
 
- 		{
 
- 			/* When using preemption tasks of equal priority will be
 
- 			timesliced.  If a task that is sharing the idle priority is ready
 
- 			to run then the idle task should yield before the end of the
 
- 			timeslice.
 
- 			A critical region is not required here as we are just reading from
 
- 			the list, and an occasional incorrect value will not matter.  If
 
- 			the ready list at the idle priority contains more than one task
 
- 			then a task other than the idle task is ready to execute. */
 
- 			if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) 1 )
 
- 			{
 
- 				taskYIELD();
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 		}
 
- 		#endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */
 
- 		#if ( configUSE_IDLE_HOOK == 1 )
 
- 		{
 
- 			extern void vApplicationIdleHook( void );
 
- 			/* Call the user defined function from within the idle task.  This
 
- 			allows the application designer to add background functionality
 
- 			without the overhead of a separate task.
 
- 			NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,
 
- 			CALL A FUNCTION THAT MIGHT BLOCK. */
 
- 			vApplicationIdleHook();
 
- 		}
 
- 		#endif /* configUSE_IDLE_HOOK */
 
- 		/* This conditional compilation should use inequality to 0, not equality
 
- 		to 1.  This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when
 
- 		user defined low power mode	implementations require
 
- 		configUSE_TICKLESS_IDLE to be set to a value other than 1. */
 
- 		#if ( configUSE_TICKLESS_IDLE != 0 )
 
- 		{
 
- 		TickType_t xExpectedIdleTime;
 
- 			/* It is not desirable to suspend then resume the scheduler on
 
- 			each iteration of the idle task.  Therefore, a preliminary
 
- 			test of the expected idle time is performed without the
 
- 			scheduler suspended.  The result here is not necessarily
 
- 			valid. */
 
- 			xExpectedIdleTime = prvGetExpectedIdleTime();
 
- 			if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
 
- 			{
 
- 				vTaskSuspendAll();
 
- 				{
 
- 					/* Now the scheduler is suspended, the expected idle
 
- 					time can be sampled again, and this time its value can
 
- 					be used. */
 
- 					configASSERT( xNextTaskUnblockTime >= xTickCount );
 
- 					xExpectedIdleTime = prvGetExpectedIdleTime();
 
- 					if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
 
- 					{
 
- 						traceLOW_POWER_IDLE_BEGIN();
 
- 						portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime );
 
- 						traceLOW_POWER_IDLE_END();
 
- 					}
 
- 					else
 
- 					{
 
- 						mtCOVERAGE_TEST_MARKER();
 
- 					}
 
- 				}
 
- 				( void ) xTaskResumeAll();
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 		}
 
- 		#endif /* configUSE_TICKLESS_IDLE */
 
- 	}
 
- }
 
- /*-----------------------------------------------------------*/
 
- #if configUSE_TICKLESS_IDLE != 0
 
- 	eSleepModeStatus eTaskConfirmSleepModeStatus( void )
 
- 	{
 
- 	eSleepModeStatus eReturn = eStandardSleep;
 
- 		if( listCURRENT_LIST_LENGTH( &xPendingReadyList ) != 0 )
 
- 		{
 
- 			/* A task was made ready while the scheduler was suspended. */
 
- 			eReturn = eAbortSleep;
 
- 		}
 
- 		else if( xYieldPending != pdFALSE )
 
- 		{
 
- 			/* A yield was pended while the scheduler was suspended. */
 
- 			eReturn = eAbortSleep;
 
- 		}
 
- 		else
 
- 		{
 
- 			#if configUSE_TIMERS == 0
 
- 			{
 
- 				/* The idle task exists in addition to the application tasks. */
 
- 				const UBaseType_t uxNonApplicationTasks = 1;
 
- 				/* If timers are not being used and all the tasks are in the
 
- 				suspended list (which might mean they have an infinite block
 
- 				time rather than actually being suspended) then it is safe to
 
- 				turn all clocks off and just wait for external interrupts. */
 
- 				if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == ( uxCurrentNumberOfTasks - uxNonApplicationTasks ) )
 
- 				{
 
- 					eReturn = eNoTasksWaitingTimeout;
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 			}
 
- 			#endif /* configUSE_TIMERS */
 
- 		}
 
- 		return eReturn;
 
- 	}
 
- #endif /* configUSE_TICKLESS_IDLE */
 
- /*-----------------------------------------------------------*/
 
- static void prvInitialiseTCBVariables( TCB_t * const pxTCB, const char * const pcName, UBaseType_t uxPriority, const MemoryRegion_t * const xRegions, const uint16_t usStackDepth ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
 
- {
 
- UBaseType_t x;
 
- 	/* Store the task name in the TCB. */
 
- 	for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ )
 
- 	{
 
- 		pxTCB->pcTaskName[ x ] = pcName[ x ];
 
- 		/* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than
 
- 		configMAX_TASK_NAME_LEN characters just in case the memory after the
 
- 		string is not accessible (extremely unlikely). */
 
- 		if( pcName[ x ] == 0x00 )
 
- 		{
 
- 			break;
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 	}
 
- 	/* Ensure the name string is terminated in the case that the string length
 
- 	was greater or equal to configMAX_TASK_NAME_LEN. */
 
- 	pxTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0';
 
- 	/* This is used as an array index so must ensure it's not too large.  First
 
- 	remove the privilege bit if one is present. */
 
- 	if( uxPriority >= ( UBaseType_t ) configMAX_PRIORITIES )
 
- 	{
 
- 		uxPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U;
 
- 	}
 
- 	else
 
- 	{
 
- 		mtCOVERAGE_TEST_MARKER();
 
- 	}
 
- 	pxTCB->uxPriority = uxPriority;
 
- 	#if ( configUSE_MUTEXES == 1 )
 
- 	{
 
- 		pxTCB->uxBasePriority = uxPriority;
 
- 		pxTCB->uxMutexesHeld = 0;
 
- 	}
 
- 	#endif /* configUSE_MUTEXES */
 
- 	vListInitialiseItem( &( pxTCB->xGenericListItem ) );
 
- 	vListInitialiseItem( &( pxTCB->xEventListItem ) );
 
- 	/* Set the pxTCB as a link back from the ListItem_t.  This is so we can get
 
- 	back to	the containing TCB from a generic item in a list. */
 
- 	listSET_LIST_ITEM_OWNER( &( pxTCB->xGenericListItem ), pxTCB );
 
- 	/* Event lists are always in priority order. */
 
- 	listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
 
- 	listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB );
 
- 	#if ( portCRITICAL_NESTING_IN_TCB == 1 )
 
- 	{
 
- 		pxTCB->uxCriticalNesting = ( UBaseType_t ) 0U;
 
- 	}
 
- 	#endif /* portCRITICAL_NESTING_IN_TCB */
 
- 	#if ( configUSE_APPLICATION_TASK_TAG == 1 )
 
- 	{
 
- 		pxTCB->pxTaskTag = NULL;
 
- 	}
 
- 	#endif /* configUSE_APPLICATION_TASK_TAG */
 
- 	#if ( configGENERATE_RUN_TIME_STATS == 1 )
 
- 	{
 
- 		pxTCB->ulRunTimeCounter = 0UL;
 
- 	}
 
- 	#endif /* configGENERATE_RUN_TIME_STATS */
 
- 	#if ( portUSING_MPU_WRAPPERS == 1 )
 
- 	{
 
- 		vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, pxTCB->pxStack, usStackDepth );
 
- 	}
 
- 	#else /* portUSING_MPU_WRAPPERS */
 
- 	{
 
- 		( void ) xRegions;
 
- 		( void ) usStackDepth;
 
- 	}
 
- 	#endif /* portUSING_MPU_WRAPPERS */
 
- 	#if ( configUSE_TASK_NOTIFICATIONS == 1 )
 
- 	{
 
- 		pxTCB->ulNotifiedValue = 0;
 
- 		pxTCB->eNotifyState = eNotWaitingNotification;
 
- 	}
 
- 	#endif
 
- 	#if ( configUSE_NEWLIB_REENTRANT == 1 )
 
- 	{
 
- 		/* Initialise this task's Newlib reent structure. */
 
- 		_REENT_INIT_PTR( ( &( pxTCB->xNewLib_reent ) ) );
 
- 	}
 
- 	#endif /* configUSE_NEWLIB_REENTRANT */
 
- }
 
- /*-----------------------------------------------------------*/
 
- #if ( portUSING_MPU_WRAPPERS == 1 )
 
- 	void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, const MemoryRegion_t * const xRegions )
 
- 	{
 
- 	TCB_t *pxTCB;
 
- 		/* If null is passed in here then we are deleting ourselves. */
 
- 		pxTCB = prvGetTCBFromHandle( xTaskToModify );
 
-         vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 );
 
- 	}
 
- #endif /* portUSING_MPU_WRAPPERS */
 
- /*-----------------------------------------------------------*/
 
- static void prvInitialiseTaskLists( void )
 
- {
 
- UBaseType_t uxPriority;
 
- 	for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ )
 
- 	{
 
- 		vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) );
 
- 	}
 
- 	vListInitialise( &xDelayedTaskList1 );
 
- 	vListInitialise( &xDelayedTaskList2 );
 
- 	vListInitialise( &xPendingReadyList );
 
- 	#if ( INCLUDE_vTaskDelete == 1 )
 
- 	{
 
- 		vListInitialise( &xTasksWaitingTermination );
 
- 	}
 
- 	#endif /* INCLUDE_vTaskDelete */
 
- 	#if ( INCLUDE_vTaskSuspend == 1 )
 
- 	{
 
- 		vListInitialise( &xSuspendedTaskList );
 
- 	}
 
- 	#endif /* INCLUDE_vTaskSuspend */
 
- 	/* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList
 
- 	using list2. */
 
- 	pxDelayedTaskList = &xDelayedTaskList1;
 
- 	pxOverflowDelayedTaskList = &xDelayedTaskList2;
 
- }
 
- /*-----------------------------------------------------------*/
 
- static void prvCheckTasksWaitingTermination( void )
 
- {
 
- 	#if ( INCLUDE_vTaskDelete == 1 )
 
- 	{
 
- 		BaseType_t xListIsEmpty;
 
- 		/* ucTasksDeleted is used to prevent vTaskSuspendAll() being called
 
- 		too often in the idle task. */
 
- 		while( uxTasksDeleted > ( UBaseType_t ) 0U )
 
- 		{
 
- 			vTaskSuspendAll();
 
- 			{
 
- 				xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination );
 
- 			}
 
- 			( void ) xTaskResumeAll();
 
- 			if( xListIsEmpty == pdFALSE )
 
- 			{
 
- 				TCB_t *pxTCB;
 
- 				taskENTER_CRITICAL();
 
- 				{
 
- 					pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) );
 
- 					( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
 
- 					--uxCurrentNumberOfTasks;
 
- 					--uxTasksDeleted;
 
- 				}
 
- 				taskEXIT_CRITICAL();
 
- 				prvDeleteTCB( pxTCB );
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 		}
 
- 	}
 
- 	#endif /* vTaskDelete */
 
- }
 
- /*-----------------------------------------------------------*/
 
- static void prvAddCurrentTaskToDelayedList( const TickType_t xTimeToWake )
 
- {
 
- 	/* The list item will be inserted in wake time order. */
 
- 	listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );
 
- 	if( xTimeToWake < xTickCount )
 
- 	{
 
- 		/* Wake time has overflowed.  Place this item in the overflow list. */
 
- 		vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) );
 
- 	}
 
- 	else
 
- 	{
 
- 		/* The wake time has not overflowed, so the current block list is used. */
 
- 		vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) );
 
- 		/* If the task entering the blocked state was placed at the head of the
 
- 		list of blocked tasks then xNextTaskUnblockTime needs to be updated
 
- 		too. */
 
- 		if( xTimeToWake < xNextTaskUnblockTime )
 
- 		{
 
- 			xNextTaskUnblockTime = xTimeToWake;
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 	}
 
- }
 
- /*-----------------------------------------------------------*/
 
- static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer )
 
- {
 
- TCB_t *pxNewTCB;
 
- 	/* If the stack grows down then allocate the stack then the TCB so the stack
 
- 	does not grow into the TCB.  Likewise if the stack grows up then allocate
 
- 	the TCB then the stack. */
 
- 	#if( portSTACK_GROWTH > 0 )
 
- 	{
 
- 		/* Allocate space for the TCB.  Where the memory comes from depends on
 
- 		the implementation of the port malloc function. */
 
- 		pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
 
- 		if( pxNewTCB != NULL )
 
- 		{
 
- 			/* Allocate space for the stack used by the task being created.
 
- 			The base of the stack memory stored in the TCB so the task can
 
- 			be deleted later if required. */
 
- 			pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocAligned( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ), puxStackBuffer ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
 
- 			if( pxNewTCB->pxStack == NULL )
 
- 			{
 
- 				/* Could not allocate the stack.  Delete the allocated TCB. */
 
- 				vPortFree( pxNewTCB );
 
- 				pxNewTCB = NULL;
 
- 			}
 
- 		}
 
- 	}
 
- 	#else /* portSTACK_GROWTH */
 
- 	{
 
- 	StackType_t *pxStack;
 
- 		/* Allocate space for the stack used by the task being created. */
 
- 		pxStack = ( StackType_t * ) pvPortMallocAligned( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ), puxStackBuffer ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
 
- 		if( pxStack != NULL )
 
- 		{
 
- 			/* Allocate space for the TCB.  Where the memory comes from depends
 
- 			on the implementation of the port malloc function. */
 
- 			pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
 
- 			if( pxNewTCB != NULL )
 
- 			{
 
- 				/* Store the stack location in the TCB. */
 
- 				pxNewTCB->pxStack = pxStack;
 
- 			}
 
- 			else
 
- 			{
 
- 				/* The stack cannot be used as the TCB was not created.  Free it
 
- 				again. */
 
- 				vPortFree( pxStack );
 
- 			}
 
- 		}
 
- 		else
 
- 		{
 
- 			pxNewTCB = NULL;
 
- 		}
 
- 	}
 
- 	#endif /* portSTACK_GROWTH */
 
- 	if( pxNewTCB != NULL )
 
- 	{
 
- 		/* Avoid dependency on memset() if it is not required. */
 
- 		#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
 
- 		{
 
- 			/* Just to help debugging. */
 
- 			( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) usStackDepth * sizeof( StackType_t ) );
 
- 		}
 
- 		#endif /* ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) ) */
 
- 	}
 
- 	return pxNewTCB;
 
- }
 
- /*-----------------------------------------------------------*/
 
- #if ( configUSE_TRACE_FACILITY == 1 )
 
- 	static UBaseType_t prvListTaskWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState )
 
- 	{
 
- 	volatile TCB_t *pxNextTCB, *pxFirstTCB;
 
- 	UBaseType_t uxTask = 0;
 
- 		if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 )
 
- 		{
 
- 			listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
 
- 			/* Populate an TaskStatus_t structure within the
 
- 			pxTaskStatusArray array for each task that is referenced from
 
- 			pxList.  See the definition of TaskStatus_t in task.h for the
 
- 			meaning of each TaskStatus_t structure member. */
 
- 			do
 
- 			{
 
- 				listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
 
- 				pxTaskStatusArray[ uxTask ].xHandle = ( TaskHandle_t ) pxNextTCB;
 
- 				pxTaskStatusArray[ uxTask ].pcTaskName = ( const char * ) &( pxNextTCB->pcTaskName [ 0 ] );
 
- 				pxTaskStatusArray[ uxTask ].xTaskNumber = pxNextTCB->uxTCBNumber;
 
- 				pxTaskStatusArray[ uxTask ].eCurrentState = eState;
 
- 				pxTaskStatusArray[ uxTask ].uxCurrentPriority = pxNextTCB->uxPriority;
 
- 				#if ( INCLUDE_vTaskSuspend == 1 )
 
- 				{
 
- 					/* If the task is in the suspended list then there is a chance
 
- 					it is actually just blocked indefinitely - so really it should
 
- 					be reported as being in the Blocked state. */
 
- 					if( eState == eSuspended )
 
- 					{
 
- 						if( listLIST_ITEM_CONTAINER( &( pxNextTCB->xEventListItem ) ) != NULL )
 
- 						{
 
- 							pxTaskStatusArray[ uxTask ].eCurrentState = eBlocked;
 
- 						}
 
- 					}
 
- 				}
 
- 				#endif /* INCLUDE_vTaskSuspend */
 
- 				#if ( configUSE_MUTEXES == 1 )
 
- 				{
 
- 					pxTaskStatusArray[ uxTask ].uxBasePriority = pxNextTCB->uxBasePriority;
 
- 				}
 
- 				#else
 
- 				{
 
- 					pxTaskStatusArray[ uxTask ].uxBasePriority = 0;
 
- 				}
 
- 				#endif
 
- 				#if ( configGENERATE_RUN_TIME_STATS == 1 )
 
- 				{
 
- 					pxTaskStatusArray[ uxTask ].ulRunTimeCounter = pxNextTCB->ulRunTimeCounter;
 
- 				}
 
- 				#else
 
- 				{
 
- 					pxTaskStatusArray[ uxTask ].ulRunTimeCounter = 0;
 
- 				}
 
- 				#endif
 
- 				#if ( portSTACK_GROWTH > 0 )
 
- 				{
 
- 					pxTaskStatusArray[ uxTask ].usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxNextTCB->pxEndOfStack );
 
- 				}
 
- 				#else
 
- 				{
 
- 					pxTaskStatusArray[ uxTask ].usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxNextTCB->pxStack );
 
- 				}
 
- 				#endif
 
- 				uxTask++;
 
- 			} while( pxNextTCB != pxFirstTCB );
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 		return uxTask;
 
- 	}
 
- #endif /* configUSE_TRACE_FACILITY */
 
- /*-----------------------------------------------------------*/
 
- #if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
 
- 	static uint16_t prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte )
 
- 	{
 
- 	uint32_t ulCount = 0U;
 
- 		while( *pucStackByte == ( uint8_t ) tskSTACK_FILL_BYTE )
 
- 		{
 
- 			pucStackByte -= portSTACK_GROWTH;
 
- 			ulCount++;
 
- 		}
 
- 		ulCount /= ( uint32_t ) sizeof( StackType_t ); /*lint !e961 Casting is not redundant on smaller architectures. */
 
- 		return ( uint16_t ) ulCount;
 
- 	}
 
- #endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) */
 
- /*-----------------------------------------------------------*/
 
- #if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )
 
- 	UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask )
 
- 	{
 
- 	TCB_t *pxTCB;
 
- 	uint8_t *pucEndOfStack;
 
- 	UBaseType_t uxReturn;
 
- 		pxTCB = prvGetTCBFromHandle( xTask );
 
- 		#if portSTACK_GROWTH < 0
 
- 		{
 
- 			pucEndOfStack = ( uint8_t * ) pxTCB->pxStack;
 
- 		}
 
- 		#else
 
- 		{
 
- 			pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack;
 
- 		}
 
- 		#endif
 
- 		uxReturn = ( UBaseType_t ) prvTaskCheckFreeStackSpace( pucEndOfStack );
 
- 		return uxReturn;
 
- 	}
 
- #endif /* INCLUDE_uxTaskGetStackHighWaterMark */
 
- /*-----------------------------------------------------------*/
 
- #if ( INCLUDE_vTaskDelete == 1 )
 
- 	static void prvDeleteTCB( TCB_t *pxTCB )
 
- 	{
 
- 		/* This call is required specifically for the TriCore port.  It must be
 
- 		above the vPortFree() calls.  The call is also used by ports/demos that
 
- 		want to allocate and clean RAM statically. */
 
- 		portCLEAN_UP_TCB( pxTCB );
 
- 		/* Free up the memory allocated by the scheduler for the task.  It is up
 
- 		to the task to free any memory allocated at the application level. */
 
- 		#if ( configUSE_NEWLIB_REENTRANT == 1 )
 
- 		{
 
- 			_reclaim_reent( &( pxTCB->xNewLib_reent ) );
 
- 		}
 
- 		#endif /* configUSE_NEWLIB_REENTRANT */
 
- 		#if( portUSING_MPU_WRAPPERS == 1 )
 
- 		{
 
- 			/* Only free the stack if it was allocated dynamically in the first
 
- 			place. */
 
- 			if( pxTCB->xUsingStaticallyAllocatedStack == pdFALSE )
 
- 			{
 
- 				vPortFreeAligned( pxTCB->pxStack );
 
- 			}
 
- 		}
 
- 		#else
 
- 		{
 
- 			vPortFreeAligned( pxTCB->pxStack );
 
- 		}
 
- 		#endif
 
- 		vPortFree( pxTCB );
 
- 	}
 
- #endif /* INCLUDE_vTaskDelete */
 
- /*-----------------------------------------------------------*/
 
- static void prvResetNextTaskUnblockTime( void )
 
- {
 
- TCB_t *pxTCB;
 
- 	if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )
 
- 	{
 
- 		/* The new current delayed list is empty.  Set
 
- 		xNextTaskUnblockTime to the maximum possible value so it is
 
- 		extremely unlikely that the
 
- 		if( xTickCount >= xNextTaskUnblockTime ) test will pass until
 
- 		there is an item in the delayed list. */
 
- 		xNextTaskUnblockTime = portMAX_DELAY;
 
- 	}
 
- 	else
 
- 	{
 
- 		/* The new current delayed list is not empty, get the value of
 
- 		the item at the head of the delayed list.  This is the time at
 
- 		which the task at the head of the delayed list should be removed
 
- 		from the Blocked state. */
 
- 		( pxTCB ) = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
 
- 		xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( ( pxTCB )->xGenericListItem ) );
 
- 	}
 
- }
 
- /*-----------------------------------------------------------*/
 
- #if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )
 
- 	TaskHandle_t xTaskGetCurrentTaskHandle( void )
 
- 	{
 
- 	TaskHandle_t xReturn;
 
- 		/* A critical section is not required as this is not called from
 
- 		an interrupt and the current TCB will always be the same for any
 
- 		individual execution thread. */
 
- 		xReturn = pxCurrentTCB;
 
- 		return xReturn;
 
- 	}
 
- #endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */
 
- /*-----------------------------------------------------------*/
 
- #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
 
- 	BaseType_t xTaskGetSchedulerState( void )
 
- 	{
 
- 	BaseType_t xReturn;
 
- 		if( xSchedulerRunning == pdFALSE )
 
- 		{
 
- 			xReturn = taskSCHEDULER_NOT_STARTED;
 
- 		}
 
- 		else
 
- 		{
 
- 			if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
 
- 			{
 
- 				xReturn = taskSCHEDULER_RUNNING;
 
- 			}
 
- 			else
 
- 			{
 
- 				xReturn = taskSCHEDULER_SUSPENDED;
 
- 			}
 
- 		}
 
- 		return xReturn;
 
- 	}
 
- #endif /* ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) */
 
- /*-----------------------------------------------------------*/
 
- #if ( configUSE_MUTEXES == 1 )
 
- 	void vTaskPriorityInherit( TaskHandle_t const pxMutexHolder )
 
- 	{
 
- 	TCB_t * const pxTCB = ( TCB_t * ) pxMutexHolder;
 
- 		/* If the mutex was given back by an interrupt while the queue was
 
- 		locked then the mutex holder might now be NULL. */
 
- 		if( pxMutexHolder != NULL )
 
- 		{
 
- 			if( pxTCB->uxPriority < pxCurrentTCB->uxPriority )
 
- 			{
 
- 				/* Adjust the mutex holder state to account for its new
 
- 				priority.  Only reset the event list item value if the value is
 
- 				not	being used for anything else. */
 
- 				if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL )
 
- 				{
 
- 					listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 				/* If the task being modified is in the ready state it will need to
 
- 				be moved into a new list. */
 
- 				if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )
 
- 				{
 
- 					if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
 
- 					{
 
- 						taskRESET_READY_PRIORITY( pxTCB->uxPriority );
 
- 					}
 
- 					else
 
- 					{
 
- 						mtCOVERAGE_TEST_MARKER();
 
- 					}
 
- 					/* Inherit the priority before being moved into the new list. */
 
- 					pxTCB->uxPriority = pxCurrentTCB->uxPriority;
 
- 					prvAddTaskToReadyList( pxTCB );
 
- 				}
 
- 				else
 
- 				{
 
- 					/* Just inherit the priority. */
 
- 					pxTCB->uxPriority = pxCurrentTCB->uxPriority;
 
- 				}
 
- 				traceTASK_PRIORITY_INHERIT( pxTCB, pxCurrentTCB->uxPriority );
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 	}
 
- #endif /* configUSE_MUTEXES */
 
- /*-----------------------------------------------------------*/
 
- #if ( configUSE_MUTEXES == 1 )
 
- 	BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder )
 
- 	{
 
- 	TCB_t * const pxTCB = ( TCB_t * ) pxMutexHolder;
 
- 	BaseType_t xReturn = pdFALSE;
 
- 		if( pxMutexHolder != NULL )
 
- 		{
 
- 			configASSERT( pxTCB->uxMutexesHeld );
 
- 			( pxTCB->uxMutexesHeld )--;
 
- 			if( pxTCB->uxPriority != pxTCB->uxBasePriority )
 
- 			{
 
- 				/* Only disinherit if no other mutexes are held. */
 
- 				if( pxTCB->uxMutexesHeld == ( UBaseType_t ) 0 )
 
- 				{
 
- 					/* A task can only have an inhertied priority if it holds
 
- 					the mutex.  If the mutex is held by a task then it cannot be
 
- 					given from an interrupt, and if a mutex is given by the
 
- 					holding	task then it must be the running state task.  Remove
 
- 					the	holding task from the ready	list. */
 
- 					if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
 
- 					{
 
- 						taskRESET_READY_PRIORITY( pxTCB->uxPriority );
 
- 					}
 
- 					else
 
- 					{
 
- 						mtCOVERAGE_TEST_MARKER();
 
- 					}
 
- 					/* Disinherit the priority before adding the task into the
 
- 					new	ready list. */
 
- 					traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority );
 
- 					pxTCB->uxPriority = pxTCB->uxBasePriority;
 
- 					/* Reset the event list item value.  It cannot be in use for
 
- 					any other purpose if this task is running, and it must be
 
- 					running to give back the mutex. */
 
- 					listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
 
- 					prvAddTaskToReadyList( pxTCB );
 
- 					/* Return true to indicate that a context switch is required.
 
- 					This is only actually required in the corner case whereby
 
- 					multiple mutexes were held and the mutexes were given back
 
- 					in an order different to that in which they were taken.
 
- 					If a context switch did not occur when the first mutex was
 
- 					returned, even if a task was waiting on it, then a context
 
- 					switch should occur when the last mutex is returned whether
 
- 					a task is waiting on it or not. */
 
- 					xReturn = pdTRUE;
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 		return xReturn;
 
- 	}
 
- #endif /* configUSE_MUTEXES */
 
- /*-----------------------------------------------------------*/
 
- #if ( portCRITICAL_NESTING_IN_TCB == 1 )
 
- 	void vTaskEnterCritical( void )
 
- 	{
 
- 		portDISABLE_INTERRUPTS();
 
- 		if( xSchedulerRunning != pdFALSE )
 
- 		{
 
- 			( pxCurrentTCB->uxCriticalNesting )++;
 
- 			/* This is not the interrupt safe version of the enter critical
 
- 			function so	assert() if it is being called from an interrupt
 
- 			context.  Only API functions that end in "FromISR" can be used in an
 
- 			interrupt.  Only assert if the critical nesting count is 1 to
 
- 			protect against recursive calls if the assert function also uses a
 
- 			critical section. */
 
- 			if( pxCurrentTCB->uxCriticalNesting == 1 )
 
- 			{
 
- 				portASSERT_IF_IN_ISR();
 
- 			}
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 	}
 
- #endif /* portCRITICAL_NESTING_IN_TCB */
 
- /*-----------------------------------------------------------*/
 
- #if ( portCRITICAL_NESTING_IN_TCB == 1 )
 
- 	void vTaskExitCritical( void )
 
- 	{
 
- 		if( xSchedulerRunning != pdFALSE )
 
- 		{
 
- 			if( pxCurrentTCB->uxCriticalNesting > 0U )
 
- 			{
 
- 				( pxCurrentTCB->uxCriticalNesting )--;
 
- 				if( pxCurrentTCB->uxCriticalNesting == 0U )
 
- 				{
 
- 					portENABLE_INTERRUPTS();
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 	}
 
- #endif /* portCRITICAL_NESTING_IN_TCB */
 
- /*-----------------------------------------------------------*/
 
- #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
 
- 	static char *prvWriteNameToBuffer( char *pcBuffer, const char *pcTaskName )
 
- 	{
 
- 	BaseType_t x;
 
- 		/* Start by copying the entire string. */
 
- 		strcpy( pcBuffer, pcTaskName );
 
- 		/* Pad the end of the string with spaces to ensure columns line up when
 
- 		printed out. */
 
- 		for( x = strlen( pcBuffer ); x < ( configMAX_TASK_NAME_LEN - 1 ); x++ )
 
- 		{
 
- 			pcBuffer[ x ] = ' ';
 
- 		}
 
- 		/* Terminate. */
 
- 		pcBuffer[ x ] = 0x00;
 
- 		/* Return the new end of string. */
 
- 		return &( pcBuffer[ x ] );
 
- 	}
 
- #endif /* ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) */
 
- /*-----------------------------------------------------------*/
 
- #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
 
- 	void vTaskList( char * pcWriteBuffer )
 
- 	{
 
- 	TaskStatus_t *pxTaskStatusArray;
 
- 	volatile UBaseType_t uxArraySize, x;
 
- 	char cStatus;
 
- 		/*
 
- 		 * PLEASE NOTE:
 
- 		 *
 
- 		 * This function is provided for convenience only, and is used by many
 
- 		 * of the demo applications.  Do not consider it to be part of the
 
- 		 * scheduler.
 
- 		 *
 
- 		 * vTaskList() calls uxTaskGetSystemState(), then formats part of the
 
- 		 * uxTaskGetSystemState() output into a human readable table that
 
- 		 * displays task names, states and stack usage.
 
- 		 *
 
- 		 * vTaskList() has a dependency on the sprintf() C library function that
 
- 		 * might bloat the code size, use a lot of stack, and provide different
 
- 		 * results on different platforms.  An alternative, tiny, third party,
 
- 		 * and limited functionality implementation of sprintf() is provided in
 
- 		 * many of the FreeRTOS/Demo sub-directories in a file called
 
- 		 * printf-stdarg.c (note printf-stdarg.c does not provide a full
 
- 		 * snprintf() implementation!).
 
- 		 *
 
- 		 * It is recommended that production systems call uxTaskGetSystemState()
 
- 		 * directly to get access to raw stats data, rather than indirectly
 
- 		 * through a call to vTaskList().
 
- 		 */
 
- 		/* Make sure the write buffer does not contain a string. */
 
- 		*pcWriteBuffer = 0x00;
 
- 		/* Take a snapshot of the number of tasks in case it changes while this
 
- 		function is executing. */
 
- 		uxArraySize = uxCurrentNumberOfTasks;
 
- 		/* Allocate an array index for each task. */
 
- 		pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) );
 
- 		if( pxTaskStatusArray != NULL )
 
- 		{
 
- 			/* Generate the (binary) data. */
 
- 			uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, NULL );
 
- 			/* Create a human readable table from the binary data. */
 
- 			for( x = 0; x < uxArraySize; x++ )
 
- 			{
 
- 				switch( pxTaskStatusArray[ x ].eCurrentState )
 
- 				{
 
- 					case eReady:		cStatus = tskREADY_CHAR;
 
- 										break;
 
- 					case eBlocked:		cStatus = tskBLOCKED_CHAR;
 
- 										break;
 
- 					case eSuspended:	cStatus = tskSUSPENDED_CHAR;
 
- 										break;
 
- 					case eDeleted:		cStatus = tskDELETED_CHAR;
 
- 										break;
 
- 					default:			/* Should not get here, but it is included
 
- 										to prevent static checking errors. */
 
- 										cStatus = 0x00;
 
- 										break;
 
- 				}
 
- 				/* Write the task name to the string, padding with spaces so it
 
- 				can be printed in tabular form more easily. */
 
- 				pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName );
 
- 				/* Write the rest of the string. */
 
- 				sprintf( pcWriteBuffer, "\t%c\t%u\t%u\t%u\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber );
 
- 				pcWriteBuffer += strlen( pcWriteBuffer );
 
- 			}
 
- 			/* Free the array again. */
 
- 			vPortFree( pxTaskStatusArray );
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 	}
 
- #endif /* ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */
 
- /*----------------------------------------------------------*/
 
- #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
 
- 	void vTaskGetRunTimeStats( char *pcWriteBuffer )
 
- 	{
 
- 	TaskStatus_t *pxTaskStatusArray;
 
- 	volatile UBaseType_t uxArraySize, x;
 
- 	uint32_t ulTotalTime, ulStatsAsPercentage;
 
- 		#if( configUSE_TRACE_FACILITY != 1 )
 
- 		{
 
- 			#error configUSE_TRACE_FACILITY must also be set to 1 in FreeRTOSConfig.h to use vTaskGetRunTimeStats().
 
- 		}
 
- 		#endif
 
- 		/*
 
- 		 * PLEASE NOTE:
 
- 		 *
 
- 		 * This function is provided for convenience only, and is used by many
 
- 		 * of the demo applications.  Do not consider it to be part of the
 
- 		 * scheduler.
 
- 		 *
 
- 		 * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part
 
- 		 * of the uxTaskGetSystemState() output into a human readable table that
 
- 		 * displays the amount of time each task has spent in the Running state
 
- 		 * in both absolute and percentage terms.
 
- 		 *
 
- 		 * vTaskGetRunTimeStats() has a dependency on the sprintf() C library
 
- 		 * function that might bloat the code size, use a lot of stack, and
 
- 		 * provide different results on different platforms.  An alternative,
 
- 		 * tiny, third party, and limited functionality implementation of
 
- 		 * sprintf() is provided in many of the FreeRTOS/Demo sub-directories in
 
- 		 * a file called printf-stdarg.c (note printf-stdarg.c does not provide
 
- 		 * a full snprintf() implementation!).
 
- 		 *
 
- 		 * It is recommended that production systems call uxTaskGetSystemState()
 
- 		 * directly to get access to raw stats data, rather than indirectly
 
- 		 * through a call to vTaskGetRunTimeStats().
 
- 		 */
 
- 		/* Make sure the write buffer does not contain a string. */
 
- 		*pcWriteBuffer = 0x00;
 
- 		/* Take a snapshot of the number of tasks in case it changes while this
 
- 		function is executing. */
 
- 		uxArraySize = uxCurrentNumberOfTasks;
 
- 		/* Allocate an array index for each task. */
 
- 		pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) );
 
- 		if( pxTaskStatusArray != NULL )
 
- 		{
 
- 			/* Generate the (binary) data. */
 
- 			uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalTime );
 
- 			/* For percentage calculations. */
 
- 			ulTotalTime /= 100UL;
 
- 			/* Avoid divide by zero errors. */
 
- 			if( ulTotalTime > 0 )
 
- 			{
 
- 				/* Create a human readable table from the binary data. */
 
- 				for( x = 0; x < uxArraySize; x++ )
 
- 				{
 
- 					/* What percentage of the total run time has the task used?
 
- 					This will always be rounded down to the nearest integer.
 
- 					ulTotalRunTimeDiv100 has already been divided by 100. */
 
- 					ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime;
 
- 					/* Write the task name to the string, padding with
 
- 					spaces so it can be printed in tabular form more
 
- 					easily. */
 
- 					pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName );
 
- 					if( ulStatsAsPercentage > 0UL )
 
- 					{
 
- 						#ifdef portLU_PRINTF_SPECIFIER_REQUIRED
 
- 						{
 
- 							sprintf( pcWriteBuffer, "\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
 
- 						}
 
- 						#else
 
- 						{
 
- 							/* sizeof( int ) == sizeof( long ) so a smaller
 
- 							printf() library can be used. */
 
- 							sprintf( pcWriteBuffer, "\t%u\t\t%u%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage );
 
- 						}
 
- 						#endif
 
- 					}
 
- 					else
 
- 					{
 
- 						/* If the percentage is zero here then the task has
 
- 						consumed less than 1% of the total run time. */
 
- 						#ifdef portLU_PRINTF_SPECIFIER_REQUIRED
 
- 						{
 
- 							sprintf( pcWriteBuffer, "\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].ulRunTimeCounter );
 
- 						}
 
- 						#else
 
- 						{
 
- 							/* sizeof( int ) == sizeof( long ) so a smaller
 
- 							printf() library can be used. */
 
- 							sprintf( pcWriteBuffer, "\t%u\t\t<1%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter );
 
- 						}
 
- 						#endif
 
- 					}
 
- 					pcWriteBuffer += strlen( pcWriteBuffer );
 
- 				}
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 			/* Free the array again. */
 
- 			vPortFree( pxTaskStatusArray );
 
- 		}
 
- 		else
 
- 		{
 
- 			mtCOVERAGE_TEST_MARKER();
 
- 		}
 
- 	}
 
- #endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */
 
- /*-----------------------------------------------------------*/
 
- TickType_t uxTaskResetEventItemValue( void )
 
- {
 
- TickType_t uxReturn;
 
- 	uxReturn = listGET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ) );
 
- 	/* Reset the event list item to its normal value - so it can be used with
 
- 	queues and semaphores. */
 
- 	listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
 
- 	return uxReturn;
 
- }
 
- /*-----------------------------------------------------------*/
 
- #if ( configUSE_MUTEXES == 1 )
 
- 	void *pvTaskIncrementMutexHeldCount( void )
 
- 	{
 
- 		/* If xSemaphoreCreateMutex() is called before any tasks have been created
 
- 		then pxCurrentTCB will be NULL. */
 
- 		if( pxCurrentTCB != NULL )
 
- 		{
 
- 			( pxCurrentTCB->uxMutexesHeld )++;
 
- 		}
 
- 		return pxCurrentTCB;
 
- 	}
 
- #endif /* configUSE_MUTEXES */
 
- /*-----------------------------------------------------------*/
 
- #if( configUSE_TASK_NOTIFICATIONS == 1 )
 
- 	uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait )
 
- 	{
 
- 	TickType_t xTimeToWake;
 
- 	uint32_t ulReturn;
 
- 		taskENTER_CRITICAL();
 
- 		{
 
- 			/* Only block if the notification count is not already non-zero. */
 
- 			if( pxCurrentTCB->ulNotifiedValue == 0UL )
 
- 			{
 
- 				/* Mark this task as waiting for a notification. */
 
- 				pxCurrentTCB->eNotifyState = eWaitingNotification;
 
- 				if( xTicksToWait > ( TickType_t ) 0 )
 
- 				{
 
- 					/* The task is going to block.  First it must be removed
 
- 					from the ready list. */
 
- 					if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
 
- 					{
 
- 						/* The current task must be in a ready list, so there is
 
- 						no need to check, and the port reset macro can be called
 
- 						directly. */
 
- 						portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
 
- 					}
 
- 					else
 
- 					{
 
- 						mtCOVERAGE_TEST_MARKER();
 
- 					}
 
- 					#if ( INCLUDE_vTaskSuspend == 1 )
 
- 					{
 
- 						if( xTicksToWait == portMAX_DELAY )
 
- 						{
 
- 							/* Add the task to the suspended task list instead
 
- 							of a delayed task list to ensure the task is not
 
- 							woken by a timing event.  It will block
 
- 							indefinitely. */
 
- 							vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
 
- 						}
 
- 						else
 
- 						{
 
- 							/* Calculate the time at which the task should be
 
- 							woken if no notification events occur.  This may
 
- 							overflow but this doesn't matter, the scheduler will
 
- 							handle it. */
 
- 							xTimeToWake = xTickCount + xTicksToWait;
 
- 							prvAddCurrentTaskToDelayedList( xTimeToWake );
 
- 						}
 
- 					}
 
- 					#else /* INCLUDE_vTaskSuspend */
 
- 					{
 
- 							/* Calculate the time at which the task should be
 
- 							woken if the event does not occur.  This may
 
- 							overflow but this doesn't matter, the scheduler will
 
- 							handle it. */
 
- 							xTimeToWake = xTickCount + xTicksToWait;
 
- 							prvAddCurrentTaskToDelayedList( xTimeToWake );
 
- 					}
 
- 					#endif /* INCLUDE_vTaskSuspend */
 
- 					/* All ports are written to allow a yield in a critical
 
- 					section (some will yield immediately, others wait until the
 
- 					critical section exits) - but it is not something that
 
- 					application code should ever do. */
 
- 					portYIELD_WITHIN_API();
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 		}
 
- 		taskEXIT_CRITICAL();
 
- 		taskENTER_CRITICAL();
 
- 		{
 
- 			ulReturn = pxCurrentTCB->ulNotifiedValue;
 
- 			if( ulReturn != 0UL )
 
- 			{
 
- 				if( xClearCountOnExit != pdFALSE )
 
- 				{
 
- 					pxCurrentTCB->ulNotifiedValue = 0UL;
 
- 				}
 
- 				else
 
- 				{
 
- 					( pxCurrentTCB->ulNotifiedValue )--;
 
- 				}
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 			pxCurrentTCB->eNotifyState = eNotWaitingNotification;
 
- 		}
 
- 		taskEXIT_CRITICAL();
 
- 		return ulReturn;
 
- 	}
 
- #endif /* configUSE_TASK_NOTIFICATIONS */
 
- /*-----------------------------------------------------------*/
 
- #if( configUSE_TASK_NOTIFICATIONS == 1 )
 
- 	BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait )
 
- 	{
 
- 	TickType_t xTimeToWake;
 
- 	BaseType_t xReturn;
 
- 		taskENTER_CRITICAL();
 
- 		{
 
- 			/* Only block if a notification is not already pending. */
 
- 			if( pxCurrentTCB->eNotifyState != eNotified )
 
- 			{
 
- 				/* Clear bits in the task's notification value as bits may get
 
- 				set	by the notifying task or interrupt.  This can be used to
 
- 				clear the value to zero. */
 
- 				pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnEntry;
 
- 				/* Mark this task as waiting for a notification. */
 
- 				pxCurrentTCB->eNotifyState = eWaitingNotification;
 
- 				if( xTicksToWait > ( TickType_t ) 0 )
 
- 				{
 
- 					/* The task is going to block.  First it must be removed
 
- 					from the	ready list. */
 
- 					if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
 
- 					{
 
- 						/* The current task must be in a ready list, so there is
 
- 						no need to check, and the port reset macro can be called
 
- 						directly. */
 
- 						portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
 
- 					}
 
- 					else
 
- 					{
 
- 						mtCOVERAGE_TEST_MARKER();
 
- 					}
 
- 					#if ( INCLUDE_vTaskSuspend == 1 )
 
- 					{
 
- 						if( xTicksToWait == portMAX_DELAY )
 
- 						{
 
- 							/* Add the task to the suspended task list instead
 
- 							of a delayed task list to ensure the task is not
 
- 							woken by a timing event.  It will block
 
- 							indefinitely. */
 
- 							vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) );
 
- 						}
 
- 						else
 
- 						{
 
- 							/* Calculate the time at which the task should be
 
- 							woken if no notification events occur.  This may
 
- 							overflow but this doesn't matter, the scheduler will
 
- 							handle it. */
 
- 							xTimeToWake = xTickCount + xTicksToWait;
 
- 							prvAddCurrentTaskToDelayedList( xTimeToWake );
 
- 						}
 
- 					}
 
- 					#else /* INCLUDE_vTaskSuspend */
 
- 					{
 
- 							/* Calculate the time at which the task should be
 
- 							woken if the event does not occur.  This may
 
- 							overflow but this doesn't matter, the scheduler will
 
- 							handle it. */
 
- 							xTimeToWake = xTickCount + xTicksToWait;
 
- 							prvAddCurrentTaskToDelayedList( xTimeToWake );
 
- 					}
 
- 					#endif /* INCLUDE_vTaskSuspend */
 
- 					/* All ports are written to allow a yield in a critical
 
- 					section (some will yield immediately, others wait until the
 
- 					critical section exits) - but it is not something that
 
- 					application code should ever do. */
 
- 					portYIELD_WITHIN_API();
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 		}
 
- 		taskEXIT_CRITICAL();
 
- 		taskENTER_CRITICAL();
 
- 		{
 
- 			if( pulNotificationValue != NULL )
 
- 			{
 
- 				/* Output the current notification value, which may or may not
 
- 				have changed. */
 
- 				*pulNotificationValue = pxCurrentTCB->ulNotifiedValue;
 
- 			}
 
- 			/* If eNotifyValue is set then either the task never entered the
 
- 			blocked state (because a notification was already pending) or the
 
- 			task unblocked because of a notification.  Otherwise the task
 
- 			unblocked because of a timeout. */
 
- 			if( pxCurrentTCB->eNotifyState == eWaitingNotification )
 
- 			{
 
- 				/* A notification was not received. */
 
- 				xReturn = pdFALSE;
 
- 			}
 
- 			else
 
- 			{
 
- 				/* A notification was already pending or a notification was
 
- 				received while the task was waiting. */
 
- 				pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnExit;
 
- 				xReturn = pdTRUE;
 
- 			}
 
- 			pxCurrentTCB->eNotifyState = eNotWaitingNotification;
 
- 		}
 
- 		taskEXIT_CRITICAL();
 
- 		return xReturn;
 
- 	}
 
- #endif /* configUSE_TASK_NOTIFICATIONS */
 
- /*-----------------------------------------------------------*/
 
- #if( configUSE_TASK_NOTIFICATIONS == 1 )
 
- 	BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction )
 
- 	{
 
- 	TCB_t * pxTCB;
 
- 	eNotifyValue eOriginalNotifyState;
 
- 	BaseType_t xReturn = pdPASS;
 
- 		configASSERT( xTaskToNotify );
 
- 		pxTCB = ( TCB_t * ) xTaskToNotify;
 
- 		taskENTER_CRITICAL();
 
- 		{
 
- 			eOriginalNotifyState = pxTCB->eNotifyState;
 
- 			pxTCB->eNotifyState = eNotified;
 
- 			switch( eAction )
 
- 			{
 
- 				case eSetBits	:
 
- 					pxTCB->ulNotifiedValue |= ulValue;
 
- 					break;
 
- 				case eIncrement	:
 
- 					( pxTCB->ulNotifiedValue )++;
 
- 					break;
 
- 				case eSetValueWithOverwrite	:
 
- 					pxTCB->ulNotifiedValue = ulValue;
 
- 					break;
 
- 				case eSetValueWithoutOverwrite :
 
- 					if( eOriginalNotifyState != eNotified )
 
- 					{
 
- 						pxTCB->ulNotifiedValue = ulValue;
 
- 					}
 
- 					else
 
- 					{
 
- 						/* The value could not be written to the task. */
 
- 						xReturn = pdFAIL;
 
- 					}
 
- 					break;
 
- 				case eNoAction:
 
- 					/* The task is being notified without its notify value being
 
- 					updated. */
 
- 					break;
 
- 			}
 
- 			/* If the task is in the blocked state specifically to wait for a
 
- 			notification then unblock it now. */
 
- 			if( eOriginalNotifyState == eWaitingNotification )
 
- 			{
 
- 				( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
 
- 				prvAddTaskToReadyList( pxTCB );
 
- 				/* The task should not have been on an event list. */
 
- 				configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL );
 
- 				if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
 
- 				{
 
- 					/* The notified task has a priority above the currently
 
- 					executing task so a yield is required. */
 
- 					portYIELD_WITHIN_API();
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 			}
 
- 			else
 
- 			{
 
- 				mtCOVERAGE_TEST_MARKER();
 
- 			}
 
- 		}
 
- 		taskEXIT_CRITICAL();
 
- 		return xReturn;
 
- 	}
 
- #endif /* configUSE_TASK_NOTIFICATIONS */
 
- /*-----------------------------------------------------------*/
 
- #if( configUSE_TASK_NOTIFICATIONS == 1 )
 
- 	BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken )
 
- 	{
 
- 	TCB_t * pxTCB;
 
- 	eNotifyValue eOriginalNotifyState;
 
- 	BaseType_t xReturn = pdPASS;
 
- 	UBaseType_t uxSavedInterruptStatus;
 
- 		configASSERT( xTaskToNotify );
 
- 		/* RTOS ports that support interrupt nesting have the concept of a
 
- 		maximum	system call (or maximum API call) interrupt priority.
 
- 		Interrupts that are	above the maximum system call priority are keep
 
- 		permanently enabled, even when the RTOS kernel is in a critical section,
 
- 		but cannot make any calls to FreeRTOS API functions.  If configASSERT()
 
- 		is defined in FreeRTOSConfig.h then
 
- 		portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
 
- 		failure if a FreeRTOS API function is called from an interrupt that has
 
- 		been assigned a priority above the configured maximum system call
 
- 		priority.  Only FreeRTOS functions that end in FromISR can be called
 
- 		from interrupts	that have been assigned a priority at or (logically)
 
- 		below the maximum system call interrupt priority.  FreeRTOS maintains a
 
- 		separate interrupt safe API to ensure interrupt entry is as fast and as
 
- 		simple as possible.  More information (albeit Cortex-M specific) is
 
- 		provided on the following link:
 
- 		http://www.freertos.org/RTOS-Cortex-M3-M4.html */
 
- 		portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
 
- 		pxTCB = ( TCB_t * ) xTaskToNotify;
 
- 		uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
 
- 		{
 
- 			eOriginalNotifyState = pxTCB->eNotifyState;
 
- 			pxTCB->eNotifyState = eNotified;
 
- 			switch( eAction )
 
- 			{
 
- 				case eSetBits	:
 
- 					pxTCB->ulNotifiedValue |= ulValue;
 
- 					break;
 
- 				case eIncrement	:
 
- 					( pxTCB->ulNotifiedValue )++;
 
- 					break;
 
- 				case eSetValueWithOverwrite	:
 
- 					pxTCB->ulNotifiedValue = ulValue;
 
- 					break;
 
- 				case eSetValueWithoutOverwrite :
 
- 					if( eOriginalNotifyState != eNotified )
 
- 					{
 
- 						pxTCB->ulNotifiedValue = ulValue;
 
- 					}
 
- 					else
 
- 					{
 
- 						/* The value could not be written to the task. */
 
- 						xReturn = pdFAIL;
 
- 					}
 
- 					break;
 
- 				case eNoAction :
 
- 					/* The task is being notified without its notify value being
 
- 					updated. */
 
- 					break;
 
- 			}
 
- 			/* If the task is in the blocked state specifically to wait for a
 
- 			notification then unblock it now. */
 
- 			if( eOriginalNotifyState == eWaitingNotification )
 
- 			{
 
- 				/* The task should not have been on an event list. */
 
- 				configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL );
 
- 				if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
 
- 				{
 
- 					( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
 
- 					prvAddTaskToReadyList( pxTCB );
 
- 				}
 
- 				else
 
- 				{
 
- 					/* The delayed and ready lists cannot be accessed, so hold
 
- 					this task pending until the scheduler is resumed. */
 
- 					vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
 
- 				}
 
- 				if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
 
- 				{
 
- 					/* The notified task has a priority above the currently
 
- 					executing task so a yield is required. */
 
- 					if( pxHigherPriorityTaskWoken != NULL )
 
- 					{
 
- 						*pxHigherPriorityTaskWoken = pdTRUE;
 
- 					}
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 			}
 
- 		}
 
- 		portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
 
- 		return xReturn;
 
- 	}
 
- #endif /* configUSE_TASK_NOTIFICATIONS */
 
- /*-----------------------------------------------------------*/
 
- #if( configUSE_TASK_NOTIFICATIONS == 1 )
 
- 	void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken )
 
- 	{
 
- 	TCB_t * pxTCB;
 
- 	eNotifyValue eOriginalNotifyState;
 
- 	UBaseType_t uxSavedInterruptStatus;
 
- 		configASSERT( xTaskToNotify );
 
- 		/* RTOS ports that support interrupt nesting have the concept of a
 
- 		maximum	system call (or maximum API call) interrupt priority.
 
- 		Interrupts that are	above the maximum system call priority are keep
 
- 		permanently enabled, even when the RTOS kernel is in a critical section,
 
- 		but cannot make any calls to FreeRTOS API functions.  If configASSERT()
 
- 		is defined in FreeRTOSConfig.h then
 
- 		portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
 
- 		failure if a FreeRTOS API function is called from an interrupt that has
 
- 		been assigned a priority above the configured maximum system call
 
- 		priority.  Only FreeRTOS functions that end in FromISR can be called
 
- 		from interrupts	that have been assigned a priority at or (logically)
 
- 		below the maximum system call interrupt priority.  FreeRTOS maintains a
 
- 		separate interrupt safe API to ensure interrupt entry is as fast and as
 
- 		simple as possible.  More information (albeit Cortex-M specific) is
 
- 		provided on the following link:
 
- 		http://www.freertos.org/RTOS-Cortex-M3-M4.html */
 
- 		portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
 
- 		pxTCB = ( TCB_t * ) xTaskToNotify;
 
- 		uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
 
- 		{
 
- 			eOriginalNotifyState = pxTCB->eNotifyState;
 
- 			pxTCB->eNotifyState = eNotified;
 
- 			/* 'Giving' is equivalent to incrementing a count in a counting
 
- 			semaphore. */
 
- 			( pxTCB->ulNotifiedValue )++;
 
- 			/* If the task is in the blocked state specifically to wait for a
 
- 			notification then unblock it now. */
 
- 			if( eOriginalNotifyState == eWaitingNotification )
 
- 			{
 
- 				/* The task should not have been on an event list. */
 
- 				configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL );
 
- 				if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
 
- 				{
 
- 					( void ) uxListRemove( &( pxTCB->xGenericListItem ) );
 
- 					prvAddTaskToReadyList( pxTCB );
 
- 				}
 
- 				else
 
- 				{
 
- 					/* The delayed and ready lists cannot be accessed, so hold
 
- 					this task pending until the scheduler is resumed. */
 
- 					vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
 
- 				}
 
- 				if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
 
- 				{
 
- 					/* The notified task has a priority above the currently
 
- 					executing task so a yield is required. */
 
- 					if( pxHigherPriorityTaskWoken != NULL )
 
- 					{
 
- 						*pxHigherPriorityTaskWoken = pdTRUE;
 
- 					}
 
- 				}
 
- 				else
 
- 				{
 
- 					mtCOVERAGE_TEST_MARKER();
 
- 				}
 
- 			}
 
- 		}
 
- 		portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
 
- 	}
 
- #endif /* configUSE_TASK_NOTIFICATIONS */
 
- /*-----------------------------------------------------------*/
 
- #ifdef FREERTOS_MODULE_TEST
 
- 	#include "tasks_test_access_functions.h"
 
- #endif
 
 
  |