Learning About Debugging

I was reading a Reddit post on how Guido van Rossum stated he wanted to make Python work faster when I came across a comment chain where somebody joked that you can make any program faster by using fewer print() statements. A reply quipped “How else am I supposed to debug my programs?”. I’m assuming it was a joke for them, but this is certainly a weakness on my part. Since I’m self-taught, I find myself using standards that make sense to me, but would be bad practice for a formally taught individual. In this case, that’s using the print() statement to help me debug by running the program and seeing what I end up with, tweaking that, running it again, and so on.

The Reddit thread includes a comment chain where somebody jokes about using fewer print() statements.

Fortunately, though, somebody in the replies provided a serious answer to the quip: debuggers and logging. Because I use Linux, I’ve gotten quite familiar with log files – any time something doesn’t work, you have to check a log file to see where the problem lies. Without log files, you’re utterly confused; with log files, you’re a quick Internet search away from your answer. However, I never applied logging in my own programs. Firstly, they’re often so small that they’re easy to review without a log file; secondly, I just didn’t know how. It’s still bad practice, though.

Fortunately, one person linked to a really solid explanation of how debuggers work from last year’s PyCon:

A video by Nina Zakharenko explaining debugging in Python

It was so enlightening to watch – she described exactly how I muck around debugging my programs, using print() statements to analyze my output, adjusting it, and so on. Clearly, my bad habit was a common amateur move that happened often enough for her to be motivated to tell people about this debugger. Not only does it look like a good habit to build, the way she explains it makes it just so easy that I don’t see why I never bothered to use it in the first place.

Hit My Tax with Assembly

Wow, Assembly is hard! I’ve been following that tutorial I mentioned a while back, and I’ve gotten to the point where I can’t follow along anymore. In lesson 6 about timer interrupts there’s quite a jump to new programming concepts and program structure, without much more guidance. So far, I’ve been able to follow along quite well, and though I wouldn’t be able to easily program something in Assembly just yet, I at least felt comfortable enough to read and understand an Assembly program. At this point, though, it’s becoming quite tricky to follow.

Part of the difficulty, I think, is that it’s clear that the website is originally written in German, and while I’m able to follow the text (fortunately, knowing some German helps me follow the sentence structure), the English translation can be a little rough. It’s terse and clipped prose, packed with information. The tutorial is also written more as a demonstration than a lesson plan. Educationally speaking, I would have put in exercises inbetween or some small challenges at the end of lessons with proposed answers at the back. At least something to provide a little more structure to the whole.

The other part, though, is the massive jump from lesson 5 to 6. The earlier lessons all involved a single pin goal (blinking or dimming it) with only a few registers. In lesson 6, though, suddenly we’re setting multiple registers, running two processes in parallel, on top of learning timer interrupts and the way it completely changes the program structure. Simply said, I’m lost!

I already knew that I wouldn’t end up actually programming much in Assembly – seeing how easy Arduino programming is predisposes me to trying C – but I figured to at least learn the basics so I can understand better what’s happening in C. At this point, the cost of investing time into learning this doesn’t really outweigh the benefit of understanding the workings. I figure that, at least for now, I understand more than I did before, and must rather work on the next project.

My First Makefile

Following that AVR Assembly tutorial I’ve been mentioning recently, I’m finding myself compiling and flashing programs to the ATtiny13 quite frequently. So, after doing that twice, I was done with repeating those steps over and over, when I could just automate that part. My first instinct was to use a simple Shell script to put the commands in, but Linux wouldn’t be Linux if somebody hadn’t already run into and solved that very same issue. So, today I learned about Makefiles.

The way I understand it, make is a program designed help in compiling – it checks whether any source files have changed and, if so, compiles them again. In programs of the size I’m writing, that’s really a negligible advantage, but I can see with larger programs that more than a second to compile having to wait over and over can get tiring quickly. The more interesting part for me is that I can use it to immediately say “flash this to the ATtiny13!” and the makefile will take care of the configuration of the commands to compile and send it. Right now, I have the following file, which I’m sure will expand as I learn about makefiles and how they work:

MICROCONTROLLER = attiny13
PROGRAMMER = usbtiny
INCPATH = /home/nextcloud/lib/avra
SRCFILE = 5_fast_pwm.asm

$(SRCFILE).hex: $(SRCFILE)
        avra -l $(SRCFILE).lst -I $(INCPATH) $(SRCFILE) -o $(SRCFILE).hex

flash: $(SRCFILE).hex
        avrdude -v -p $(MICROCONTROLLER) -c $(PROGRAMMER) -U flash:w:$(SRCFILE).hex:i

clean:
        rm -f $(SRCFILE).hex $(SRCFILE).obj $(SRCFILE).eep.hex $(SRCFILE).asm.lst

Right now, the filenames it creates are a little ugly (“5_fast_pwm.asm.hex”, for instance), so I’m sure I’ll learn how to deal with that better in time. One of my favorite features is the clean command, though. This way of doing it ends up with me having a lot of cluttering files in there, and having one command in the same set to clean it is great.

Assemly Programming on Linux

As I mentioned a few posts back, I’ve been interested in following a tutorial on programming microcontrollers in Assembly. There’s been some interesting challenges to overcome, but this morning I’ve finally done it and can actually start the tutorial proper. Considering how tricky it was for an average schmuck like me to do this, I figured it’d be worth a small write-up for other people wanting to try this as well.

