Tag Archives: kernel


Vacation is almost over and I made lots of progress over the past 2 weeks.

A small recap here:

  1. ADC is working together with the camera and mpu9250. This was quite an adventure and resulted in a bit of hardware and kernel hacking. Details here.
  2. Changed from access point to Ad-Hoc mode. As soon as I did this, the rt2800 driver I’m using for the Alfa 036H card started crashing. It looks like a known problem and it happens on the desktop as well. So I switched to a TL-WN722 card.
  3. The new wifi card works ok, no more disconnects or driver issues. BUT the usb interrupt is killing all my CPU. I started optimizing both the usb driver and my network usage to avoid flooding the interface with many packets. This resulted in 1 week of kernel/driver debugging and a fixed 30Hz packet rate for the inputs.
  4. Once the wifi/usb driver started working reliably, I got another kernel freeze when the i2c driver timed out. A few days of debugging revealed nothing so I ended up increasing the timeout value from 150ms to 500ms. Seems ok for now.
  5. In some rare cases the wifi disconnects mysteriously. After a few days of work I figured out it was the combination of high CPU usage + high thread priority of the brain. This caused the USB driver to have big latency when serving interrupts (probably) and the wifi card to drop the connection. I fixed this by optimizing the PIGPIO library (10% less CPU), using the libpigpio.a instead if libpigpiod_if.a (the socket interface) and optimizing my code a bit more. Overall CPU usage dropped from 60-70% to 30-40% now.
  6. I recompiled the kernel to remove everything I don’t need and also optimized my pipaOS image to remove all cron jobs and services. I have a very clean image now that seems to be very reliable and boots in 20-22 seconds.
  7. The FIFO inside the mpu9250 seems to fail sometimes if it gets full. It’s 4096 bytes big and my sample is only 12 bytes big. So when it gets full some samples get split in half. For this reason I was resetting the fifo when it had more than 4000 samples but even this failed sometimes. It seems that the samples are not written to the fifo atomically by the mpu so when asking for the fifo size I would get any number – even odd number of bytes sometimes. I fixed this one by resetting in a different way – shutting down the fifo and reconfiguring it. Seems to work for now.
  8. I finished my UBLOX protocol implementation and tested with my RCTimer Neo6 gps but it kept loosing the fix. Seems like a hardware problem that I caused some months ago after a hardcore crash of my previous quad so I ordered a new GPS module. Note to self – finish editing the footage of the crash and post it here.


That’s it.

The end results of these weeks are:

  1. A very stable raspbian image with a very small kernel (2.1Mb vs 3Mb) and only 1-2 user processes after boot.
  2. Very stable i2c transactions with the MPU, the ADC, the Barometer and sonar.
  3. UBLOX GPS code with protocol detection is done.
  4. Ad-hoc wifi works very nicely now with stable connection.
  5. Lowered CPU usage and started using RT scheduling for the main thread. This results in a rock stable 100Hz main loop.
  6. Some optimizations for the USB fiq driver and the ath9k driver that I’ll submit soon.
  7. Input stream uses a non-reliable channel now with a fixed 30Hz frequency instead of the previous reliable channel. Works better in low-connectivity situations.
  8. I started to be familiar a bit with kernel and driver code. This will probably prove useful in the future.
  9. All the hardware that I’m interested in is now working and connected. This includes:
  • raspi camera
  • accelerometer / gyroscope / compass
  • barometer / thermometer
  • sonar
  • adc
  • gps
  • camera servo
  • motors


Now I’m working on creating a test rig for the quadcopter to check my pids. It involves a clothes hanger, zip ties, a chair, a wood stick and some strings. I’ll make a youtube video of this one in action but here’s a photo in the mean time:


Happy new year!

Odroid W ADC

One of the advantages of the Odroid W is that is has 2 onboard ADCs that are perfect for the current/voltage sensor. They support up to 2.5v max while the AttoPilot 90A/50V goes to 3.3v max. This reduces the range to 67A and 37V which is more than enough for the 50A silkopter will use at max throttle.

Hardkernel provided a Raspbian image with the modules needed to get the 5T619 chip functional – including the adc – but when I tried it a few weeks ago the mpu9250 was getting regular bus errors and even kernel panics.

A few days ago I decided to test some more on a raspberry pi model A, to eliminate any unknowns from the odroid w board. So I connected a SRF02 sonar to i2c-0 to simulate the 5T619 and the mpu9250 to i2c-1. Simply trying to talk to both of them resulted in kernel panics. After 2 evenings of debugging it turns out that the hardkernel raspbian kernel had combined transactions turned on and the i2c-bcm2708.c kernel module has an issue with combined transactions if one or both of the busses has heavy traffic. I managed to find the bug – a small one actually – and the kernel panic was gone.

So I could talk to the mpu and I could talk to the sonar and also the adc chip on the odroid board.

However, as soon as I started raspivid or raspistill – or anything using the camera – i2c-0 stopped working even after killing the process. Turns out that the GPU makes use of the i2c-0 to talk to the camera and it changes the SCL.0 and SDA.0 pins from ALT0 to IN. And it leaves them like that until a reboot or I manually change them back…

So now I have the ADC working, the camera working as well but not both together. My only chance is to change the i2c-0 pin mode back to IN after every call to mmal and hope the camera doesn’t use the bus between mmal calls. Hopefully this will fix the issue but it’s a very ugly hack.

At least I have ADC working, the battery module committed in the brain and integrating the battery capacity from the current readings.

Next I want to autodetect the number of cells in the battery and estimate the capacity at startup.

Also it would be nice if the ground station detected when the battery was replaced and ask for the capacity of the new one.