Where I describe how to use the Library functions in AVR_C.
This page describes where to find specific functions for programming an AVR microcontroller in Standard C using functions similar to the Arduino Language Reference. In this case, the AVR_C framework consists of:
The Standard C Library is provided by AVR Libc. This library is incredibly important as it provides the ability to develop code in Standard C for the AVR family of microcontrollers. It has all of the functionality you would expect if your were using the a Standard C book such as The C Programming Language Kernighan and Ritchie (available in PDF and paper copy). I recommend having a link to the online manual open while developing code.
Where I attempt to direct all of the questions, pertaining to Developing in C for the Arduino Uno.
A: There is more than one way!
CLI methods
# identify using device
ls /dev/tty* | grep -E 'ACM|USB'
# identify using tio
tio -l
# if you have multiple devices, using tio will provide more information
GUI methods
A: C is the ideal combination of a common language and a language which is “close” to the hardware. For example, the AVR assembly language allows writing directly to the hardware (the best example of “close”), except it is not commonly known or easily understood. On the other hand, Python is widely known and easily understood, however, due to it’s requirement to be compiled on-board, it is too large to fit into the memory of the ATmega328P (the microcontroller used by the Arduino Uno). The Arduino approach is to use C++, however, C++ is a little more abstract and requires more memory than C. It’s a good compromise for teaching, however, it is not the best language for embedded development.
Where I describe the process of developing code for the Arduino Uno(AVR ATmega328P), specifically, the build process.
The middle three steps compile/link/locate are typically called the build process, which can simplify the five steps to three:
For a detailed and very worthwhile description of the three steps in Build, I highly recommend this page, Compiling, Link and Locating: Barr Group.
The image is a typical start-up build sequence, I need to cd three times, to get into the specific folder. Once there, I use make clean to ensure I have a clean start (source code and makefile only) then I execute a make flash.
Where I describe the process of developing code for the Arduino Uno(AVR ATmega328P), specifically, editing the code.
Description | Windows Keys | macOS Keys |
---|---|---|
Copy selection | Ctrl - c | Cmd - c |
Paste clipboard | Ctrl - v | Cmd - v |
Select all | Ctrl - a | Cmd - a |
Description | Windows Keys | macOS Keys |
---|---|---|
Tool Palette | Ctrl-Shift-p | Cmd-Shift-p |
Build Task | Ctrl-Shift-b | Cmd-Shift-b |
Description | Command/key | Comments |
---|---|---|
Change directories | cd | Use to change folders |
Expand current text to a folder name | Tab | Type first few letters then hit Tab |
Present working directory | pwd | What folder are you in? |
List contents of directory | ls | Show what is in the folder |
List folder in tree format | tree | Show what is in the folder |
Previous command | Up arrow | display previous command |
Open serial monitor | tio [ acm | usb ] | Pick one of the two options based on your controller board serial port |
This is a a very simple configuration. The left-half of your window is VS Code and the right half of your window is your CLI (terminal application.) Use tabs on both to view multiple files or instances.
Where I describe the process of developing code for the Arduino Uno(AVR ATmega328P), specifically, uploading code to the Uno.
The middle three steps compile/link/locate are typically called the build process, which can simplify the five steps to three:
The most important step in uploading to the Uno is to ensure your env.make file is using the correct serial port. The easiest method for this is to plug-in your Uno and use the Arduino IDE and Tools -> Port to identify the port used by the Uno. Here is a screenshot of this process on the Mac:
Where I discuss how to implement and use git to develop code in C for the Arduino Uno.
In this post, I’ll describe how to use git to add the Lab content. I’ll also offer some guidance as to how to use git in your own projects. I am not a git expert and I’ll try not to stray too far from status->add->commit-push…
Where I describe a new error caused by a bug in GCC 12 as it relates to the AVR microcontrollers.
While debugging a setup script, I ran across this error on my Linux system, however, it didn’t show up on my macOS or Windows computers.
$ make flash
avr-gcc -Os -mcall-prologues -g3 -std=gnu99 -Wall -Werror -Wundef -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -DF_CPU=16000000UL -DBAUD=9600UL -DSOFT_RESET=0 -I. -I../../Library -mmcu=atmega328p -c -o main.o main.c
main.c: In function 'main':
main.c:33:9: error: array subscript 0 is outside array bounds of 'volatile uint8_t[0]' {aka 'volatile unsigned char[]'} [-Werror=array-bounds]
33 | PORTB &= ~_BV(PORTB5);
| ^~
cc1: all warnings being treated as errors
make: *** [<builtin>: main.o] Error 1
$
It does seem rather odd as 0 is certainly not “outside array bounds”, therefor I had no idea as to how to remediate it.
Where I demonstrate how to use make and makefiles to automate your build process.
While this entry accurately describes how to use a Makefile, the approach has changed significantly. See Developing in C for the ATmega328P: Make, Makefile and env.make for the latest information.
We’ll use the Makefile from Elliot William’s book, he has in the folder setupProject. This Makefile is comprehensive and delivers an Arduino IDE type of simplicity with significantly increased speed. I’ve made some changes to it to make it easier to switch between different types of systems. Here is the file:
Where I compare the execution speeds of different combinations of boards and languages. I will continue to update this post with other languages and processor combinations.
ucontroller/Speed(MHz) | Method* | frequency | Language |
---|---|---|---|
ATSAMD21/48Mhz | Integral | .6kHz | CircuitPython |
ATSAMD21/48Mhz | Integral function | .7kHz | CircuitPython |
ATSAMD21/48Mhz | Library | .7kHz | CircuitPython |
RP2040/133Mhz | Integral function | 1.0kHz | CircuitPython |
RP2040/133Mhz | Library | 1.44kHz | CircuitPython |
ATmega328/16MHz | struct/function pointer | 6.1kHz | Arduino C++ |
ATmega328/16MHz | words in an infinite loop | 27KHz | FlashForth |
ATmega328/16MHz | struct/function pointer | 55kHz | C |
ATmega328/16MHz | struct/function pointer | 56kHz | Arduino C++ w/ native toggle |
ATmega328/16MHz | Assembly language toggle | 108kHz | FlashForth |
ATmega328/16MHz | Assembly language toggle inlined | 444kHz | FlashForth |
RP2040/133Mhz | struct/function pointer | 578.7kHz | C |
RP2040/133Mhz | words in an infinite loop | 2.841 MHz | Mecrisp Forth |
*See text for an explanation of method. |
While writing about CircuitPython and the FIDI board, I was curious as to the execution speed of CircuitPython on a extremely powerful (relative to the AVR ATmega328) ARM M0+ microcontroller. The M0+ is a modern RISC 32-bit processor with a considerable amount of memory, while the ATmega is 20 year old RISC 8-bit processor with a limited amount of memory. That said, one can’t run CircuitPython on ATmega processors, one must use C or Forth.
Where I discuss what to do once you’ve downloaded a repository from Github.
I’ve advocated using the AVR_C (among others) repository to learn how to use C instead of the Arduino “C++” language. (I write C++ in quotes as while the language used is C++, there are some extensions which some people assume are part of the language, causing more confusion.) In this post, I want to start a short series on using Git as it is extremely helpful, once you begin to develop code. And it becomes mandatory, once you begin using someone’s git repository.