Notes
This is a collection of random notes for myself that I thought could be useful for the general public as well. They are in no particular order and the list should grow over time if I can get myself to actually do this.
General
# When you need to pull up a color picker quickly,
zenity --color-selectionis a handy one you probably have already installed.# In optimized binaries, GDB sometimes lies about the content of variables and/or function parameters that are higher in the stack than the actually currently executing function. The reason may be that the particular variable is only stored in a register, which is then overwritten by the logic further down the stack. Such optimizations may not always result in a
<optimized out>placeholder, so be wary!# To test a static website quickly, you can use Python’s built-in HTTP server to do it:
python -m http.serverThis will serve the current directory on localhost, port 8000. Don’t use it for production, though, it’s not secure enough for that.
# Aggregation over indirection
Whenever you are designing an API with callbacks, and the API has its own state struct that can be embedded in other structs, you can avoid a
void *user_datapointer by just using the offset of the embedded struct, which saves memory:/** For @field_ptr pointing to memory that is a field named @field_name * from the parent struct of type @parent_type, gets a pointer to the parent * struct. */ #define CONTAINER_OF(field_ptr, parent_type, field_name) \ ((parent_type *)((char *)field_ptr - offsetof(parent_type, field_name)))# Getting the shell script directory
# Killing a hung SSH session
Enter~.– in this order
# Complete reference of standard HTML entities (a.k.a. named characters)
Microchip SAM D5x/E5x series
This is a family of 32-bit ARM microcontrollers by Microchip. You can find some basic info on them on Microchip’s official website if you’re interested. As I work with these at my day job, I am collecting some notes on specific behaviour related to them. Perhaps some other developers using these will find it useful.
Please note that this is not meant to be a comprehensive documentation. For that, you still need to see the official resources. This is only meant as an explainer of things that I personally got wrong at some point.
Also note that all of this is written from the perspective of bare-metal programming of the chip – we are writing our own library from scratch, not using Microchip’s HPL, which may be taking care of some or all of these things by itself.
DMAC
This is the Direct Memory Access Controller peripheral, facilitating DMA, i.e. autonomous operations on memory regions without the intervention of the CPU.
- # The
TCMPL(Transmission Complete) interrupt flag is set after the completion of each and every descriptor withBTCTRL.BLOCKACTset toINT. If you are transferring multiple regions of memory and only wish to interrupt after all of them are complete, only the last descriptor has to haveBTCTRL.BLOCKACTset toINT; the others have to have it set toNOACT.- Presumably,
BTCTRL.EVOSELwould work much the same way, but I have not had a use for that yet.
- Presumably,
PORT
This peripheral controls the GPIO pins of the SAM.
# A pin may operate in an open-drain mode, but the way we set its value is different to the one we do it with a “classic” totem-pole (push-pull) output.
Instead of continuous flipping of the
OUTregister to change the value, we set itsOUT=0,PINCFGx.PULLEN=1, andPINCFGx.INEN=1(the last one is so that we can read the actual pin value while we’re not driving it – useful e.g. for bit-banged I²C to read the ACK signals and clock stretching). Now, to set the pin’s value, we use theDIRregister. Note, however, that to drive the pin low,DIRneeds to be set; and to keep it floating,DIRneeds to be cleared – i.e. the opposite way than may be intuitive.- Operation in open-source mode would be the same, just set
OUT=1, then setDIR=1to drive high and clearDIR=0to keep floating.
- Operation in open-source mode would be the same, just set
SERCOM USART
This is the peripheral for serial communication via UART/USART.
- # Interrupts while transmitting (
TX) work as follows:- TL;DR:
- Write into
DATA. - Wait for
DREinterrupt (but ignoreTXCfor now!). - If you have more data to transmit, go to 1; if not, continue.
- Wait for
TXCinterrupt. - Transmission is finished.
- Write into
- Explainer:
DRE(Data Register Empty) signals that we can write another character/word into theDATAregister (which will then get written into the internal hardware buffer of the SERCOM peripheral). It does not mean the actual transmission on the actual wire has finished – if we turn TX off right after this interrupt, the transmission will not finish.TXC(TX Complete) interrupt signals that everything that has been submitted into the internal buffer so far has been transmitted over the wire.- You will probably want to use the DMAC peripheral so as not to hog up the CPU just by transmitting a message and handling the relevant interrupts. This means that you will be handling writes to
DATAand theDREinterrupt via the DMAC trigger (steps 1–3 in the TL;DR), but you still absolutely have to handle theTXCseparately after the DMAC transmission is finished (steps 4 and 5 in the TL;DR), lest your messages will not be transmitted properly.
- TL;DR:
ICM
This is the SAM’s SHA hardware accelerator.
# To get actually portable SHA hashes, you always need to do padding, even if the message length is SHA block aligned. This is not really specific to SAM, it’s just how SHA works, but I learned it the hard way while dealing with the ICM, so I’m putting it here.
# The
TRSIZEvalue in the descriptor is set to the number of SHA blocks minus one- The official documentation is not very clear about this.