-
1K challenge
01/06/2017 at 00:56 • 0 commentsTime's up for the 1K challenge and the project is still in progress. The compiled object code is nowhere near 1K, even the hex file is only 800 bytes, so size is not an inhibitor for this project. Some glitches in writing to EEPROM still exist, but they will unravel over the weekend.
The project will be finished within a week, because that's when I'll be presenting part of it at the disobey.fi conference. There will be details on the password manager that started this project in the first place too when I post links to slides after the conference on the 15th of January.
-
Timing and Architecture
01/06/2017 at 00:44 • 0 commentsI've mentioned before the data read from the bus is about ten times as fast as the data that is written to EEPROM. As the readable data is extremely volatile, reading it must always have highest priority. This is what interrupts are used for, they do actions that have to be done before a specific deadline. In the TWI case the deadline for storing a byte from the bus into RAM is just before the transmission of a new byte starts.
Below we can see the timing of the interrupt routines. The yellow debug signal is pulled low during USI overflow of start condition interrupt handler. The green signal is flashed whenever a new byte is found in the buffer by the main function. A shared buffer is the way the interrupt routines are communicating with the main function.
Transferring the byte from RAM to EEPROM has a deadline much longer in the future. It is sufficient to finish the transfer before the microcontroller is shut down as that's when we lose the contents of the RAM. We can use a data pipeline where data is constantly copied from the buffer to the EEPROM, but this will be progressing a lot more slowly than the sniffing.
Below we see the timing of EEPROM writes. The green signal is pulled low while a byte is being written from the buffer to EEPROM. The yellow signal shows when bytes are received on the TWI bus.
As the oscilloscope captures show, the software architecture is very simple, with interrupt routines producing data to a buffer and the main function consuming that data by storing it in long-term memory.
-
Debugging without printf
12/20/2016 at 19:35 • 0 commentsIt's very common to use a serial connection to your laptop for debugging with printf statements. This is usually okay when the stuff that is being done is slower than the serial connection. When working with interrupt driven code and fast signals the serial connection will cause disturbances and bugs that happen due to timing issues. In other words your debbugging code will be working against you.
Flipping pins to blink LEDs is another approach that works well for showing that a certain state in the program has been reached. This causes very little disturbance as it only takes one opcode to switch a pin state. However, when interrupts are happening at 10KHz, the human eye will not be able to perceive those blinks.
This is where it's good to have access to an oscilloscope or a logic analyzer. They can be found in schools, universities, hacklabs, and in Helsinki even in some libraries. Don't be afraid to ask for them, they are very often not in active use. In the scale of oscilloscopes a 100KHz TWI signal is slow, as they are often able to sample at several MHz.
When I'm debugging my TWI signal handler interrupts I'd switch the state of a pin every time an interrupt routine is entered and exited. From a programming point of view this is not different from blinking LEDs. Since I have access to an oscilloscope with many digital inputs I simply use a separate pin for every individual interrupt. This way I can very easily see on my oscilloscope screen when each of my interrupt routines are executing and locate errors. As I'm also showing the data and clock signals on the oscilloscope I can verify that operations happen when they are supposed to. Since I can capture a burst of signals and analyze it statically, my human eyes are well capable of understanding what is happening.
If you've never worked with oscilloscopes, do try it out. Learn how to use triggers and set it up to catch the part that you are debugging. This might be overkill for many projects but for some you just can't do without it.
blue:SDA, red:SCL, green:TWI start condition interrupt, yellow:TWI byte/ack received interrupt
-
Timing constraints
12/14/2016 at 05:24 • 0 commentsThe development has reached a point where it is clear the actions needed for sniffing are possible with the ATTiny45, even If there wont be a lot of time to waste. Sniffing a 100KHz signal with a microcontroller running at 8MHz only leaves 80 clocks per bit on the TWI bus which is not exactly a lot. Therefore some interrupt handling routines have to be made to fit that constraint, so some effort to optimize has to be done.
Optimizing for speed is easily done by using C or ASM as the language. As I'm already hitting these constraints with C, I've decided to go for ASM. Luckily there is very little arithmetic and complex logic needed in the project so this will not be a big problem. Since I'm reaching high speeds by the means of less instructions, this will have the natural effect of making the binary tiny and reaching the 1024 byte limit is not a risk.
Another timing related issue is the speed of writing to the EEPROM. It can only write at a baudrare of approximately 10KHz, which means I'll miss ten bytes on the bus if I stop to write a single bus to the EEPROM. Luckily most devices that require human interaction will be having long breaks (hundreds of milliseconds) between transmissions that can be used for moving the sniffed data from RAM to long-term storage.
Some design descisions will have to be made on the basis of these timing limitations. Since I'm originally working on the implant with a particular device in mind, the descisions will be made according to what is the best way to deal with timing in that device. Effort will be made to make the code readable and editable to fit other needs