User request video lesson

I like making videos and I like talking about / teaching embedded systems, so it should be no surprise there have been a few video tutorials on this site in the past.  I’m starting to get the bug again and want to post something that people working with embedded microcontrollers want, but I’m not totally sure what to show.  This lead to an opportunity, rather than try and guess what people want, I’m going to ask you the  people what you want to see! Here are the details:

  • Post a comment here telling me what you want to see in a tutorial video
  • My plan is to make a ~10 minute video about one or two topics
  • Topic areas include
    • Development tools (Logic analyzers, Rigol DS1052 Scope, PICKIT3, AVR Dragon, IDEs, Toolchains)
    • Microcontrollers (PIC16, PIC24F, ATMega, MSP430, STM32)
    • Processor peripherals (GPIO, Timers, ADC, Watchdog, PWM)
    • Bus protocols (SPI, I2C, CAN, RS232)
    • C programming (Modular programming, code reuse, basics through interrupts and threads)
    • Interfacing with devices (LCDs, buttons, keypads, EEPROM, accelerometers, etc)
    • Eagle PCB
    • Embedded Linux development (Raspberry Pi dev, Pi toolchain)
  • The video will be uploaded to youtube and posted here

Let me know about that thing you always wanted to know but never learned, I’ll make a video!

Compile using ffmpeg libraries

Tonight I wanted to play around with the ffmpeg API and see how complicated it was.  I downloaded the example decoding_encoding.c file and tried to compile it against a local build of ffmpeg I made based on their Ubuntu compiling tutorial.

Well let me tell you, ffmpeg sucks at getting people up to speed.  Yeah it’s great they have a few examples on how to use the API, but their makefile is dependent on pkg-config, so it is totally useless for a cross compilation, you would have to add the libs path to your build machine, which is dumb.  Not to mention the libraries they use in the example makefile are missing library references required for the example, leading to a TON of missing symbol errors!  Well after a bunch of searching I found one or two references to people who got the examples built which lead to the commands to build the damn thing on my machine.  This post is for everyone wanting to get started with the ffmpeg API and so I don’t loose it!  Enjoy :-)

The -I and -L paths should be to your ffmpeg build, mine was obviously /home/s1axter/projects/ffmpeg_sources/ffmpeg_build/

gcc -Wall -I/home/s1axter/projects/ffmpeg_sources/ffmpeg_build/include -c -o decoding_encoding.o decoding_encoding.c

gcc -Wall -L/home/s1axter/projects/ffmpeg_sources/ffmpeg_build/lib -L/usr/lib/i386-linux-gnu -o decoding_encoding decoding_encoding.o -lavformat -lavcodec -lswscale -lavdevice -lavfilter -lfdk-aac -lpostproc -lswresample -lx264 -lavutil -lvpx -lvorbisenc -lvorbis -lmp3lame -ltheora -ltheoraenc -ltheoradec -lva -ldl -lz -pthread -lm

And a Makefile: ffmpeg makefile

Raspberry Pi – Cross Compile & Kernel

This is the first post in a series on getting down into the bits of a Raspberry Pi Linux installation. It assumes familiarity with the Linux build process, gcc, make, apt-get, ssh, etc.

Lately I have been thinking about a project that would require a beefy embedded system, one with embedded Linux, fast, and lots of storage.  It turns out the RaspberryPi has all the requirements for this project, and I have one laying around, so I figured I would pull it out and get a full development toolchain started to see what the little Pi could do. This project might require a Linux driver module, so for that I need to compile the kernel and modules too. All steps were done on an Xubuntu 12.10 32-bit machine with the Ubuntu GCC/binutils/make packages installed.

Image

The first step was getting an image running.  I tried a few and the Arch Linux image is prefect for an embedded project, it doesn’t contain all the X crap by default, it boots  in ~10 seconds (thanks to systemd) and the stock image only takes up about 450Mb on a flash drive, leaving lots of space.  Here is the image (I used the version from Nov 2013), here is how to make an SD card.

Toolchain

The next step was to get a cross compiler toolchain build.  I have seen a lot of posts that say “do an apt-get install gcc-arm-linux-xxxxx on Debian”, that’s all well and good if like relying on Debian, I would like full control over my toolchain, and I don’t want to have to export tons of bash variables for tool locations.  Fortunately, there is an awesome application called crosstool-ng that makes downloading and building a custom compiler and tools a breeze.  I followed this post successfully and put the output directory of the cross compiler binaries within my home directory, this way the ARM compiler isn’t system wide and I can move it where I want it.  I did have to install some packages “sudo apt-get install gperf texinfo gawk libtool automake libncurses5-dev”. The test application compiled without issue and a quick SSH got me “Hello world” on the Pi command line.

Kernel

Rebuilding the kernel and modules seemed a little daunting, but actually it’s pretty easy once you do it. These two references (PDF and elinux) were good for understanding the process.  The kernel for the Raspberry Pi is build from a central git repo, so you just need to clone the repo and you have the whole kernel source all patched and ready to go.