Firstly, I noticed that the originating pool of information on Assembly programming online now has a surprisingly small number of sources. Mostly, if you’ll look into the uses of AVRDUDE to upload programming to microcontrollers, it will be about uploading C code. The same goes for the main Arch Wiki article on compiling for AVR. That makes perfect sense, of course, because it’s easier to do more with C than with Assembly for the average person; and, from what I’ve read, the speed advantages of Assembly over C for a lot of these purposes are negligable. Apparently, AVR microchips are already optimized quite a bit for C, and the slight advantage that you may get by programming in Assembly pales in comparison to just getting a faster microchip to begin with. So, given that programming these in Assembly mostly seems to be a niche hobby (the programming equivalent of choosing off-the-grid survival rather than camping, perhaps?), there seem to be less than a dozen people online that are a solid source for programming in Assembly, and less when you want answers directly for Linux.

The issue there is that one of the main methods of doing Assembly coding and uploading seems to be Microchip Studio (formerly Atmel Studio, and often referred to as such online, still). The big issue being that this is online available for Windows. So, for Linux, you have to get a little creative. The actual programming, of course, isn’t that tough: use whatever editor or IDE you prefer; my favorite is still Vim, largely because my needs are small and this seems quite fine. The first problem is compiling your assembly, however.

As wonderful as the Arch Wiki usually is, the only relevant post I could find about Assembly is their listing of programming languages. All that tells me is that as is the compiler provided by the packages binutils, fasm, nasm, and yasm. Those, though, are general Assembly compilers. What it doesn’t mention is that there’s also a compiler available specified for the Atmel AVR microchips: avra. Furthermore, the person who wrote the tutorial I linked to at the start also coded his own assembler: gavrasm. Once you’ve written your Assembly file, compiling is ridiculously easy. For example, using gavrasm, you just type:

gavrasm -seb example_file.asm

Or for avra, it’s:

avra example_file.asm -o example_file.hex

Both will give you a hex file that you can upload to your microcontroller. A crucial difference in my case with the ATtiny13 is that gavrasm had its own definitions file for AVR microcontrollers, so didn’t need me to include those. Avra, however, doesn’t, and needed me to supply it. Fortunately, somebody has kindly provided a whole list of them over on GitHub, so I just downloaded the relevant one for me, which turned out to be “tn13def.inc”.

After compiling the .hex file, I needed to figure out how to upload it to the microcontroller via ISP. The tutorial linked above explained a good setup for an ISP header set, and the right connections to the microchip in the first lesson, but it used Microchip Studio for the uploading. So, I had to figure out the Linux alternative. AVRDUDE is that solution, but it took a little more fiddling to get working. Firstly, I needed to figure out what exactly my usb programmer was called (as there are multiple types). Using the command “lsusb” gave me the following output:

Bus 002 Device 013: ID 1781:0c9f Multiple Vendors USBtiny

So, I guessed that “usbtiny” would be the correct name. Using the information provided by Mitchel Davis in episode 5 of his YouTube playlist on Bare-Metal MCU, I ended up with the following command for AVRDUDE:

avrdude -v -p attiny13 -c usbtiny -U flash:w:2_led_on.hex:i

That calls AVRDUDE in verbose (-v) mode for more feedback, telling it we’re programming an attiny13 (-p attiny13) using a usbtiny programmer (-c usbtiny), and that we’re uploading and writing to flash memory, the hex file (-U flash:w:2_led_on.hex) and doing that immediately (:i). That looked great, except it didn’t work. Luckily, the verbose command let me know that it was a permissions issue for the USB programmer. So, sudo-ing the command made it work. Ideally, I’d like to find the correct permissions setting for my user so I wouldn’t have to use sudo for this, but I haven’t been able to find the right one yet. Neither adding uucp nor tty has helped, nor has installing usbasp-udev and avrisp-udev.

So, there’s more to learn still. Possibilities to improve the workflow, for instance, lie in using makefiles to set up some standard settings. And, of course, trying to fix those permissions errors. Either way, with the process described here, I managed to write, compile, and upload the relevant program from the tutorial linked above. So, more learning lies ahead!

AVR ISP

I’m trying to learn a bit about in-system programming of microchips, and specifically some of the Atmel chips. I have an Arduino Uno lying around, on which I programmed a simple Pomodoro timer, as well as an ATtiny that I wanted to use to experiment more with.

That Pomodoro timer idea was a lot of fun to make, and taught me a bit about bit masking and so on, but I never got to putting it on some perf board, because that would either require getting a 16Mhz crystal in (something I’d just not gotten around to) or otherwise setting some fuses in the Atmega328P (something I had no idea how to do). Recently, I found this tutorial on Assembly programming microchips that seemed quite fun, and it require the purchase of an AVR programmer. Fortunately, you can pick one up for about €5 if you go off-brand, so I just got one. As luck would have it, that’s exactly what I need for both purposes.

The tutorial on Assembly I’m intending to follow is written for Windows, and so includes plenty of references to Atmel Studio. As is usual in these cases, Atmel Studio is not available on Linux, so I had to explore alternatives. After a lot of hits and misses (usually involving using an Arduino Uno as a programmer), I end up finding a YouTube channel where somebody made a helpful tutorial series on moving from using an Arduino to going as close to “bare metal” (i.e. using little software) as possible. So, not only do I learn I can use AVRDude on Linux to achieve my goal of following the Assembly tutorial, I also learn that I can flash my Atmega328P with this thing so that I can break that out of the Uno board and use it standalone. Score!

I look forward to being able to complete that Pomodoro project in its first iteration soon, and thereby picking up some relevant skills for the later tutorial as well.