July 30, 2013

Creating a linux device driver for the raspberry PI

first (i had hard times figuring out what missed me for correct compilation of a driver module ) ,try to Install the module-assistant for debian (i assume you’re logged in as ROOT ):
$ apt-get install module-assistant
$ m-a prepare(trys to get linux-headers )

At this epoch, you get an error : cant locate 3.6.11+ linux headers ( if you run the same version as mine is ..)
in doubt, you can check your linux version :

$ uname -r

thats bullshit.. GPL, linux, and so on… looks like it’s an adventure to get something going straight easy on the linux/raspberry Pi world.. :(
OK, lets get the linux headers (wget) from here : linux-headers-3611_3611-2_armhf (huge - i eihis.Com hosts it )
then, unpack it :

$ dpkg -i linux-headers-3.6.11+_3.6.11+-2_armhf.deb

At this point, the 3.6.11+ headers (tree) should be found here : /usr/src/linux-headers-3.6.11+
So, now let’s create a link to it for Kernel’s MAKE , after removing existing (bad) ones directories links :

$ rm -r /lib/modules/3.6.11+/build
$ rm -r /lib/modules/3.6.11+/src

[may be present. in my case, it was, but i tried many things before so, anyway, in a doubt , do it ]
Now, actually create the links :

$ ln -s /usr/src/linux-headers-3.6.11+ /lib/modules/3.6.11+/build
$ ln -s /usr/src/linux-headers-3.6.11+ /lib/modules/3.6.11+/src

now time to reboot ..

$ reboot

upon new login , CD to the directory of the module you want to compile, then ‘make’ to execute the Makefile.( beware of the Makefile name : case sensitive ! )
now, in the directory where your module.c code was, you get a module.ko file. thats the kernel module file created.
the Makefile should look like this :

obj-m :=yourmodule.o
KDIR :=/lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
[tab here] $(MAKE) -C $(KDIR) M=$(PWD) modules

where :
obj-m is the name of the object you want to build. the corresponding object.c file will be found by the MAKE command…
KDIR is the build directory (where parameters for kernel build,headers, and so on are located )
PWD is the destination (output .ko file) directory ( the current directory where your makefile and yourmodule.c file are located, for instance )

in case of problem, you can start by checking if the links have been created, actually.
Doing a :

$ ls -al /lib/modules/3.6.11+/build

should return :

/lib/modules/3.6.11+/build -> /usr/src/linux-headers-3.6.11+

If everything has run, you should now have a yourmodule.ko file into the current projects directory.
wich prove that the link is existing…
If everything has run, you should now have a yourmodule.ko file into the current projects directory.
you can test it by doing :

$ insmod yourmodule.ko

And stop it by doing :

$ rmmod yourmodule

I guess you now what to put in your ‘yourmodule.c’ file. hello world program examples can be found at many places dealing with linux driver’s compilation how-to websites.
This information post uses many sources (not listed) where i’ve found, finally, the way to compile drivers with no errors on the Raspberry Pi RASPBIAN , linux version 3.6.11+.
Hope this helps !

portions of code, with adaptations ,updates, modifications, and also Informations are coming from :

http://www.tldp.org/LDP/lkmpg/2.6/lkmpg.pdf (The linux kernel Module programming guide )

http://www.linuxforu.com/2011/04/character-device-files-creation-operations/ ( full of usefull articles )

http://gauss.ececs.uc.edu/Courses/c4029/lectures/work_queue.pdf ( work queues in Linux )


May 23, 2010

A remote 4 SERVOs Driving module diagram

Filed under: PIC progs and schematics — Tags: , , , , , — admin @ 6:48 pm

I’ve moved and been away for a little time…

Now i’m back with a project about the remote control of servomotors with a PIC as controller , and discrete ICs to generate the correct timings pulses necessary to drive the servos.

In the way i look at the things, i’m having trouble with the fact that the PIC microcontroller could be used only as a PWM generator, that’s the reason why i decided to develop a remote board , that could take in charge the generation of correct sized pulses in the 20ms period , providing that the PIC has pre-loaded the duration time into each timers.

I came out with a concrete solution designed to be stack-able and easily customizable for all of you , robots addicts ! It uses 4516 CMOS counters and 4011 classic CMOS gates

Take a look at this ( click to enlarge )

So what the hell is that ?

The clock for each counters is the same one , a 8KHz tunable clock, wich input is ‘clock in’ on my diagram.

A ‘load pulse’ is generated on the counter’s ‘Sx_LOAD’ input : it enables the loading of the data PD0,PD1,PD3,PD4 (binary) into the selected counter ( each of them have a separate ‘load data’ line ).
Each counter is counting down so it will be set at the binary value PD when the ‘load pulse’ is applied, then imediatly after the pulse has come to the low level, they will start counting down.In this mean time, the ‘carry out’ pin of the counter gets High, hence the ‘SERVO_x’ pin also.
When then counter reachs the ‘zero’ value, it’s ‘Carry Out’ gets low. so the generated ‘SERVO_x’ pulse will also get down, and the NAND gate then disables the clock to reach the counter’s clock input : the counter stops counting.

Then a new cycle can start again, by loading a new value into PD by a ‘load_pulse’ on the related pin, after , in the case of servomotors driving, around 20ms (minus the servo pulse time) of waiting time.

I could have added a 2->4 decoder onto the 4 servo board, but i have first decided to keep the ‘Sx_LOAD’ as-is to keep that diagram simple and easily customizable.

One of the important thing is that the counters are 4 bit counters, wich means that the servo will have a 4 bit resolution for positioning, hence a 11.25° resolution. ( 16 * 11.25° = 180° ) .

The timing are also important to understand :

A standard servo is operating from around 0.5ms to 2.5ms pulse length ( thats what i’ve experienced for my side ).
If you get deeper into my diagram logic, you’ll catch that the generated ’servo pulse’s’ duration is the sum of the ‘load_pulse’ time with the counter’s preset datas down count.
If we use a 0.5ms ‘load pulse’ duration, the preset datas combined with the 8KHz clock pulses will provide a covering of the needed time range , from 0.5ms to 2.375ms.

With that kind of remote timers, the robot’s microcontroller just has to manage the ‘load pulses’ and PD datas each 20ms.

Some of you could ask : so and..whats the gain there ?

If the microcontroller takes 0.5ms for each ‘load pulse’, and each load pulse must come every 20ms, then we can achieve a 40 servos driving with one microcontroller (theorical calculation)
Practically lets take a look at a 32 servos system :

  1. 4 Bits port for PD ( duration data )
  2. 6 Bits port for Servo Selection ( a 6 to 32 decoder , wich routes the ‘load_pulse’ to the needed servo) + 1 extra bit to enable decoding.

We have around 11 output Port-bits to achieve a 32 servo driving system - lets say it’s 12bits.
The only routine we have to code is a timer routing into the microcontroller.This routine has to happend every 20ms.
Each time the routine is executed, it programs PD0,PD1,PD2,PD3 of servo number ‘N’ then it programs the ’servo select’ port (6bits) , with the number ‘N’ , then sends a pulse of 0.5ms duration enabling the servo selection decoding (a ’decode_and_load_enable’ bit).
then the routine skips to the next servo in the list and repeat the cycle from the start : programming PD0,PD1,PD2,PD3, for the next servo ,  and so on for the 32 servos.

As we’ve already seen before,  if we use 32 servos, the complete routine will take about 0.5ms x 32 = 16ms.
So we are free with an extra processor time of about 4ms before the 20ms deadline.
If for example, we use a PIC18F @ 32MHz , those 4ms mean a lot of instructions and time to do other stuff than just driving the servos : our microcontroller has now time to do interesting stuff like converting probe datas , doing neural computations and so on , as a 4ms time @32 MHz means 32000 instructions.

Stay tuned !



cat{ } { post_69 } { } 2009-2015 EIhIS Powered by WordPress