You are on page 1of 6

8/9/2016

www.aeslab.com/class_notes/DeviceDrivers.txt

LinuxDeviceDriverDevelopment

Day1:

LinuxKernelModuleProgramming

CharDriverDevelopment

ImplementationofLEDCharDriveronWEGA
Day2:

LinuxInterruptHandling&Programming

ImpleentationofSwitchInterruptonWEGA

Interrupts(BottomHalfsMechanisms)

SoftIRQs,WorkQueues,Tasklets

KernelSyncronizationMechanisms

(AtomicOperations,SpinLocks,Mutex)

IntrotoBlock,USB,NetworkDrivers

FirstKernelModule
geditmod1.c&
#include<linux/kernel.h>
#include<linux/module.h>
voidprint_greetings(void)
{

printk(KERN_ALERT"WelcometoKernelProgramming\n");
}
EXPORT_SYMBOL(print_greetings);
intinit_module(void)
{

printk(KERN_ALERT"HelloWorldsimplemoduleisloaded\n");

print_greetings();

return0;
}
voidcleanup_module(void)
{

printk(KERN_ALERT"simplemoduleisunloaded\n");
}
MODULE_LICENSE("GPL");

geditMakefile&
KERN_SRC=/lib/modules/`unamer`/build
objm+=mod1.o
objm+=mod2.o
all:

makeC${KERN_SRC}M=${PWD}modules

clean:

rmfmod1.komod1.o

http://www.aeslab.com/class_notes/Device%20Drivers.txt

1/6

8/9/2016

www.aeslab.com/class_notes/DeviceDrivers.txt

ls/lib/module/`unamer`/build
sudoaptgetinstalllinuxheaders$(unamer)kernelsource$(unamer)

lsmod
cat/proc/modules
sudoinsmodmod1.ko
lsmod
dmesg|tail
sudormmodmod1
lsmod
dmesg|tail
externvoidprint_greetings(void);

KernelModulesParameters:

sudoinsmodmod1.koblock_size=512block_name="RootFS"

#include<linux/moduleparam.h>

#include<linux/stat.h>

staticintblock_size=0;
staticchar*block_name="None";

module_param(block_size,int,S_IRUGO);
module_param(block_name,charp,S_IRUGO);

#defineBUFF_SZ80

#defineGPIO_P3_9
105

unsignedintmaj_num=0;

charlbuff[BUFF_SZ];

intmy_led_open(structinode*in,structfile*fs)
{

led_init(GPIO_P3_9);

printk(KERN_ALERT"Thisismydeviceopenfunc\n");

return0;
}