The Arch Linux build has a handy feature enabled, it outputs the kernel config for the running kernel in the /proc directory, which means if you use this config as the base for your config, all the settings match the current kernel, which you know works. Copy the file /proc/config.gz from your Pi, uncompress it to ‘.config’ in the root of your kernel source and it will be read by menuconfig, can’t get easier than that!

Now, because I compiled the toolchain into a local home directory I need to pass the path to it for each call to make.  This isn’t that bad because I plan on making scripts that build the kernel and modules whenever I need them.  Here is an example of how to run menuconfig and the final make:

make ARCH=arm CROSS_COMPILE=/home/s1axter/raspi/toolchain/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi- menuconfig
make ARCH=arm CROSS_COMPILE=/home/s1axter/raspi/toolchain/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-

The kernel make builds both the kernel and the modules for that version of the kernel.  You have to copy over both the new kernel and the kernel modules since you can’t use the old modules that exist on the Pi.  Again, rather than export a bash variable like the elinux source says I pass the module folder path in the make command.

make modules_install ARCH=arm CROSS_COMPILE=/home/s1axter/raspi/toolchain/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi- INSTALL_MOD_PATH=/home/s1axter/raspi/kernel/modules

After these build steps use sftp or some other means to get the modules and firmware directories in the ‘modules/lib/’ folder into the ‘/lib’ folder on the Pi. The kernel new image is ‘arch/arm/boot/Image’  from the kernel source folder and needs to replace /boot/kernel.img on the Pi (Make a backup, just incase).  I used scp/sftp, so I logged into the Pi and did a ‘sync‘ command to make sure everything was written to the SD card and then ‘reboot’.  I might have been lucky but the Pi came back up and my kernel went from 3.10.18 to 3.10.25!

Good luck

 

GoPro timelapse ffmpeg

So I got a GoPro this Christmas for skiing.  Yesterday I took some footage on the mountain, including some time lapse shots which I wanted to stitch together to make a sped-up video.  I’ve used ffmpeg a bunch, so I knew it could do the job.  There isn’t much to making a movie from the images, and the following command works pretty good.  The only tricky part was the GoPro doesn’t start all timelapses at G0020001.JPG, mine was at G0020069.JPG. The timelapse setting was one picture every 0.5 sec and the output is 10 fps.  The GoPro still are also 4000×3000, so I convert them to 1920×1080 to match the video frame size, this adds a little distortion but still looks pretty good.

ffmpeg.exe -f image2 -r 10 -start_number 69 -i G002%04d.JPG -vcodec libx264 -pix_fmt yuvj420p -s 1920×1080 out.mp4

The 10 fps had some weird conflicts with my editor, so 29.97 fps might work better.

C Preprocessor Macro Demo Video

Here is a demo video on using C Preprocessor macros to make your code easier to read and write.

As promised, here is the code in the demo program

And don’t forget to check out the original articles

http://www.mybitbox.com/2012/11/robust-c-code-part-1-c-preprocessor/
http://www.mybitbox.com/2012/12/robust-c-code-part-2-advanced-c-preprecessor/
http://www.mybitbox.com/2012/12/robust-c-code-part-3-wrapping-c/

S1axter

Gerbmerge issues on Ubuntu 12.10

Gerbmerge is used to panelize multiple PCB gerber files into one gerber.  This allows you to submit one “board” that has multiple copies on it.  Note, gerbmerge was developed for Eagle PCB generated gerber files

Installing gerbmerge on Ubuntu 12.10 (Actually Xubuntu 12.10, but things should be the same with regular Ubuntu) didn’t work right out of the box, here is what needs to be modified:

Edit setup.py from gerbmerge 1.8 source: Change line 40:

From: DestLib = distutils.sysconfig.get_config_var(‘LIBPYTHON’)
To: DestLib = distutils.sysconfig.get_python_lib()

Run sudo python setup.py install

Check the ‘installed_file’ file and see where gerbmerge was installed, mine was “/usr/local/lib/python2.7/dist-packages/gerbmerge/gerbmerge.py”

Edit /usr/bin/gerbmerge to point to this location. The “installed_files” file will also tell you where the testdata was installed.

Source: Installing on a Mac: http://karplus4arduino.wordpress.com/tag/gerbmerge/

ARM cross compiling in 5 minutes

I was poking around tonight and started playing with some ARM cross compiling on my x86 Xubuntu 12.10 desktop via QEMU.  If you want to start building for ARM, follow these steps

Using Synaptic install “gcc-4.6-arm-linux-gnueabi”,”qemu-kvm”,”qemu-kvm-extras” and all the dependencies. (Maybe someone can post the full “apt-get install” command as a comment)

Make a small C file.  Example

#include<stdio.h>
int main(){
printf(“Hello ARM World\n”);
}

Build the binary: “arm-linux-gnueabi-gcc-4.6 hello.c -o hello”

Run the ARM binary using Qemu via “qemu-arm -L /usr/arm-linux-gnueabi/ ./hello”

Should output “Hello ARM World”

Pretty easy, now you have an ARM cross compiler toolchain.

Useful QEMU ARM links:

http://www.linuxforu.com/2011/06/qemu-for-embedded-systems-development-part-1/
http://www.cnx-software.com/2011/02/10/emulate-an-arm-plaform-with-qemu-on-ubuntu-10-10/

