Tag Archives: c

Learn from my AVR mistakes

I’m learning a lot programming in AVR C.  There’s are a few subtleties to watch out for, and some of them have had me banging my head against the wall for days.  This post is an attempt to prevent anyone else playing with AVR outside of AVR Studio (I’m using Linux and the command line) from having the same issues.

Sections for avr-objcopy

When you compile an AVR C program, you get object code, which you have to convert into HEX format to flash onto the chip.  You do this using avr-objcopy, and there are apparently several valid ways of doing it.  I recommend learning about what the -j and -R flags are doing when you come across tutorials with this command in them.  I was using one from a tutorial that looked like this:

avr-objcopy -j .text -O ihex some.o some.hex

That’s all fine and dandy except it only works for programs that don’t end up using the .data section of the object code! Now, this wouldn’t be a big deal if there were any warnings about this, but there aren’t – you just have to know to add a -j .data. A better solution, posted here by clawson, is to use the -R flag to remove parts you know you do not want. Here’s my current strategy:

avr-objcopy -R .fuse -R .lock -R .eeprom some.o some.hex

This fixed 2 separate problems when I did it, one with struct initialization and one with my LCD displaying block characters for strings but working for single characters.

Parsing WFM Oscilloscope files in C

So, I got this Rigol Oscilloscope – I wrote a little instructable about it. One cool feature is the ability to save waveforms to a USB stick. There are many options for the file format, but the default is a WFM file. Now, a true minimalist could just use the CSV option, but the WFM is a binary format that contains a lot more information directly from the scope. I wrote a little C program hosted on github that allows you to convert those pesky proprietary files into something useful – namely a gnuplot image!

This is super alpha, and I’ll happily take patches. Cheers!

Burst C++ Library

I made a little C++ library called burst. The idea is to extend the awesomeness of Boost with convenience functions for common tasks (mainly my own common tasks, but maybe others can benefit as well). The current trunk is here. Here’s a quick example:

And just that quick (3 lines) you’re sending an HTTP request to boost.org’s root page and streaming the result to STDOUT. Pretty cool, eh? What if you want a different website?

It’s nearly as easy as Ruby’s open-uri! Inheriting from it makes it even better, since you can quickly customize a web api class around the gory HTTP details Burst.Asio.HTTP.Client does for you.

1,000,000th Fibonacci Number One-Liner in C

This is possibly the best one-liner I’ve ever written:

gcc -x c -o /tmp/out - -lgmp <<< '#include <stdlib.h> 
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <gmp.h>
void omg_i_love_leonardo_of_pisa(uint32_t num, mpz_t * result) { mpz_t retval, last, tmp; mpz_init(retval);
 mpz_init(last); mpz_init(tmp); uint32_t i = 1; if(num == 0) return; mpz_set_ui(retval, 1U); 
mpz_set_ui(last, 0U); for(; i < num; i++) { mpz_set(tmp, retval); mpz_add(retval, retval, last); 
mpz_set(last, tmp); } mpz_set(*result, retval); } int main() { uint32_t num; mpz_t fibo; mpz_init(fibo);
omg_i_love_leonardo_of_pisa(1000001, &fibo); mpz_out_str(stdout, 10, fibo); printf("\n"); return 1; }
' && time /tmp/out

It compiles a C program given from STDIN, puts it in /tmp/out, and runs it with time to find the time it takes to run. It generates the 1,000,000th Fibonacci number. Try it!

Update May 21, 2011

I changed the algorithm to do a matrix multiplication trick. The only problem is it goes over the number you ask for currently. I'm going to fix this with memoization soon.

gcc -x c -o /tmp/out - -lgmp <<< '#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <gmp.h>
void print_state(mpz_t* fm2, mpz_t* fm1, mpz_t* f, uint32_t n){gmp_printf("fib(%d) = %Zd\n", n, f);}
#define NEXT_FIB() mpz_set(oldfm1, fm1);mpz_set(oldf, f);mpz_mul(f, f, f);mpz_mul(tmp, fm1, fm1);\
mpz_add(f, f, tmp);mpz_mul(fm1, oldf, fm1);mpz_mul(tmp, oldfm1, fm2);mpz_add(fm1, fm1, tmp); \
mpz_set(tmp, fm2);mpz_mul(fm2, oldfm1, oldfm1);mpz_mul(tmp, tmp, tmp);mpz_add(fm2, fm2, tmp);\
n += i;i *= 2;
int main(){mpz_t fm2, fm1, f;uint32_t n = 2;uint32_t i = 1;mpz_inits(fm2, fm1, f, NULL);mpz_set_si(fm2,
0);mpz_set_si(fm1, 1);mpz_set_si(f, 1);mpz_t oldf, oldfm1, tmp;mpz_inits(oldf, oldfm1, tmp, NULL);
uint32_t g = 1000000;while(n<g){NEXT_FIB();}print_state(&fm2, &fm1, &f, n);return 0;}' && time /tmp/out

This outputs almost immediately on my Intel Atom:

fib(1048577) = 19202837189514814.................

real	0m0.840s
user	0m0.280s
sys	0m0.010s

The code is here. Feel free to fork and improve!

Update August 30, 2013

I ended up looking at this again, and I improved it immensely. Apparently, gmp has built-in fibo functions (!!):

int main()
  int n = 1000000;
  mpz_t fm2;
  mpz_inits(fm2, NULL);
  mpz_fib_ui(fm2, n);
  gmp_printf("fib(%d) = %Zd\n", n, fm2);
  return 1;

This produces a number MUCH faster than the above implementation. It also makes a nicer oneliner:

gcc -x c -o /tmp/out - -lgmp <<< '#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <gmp.h>
int main() { int n = 1000000; mpz_t fm2; mpz_inits(fm2, NULL); mpz_fib_ui(fm2, n); gmp_printf(\"fib(%d) = %Zd\n\", n, fm2); return 1; }" && time /tmp/out

real    0m0.057s
user    0m0.040s
sys     0m0.008s