Beruflich Dokumente
Kultur Dokumente
EmbeddedfromScratch:
Systembootandhardwareaccess
FedericoTerraneo
federico.terraneo@polimi.it
Outline 2/ 28
Baremetalprogramming
HWarchitectureoverview
Linkerscript
Bootprocess
Highlevelprogramminglanguagesrequirements
Assemblerstartupscript
Hardwareaccess
Memorymappedperipheralregisters
Datasheets
Bitmanipulation
Example
BlinkingLED
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 3/ 28
HWarchitectureoverview
Systemmemory
Processesrunningontopofan
operatingsystemsliveina
virtualaddressspace
PointershandledinCprogram
canonlyaccessaddressesin
thevirtualspace
Aprocessiscompletelyisolated
fromthephysicaladdressspace
Loadingaprogramintomemory
isresponsibilityoftheoperating
system
Processescan'taccessHW
peripherals,butonlymake
syscallstotheOS
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 4/ 28
HWarchitectureoverview
ThisclassshowshowprogrammingisdonewithoutanOS
abstraction
Tolearnhowtoprograminabaremetalenvironment
ToseehowprogrammingisdoneinsideanOS
Tothesakeofsimplicitythetargetwillbeamicrocontroller
AcomputingdevicethatevennowadaysisoftenprogrammedwithoutanOS
Microcontrollerarchitecture
AsinglechipincludingCPUcore,memoryandperipherals
Acomputeronachip
WewillbeusingtheSTM32F407microcontroller
32bitsCPU,popularARM(CortexM4)architecture
Onchip192KBRAMand1MBofFlashmemory
Widerangeofonchipperipherals(USB,Ethernet,
ADC/DAC,Serialport,GPIO,etc...)
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 5/ 28
STM32F407HWarchitectureoverview
Nosupportforvirtualmemory Simplified
STM32F407Memorymap
C/C++programsarewritteninterms
ofphysicaladdresses 0xFFFFFFFF
ProgramcodeislocatedintheFlash,
Flashismemorymappedfromaddress0x0 Peripherals
DirectcodeexecutionfromFlashispossible
0x40000000
Stack,heapandglobalvariablesare
placedinRAM 0x2001FFFF
RAMismemorymappedat0x20000000 RAM
0x20000000
Addressesstartingfrom0x40000000
arereservedtohardwareperipherals 0xFFFFF
Issparselyused,mostlyunmapped
Flash
0x0
Partoftheaddressspaceisunmapped
Accessingunmappedareascausesafaultinterrupttobegenerated
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 6/ 28
Linkerscript
Thecompilationstagedoesnotdiffer Simplified
STM32F407Memorymap
fromOSbasedenvironments
Atthelinkingstage,whengenerating 0xFFFFFFFF
thebaremetalprogramthelinkerneeds
Peripherals
toknowwheretoplace
Code(.textsection)Flashmemory 0x40000000
Data(.data/.bss)RAM
0x2001FFFF
StackandHeaparealsoallocatedinRAM,but
atruntime RAM
0x20000000
Thisisthepurposeofthelinkerscript
Anadditionalfilepassedtothelinkerto 0xFFFFF
describethememoryregionsofthearchitecture Flash
0x0
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 7/ 28
LinkerscriptforaCprogramonSTM32F407(1/2)
ENTRYtellsthelinkerthefirst ENTRY(Reset_Handler)
functionthatwillbecalledatboot MEMORY
{
MEMORYsectionspecifiesthe flash(rx):ORIGIN=0x00000000,LENGTH=1M
hardwarememorylayout ram(wx):ORIGIN=0x20000000,LENGTH=128K
}
_stack_topisavariabledefining
thestartaddressoftheStack _stack_top=0x20000000+128*1024;
SECTIONSblocktellsthelinker SECTIONS
{
howtomaptheprogramsections .=0;
intomemoryregions
.text:
.isaspecialvariablecalled {
locationcounterthatis /*Startupcodemustgoataddress0*/
KEEP(*(.isr_vector))
incremented,aftereachsection *(.text)
mapping,bythesectionsize .=ALIGN(4);
*(.rodata)
}>flash
Thisblockmapsthe.isr_vector,
.textand.rodatasectionstothe .=ALIGN(8);
_etext=.;
Flash
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 8/ 28
LinkerscriptforaCprogramonSTM32F407(2/2)
Thisblockmapsthe.datasectiontoRAM,
.data:
butplacesalsoacopyofitintheFlash {
(toinitializeitatboot) _data=.;
*(.data)
.=ALIGN(8);
Thisblockmapsthe.bss,sectionto _edata=.;
}>ramAT>flash
RAM,
_bss_start=.;
.bss:
{
Thelinkerscriptdefinesmanyvariablesthat *(.bss)
willbeusedforinitializingsectionsat .=ALIGN(8);
runtimeandALIGNcommandstosatisfy }>ram
thealignmentrequirementsoftheprocess _bss_end=.;
ABI(ApplicationBinaryInterface) _end=.;
}
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 9/ 28
Bootprocess
ACPUcanbeseenasacomplexstatemachineexecutingthe
instructionpointedbytheProgramCounter(orInstructionPointer)
register,andincrementingittoexecutethenextinstruction
Question:Wheredoestheprocessorstartexecutingcodefrom,
whenthesystemispoweredon?
Theanswerisarchitecturedependent,buttherearetwocommon
solutions
1)SettheProgramCountertoapredefinedaddress(e.g.,0x0)toidentifythe
firstinstructiontoexecute
2)Readapredefinedmemorylocationcontainingtheaddressofthefirst
instruction,andusethatvaluetoinitializetheProgramCounter(ARMCortex
processorsapproach)
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 10/ 28
Bootprocess
IntheSTM32F407theaddressofthefirstinstructionmustbe
placedat0x00000004
Question:Isitenoughtoputtheretheaddressofthemain()
functionofaCprogram?
Answer:NOHighlevelprogramminglanguagesmakeassumption
aboutthestateoftheirexecutionenvironment
BeittheabstractionofaprocessinaOSorabaremetalmachine
Asmallpartoftheprogramneedstobewritteninassembler
Thepartexecutedatbootaimsatsatisfyingtheassumptionsabove
WearegoingtoseeassumptionsmadeforCandC++programs
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 11/ 28
Cprogramminglanguagerequirements
Thestackpointerregistermustpointtothetopofasuitablememoryarea
Thecompilerimplicitlyusesthestacktoallocatelocalvariableswithinfunctions
Untilthestackpointerisinitializedonlyassemblercodecanbeexecuted
Globalandstaticinitializedvariablesmustsettotheirinitialvalue
SincetheyareplacedinRAM,andafterthepoweronthecontentofRAMisrandom,
theymustbeexplicitlyinitialized
Globalandstaticuninitializedvariablesmustbesetto0
Iftheprogramusestheheap,additionalsupportisrequired
Forbaremetalembeddedsystemstheenvironmentmaychoosetonotprovideanheap
inthememory
IftheprogramusestheCstandardlibrary,certainsyscallsneedtobe
providedtoperformtherequestedhighleveloperations
Forexamplewrite()iscalledbyprintf,open()whenopeningafile
Forbaremetalembeddedsystemstheenvironmentmaychoosetonotprovidean
implementationofthesesyscalls
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 12/ 28
Cprogramminglanguagestartupscript(1/2)
AssemblerfileidentificationforARM .syntaxunified
.cpucortexm4
CortexM4processors .thumb
Sectioncontainingatableofpointers .section.isr_vector
.global__Vectors
0x00000000=stackpointerinit __Vectors:
definedinthe
0x00000004=programcounterinit .word_stack_top
linkerscript
.wordReset_Handler
.section.text
Reset_Handlerfunctiondeclaration .globalReset_Handler
.typeReset_Handler,%function
Reset_Handler:
/*Copy.datafromFLASHtoRAM*/
ldrr0,=_data
ldrr1,=_edata definedinthe
ldrr2,=_etext linkerscript
cmpr0,r1
Thisblockcopies.datasection beqnodata
fromFlashtoRAM(asshownin subsr2,r2,#4
dataloop:
thelinkerscript) ldrr3,[r2,#4]!
strr3,[r0],#4
cmpr1,r0
bnedataloop
nodata:
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 13/ 28
Cprogramminglanguagestartupscript(2/2)
/*Zero.bss*/
ldrr0,=_bss_start
definedinthe
ldrr1,=_bss_end
linkerscript
cmpr0,r1
beqnobss
Thisblocksettozero.bsssection movsr3,#0
bssloop:
strr3,[r0],#4
cmpr1,r0
bnebssloop
nobss:
/*Jumptomain()*/
blisthefunctioncallinstruction blmain
/*Ifmain()returns,endlessloop*/
inARMassembly loop:
bloop
.size Reset_Handler,.Reset_Handler
WewillNOTseehowtoprovideaheapnorhowto
implementsyscallsinabaremetalenvironment
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 14/ 28
C++programminglanguagerequirements
AlltherequirementsfortheCprogramminglanguage
AswithC,theheapandsyscallsmaybeomittedifnotused
Constructorsofglobalobjectsneedtobecalledbeforemain
C++classescanhaveconstructors
C++objectscanbedeclaredasglobalvariable
Theirconstructorsneedtobecalled!
Iftheprogramusesexceptions,additionalsectionsaregeneratedby
thecompilerthatneedtobehandledinthelinkerscript
Forbaremetalembeddedsystemstheenvironmentmaychoosetonotprovide
C++exceptionsupport
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 15/ 28
LinkerscriptforaC++programonSTM32F407
Nodifferencewithrespectto ENTRY(Reset_Handler)
Cprogramcase
SECTIONS
{
.=0;
.text:
{
/*Startupcodemustgoataddress0*/
.init_arraysectioncontainsa KEEP(*(.isr_vector))
table(builtbythecompiler) *(.text)
offunctionpointerstothe .=ALIGN(4);
*(.rodata)
constructorsofglobalobjects
/*Tableofglobalconstructors,forC++*/
.=ALIGN(4);
__init_array_start=.;
KEEP(*(.init_array))
__init_array_end=.;
Nomoredifferenceswithrespect }>flash
toCprogramcase
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 16/ 28
C++programminglanguagestartupscript
Nodifferencewithrespectto
.globalReset_Handler
Cprogramcase .typeReset_Handler,%function
Reset_Handler:
Reset_Handlerfunctionfirst
initializes.dataand.bss,asglobal nobss:
/*CallglobalcontructorsforC++
constructorsmayreferenceother Can'tuser0r3asthecallee
globalvariables doesn'tpreservethem*/
ldrr4,=__init_array_start
ldrr5,=__init_array_end
cmpr4,r5
beqnoctor
ctorloop:
Thisloopcallsthefunction ldrr3,[r4],#4
blxr3
pointersonebyone cmpr5,r4
bnectorloop
Nomoredifferenceswithrespect noctor:
/*Jumptomain()*/
toCprogramcase blmain
/*Ifmain()returns,endlessloop*/
loop:
bloop
.size Reset_Handler,.Reset_Handler
FedericoTerraneo AdvancedOperatingSystems
Outline 17/ 28
Baremetalprogramming
HWarchitectureoverview
Linkerscript
Bootprocess
Highlevelprogramminglanguagesrequirements
Assemblerstartupscript
Hardwareaccess
Memorymappedperipheralregisters
Datasheets
Bitmanipulation
Example
BlinkingLED
FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 18/ 28
HW/SWinterfacing
Question:howcansoftwareinteractwithhardware?
Peripheralregisters
Mostcommonwayusedbyhardwareperipheralstoexposetheir
functionalitytothesoftware
Memorylocationsmappedtospecificaddressesintheprocessor
addressspace
MustnotbeconfusedwithCPUregisters!
Mappedatphysicaladdresses(notvirtualones)
Inoperatingsystemswithmemoryprotection(Linux,Mac,Windows)are
accessibleonlyfromwithintheOSkernel
Inamicrocontrollerenvironmenttheyarefreelyaccessible
FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 19/ 28
Memorymappedperipheralregisters:
Similaritieswithprogramminglanguagesvariables
Accessibleinthesameway
Forexample,throughload/storeassemblerinstructionsinRISCprocessors
Inmanycasestheycanbereadandwritteninsoftware
Evenifsomeregistersmaybereadonly
8,16or32bitwide,justlikeunsignedchar,unsignedshortand
unsignedintdatatypesinC/C++
FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 20/ 28
Memorymappedperipheralregisters:
Differenceswithprogramminglanguagesvariables
Whatgetswritteninthoseregisterscausesactionsintherealworld
SuchasaLEDturningon,anADCinitiatingaconversion,acharacterbeingsent
throughaserialport,etc...
Theyareatwellspecifiedmemoryaddresses
WhenavariableisallocatedinRAM,whetheronthestackortheheap,tothe
programmeritdoesntmattertheaddresswhereitisallocated
Whileifaperipheralregisterismappedattheaddress0x101e5018the
programmerneedstobesurethatiswritingatthataddress
Peripheralregistersarenotatexclusiveusetotheprogrammer,
theyaresharedbetweenthehardwareandsoftware
Thehardwarecandecidetochangethecontentofaregistertosignaleventsor
statusflags,whilevariablessimplykeepthevaluestoredinthembythe
programmer
FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 21/ 28
Memorymappedperipheralregisters
Question:Howcanaprogrammerknowtheperipheralsavailablein
agivenarchitecture?
Foramicrocontroller,availableperipheralsaredetailedina
document,usuallycalleddatasheetorreferencemanual
Datasheetsareusuallyavailableatthemanufacturerswebsite
Question:Assumingthereisa32bitregistercalledIODIR0,at
address0xe0028008,howtoaccessfromaC/C++program,
writing0toit?
FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 22/ 28
Memorymappedperipheralregisters(accessmethod1)
voidclearReg()
{
(*((volatileunsignedint*)0xe0028008))=0;
}
WeuseaCcastoperatortocastthe0xe0028008numbertoapointerto
anunsignedintdatatype.
Thechoiceofanunsignedintisduetothatfactthattheregisterisa32bitregisterand
unsignedintisa32bitdatatype(ona32bitprocessor)
The'*'attheleftdereferencesthepointer,thusgivingaccesstothe
memorylocationpointedtobythepointer
Zeroiswrittenintothataddress
volatilekeywordisnecessarytodisablecompileroptimizations
Suchasinstructionreorderingandredundantwriteeliminationthatcauseproblemsas
thecompilerisnotawarethatatthatmemorylocationthereisaperipheralregister
FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 23/ 28
Memorymappedperipheralregisters(accessmethod1)
#defineIODIR0(*((volatileunsignedint*)0xe0028008))
voidclearReg()
{
IODIR0=0;
}
Morereadablecode
Makeswritingtoaperipheralregistermoresimilarinsyntaxtowritingtoa
variable
UseofthesymbolicnameIODIR0canbeeasilylookedupinthedatasheet
Commonpractice:togroupmacrosdefiningallregistersofan
architectureinanheaderfile
Mostmicrocontrollermanufacturersalreadyprovidethatheaderfile
FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 24/ 28
Memorymappedperipheralregisters(accessmethod2)
Rarelyaperipheralhasonlyoneregister
Usuallyaperipheraliscontrolledthroughasetofregisters,thatareoften
mappedatcontiguousorclosebyaddresses
Thisallowsgroupingallperipheralregistersinadatastructure,like
this
structGpioPeripheral
{
volatileunsignedintCRL;
volatileunsignedintCRH;
volatileunsignedintBSRR;
volatileunsignedintBRR;
};
#defineGPIO((structGpioPeripheral*)0xfeeeaba0)
FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 25/ 28
Memorymappedperipheralregisters(accessmethod2)
Usingthismethod,thecodetoclearregisterCRLintheGPIO
peripheralis:
voidclearReg()
{
GPIO>CRL=0;
};
Therearenodifferences,noteveninperformancebetweenthetwo
methods
Somemanufacturershoweverusethefirstmethod,somethesecond
one,soitisnecessarytoknowboth
FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 26/ 28
Datasheets
Thefigurebelowshowsatypicalperipheralregisterasdocumented
inadatasheet
Informationprovidedforeachregister
Name(e.g.,REGEXAMPLE)
Addressinmemory(0xE0000004)
Meaningandaccesspermissionsofallthebits
Whethertheyarereadable(r)and/orwritable(w)
Somebitsmaybeunused
FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 27/ 28
Bitmanipulation
Giventhefollowingregisterrepresentationincode:
#defineREGEXAMPLE(*((volatileunsignedchar*)0xe0000004))
Questions
1)HowtosetbitENto1leavingtheotherbitsunaffected?
2)HowtoclearbitCNF2to0leavingtheotherbitsunaffected?
3)HowtotestifbitFLAGAissetto1?
Answers
1)REGEXAMPLE|=(1<<0);
2)REGEXAMPLE&=~(1<<2);
3)if(REGEXAMPLE&(1<<4)){}
FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 28/ 28
Bitmanipulation
FedericoTerraneo AdvancedOperatingSystems