http://wiki.debian.org/QemuUserEmulation

 

Nixie clock demo

The latest project, a nixie clock, is almost done! Just needs a few more tweaks and a replacement driver chip for the left most digit.

Robust C Code Part 3 – Wrapping C

In the last segment in this series “Robust C Code Part 2 – Advanced C Preprocessor” I talked about the preprocessor concatenation directive.  In this segment I will talk about using the preprocessor to wrap C code, and what an L-value is. Now this is getting a little technical, so you might want to brush up on C.

The macros I defined in parts 1 and 2 of the series are rather simple. Many times I want to wrap multiple C statements in a macro and use them just as a regular statements.  This seems rather straight forward we could do the following

#define setup_some_hardware()            hw_register1=0×12;hw_register2=0×34;hw_register3=0×56

This will work most of the time since the statements are executed one after another, however this is dangerous because the statements are not grouped in the same scope.  You can think of scope as groups of variables that can ‘see’ each other.  If you have 2 functions, one with ‘int x’ inside and one with ‘int y’ inside, the variables can not ‘see’ each other since they are are in different functions, which means you can’t do x=y; they exist in different scope. A new scope can be created with curly braces {}, which means loops, if statement  and functions all have their own scope.  The three statements in the previous macro can exist in different scopes like in this example:

// Check the hardware and enabled if off
if(HWREGISTER.ON == false)
setup_some_hardware();

An if() statement without curly braces {} will execute the single next statement if the condition is true.  This causes a problem because the preprocessor expands the macro to:

// Check the hardware and enabled if off
if(HWREGISTER.ON == false)
hw_register1=0×12;hw_register2=0×34;hw_register3=0×56

This results in hw_register2 and hw_register3 ALWAYS being set and only hw_register1 affected by the if() statement.  In C you can’t have semicolons in parentheses, so what do you do to group the statements?  One solution is to add curly braces {} to macros that don’t return a value so all statements are in the same scope.  This seems logical however in C you can’t have a semicolon after a brace which means you have some statements with semicolons and some without, which can lead to some really hard to find bugs.

The solution for this problem is to wrap the multiple statements in do{ }while(0).  If you took  CS101, the do{}while() loop will always allow one execution before evaluating the condition in the while().  Since while(0) is always false any good ANSI C preprocessor will remove the do{}while(0) and only execute the code once.  Since the loop uses curly braces to create a new scope, all statements are in the same scope and a semicolon can be used on the statement.

#define setup_some_hardware()            do{hw_register1=0×12;hw_register2=0×34;hw_register3=0×56;}while(0)

// Check the hardware and enabled if off
if(HWREGISTER.ON == false)
setup_some_hardware();

An additional benefit of the scope created by the do{ }while(0) is that new variables can be created in the new scope.

#define swap_int(val1,val2)              do{int tmp; tmp=val1; val1=val2; val2=tmp;}while(0)

if(some_condition)
swap_int(x,y);

A little known/understood element in C is the L-value. L-values can be though of as the value returned from the right side of a C statement to the left side of the statement. a do{ }while() loop has no L-value and will result in a compiler error if an L-value is expected, so any statement that returns a value should NOT use do{ }while(0) wrapping.  A good rule of thumb is if the statement returns a value use parathenses, if it doesn’t, use do{ }while(0).

The following is an excerpt from a UART C header which uses the preprocessor to give more developer friendly names to sequences of statements and convoluted register names:

#define uart1_interrupt_rx_enable()      do{IEC0bits.U1RXIE = 1;}while(0)
#define uart1_interrupt_rx_disable()     do{IEC0bits.U1RXIE = 0;}while(0)
#define uart1_interrupt_rx_clear()         do{IFS0bits.U1RXIF = 0;}while(0)
#define uart1_interrupt_rx_set()             do{IFS0bits.U1RXIF = 1;}while(0)
#define uart1_interrupt_tx_enable()      do{IEC0bits.U1TXIE = 1;}while(0)
#define uart1_interrupt_tx_disable()     do{IEC0bits.U1TXIE = 0;}while(0)

#define uart1_tx_buffer_full()              (U1STAbits.UTXBF == 1)
#define uart1_tx_last_done()               (U1STAbits.TRMT==1)
#define uart1_rx_overrun_get()           (U1STAbits.OERR)

#define uart1_reset()             do{U1MODE = 0;U1STA = 0;}while(0)
#define uart1_enable()         do{U1MODEbits.UARTEN = 1;}while(0)

 All the preprocessor macros that I have shown will compile down into “in line” instructions.  This speeds up execution compared to functions since the processor doesn’t have to create a stack frame and branch to another location in code just to do a simple bit set.  The one downside is highly used macros with multiple statements will be injected into the source each time they are used, which can lead to larger code.  I try and keep preprocessor macros short and simple to reduce this.

Nixie test

Here is a short video of the nixie tube clock with the first nixie tube connected.  The controller board uses a PIC24FV32KA302 processor, a 74HC595 shift register, a 74LS374 octal latch and 74141 driver chip to control an IN-14 nixie tube.

Check back for more on the clock.

WordPress Themes