Raspberry Pi C/C++ Baremetal Programming | Using C to Direct-Register Control Your Raspberry Pi

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in my previous tutorial i demonstrated how to write arm assembly to perform direct to register programming on a raspberry pi by directly controlling the gpio registers on the arm processor we were able to get an led to blink on and off the problem however was that we wrote that tutorial all on assembly the problem with programming and assembly is that assembly isn't a very scalable language and as you add more features to your code the code gets hard to manage hard to understand and is often not maintainable by other programmers unfamiliar with your code base the correct way to do this instead is to use a compiled language so in this video i'll be showing you guys how to make a project and write code in c that will perform the same direct register functionality all without the hassle of writing an assembly also to be alerted when i put up videos on the raspberry pi bare metal programming and other low-level topics hit that subscribe button and hit the notification bell now the way we'll do those will be pretty similar to the first video um at the risk of being hypocritical there actually is a little bit of assembly that we have to use this assembly will be called start.s and that'll be the glue code that gets the code control from assembly into our c code once we've compiled and assembled our assembly we will then begin writing our code in c now here what we're going to do is compile our c code into an object file what we have to do after that is take all of our object files we've created so main.o and start.o and use a linker script to assemble them in the correct order and produce our kernel 7l that the raspberry pi will boot now what a script does is it actually pretty cleanly just lays out the layout of an elf image that you create at compile time and you can actually put what order the symbols appear in and what segments and sections appear in what order the reason we want to do this is we want the start symbol so you know the beginning of our code our start.s here to appear first in the image so that when the assembler creates the assembly and the compiler creates the elf we don't accidentally have main.c appearing first without the startup code happening doing this in the linker script allows us to confirm that our elf is assembled in the correct order and another thing we'll introduce in this video is the idea of a board support package header file so in this case we have the bcm 2837 header file looks like written by apple i found this online but basically if you remember from our previous video we were going through and we were pulling out all these addresses from the data sheet manually and putting them into our code by hand as you begin to interface with more peripherals on the chip this gets very hard to maintain and honestly annoying to do people that produce chips often publish header files that have all of these addresses extracted and they define named for them so instead of us having to manually define constants that we'll use we can just use the values specified in this header file so for example for the function select zero we can just use this word as opposed to this address for the uh gp set zero we can just use this constant instead of this address etc so currently we're in a spot where we have this assembly written i'll kind of just walk through what this does um line one we're saying section.txt.boot the reason why we have a dot text.boot section is we want to specify in our linker file that this part of the code starts first right so we have this part happening in front of the dot text so when the arm processor gets to execution it goes to run start code first and then after that all we do is we have our start symbol which loads the address of main our actual c code address into register three and then we jump to that address this should never return we should never get back to this point um but when main does return if it ever does we'll eventually get to the halt symbol which just branches to itself and kind of infinitely loops so yeah now we can actually go into the c part of the code and begin to write code that will get ran on the processor not an assembly so now that we're actually executing code in main we want to write two functions that will make our life a little easier when doing direct transcript programming the first function is going to be a write 32 function that's going to take a address as input and write a value there we'll be able to use this function and plug in these addresses from the header file write data to those addresses so the right 32 function will take a void star of dest and a uint value we need to do a type def unsigned int as uint just so it doesn't yellow does something compile and what this function will do is it will cast the destination pointer into a destination u pointer and we're going to write the value to that pointer this is our right functionality and this will return nothing and then we're gonna do the same thing but we're gonna have a read instead so read 32 is going to have a source and it's going to only take in that source we could do source view equals source and then we're just going to return source delete all this and make sure it returns to you in cool so now we have two basic functions that we can write and read to these peripheral addresses very cool so now that we have those written we need to do a few more things all right so in our previous video we needed to set the function of pin 21 to be an output right so we had to write to gpf select two these are actually not spelled out in the datasheet in the header file but we can add those in pretty quickly so the offsets are going to be plus four and plus eight for gpio function select one and for two so we're gonna take this here and then we are going to take a register a uint and it's gonna be the gpf cell 2 and we're going to say that it's equal to read 32 this address this will read from this address the chip and give us the current value in that register then we need to do is we need to make sure that pin 21 is set to be a output just like our previous video right so we're gonna say that that value or equals one left shifted by three which is going to turn pin 21 into an output that's the same as before right but then now that we have done this in ram right this is currently on the chip in ram we need to actually put it back into this address here from the data sheet so just like before we'll do a write 32 we're going to write to this address this value and after that gets ran we have turned pin 21 into an output pretty straightforward now we're gonna do like we did before in our previous video we're going to have an infinite loop where we are going to set the output to be turned on right so we need to turn on pin 21 and turn off pin 21. in between there we need to have sleeps right so delay and delay so the way we do that just look at it before we need to write 32 to the [Music] gpio set functionality from the header sheet from the data sheet right so the set and what are we gonna write there we are going to write one left shifted by 21 and then we are going to the same thing but instead of the gpio set we're going to have the gpio clear just like before so this is turning on pin 21 this is turning off pin 21 and then here we're going to do a very lazy loop um just to make sure that the chip actually actually sleeps for a certain number of cycles so we can actually see an observable delay so what will happen here is we will do um i equals zero while i is less than we'll do ox eighty thousand well we'll do eight hundred thousand just to be safe if we don't make that number high enough what will actually happen is the led will blink so fast the human eye can't observe it and as a result it'll appear like our code isn't working it's just permanently on but that's that's not going to be the case right um so we'll do that and we'll say i plus plus and then we'll do the same thing we'll copy this code and put it down here all right let's zoom out a little bit just kind of talk about it so what have we done right we've created two functions a right 32 to write to a location and a read 32 to read from a location to return it we use that read 32 to pull out the current state of the gpio function selector for bus two and save that in a variable uh we're then adding some information right we're using the or flag here the or operation to add information so we're turning pin 21 into an output and this bit selector here is you know comes out of the data sheet just like our previous tutorial um and then we're taking that value and writing it back into this function selector here and then we are creating a counter for infinite loop where within the infinite loop we write to the gpio set for pin 21 and we'll turn that pin on and that's where our led is going to live and then from there we take another counter and we iterate over it to create a delay so nothing should happen here it should just hang for some number of actual human observable time and then we do the same thing where we write 32 to gpio clear and we do that to set uh pin 21 to be off and then sleep and then this should run infinitely so we'll pull up our terminal here i never actually included the uh header file make sure you uh actually include your header files otherwise they'll be very upset 2837.h try this again one thing we forgot to do is this needs to be a source you not the source if you try to do reference of void pointer the compiler will get mad um after we figured that out let's type make and now the kernel 7 elf is created and we can put the kernel 7 image onto our sd card and put it into our raspberry pi and see what happens let's do that right now boom and there you go you can see here that the led is blinking on and off um our delay timer is a little long it's closer to like five or six seconds and it is one second but that's okay um anyway guys i hope you learned something in this video uh getting your code to be the same functionality in c as it is in assembly is not that hard so if you like this video do me a favor hit like hit subscribe and i'll see you guys next time take care [Music]
Info
Channel: Low Level Learning
Views: 88,601
Rating: undefined out of 5
Keywords: raspberry pi, pico, rpi, microcontroller, arduino, maker, craft, hobby, electronics, wires, temperature, safety, project, board, electric, leds, led, thonny, python, micropython, os, ide, onewire, ds18b20, circuitpython, review, launch, measure, probe, rp2040, specs, specifications, how to, guide, programming, Pico emulation, retro games raspberry pi pico, etaprime, eta prime, raspberry pi pico, arm cortex m0+, low cost
Id: mshVdGlGwBs
Channel Id: undefined
Length: 9min 48sec (588 seconds)
Published: Fri Aug 20 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.