Getting Started with Baremetal Arduino C Programming | No IDE Required [Linux SDK]
Vložit
- čas přidán 27. 08. 2024
- When I started writing code for the Arduino, I felt like the code was abstracted too far away from the processor. While this is the intent of Arduino, I wanted to get down to a lower level. In this video, we learn how to write native C code without any of the Arduino IDE overhead and flash it directly to your Arduino. We go deep into the world of embedded microcontrollers and learn how bitmasks work, how to set and unset flags on a register, and use them all to do the Blink LED in C.
SOCIALS:
Follow me on Twitter: / lowlevellearni1
Follow me on Twitch: / lowlevellearning
Join me on Discord!: / discord
Great tutorial on this. I'm a retired low level C programmer (did lots of automation and motion control) and have just bought an Arduino to play with and was a little annoyed by all the high level calls to IDE functions, since I normally wrote those myself for whatever device I was working on. You just showed me how to get down to the level of coding that I wanted. Thanks!
That's exactly how I felt! I'm glad you learned something. Thanks for watching.
Is atmel studio still a thing? They had great documentation, before the arduino I used to use it to program the avr butterfly and it was great.
So you are wasting time by reinventing wheel 😅
@@rijo1254nah it's not a time wasted. Wasting time is using all high abstraction and not knowing enough how those works on low level and the first thing you will do when a bug occured is to google it.
@@rijo1254 it’s not reinventing the wheel, programming at the register level is extremely useful particularly for low power operation, such as with the MSP430
This tutorial is what I wanted to try for a while: getting out from arduino IDE and doing things in terminal. And, after watching I did this. With small modifications in makefile I ran same Blink example under cheap clone based on Nano with 168p. That hooked me to dive deeper. I hope more low level arduino videos from you in future :)
Awesome! I'm happy to hear you were able to get this to work on other MCU's. I'll definitely be going deeper into bare metal AVR programming in future videos.
Holy shit how do you not have a billion followers! This is the best example of Direct to register programming I've seen
In the second build command, avr-gcc -o main.o main.bin, it's crucial to specify the target frequency and controller (-DF_CPU=16000000UL -mmcu=atmega328p) to avoid unexpected behavior. Additionally, if the -c flag is removed from the first command, the second command becomes unnecessary, especially when dealing with single c files or libraries.
I've been struggling to bug fix some weird behavior in my program and this is what fixed it. Thanks!
Please do more of this, I really enjoyed the video, but this is one of my first contacts with actual c code for arduino so it's really hard (for me at least haha), and you're tutorials are amazing
More to come!
You are really good at this, the tutorials are clear and concise and exceptionally well explained. I hugely enjoy that format.
Great tutorial. I got this up an running in an evening using my new Raspberry Pi 400. All the AVR & GCC tools required are available in the Raspberry Pi repositories.
There could not have been a better video explaining the concept. Really amazing. Thank you.
We learned the fundamentals of controlling a port (pin) in this case, of an arduino shell, which is amazing. All we have to do is imagine the opportunities from here !
I'm moving from high level ML/ web dev to embedded dev/ ML.
I was messing with Arduino, and was like what the heck are all of these high level functions??
I may as well use python at that point.
Very awesome to come across some true low level tutorials for Arduino
Nice one, I enjoyed watching this and adding to my Arduino knowledge base. Thanks.
Awesome! I'm happy you learned something.
thank god for this video! i had just gotten this and I know what you meant when you said it felt like python, all these built in functions that basically keep the actual functionality to seem like magic
So setting a bit in some register to 1 to make an LED turn on isn't magic to you?
This is great! When I got started with Arduino I felt that Arduino C was a crutch and there was really no resources to help transition into proper low-level coding for the AVR, I think this is a great introduction into the absolute basics for those that want to start making more performant code and get the most out of their AVRs. Arduino definitely has it's place as a teaching aid, but I think they really need to work on a proper learning path for transitioning into proper code.
Amazing video mate. Watching this and listening to take it easy by the eagles was a unique experience reminding me of better days. I need to do something like this soon.
One issue is that output file should be named "led.elf", because that is a format coming from "gcc -o" command. "bin" extension suggest that content from this file can be directly copy to Flash memory at address 0 in a microcontroller. You can extract bin format using "avr-objcopy -O binary" option.
The best tutorial ever, you helped me a lot. Thank you
You're welcome!
Hi! Nice video. Just a couple of comments:
1. May be nitpicking but, _delay_ms() does not do a “nop” in a loop: it compiles to an empty loop. You may find a nop (and maybe an “rjmp .” or two) *after* the loop if the delay is not a multiple of the cycle duration, but the body of the loop is empty.
2. Recent versions of avrdude can read directly the elf file. No need to convert it to ihex.
7:32-ish
I love bitwise operations... you can replace the set/unset code with a simple XOR to repeatedly flip the bit! Then your loop is just..
for(;;) {
PORTB ^= 1
Could you explain, please?
@@Fernando-du5ujLearn boolean logic.
Buen protip
The empty for() is ugly, use a while() loop!
Gotta nitpick a little sorry, -Os is technically optimise for space, but also speed but not as much as -O2
Thanks for the additional input! I'm bound to mess something up, haha.
Eheh I was scanning the comments for this. Great job anyway 👍
I am always amazed at how simple the operation of a chip like this really is. I don't in any way suggest that simple means easy, the familiarity with the underlying operations requires a lot of time at the keyboard. Thank you
I really hope this video turns into a series
You are the best! Been trying to figure this out all day.
Just discovered this channel! This is awesome, looking forward to more of these videos!
you should do a video about the SAMD21 Cortex-M0+ MCU on the Arduino Nano 33 IoT, it would be cool since it uses a different architecture ✨✨
PORTB ^= (1
Simple elegance has been lost in the art of programming. I've seen terrible things done with Arduino. One of the worst was someone actually putting a delay() loop IN an interrupt service routine!
I got the same immediate reaction from how high-level the arduino IDE felt.
Can you add a tutorial on how to program a blank atmega328p (no bootloader) using avr-gcc and avrdude?
Works with sinulIDE too, very nice now I can practice my software even without hardware.
Tip: you don't have to run those serial port commands as root if you add yourself to the 'dialout' group.
CORRECTION: The avr-gcc -0s flag optimizes for SIZE, not speed.
yeah, was about to say
Great. But then the question becomes: if the advantage of Arduino is not having to go down to the bare metal and you nevertheless go down to it, why not dispense with the Arduino and work with other more powerful micro controllers?
The the great advantage of the Arduino for non-coders is the IDE. That is who the IDE was designed for and it enables then to do quite complex projects that would otherwise be beyond them. There is a whole range of different microcomputers in the Arduino range from little 8 bitters like the AVR right up to 32/64 bit ARM ones. so the range of possible projects even with the IDE is quite vast. But this is not the only way to create programs on the Arduino, and if you want the fastest most compact code in the lowest cost micro then the Arduino IDE is definitely not the best way. That is whn you need bare metal coding.
@@ruffrecords Yes also using the Arduino IDE you really never learn true embedded programming you just get a small taste of it. This video is also great to teach people true embedded programming.
@@ipodtouch470 After a lot more digging and playing with the Arduino IDE I have how revised my opinion of it. The reason is that, as several people have discovered, you do not have to use the built in setup() and loop() paradigm. You can easily recreate the project shown in the above video simply by opening a new sketch and deleting the entire contents of the sketch and replacing it with a regular main() al la regular C. The advantage of doing it this way is you do not have to worry about installing a bunch of other files or creating a make file and you retain the other advantages of the IDE including code completion.
Nice. I am a retired software engineer with no background in microcontroller programming. I recently started doing some arduino stuff but have been very uneasy about the amount that this (admittedly helpful) framework hides. Better to have a deeper understanding....
Awesome. Thanks!
Great video, but there is one thing i don't understand. Where is the "PORTB" coming from? Obviously from the library "avr/io.h", but when i want to use a different programming language where i don't have that library i must be able to program my MCU right?
Are you planing to do a tutorial that low level or can someone guide me to one if it's already exist?
what's the difference between DDRB = DDRB | (1
Oh, I get it now. It's so you can change that specific bit WITHOUT changing any other bit of DDRB.
They do but the first leaves all the other bits unchanged, the second does not. This is known as an unwanted side effect.
Sir actually i am planning to learn c first then after 7-8 months c++ so my question is that will i able to use arduino just after c language or i have to necessary wait till i lean c++ 😓😓
Great video! Does the Arduino bootloader still need to be flashed to the board? Where does that fit into this architecture?
Thank you!
The way that you're able to flash the board over USB is via the Arduino bootloader that's baked into board by default, so no you don't need to flash it again.
If you were to overwrite the area in memory where the bootloader lives, you would need to flash the board using a ICSP programmer. I'll be making a video on that in the coming weeks.
Thanks for watching!
I enjoyed this video pretty well. I think I need to go down low with AVR. I just got a book that will help me a great deal. I want to be proficient in AVR.
Thank you
Pls help me with the book. Thanks
@@udeolisachukwudalu1309
Where is your location? If you're in Imo state, come down to Imo State University Owerri. You can as well learn tons of other useful microcontroller projects. Thank you.
Love this!
Great tutorial! Just wondering why the compilation and linking needs to be split up in two steps? Could the same be achieved with only one call to avr-gcc?
Useful work ! How I can find a reference manual about avr macro and avr functions ?
Would this tutorial work the same for elegoo uno atmega328p?
Mr.LLL, will be great addition if you can share your GITHUB Repos, actually in general share to stumble users in GH to view your videos and be generate more traffic to excellent tutorial. WOW COOL
For you to understand how most explanations about Arduino are very bad, that's not the case in this video, I'm trying to understand the logic behind such PORB, PORTC..... I only found bad things, and in your video in part 11 :00 clearly shows what the design of the doors would be like and their reference relationship, most people don't understand why they don't present a drawing like yours, where can I get drawings like this
So how we are able to flash it?there is a flasher to do so ...?
Really great tutorial, first time i have seen how to actually write C and flash it onto the microcontroller. However, there is something still unclear… If i wanted to have, lets say, 2 leds, on 2 different ports, would the writing to the PORTB be exclusive? like, if i say PORTB = PORTB | (1
Port B is an 8 bit port (bits 0 to 7) so there is no PORTB13!
Wait a minute. Are you using vi, and aligning with tabs? Evil! :))
How would I do something similar with the Arduino R4 Wifi?
it has a different architecture entirely ( arm architecture while most classic arduinos use the AVR architecture ) so you're gonna have to look up it's own tool chain and schematics
can you show the windows version ?
I assume with msys2 not much will change.
But still not sure what are the necessary changes.
cool video)
Youuuuuu are Great!!!!!!!!! I love you :)))
very interesting & wonderful Arduino GPIO video info. I am wanting to have the Orange Pi-5 Debian-Bullseye Python GPIO PWM pins control the servo Pan/Tilt camera motors. Do you have any suggestions on how to use OPi.GPIO which is a drop-in for RPi.GPIO. I can get the GPIO pins on/off to work. However, PWM is giving me errors. Next, will be I2C on the OPi5. 🧐 Thank you.
Fellow i3 user. Nice.
Do arduinos have interrupts? I remember a little bit from x86 asm that you can use interrupts to run code periodically instead of doing nops on the cpu, so it's better performance and less battery.
They do! I have a video on AVR timer interrupts on the channel :)
@@LowLevelLearning I’m finding more and more videos. You’ve done a lot of really cool stuff, rust too?? Really? That’s pretty wild.
Seems like I need to actually learn C and how to write Makefiles before I can program microcontrollers. While I understood everything in the video, I don't know the bitwise notation nor do I know much about C syntax.
Did you ever ride a bicycle without first having to learn how to ride a bicycle?
I'm really unhappy coz you skipped the entire startup code, linker file etc
thanks!
I like writing that as PORTB &=~ (1
I personally like to use Geany, would the same principles apply there too?
Yes
HELL YES!
Where can I learn this things? The resources in the internet for low-level programming like this is so limited
You are lucky to have the internet. When I started out programming micros back in the 70s the internet did not exist. The only information came from the data books supplied by the manufacturer. These days those same data sheets are now readily available on line. Nobody taught you haw to write assembly language and it was not until a decade later that C compilers for micros became available and I learnt C from a book too.
"Make: AVR Programming"
is a great book and teached me all of this.
I tried to expand on this by adding a function call to a function defined in my_lib.c and during the linking step I had to add the mmcu option, same as in the build and assemble step. Otherwise the program behaved very strangely with the led not blinking as intended.
I.e. compile, assemble and link such:
avr-gcc -Os -DF_CPU=16000000UL -mmcu=atmega328p -c -o led_driver.o led_driver.c
avr-gcc -Os -DF_CPU=16000000UL -mmcu=atmega328p -c -o main.o main.c
avr-gcc -mmcu=atmega328p -o main.elf main.o led_driver.o
No idea why the mmcu option needs to be added when multiple objects files are added at the link step but is not needed when linking main alone..
Can you do a video like this for ESP32 ADC channels?
What happened
Cool! 👌
Thanks! 😄
I had an arduino mega2560 clone laying around, this is the make file that manages to flash to my board:
default:
avr-gcc -Os -DF_CPU=16000000UL -mmcu=atmega2560 led.c -o led.bin
avr-objcopy -O ihex -R .eeprom led.bin led.hex
avrdude -D -F -V -c avrispmkII -p ATMEGA2560 -P /dev/ttyACM0 -b 115200 -U flash:w:led.hex
If I separate the avr-gcc command as shown in the video I get the following error:
avr:6 architecture of input file `led.o' is incompatible with avr output
If I use the arduino programmer (-c arduino) then I get the following error:
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
If I use for example the avrispmkII programmer (I use this one as in the IDE it was selected by default) then I get the following error:
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: stk500v2_command(): command failed
Adding the -D flag solves the problem.
I don't know why it works now. But it works fine at the time being.
Trying to solve the issue I added my user to the group that appeared on the output of the following command: ls -l /tty/ACM0
The code had to be modified because the pin that controls the LED is the PB7.
Thank you for the video!
EDIT:
Reading the comments of the video I found the one by @Edgar Bonet, the make file could be further reduced as avrdude can read directly the ELF file:
default:
avr-gcc -Os -DF_CPU=16000000UL -mmcu=atmega2560 led.c -o led.bin
avrdude -D -F -V -c avrispmkII -p ATMEGA2560 -P /dev/ttyACM0 -b 115200 -U flash:w:led.bin
thank you for your comment, the "avrispmkII " saved my day
sadly you used the pre made arduino libraries. It would be better if you checked the datasheet registers values and created pointers to them.
but great video, though
What arduino libraries he used?
@@hidingsounds763 AVR.h it seems
@@filipesiegrist That is NOT so! He actually used the avr-libc libraries which are part of the gcc avr toolchain.
Hey everybody,
I'm so Stück right now. I work on Linux (I just switched recently, so I'm getting used to it).
I have installed VSC and all the packages but somehow my header files cannot be opened by my program.
I have absolutely no idea how to fix that... I guess there is some Path missing.
Can someone please help me fixing this issue?
I am so ready to learn more about low level programming but this problems drains all my enthusiasm out of my soul...
Update: in Case any other people reading this comment and having the same problem. Please use VIM. I just used it and it worked in like no time. So glad and excited to dig deeper now :)
The idea behind Arduino is make it possible to design stuff without wasting time on how setup the system or worry about which registers should be loaded with what bits.
Your question "did you learn anything by using Arduino" is meaningless. You could design amazing systems with Arduino. You could prototype anything relatively quickly with Arduino. All that without reading much data sheets.
However, that doesn't mean one should not try programming Atnel MCUs with c, c++ or assembly.
If you think this, why did you watch this video about programming without the Arduino framework?
Interesting to see what happens behind the scene, but I find amusing that you state that the Arduino IDE is not teaching you anything, while writing explicit code in C does.
From educational standpoint this teach you how the controller send and received data; but in real case scenario where you use no IDE. you are forced to use machine code, not C.
The IDE is there to simplify things for people that actually write code to use micro-controllers; it is not there to teach you how a specific micro-controller works, and nobody in their right state of mind working on hardware daily, would give up the IDE just to use C code to write explicit registry calls (unless you need to do that for specific purposes on-field; which is one in a million case).
Ask any 6 figure developer if they would give up their IDE and write code on VI only, and most likely the answer is no; beside the old dinosaur that think that writing everything by hand is a display of his/her skills. When you have to deliver in a company you have no time for frivolities; you have to be fast, efficient and effective.
So I think that your video is spot on from a training perspective, but it give away a strange sense of entitlement in thinking that there are common cases where you actually use this approach. There are cases of course, but are far in between, outside the academic context (and this is coming from someone that has been in the field for decades, so it is first hand experience). Knowing how to do it without an IDE and learning how the MC works is a great thing to do; but once you learn and get hired to produce, you rely heavily on manufacturer IDE or standard IDE for making your life easier. It is 2022 after all, so it is logic that progress make life easier and let you be more productive.
Thanks for the very well made and interesting video
why c and not c++, can we program using php why linux and not windows?
C++ is bloat and a microcontroller has limited program memory.
PHP is a scripting language for web development, not a programming language.
The Linux toolchain for AVR is far more accessible than it is on Windows.
These are why!