Professional Documents
Culture Documents
TheArchitectureofOpenSourceApplications(Volume2):FreeRTOS
FreeRTOS
ChristopherSvec
FreeRTOS(pronounced"freearrtoss")isanopensourcerealtimeoperatingsystem(RTOS)forembedded
systems.FreeRTOSsupportsmanydifferentarchitecturesandcompilertoolchains,andisdesignedtobe
"small,simple,andeasytouse".
FreeRTOSisunderactivedevelopment,andhasbeensinceRichardBarrystartedworkonitin2002.Asforme,
I'mnotadeveloperoforcontributortoFreeRTOS,I'mmerelyauserandafan.Asaresult,thischapterwill
favorthe"what"and"how"ofFreeRTOS'sarchitecture,withlessofthe"why"thanotherchaptersinthisbook.
Likealloperatingsystems,FreeRTOS'smainjobistoruntasks.MostofFreeRTOS'scodeinvolvesprioritizing,
scheduling,andrunninguserdefinedtasks.Unlikealloperatingsystems,FreeRTOSisarealtimeoperating
systemwhichrunsonembeddedsystems.
BytheendofthischapterIhopethatyou'llunderstandthebasicarchitectureofFreeRTOS.MostofFreeRTOS
isdedicatedtorunningtasks,soyou'llgetagoodlookatexactlyhowFreeRTOSdoesthat.
Ifthisisyourfirstlookunderthehoodofanoperatingsystem,Ialsohopethatyou'lllearnthebasicsabouthow
anyOSworks.FreeRTOSisrelativelysimple,especiallywhencomparedtoWindows,Linux,orOSX,butall
operatingsystemssharethesamebasicconceptsandgoals,solookingatanyOScanbeinstructiveand
interesting.
3.1.Whatis"Embedded"and"RealTime"?
"Embedded"and"realtime"canmeandifferentthingstodifferentpeople,solet'sdefinethemasFreeRTOS
usesthem.
Anembeddedsystemisacomputersystemthatisdesignedtodoonlyafewthings,likethesysteminaTV
remotecontrol,incarGPS,digitalwatch,orpacemaker.Embeddedsystemsaretypicallysmallerandslower
thangeneralpurposecomputersystems,andarealsousuallylessexpensive.Atypicallowendembedded
systemmayhavean8bitCPUrunningat25MHz,afewKBofRAM,andmaybe32KBofflashmemory.A
higherendembeddedsystemmayhavea32bitCPUrunningat750MHz,aGBofRAM,andmultipleGBof
flashmemory.
Realtimesystemsaredesignedtodosomethingwithinacertainamountoftimetheyguaranteethatstuff
happenswhenit'ssupposedto.
file:///D:/documents/0_A_LinuxKernel/The%20Architecture%20of%20Open%20Source%20Applications%20(Volume%202)_%20FreeRTOS.html
1/14
28/12/2015
TheArchitectureofOpenSourceApplications(Volume2):FreeRTOS
Apacemakerisanexcellentexampleofarealtimeembeddedsystem.Apacemakermustcontracttheheart
muscleattherighttimetokeepyoualiveitcan'tbetoobusytorespondintime.Pacemakersandotherreal
timeembeddedsystemsarecarefullydesignedtoruntheirtasksontime,everytime.
3.2.ArchitectureOverview
FreeRTOSisarelativelysmallapplication.TheminimumcoreofFreeRTOSisonlythreesource( .c )filesand
ahandfulofheaderfiles,totallingjustunder9000linesofcode,includingcommentsandblanklines.Atypical
binarycodeimageislessthan10KB.
FreeRTOS'scodebreaksdownintothreemainareas:tasks,communication,andhardwareinterfacing.
Tasks:AlmosthalfofFreeRTOS'scorecodedealswiththecentralconcerninmanyoperatingsystems:
tasks.AtaskisauserdefinedCfunctionwithagivenpriority. tasks.c and task.h doalltheheavy
liftingforcreating,scheduling,andmaintainingtasks.
Communication:Tasksaregood,buttasksthatcancommunicatewitheachotherareevenbetter!Which
bringsustothesecondFreeRTOSjob:communication.About40%ofFreeRTOS'scorecodedealswith
communication. queue.c and queue.h handleFreeRTOScommunication.Tasksandinterruptsuse
queuestosenddatatoeachotherandtosignaltheuseofcriticalresourcesusingsemaphoresand
mutexes.
TheHardwareWhisperer:Theapproximately9000linesofcodethatmakeupthebaseofFreeRTOSare
hardwareindependentthesamecoderunswhetherFreeRTOSisrunningonthehumble8051orthenewest,
shiniestARMcore.About6%ofFreeRTOS'scorecodeactsashimbetweenthehardwareindependent
FreeRTOScoreandthehardwaredependentcode.We'lldiscussthehardwaredependentcodeinthenext
section.
HardwareConsiderations
ThehardwareindependentFreeRTOSlayersitsontopofahardwaredependentlayer.Thishardwaredependent
layerknowshowtotalktowhateverchiparchitectureyouchoose.Figure3.1showsFreeRTOS'slayers.
Figure3.1:FreeRTOSsoftwarelayers
FreeRTOSshipswithallthehardwareindependentaswellashardwaredependentcodeyou'llneedtogeta
systemupandrunning.Itsupportsmanycompilers(CodeWarrior,GCC,IAR,etc.)aswellasmanyprocessor
architectures(ARM7,ARMCortexM3,variousPICs,SiliconLabs8051,x86,etc.).SeetheFreeRTOSwebsite
foralistofsupportedarchitecturesandcompilers.
FreeRTOSishighlyconfigurablebydesign.FreeRTOScanbebuiltasasingleCPU,barebonesRTOS,
supportingonlyafewtasks,oritcanbebuiltasahighlyfunctionalmulticorebeastwithTCP/IP,afilesystem,
andUSB.
Configurationoptionsareselectedin FreeRTOSConfig.h bysettingvarious #defines .Clockspeed,heap
size,mutexes,andAPIsubsetsareallconfigurableinthisfile,alongwithmanyotheroptions.Hereareafew
file:///D:/documents/0_A_LinuxKernel/The%20Architecture%20of%20Open%20Source%20Applications%20(Volume%202)_%20FreeRTOS.html
2/14
28/12/2015
TheArchitectureofOpenSourceApplications(Volume2):FreeRTOS
examplesthatsetthemaximumnumberoftaskprioritylevels,theCPUfrequency,thesystemtickfrequency,
theminimalstacksizeandthetotalheapsize:
#defineconfigMAX_PRIORITIES((unsignedportBASE_TYPE)5)
#defineconfigCPU_CLOCK_HZ(12000000UL)
#defineconfigTICK_RATE_HZ((portTickType)1000)
#defineconfigMINIMAL_STACK_SIZE((unsignedshort)100)
#defineconfigTOTAL_HEAP_SIZE((size_t)(4*1024))
HardwaredependentcodelivesinseparatefilesforeachcompilertoolchainandCPUarchitecture.Forexample,
ifyou'reworkingwiththeIARcompileronanARMCortexM3chip,thehardwaredependentcodelivesinthe
FreeRTOS/Source/portable/IAR/ARM_CM3/ directory. portmacro.h declaresallofthehardwarespecific
functions,while port.c and portasm.s containalloftheactualhardwaredependentcode.Thehardware
independentheaderfile portable.h #include 'sthecorrect portmacro.h fileatcompiletime.FreeRTOS
callsthehardwarespecificfunctionsusing #define 'dfunctionsdeclaredin portmacro.h .
Let'slookatanexampleofhowFreeRTOScallsahardwaredependentfunction.Thehardwareindependentfile
tasks.c frequentlyneedstoenteracriticalsectionofcodetopreventpreemption.Enteringacriticalsection
happensdifferentlyondifferentarchitectures,andthehardwareindependent tasks.c doesnotwanttohaveto
understandthehardwaredependentdetails.So tasks.c callstheglobalmacro portENTER_CRITICAL() ,glad
tobeignorantofhowitactuallyworks.Assumingwe'reusingtheIARcompileronanARMCortexM3chip,
FreeRTOSisbuiltwiththefile FreeRTOS/Source/portable/IAR/ARM_CM3/portmacro.h whichdefines
portENTER_CRITICAL() likethis:
#defineportENTER_CRITICAL()vPortEnterCritical()
vPortEnterCritical() isactuallydefinedin FreeRTOS/Source/portable/IAR/ARM_CM3/port.c .The
port.c fileishardwaredependent,andcontainscodethatunderstandstheIARcompilerandtheCortexM3
chip. vPortEnterCritical() entersthecriticalsectionusingthishardwarespecificknowledgeandreturnsto
thehardwareindependent tasks.c .
The portmacro.h filealsodefinesanarchitecture'sbasicdatatypes.Datatypesforbasicintegervariables,
pointers,andthesystemtimertickdatatypearedefinedlikethisfortheIARcompileronARMCortexM3chips:
#defineportBASE_TYPElong//Basicintegervariabletype
#defineportSTACK_TYPEunsignedlong//Pointerstomemorylocations
typedefunsignedportLONGportTickType//Thesystemtimerticktype
3.3.SchedulingTasks:AQuickOverview
TaskPrioritiesandtheReadyList
file:///D:/documents/0_A_LinuxKernel/The%20Architecture%20of%20Open%20Source%20Applications%20(Volume%202)_%20FreeRTOS.html
3/14
28/12/2015
TheArchitectureofOpenSourceApplications(Volume2):FreeRTOS
Eachtaskhasauserassignedprioritybetween0(thelowestpriority)andthecompiletimevalueof
configMAX_PRIORITIES1 (thehighestpriority).Forinstance,if configMAX_PRIORITIES issetto5,then
FreeRTOSwilluse5prioritylevels:0(lowestpriority),1,2,3,and4(highestpriority).
FreeRTOSusesa"readylist"tokeeptrackofalltasksthatarecurrentlyreadytorun.Itimplementstheready
listasanarrayoftasklistslikethis:
staticxListpxReadyTasksLists[configMAX_PRIORITIES]/*Prioritisedreadytasks.*/
pxReadyTasksLists[0] isalistofallreadypriority0tasks, pxReadyTasksLists[1] isalistofallready
priority1tasks,andsoon,allthewayupto pxReadyTasksLists[configMAX_PRIORITIES1] .
TheSystemTick
TheheartbeatofaFreeRTOSsystemiscalledthesystemtick.FreeRTOSconfiguresthesystemtogeneratea
periodictickinterrupt.Theusercanconfigurethetickinterruptfrequency,whichistypicallyinthemillisecond
range.Everytimethetickinterruptfires,the vTaskSwitchContext() functioniscalled.
vTaskSwitchContext() selectsthehighestpriorityreadytaskandputsitinthe pxCurrentTCB variablelike
this:
/*Findthehighestpriorityqueuethatcontainsreadytasks.*/
while(listLIST_IS_EMPTY(&(pxReadyTasksLists[uxTopReadyPriority])))
{
configASSERT(uxTopReadyPriority)
uxTopReadyPriority
}
/*listGET_OWNER_OF_NEXT_ENTRYwalksthroughthelist,sothetasksofthesame
prioritygetanequalshareoftheprocessortime.*/
listGET_OWNER_OF_NEXT_ENTRY(pxCurrentTCB,&(pxReadyTasksLists[uxTopReadyPriority]))
file:///D:/documents/0_A_LinuxKernel/The%20Architecture%20of%20Open%20Source%20Applications%20(Volume%202)_%20FreeRTOS.html
4/14
28/12/2015
TheArchitectureofOpenSourceApplications(Volume2):FreeRTOS
Figure3.2:BasicviewofFreeRTOSReadyList
Nowthatwehavethehighleveloverviewoutoftheway,let'sdiveintothedetails.We'lllookatthethreemain
FreeRTOSdatastructures:tasks,lists,andqueues.
3.4.Tasks
Themainjobofalloperatingsystemsistorunandcoordinateusertasks.Likemanyoperatingsystems,the
basicunitofworkinFreeRTOSisthetask.FreeRTOSusesaTaskControlBlock(TCB)torepresenteachtask.
TaskControlBlock(TCB)
TheTCBisdefinedin tasks.c likethis:
typedefstructtskTaskControlBlock
{
volatileportSTACK_TYPE*pxTopOfStack/*Pointstothelocationof
thelastitemplacedon
thetasksstack.THIS
MUSTBETHEFIRSTMEMBER
OFTHESTRUCT.*/
xListItemxGenericListItem/*Listitemusedtoplace
theTCBinreadyand
blockedqueues.*/
xListItemxEventListItem/*Listitemusedtoplace
theTCBineventlists.*/
unsignedportBASE_TYPEuxPriority/*Thepriorityofthetask
where0isthelowest
file:///D:/documents/0_A_LinuxKernel/The%20Architecture%20of%20Open%20Source%20Applications%20(Volume%202)_%20FreeRTOS.html
5/14
28/12/2015
TheArchitectureofOpenSourceApplications(Volume2):FreeRTOS
priority.*/
portSTACK_TYPE*pxStack/*Pointstothestartof
thestack.*/
signedcharpcTaskName[configMAX_TASK_NAME_LEN]/*Descriptivenamegiven
tothetaskwhencreated.
Facilitatesdebugging
only.*/
#if(portSTACK_GROWTH>0)
portSTACK_TYPE*pxEndOfStack/*Usedforstackoverflow
checkingonarchitectures
wherethestackgrowsup
fromlowmemory.*/
#endif
#if(configUSE_MUTEXES==1)
unsignedportBASE_TYPEuxBasePriority/*Theprioritylast
assignedtothetask
usedbythepriority
inheritancemechanism.*/
#endif
}tskTCB
TaskSetup
We'vealreadytouchedonhowataskisselectedandscheduledwiththe pxReadyTasksLists arraynowlet's
lookathowataskisinitiallycreated.Ataskiscreatedwhenthe xTaskCreate() functioniscalled.FreeRTOS
usesanewlyallocatedTCBobjecttostorethename,priority,andotherdetailsforatask,thenallocatesthe
amountofstacktheuserrequests(assumingthere'senoughmemoryavailable)andremembersthestartofthe
stackmemoryinTCB's pxStack member.
file:///D:/documents/0_A_LinuxKernel/The%20Architecture%20of%20Open%20Source%20Applications%20(Volume%202)_%20FreeRTOS.html
6/14
28/12/2015
TheArchitectureofOpenSourceApplications(Volume2):FreeRTOS
Thestackisinitializedtolookasifthenewtaskisalreadyrunningandwasinterruptedbyacontextswitch.This
waytheschedulercantreatnewlycreatedtasksexactlythesamewayasittreatstasksthathavebeenrunning
forawhiletheschedulerdoesn'tneedanyspecialcasecodeforhandlingnewtasks.
Thewaythatatask'sstackismadetolooklikeitwasinterruptedbyacontextswitchdependsonthe
architectureFreeRTOSisrunningon,butthisARMCortexM3processor'simplementationisagoodexample:
unsignedint*pxPortInitialiseStack(unsignedint*pxTopOfStack,
pdTASK_CODEpxCode,
void*pvParameters)
{
/*Simulatethestackframeasitwouldbecreatedbyacontextswitchinterrupt.*/
pxTopOfStack/*OffsetaddedtoaccountforthewaytheMCUusesthestackon
entry/exitofinterrupts.*/
*pxTopOfStack=portINITIAL_XPSR/*xPSR*/
pxTopOfStack
*pxTopOfStack=(portSTACK_TYPE)pxCode/*PC*/
pxTopOfStack
*pxTopOfStack=0/*LR*/
pxTopOfStack=5/*R12,R3,R2andR1.*/
*pxTopOfStack=(portSTACK_TYPE)pvParameters/*R0*/
pxTopOfStack=8/*R11,R10,R9,R8,R7,R6,R5andR4.*/
returnpxTopOfStack
}
TheARMCortexM3processorpushesregistersonthestackwhenataskisinterrupted.
pxPortInitialiseStack() modifiesthestacktolookliketheregisterswerepushedeventhoughthetask
hasn'tactuallystartedrunningyet.KnownvaluesarestoredtothestackfortheARMregisters xPSR,PC,LR,
and R0 .Theremainingregisters R1 R12 getstackspaceallocatedforthembydecrementingthetopof
stackpointer,butnospecificdataisstoredinthestackforthoseregisters.TheARMarchitecturesaysthat
thoseregistersareundefinedatreset,soa(nonbuggy)programwillnotrelyonaknownvalue.
Afterthestackisprepared,thetaskisalmostreadytorun.Firstthough,FreeRTOSdisablesinterrupts:We're
abouttostartmuckingwiththereadylistsandotherschedulerstructuresandwedon'twantanyoneelse
changingthemunderneathus.
Ifthisisthefirsttasktoeverbecreated,FreeRTOSinitializesthescheduler'stasklists.FreeRTOS'sscheduler
hasanarrayofreadylists, pxReadyTasksLists[] ,whichhasonereadylistforeachpossibleprioritylevel.
FreeRTOSalsohasafewotherlistsfortrackingtasksthathavebeensuspended,killed,anddelayed.These
areallinitializednowaswell.
Afteranyfirsttimeinitializationisdone,thenewtaskisaddedtothereadylistatitsspecifiedprioritylevel.
Interruptsarereenabledandnewtaskcreationiscomplete.
3.5.Lists
Aftertasks,themostusedFreeRTOSdatastructureisthelist.FreeRTOSusesitsliststructuretokeeptrackof
tasksforscheduling,andalsotoimplementqueues.
file:///D:/documents/0_A_LinuxKernel/The%20Architecture%20of%20Open%20Source%20Applications%20(Volume%202)_%20FreeRTOS.html
7/14
28/12/2015
TheArchitectureofOpenSourceApplications(Volume2):FreeRTOS
Figure3.3:FullviewofFreeRTOSReadyList
TheFreeRTOSlistisastandardcirculardoublylinkedlistwithacoupleofinterestingadditions.Here'salist
element:
structxLIST_ITEM
{
portTickTypexItemValue/*Thevaluebeinglisted.Inmostcases
thisisusedtosortthelistin
descendingorder.*/
volatilestructxLIST_ITEM*pxNext/*PointertothenextxListIteminthe
list.*/
volatilestructxLIST_ITEM*pxPrevious/*PointertothepreviousxListItemin
thelist.*/
void*pvOwner/*Pointertotheobject(normallyaTCB)
thatcontainsthelistitem.Thereis
thereforeatwowaylinkbetweenthe
file:///D:/documents/0_A_LinuxKernel/The%20Architecture%20of%20Open%20Source%20Applications%20(Volume%202)_%20FreeRTOS.html
8/14
28/12/2015
TheArchitectureofOpenSourceApplications(Volume2):FreeRTOS
objectcontainingthelistitemand
thelistitemitself.*/
void*pvContainer/*Pointertothelistinwhichthislist
itemisplaced(ifany).*/
}
FreeRTOSfrequentlyneedstoaccessalistacrossmultiplefor()andwhile()loopsaswellasfunctioncalls,and
soituseslistfunctionsthatmanipulatethe pxIndex pointertowalkthelist.Thelistfunction
listGET_OWNER_OF_NEXT_ENTRY() does pxIndex=pxIndex>pxNext andreturns pxIndex .(Ofcourseit
doestheproperendoflistwraparounddetectiontoo.)Thiswaythelistitselfisresponsibleforkeepingtrackof
"whereyouare"whilewalkingitusing pxIndex ,allowingtherestofFreeRTOStonotworryaboutit.
file:///D:/documents/0_A_LinuxKernel/The%20Architecture%20of%20Open%20Source%20Applications%20(Volume%202)_%20FreeRTOS.html
9/14
28/12/2015
TheArchitectureofOpenSourceApplications(Volume2):FreeRTOS
Figure3.4:FullviewofFreeRTOSReadyListafterasystemtimertick
The pxReadyTasksLists[] listmanipulationdonein vTaskSwitchContext() isagoodexampleofhow
pxIndex isused.Let'sassumewehaveonlyoneprioritylevel,priority0,andtherearethreetasksatthat
prioritylevel.Thisissimilartothebasicreadylistpicturewelookedatearlier,butthistimewe'llincludeallof
thedatastructuresandfields.
AsyoucanseeinFigure3.3, pxCurrentTCB indicatesthatwe'recurrentlyrunningTaskB.Thenexttime
vTaskSwitchContext() runs,itcalls listGET_OWNER_OF_NEXT_ENTRY() togetthenexttasktorun.This
functionuses pxIndex>pxNext tofigureoutthenexttaskisTaskC,andnow pxIndex pointstoTaskC's
listelementand pxCurrentTCB pointstoTaskC'sTCB,asshowninFigure3.4.
Notethateach structxListItem objectisactuallythe xGenericListItem objectfromtheassociatedTCB.
3.6.Queues
FreeRTOSallowstaskstocommunicateandsynchronizewitheachotherusingqueues.Interruptservice
routines(ISRs)alsousequeuesforcommunicationandsynchronization.
file:///D:/documents/0_A_LinuxKernel/The%20Architecture%20of%20Open%20Source%20Applications%20(Volume%202)_%20FreeRTOS.html
10/14
28/12/2015
TheArchitectureofOpenSourceApplications(Volume2):FreeRTOS
Thebasicqueuedatastructureis:
typedefstructQueueDefinition
{
signedchar*pcHead/*Pointstothebeginningofthequeue
storagearea.*/
signedchar*pcTail/*Pointstothebyteattheendofthe
queuestoragearea.Onemorebyteis
allocatedthannecessarytostorethe
queueitemsthisisusedasamarker.*/
signedchar*pcWriteTo/*Pointstothefreenextplaceinthe
storagearea.*/
signedchar*pcReadFrom/*Pointstothelastplacethataqueued
itemwasreadfrom.*/
xListxTasksWaitingToSend/*Listoftasksthatareblockedwaiting
topostontothisqueue.Storedin
priorityorder.*/
xListxTasksWaitingToReceive/*Listoftasksthatareblockedwaiting
toreadfromthisqueue.Storedin
priorityorder.*/
volatileunsignedportBASE_TYPEuxMessagesWaiting/*Thenumberofitemscurrently
inthequeue.*/
unsignedportBASE_TYPEuxLength/*Thelengthofthequeue
definedasthenumberof
itemsitwillhold,notthe
numberofbytes.*/
unsignedportBASE_TYPEuxItemSize/*Thesizeofeachitemsthat
thequeuewillhold.*/
}xQUEUE
Thisisafairlystandardqueuewithheadandtailpointers,aswellaspointerstokeeptrackofwherewe'vejust
readfromandwrittento.
Whencreatingaqueue,theuserspecifiesthelengthofthequeueandthesizeofeachitemtobetrackedbythe
queue. pcHead and pcTail areusedtokeeptrackofthequeue'sinternalstorage.Addinganitemintoa
queuedoesadeepcopyoftheitemintothequeue'sinternalstorage.
FreeRTOSmakesadeepcopyinsteadofstoringapointertotheitembecausethelifetimeoftheiteminserted
maybemuchshorterthanthelifetimeofthequeue.Forinstance,consideraqueueofsimpleintegersinserted
andremovedusinglocalvariablesacrossseveralfunctioncalls.Ifthequeuestoredpointerstotheintegers'
localvariables,thepointerswouldbeinvalidassoonastheintegers'localvariableswentoutofscopeandthe
localvariables'memorywasusedforsomenewvalue.
Theuserchooseswhattoqueue.Theusercanqueuecopiesofitemsiftheitemsaresmall,likeinthesimple
integerexampleinthepreviousparagraph,ortheusercanqueuepointerstotheitemsiftheitemsarelarge.
NotethatinbothcasesFreeRTOSdoesadeepcopy:iftheuserchoosestoqueuecopiesofitemsthenthe
queuestoresadeepcopyofeachitemiftheuserchoosestoqueuepointersthenthequeuestoresadeep
copyofthepointer.Ofcourse,iftheuserstorespointersinthequeuethentheuserisresponsibleformanaging
thememoryassociatedwiththepointers.Thequeuedoesn'tcarewhatdatayou'restoringinit,itjustneedsto
file:///D:/documents/0_A_LinuxKernel/The%20Architecture%20of%20Open%20Source%20Applications%20(Volume%202)_%20FreeRTOS.html
11/14
28/12/2015
TheArchitectureofOpenSourceApplications(Volume2):FreeRTOS
knowthedata'ssize.
FreeRTOSsupportsblockingandnonblockingqueueinsertionsandremovals.Nonblockingoperationsreturn
immediatelywitha"Didthequeueinsertionwork?"or"Didthequeueremovalwork?"status.Blockingoperations
arespecifiedwithatimeout.Ataskcanblockindefinitelyorforalimitedamountoftime.
AblockedtaskcallitTaskAwillremainblockedaslongasitsinsert/removeoperationcannotcompleteand
itstimeout(ifany)hasnotexpired.IfaninterruptoranothertaskmodifiesthequeuesothatTaskA'soperation
couldcomplete,TaskAwillbeunblocked.IfTaskA'squeueoperationisstillpossiblebythetimeitactually
runsthenTaskAwillcompleteitsqueueoperationandreturn"success".However,bythetimeTaskAactually
runs,itispossiblethatahigherprioritytaskorinterrupthasperformedyetanotheroperationonthequeuethat
preventsTaskAfromperformingitsoperation.InthiscaseTaskAwillcheckitstimeoutandeitherresume
blockingifthetimeouthasn'texpired,orreturnwithaqueueoperation"failed"status.
It'simportanttonotethattherestofthesystemkeepsgoingwhileataskisblockingonaqueueothertasks
andinterruptscontinuetorun.Thiswaytheblockedtaskdoesn'twasteCPUcyclesthatcouldbeused
productivelybyothertasksandinterrupts.
FreeRTOSusesthe xTasksWaitingToSend listtokeeptrackoftasksthatareblockingoninsertingintoa
queue.Eachtimeanelementisremovedfromaqueuethe xTasksWaitingToSend listischecked.Ifataskis
waitinginthatlistthetaskisunblocked.
Similarly, xTasksWaitingToReceive keepstrackoftasksthatareblockingonremovingfromaqueue.Each
timeanewelementisinsertedintoaqueuethe xTasksWaitingToReceive listischecked.Ifataskiswaiting
inthatlistthetaskisunblocked.
SemaphoresandMutexes
FreeRTOSusesitsqueuesforcommunicationbetweenandwithintasks.FreeRTOSalsousesitsqueuesto
implementsemaphoresandmutexes.
What'sTheDifference?
Semaphoresandmutexesmaysoundlikethesamething,butthey'renot.FreeRTOSimplementsthem
similarly,butthey'reintendedtobeusedindifferentways.Howshouldtheybeuseddifferently?Embedded
systemsguruMichaelBarrsaysitbestinhisarticle,"MutexesandSemaphoresDemystified":
Thecorrectuseofasemaphoreisforsignalingfromonetasktoanother.Amutexismeanttobetakenand
released,alwaysinthatorder,byeachtaskthatusesthesharedresourceitprotects.Bycontrast,tasksthat
usesemaphoreseithersignal["send"inFreeRTOSterms]orwait["receive"inFreeRTOSterms]notboth.
Amutexisusedtoprotectasharedresource.Ataskacquiresamutex,usesthesharedresource,thenreleases
themutex.Notaskcanacquireamutexwhilethemutexisbeingheldbyanothertask.Thisguaranteesthat
onlyonetaskisallowedtouseasharedresourceatatime.
Semaphoresareusedbyonetasktosignalanothertask.ToquoteBarr'sarticle:
Forexample,Task1maycontaincodetopost(i.e.,signalorincrement)aparticularsemaphorewhenthe
"power"buttonispressedandTask2,whichwakesthedisplay,pendsonthatsamesemaphore.Inthis
scenario,onetaskistheproduceroftheeventsignaltheothertheconsumer.
Ifyou'reatallindoubtaboutsemaphoresandmutexes,pleasecheckoutMichael'sarticle.
Implementation
FreeRTOSimplementsanNelementsemaphoreasaqueuethatcanholdNitems.Itdoesn'tstoreanyactual
dataforthequeueitemsthesemaphorejustcareshowmanyqueueentriesarecurrentlyoccupied,whichis
trackedinthequeue's uxMessagesWaiting field.It'sdoing"puresynchronization",astheFreeRTOSheader
file semphr.h callsit.Thereforethequeuehasaitemsizeofzerobytes( uxItemSize==0 ).Each
file:///D:/documents/0_A_LinuxKernel/The%20Architecture%20of%20Open%20Source%20Applications%20(Volume%202)_%20FreeRTOS.html
12/14
28/12/2015
TheArchitectureofOpenSourceApplications(Volume2):FreeRTOS
3.7.Conclusion
We'vecompletedourlookattheFreeRTOSarchitecture.Hopefullyyounowhaveagoodfeelforhow
FreeRTOS'stasksrunandcommunicate.Andifyou'veneverlookedatanyOS'sinternalsbefore,Ihopeyou
nowhaveabasicideaofhowtheywork.
ObviouslythischapterdidnotcoverallofFreeRTOS'sarchitecture.Notably,Ididn'tmentionmemoryallocation,
ISRs,debugging,orMPUsupport.ThischapteralsodidnotdiscusshowtosetuporuseFreeRTOS.Richard
Barryhaswrittenanexcellentbook,UsingtheFreeRTOSRealTimeKernel:APracticalGuide,whichdiscusses
exactlythatIhighlyrecommenditifyou'regoingtouseFreeRTOS.
3.8.Acknowledgements
IwouldliketothankRichardBarryforcreatingandmaintainingFreeRTOS,andforchoosingtomakeitopen
source.Richardwasveryhelpfulinwritingthischapter,providingsomeFreeRTOShistoryaswellasavery
valuabletechnicalreview.
ThanksalsotoAmyBrownandGregWilsonforpullingthiswholeAOSAthingtogether.
Lastandmost(theoppositeof"notleast"),thankstomywifeSarahforsharingmewiththeresearchandwriting
forthischapter.LuckilysheknewIwasageekwhenshemarriedme!
ThisworkismadeavailableundertheCreativeCommonsAttribution3.0Unportedlicense.Pleaseseethefull
descriptionofthelicensefordetails.
Backtotop
file:///D:/documents/0_A_LinuxKernel/The%20Architecture%20of%20Open%20Source%20Applications%20(Volume%202)_%20FreeRTOS.html
13/14
28/12/2015
TheArchitectureofOpenSourceApplications(Volume2):FreeRTOS
BacktoTheArchitectureofOpenSourceApplications.
file:///D:/documents/0_A_LinuxKernel/The%20Architecture%20of%20Open%20Source%20Applications%20(Volume%202)_%20FreeRTOS.html
14/14