inmy_led_write(structfile*fp,char*ubuff,intsz,loff_toffset)
{

copy_from_user(lbuff,ubuff,sz);

printk(...

if(lbuff[0]=='O'&&lbuff[1]=='N')

led_on(GPIO_P3_9);
else
if(lbuff[0]=='O'&&lbuff[1]=='F'&&lbuff[2]=='F')

led_off(GPIO_P3_9);
else

printk(KERN_ALERT"InvalidLEDstatevalue\n");

http://www.aeslab.com/class_notes/Device%20Drivers.txt

2/6

8/9/2016

www.aeslab.com/class_notes/DeviceDrivers.txt

.....

.....

structfile_operationsmy_led_fops={

.owner=THIS_MODULE,

.open=my_led_open,

.release=my_led_close,

.read =my_led_read,

.write=my_led_write};

initfunc

cleanupfunc

unregister_chrdev(maj_num,"MY_LED_DRV");

maj_num=register_chrdev(0,"MY_LED_DRV",&my_led_fops);
printk(KERN_ALERT"ChrDevregisteredwithMajNum%d\n",maj_num);

my_led.c>my_led.ko>insmodmy_led.ko>
cat/proc/devices>245MY_LED_DRV>sudomknod/dev/my_ledc2450
blinky.c

#defineLED_ON 105

#defineLED_OFF106

main()
{

intfd;

intloop=20;

fd=open("/dev/my_led",0666);

while(loop)
{

ioctl(fd,LED_ON,0);

sleep(2)

ioctl(fd,LED_OFF,0);

sleep(2);
}
close(fd);

//ioctl(fd,LED_CNTL,1);write(fd,"ON",3);
//ioctl(fd,LED_CNTL,0);write(fd,"OFF",4);

1.fd=open("/dev/my_led",0666);user_space

VFS

>open_250()

>my_led_fops>open()

>my_led_open()

http://www.aeslab.com/class_notes/Device%20Drivers.txt

maj_numdev_namefops*
12
abc
fo1

250
my_led_dev
my_led_fops
3/6

8/9/2016

www.aeslab.com/class_notes/DeviceDrivers.txt

register_chrdev(.....)

intled_init(intgpio_num)
{

intretVal=0;

retVal=
gpio_request(gpio_num,"sled");
if(retVal<0)returnretVal;

retVal=gpio_direction_output(gpio_num,1);
returnretVal;

voidled_on(intgpio_num)
{

gpio_set_value(gpio_num,1);
}
voidled_off(intgpio_num)
{

gpio_set_value(gpio_num,0);
}
voidled_deinit(intgpio_num)
{

gpio_free(gpio_num);
}

ioctl:
longmy_led_ioctl(structfile*fs,unsignedintcmd,unsignedlongargp)
{

printk()

//printthecmd

switch(cmd)

{
caseLED_ON:

//Processthecmd

caseLED_OFF:

default:

printk(KERN_ALERT"InvalidIOCTLCmd...\n");

#defineLED_IOCTL_SETVAL_IOR('r',1,structdirent[2])
#defineIOCTL_SET_GPIO_IOWR(IOC_MAGIC,2,int)
http://www.aeslab.com/class_notes/Device%20Drivers.txt

4/6

8/9/2016

www.aeslab.com/class_notes/DeviceDrivers.txt

Interrupts:

kernel/irq/manage.c
structirq_chip
arch/arm/machomap2/irq.c
arch/arm/platomap/include/plat/irqs.h

#include<linux/interrupt.h>
#include<linux/irq.h>
#include<asm/irq.h>

1.

//request_irq(irq_num,handler_func,flags,name,dev_id);

request_gpio(gpio_num);
gpio_direction_input(gpio_num);
request_irq(gpio_to_irq(gpio_num),my_switch_handler,0,"WEGA_SW1",0);

2.

free_irq(gpio_to_irq(gpio_num),0);

3.irqreturn_tmy_switch_handler(intirq_num,void*devid)

led_toggle();
printk(KERN_ALERT"Interruptoccured%d\n",irq_num);

returnIRQ_HANDLED;

voidled_toggle(void)
{

staticintled_status=0;

if(led_status=(!led_status))

led_on();
else

led_off();

BottolHalfs:(softirq,workqueue,tasklets)

WorkQueues:
vidrivers/input/keyboard/lm8323.c

staticstructwork_structled_workq;

1.

InInit_func:
INIT_WORK(&led_workq,led_toggle_work_handle);

2.

InIRQ_Handler:
schedule_work(&led_workq);

3.

voidled_toggle_work_handle(structwork_struct*work)

http://www.aeslab.com/class_notes/Device%20Drivers.txt

5/6

8/9/2016

www.aeslab.com/class_notes/DeviceDrivers.txt

TASKLETS:

drivers/input/keyboard/omapkeypad.c
1.

//DECLARE_TASKLET(tasklet_name,tasklet_function,tasklet_data);
DECLARE_TASKLET(tasklet_led,tasklet_led_toggle_function,0);

2.

tasklet_schedule(&tasklet_led);

3.

voidmy_tasklet_function(unsignedlongdata)
{

KernelSync:

AtomicOperations

Mutex/Semaphores

DEFINE_MUTEX(mutex_name);

mutex_lock(&mutex_name);

mutex_unlock(&mutex_name);

SpinLock

spinlock_tmy_spinlock;

spin_lock(&my_spinlock);

spin_unlock(&my_spinlock);

Block/MTD/NetworkDrivers:

Contact:

Support:
H/W
:

vasu@easyarm.com(9535504414)
info@easyarm.com
support@phytec.in

http://www.aeslab.com/class_notes/Device%20Drivers.txt

6/6

You might also like