1 1 nov. 24, 2015 kyu ho park lecture 11 time handling,gpio and i/o systems

59
1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Upload: arron-clarke

Post on 29-Jan-2016

213 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

11

Nov. 24, 2015Kyu Ho Park

Lecture 11 Time Handling,GPIO and I/O Systems

Page 2: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Time Management Representing time in UNIX and LINUX: It is represented in seconds

before or after the epoch January 1,1970 UTC(Universal Coordinated Time).

UTC is sometimes improperly referred to as UCT. System call time():

#include <time.h>time_t time(time_t *t);/*time() returns the number in seconds since the epoch. It fills in t with the number of seconds since the epoch. */

struct tmstruct tm{

int tm_sec;int tm_min;int tm_hour;int tm_mday; /*day of month*/int tm_mon;…

}

2

Page 3: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

gettimeofday( )#include <sys/time.h>#include <unistd.h>int gettimeofday(struct timeval *tv, struct timezone *tz);

struct timeval{int tv_sec; /* seconds*/int tv_usec;/*microseconds*/

};struct timezone{

int tz_minuteswest;/*minutes west of Greenwich*/int tz_dsttime; /type of dst(daylight saving time)

correction*/}

3

Page 4: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

stime()#include <time.h>int stime( const time_t *tp);/* tp; UTC time to set return value: 0 normal, -1 error*/

4

Page 5: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

sleepingunsigned int sleep(unsigned int sec);

void usleep(unsigned long usec);

int nanosleep(struct timespec *req, struct timespec *rem);/* it causes the current process to sleep the amount of time specified in req, unless a signal is received by the process.if nanosleep()terminates due to a received signal,and if rem is not NULL, set rem to represent the amount of time remaining in the sleep peroid. */struct timespec{

long int tv_sec;long int tv_nsec;

}

5

Page 6: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

interval timer Interval timer delivers signals to a process on a regular period.#intclude <sys/time.h>int setitimer(int which, const struct itimerval *value, struct itimerval

*oldvalue);, where

which: one of {ITIMER_REAL, ITIMER_VIRTUAL,ITIMER_PROF},value: value for time interval.

struct itimerval {struct timeval it_interval; /* next value*/struct timeval it_value; /* current value */

};struct timeval {

long tv_sec; /* seconds*/long tv_usec; /* microseconds */

};

6

Page 7: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Three timers ITIMER_REAL:

It tracks time in terms of the clock on the wall, that is, real time and delivers a SIGALRM signal when the given time interval elapses.

ITIMER_VIRTUAL:It counts time only when the process is executing at user mode, excluding any system calls the process makes and delivers a SIGVTALRM.

ITIMER_PROF:It counts execution time of the process including at user mode and kernel mode.

7

Page 8: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

example/* itimer.c */#include <stdio.h>#include <stdlib.h>#include <sys/wait.h>#include <unistd.h>#include <string.h>#include <signal.h> #include <sys/time.h>void catch_signal (int ignored) {

static int iteration=0;printf(“caught interval timer signal, iteration %d \

n”,iteration++);

}pid_t start_timer (int interval) {

pid_t child:struct itimerval it;struct sigaction sa;if (!(child = fork())) {

memset (&sa, 0, sizeof (sa));sa.sa_handler = catch_signal;sigemptyset(&sa.sa_mask);sa.sa_flags = SA_RESTART;sigaction(SIGALRM, &sa, NULL);memset(&it, 0, sizeof(it));it.it_interval.tv_sec = interval;it.it_value.tv_sec = interval;setitimet(ITIMER_REAL, &it,

NULL);while (1) pause();

}return child;

}

8

void stop_timer (pid_t child) {kill (child, SIGTERM);

}int main (int argc, const char **argv) {

pid_t timer = 0;printf(“Demonstrating itimers for 10

seconds, ”“please wait... \ n”);

timer = start_timer(1);sleep(10);stop_timer(timer);printf(“Done. \ n”);return 0;

}

Page 9: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

HZ

9

The Tick Rate: HZThe frequency of the system timer (the tick rate) is programmed on system boot based on a static preprocessor define, HZ. The value of HZ differs for each supported architecture. In fact, on some supported architectures, it even differs between machine types.The kernel defines the value in <asm/param.h>. The tick rate has a frequency of HZ hertz and a period of 1/HZ seconds. For example, in include/asm-i386/param.h, the i386 architecture defines:

#define HZ 1000 /* internal kernel time frequency */

HZ : Number of timer interrupt per second, if HZ=1000 , every 1ms the timer interrupt occurs.

tick : 1/HZ

Page 10: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Frequency of the Timer Interrupt

10

Page 11: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

jiffies Global variable jiffies defined at

<linux/jiffies.h> jiffies_64 : Every time a timer interrupt

occurs, the internal kernel counter is incremented. The counter is a 64-bit variable and is called jiffies_64. At system boot, it is initialized to 0.

1 jiffy is 1 tick(=1/HZ sec) in case of 32_bit jiffies, it will be overflowed

after 49.7 days when HZ=1000. in case of jiffies_64, no overflow during the

whole life of a user.

11

Page 12: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Kernel Timer kernel timer structure: struct timer_list

#include <linux/timer.h>struct timer_list{

struct list_head entry;unsigned long expires; /* time of expiration in jiffy */spinlock_t lock;void (*function)(unsigned long); /* timer handler */unsigned long data; /* passed as the argument to

function function is called*/struct tvec_t_base_s *base; /*for internal use */

}

12

Page 13: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

init_timer(), add_timer(), and del_timer()

init_timer() :Initialize the kernel timer struct.

add_timer():Add the kernel timer to the kernel( timer_list at THE KERNEL).

del_kernel:Remove the added kernel timer from the timer_list at the kernel.The return value is 1 if successful, 0 otherwise.

13

Page 14: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Example of Kernel Timerchar m_data[128];struct timer_list kerneltimer;void init_timer(struct timer_list *kerneltimer);void kerneltimer_handler(unsigned long arg){…}led_timer_init( …){

..init_timer(&kerneltimer);timer_expires = get_jiffies_64() + (5*HZ/10);/* 0.5 sec later, the timer expires

*/timer.data = (unsigned long) &m_data[0];timer.function=kerneltimer_handler;add_timer(&kerneltimer);

}led_timer_exit(void){

….del_timer(&kerneltimer);

}

14

Page 15: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

GPIO

15

Reference: Linux/Documenttion/gpio.txt

Page 16: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

GPIO Characteristics GPIO: General Purpose Input/Output. Characteristics

Output values are writable( high=1, low=0). Input values are readable(1,0). Inputs can open be used as IRQ signals. A GPIO can be configured as either input or

output. Most GPIOs can be accesses while holding

spinlocks.

16

Page 17: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

GPIO functions#include <linux/gpio.h>int gpio_is_valid(int number);/* to test whether the gpio number is valid */To set the direction as input or output,int gpio_direction_input(unsigned gpio);int gpio_direction_output(unsigned gpio, int value);

To get or set a value,int gpio_get_value(unsigned gpio);void gpio_set_value(unsigned gpio, int value);

17

Page 18: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

GPIO functions#include <linux/gpio.h>int gpio_request(unsigned gpio, const char *label);/*request gpio, returning 0 or negative errno. non-null labels ,which is a string that can later appear in sysfs, may be useful for diagnosis. */

void gpio_free(unsigned gpio);/* release previously claimed gpio */

18

Page 19: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

GPIO functions#include <linux/gpio.h>int gpio_to_irq(unsigned gpio);/* map gpio numbers to IRQ numbers */

19

Page 20: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Interrupt in Beagleboard(BB)

20

Page 21: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Interrupt Procedure at BB

21

Page 22: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

BB

22

Page 23: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

LED(USER0 and USER1)

23

Page 24: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Button

24

Page 25: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

registering and freeing the interrupt handler

int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev);

void free_irq(unsigned int, void *);

25

Page 26: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

button_isr

int led_state=0;static irqreturn_t button_isr(int irq, void *dev_id, struct pt_regs *regs){

gpio_set_value(149 /* gpio # */, led_state /* 0 or 1 */); gpio_set_value(150 /* gpio # */, (led_state = (led_state>0)?0:1)

/* 0 or 1 */);

return IRQ_HANDLED;}

26

Page 27: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

How to get button_irqstatic struct gpio led_gpios[] = { {149, GPIOF_OUT_INIT_LOW, "USER LED 0" }, {150, GPIOF_OUT_INIT_LOW, "USER LED 1" },}; static int button_gpio= 4; /* USER BUTTON */static unsigned int button_irq;…..static void led_button_init () {….. ret = gpio_request_one(button_gpio, GPIOF_IN, "LED status change button"); if(ret < 0) { printk(KERN_ERR "failed to request GPIO %d, error %d\n", button_gpio, ret); goto error; } ret = gpio_direction_input(button_gpio); if(ret < 0) { target_gpio = button_gpio; goto error_conf; } // change button input to IRQ button_irq = gpio_to_irq(button_gpio); ……

}

27

Page 28: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

led_button_exit( ) modulestatic void led_button_exit(){gpio_free(button_gpio); gpio_free_array(led_gpios, ARRAY_SIZE(led_gpios));  free_irq(button_irq, NULL);  printk(KERN_ERR "Clearing ISR test setting completed.\n");}

28

Page 29: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

29

Input/Output [Tanenbaum]

1 Principles of I/O hardware2 Principles of I/O software3 I/O software layers4 Clocks

Page 30: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

View of the Kernel

Page 31: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

I/O Devices Two categories:

Block devices and Character devices Block devices: that store information in

fixed-size blocks, each one with its own address.

Character devices: A character device delivers or accepts a stream of a characters without regard to any block structure. It is not addressable and does not have any seek operation.

31

Page 32: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

I/O Devices Some devices just do not fit in. Clocks:

Not block addressable Nor do they generate or accept

character streams All they do is cause interrupts at well-

defined intervals Memory-mapped screens:

32

Page 33: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

33

Device Controllers I/O devices have components:

mechanical component electronic component

The electronic component is the device controller may be able to handle multiple devices

Controller's tasks convert serial bit stream to block of

bytes perform error correction as necessary make available to main memory

Page 34: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

34

Memory-Mapped I/O (1)

Separate I/O and memory space Memory-mapped I/O Hybrid

Page 35: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

35

Memory-Mapped I/O (2)

(a) A single-bus architecture(b) A dual-bus memory architecture

Page 36: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

36

Direct Memory Access (DMA)

Operation of a DMA transfer

Page 37: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

37

Interrupts Revisited

How interrupts happens. Connections between devices and interrupt controller actually use interrupt lines on the bus rather than dedicated wires

Page 38: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

38

Principles of I/O SoftwareGoals of I/O Software (1)

Device independence programs can access any I/O device without specifying device in advance

· (floppy, hard drive, or CD-ROM)

Uniform naming name of a file or device a string or an

integer not depending on which machine

Error handling handle as close to the hardware as

possible

Page 39: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

39

Goals of I/O Software (2)

Synchronous vs. asynchronous transfers blocked transfers vs. interrupt-driven

Buffering data coming off a device cannot be

stored in final destination Sharable vs. dedicated devices

disks are sharable tape drives would not be

Page 40: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

40

Programmed I/O (1)

Steps in printing a string

Page 41: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

41

Programmed I/O (2)

Writing a string to the printer using programmed I/O

Page 42: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Read( )

Page 43: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

43

I/O Software Layers

Layers of the I/O Software System

Page 44: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

44

Device Drivers

Logical position of device drivers is shown here Communications between drivers and device

controllers goes over the bus

Page 45: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

45

Device-Independent I/O Software (1)

Functions of the device-independent I/O software

Uniform interfacing for device drivers

Buffering

Error reporting

Allocating and releasing dedicate devices

Providing a deice-independent block size

Page 46: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

46

Device-Independent I/O Software (2)

(a) Without a standard driver interface(b) With a standard driver interface

Page 47: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

47

Device-Independent I/O Software (3)

(a) Unbuffered input(b) Buffering in user space(c) Buffering in the kernel followed by copying to user

space(d) Double buffering in the kernel

Page 48: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

48

Device-Independent I/O Software (4)

Networking may involve many copies

Page 49: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

49

User-Space I/O Software

Layers of the I/O system and the main functions of each layer

Page 50: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Linux Device files

Device file Device access path is provided by the device node. Major Number: device type, Minor Number: the device instance Major number :

0 ~ 255 Include/linux/major.h

# mknod /dev/DUMMY_DEVICE c 254 0

Page 51: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Device Driver

open(····)

read(····)

write(····)

ioctl(····)

close(····)

Application S/W

insmod

rmmod

xxx_init(····){ :}

xxx_interrupt(····){ :}

struct file_operations

xxx_fop = { open : xxx_open, read : xxx_read, write : xxx_write, ioctl : xxx_ioctl, release : xxx_release} ;

xxx_open(····){ :}

xxx_read(····){ :}xxx_write(····){ :}xxx_ioctl(····){ :}

{ :}

xxx_release(····)

xxx_exit(····){ :}

H/W interrupt

Page 52: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

module

#include <linux/init.h>#include <linux/module.h>MODULE_LICENSE(“BSP?GPL);static int hello_init(void){ printk(KERN_ALERT “Hello,world\n”);

return 0;}

Static void hello_exit(void){ printk(KERN_ALERT “Goodbye, world\n”);}module_init(hello_init);module_exit(hello_exit);

Page 53: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Loadable Module The Linux Device Driver is a loadable

kernel module which is loaded when necessary and unloaded later.

# insmod ./hello.ko # rmmod hello

Linux Device Driver

Page 54: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Computer Engineering Research Lab, EECS, KAIST

Making a Linux Device file Linux File Type

Regular file Directory Special file

Character device file Block device file

FIFO Socket Symbolic link

Making a special file Use mknod shell command Major number / minor number p : FIFO, b : block special file, c : character special file

# mknod /dev/DUMMY_DEVICE c 254 0

# mknod /dev/DUMMY_DEVICE c 254 0

Page 55: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Computer Engineering Research Lab, EECS, KAIST

Device driver Interface System Call

To enter system kernel File operations : read, write, ioctl Process operations : fork, exec, signal

Page 56: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Computer Engineering Research Lab, EECS, KAIST

Device Driver Device structure

Device data structure Name File_operation structure

/* fs/device.c */struct device_struct { const char * name; struct file_operations * fops;}

/* include/linux/fs.h */struct file_operations { .lseek =dummy_lseek, .read = dummy_read, .write =dummy_write, .readdir = .poll = .ioctl = .mmap = .open =dummy_open, .flush = .release =dummy_close, .fsync = .fasync = …}

/* fs/device.c */struct device_struct { const char * name; struct file_operations * fops;}

/* include/linux/fs.h */struct file_operations { .lseek =dummy_lseek, .read = dummy_read, .write =dummy_write, .readdir = .poll = .ioctl = .mmap = .open =dummy_open, .flush = .release =dummy_close, .fsync = .fasync = …}

Page 57: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Computer Engineering Research Lab, EECS, KAIST

Device Driver Registration of device driver

To get the device number (Major, Minor) register_chrdev_region() Registration of device name and file_operation structure cdev_add()

Deletion

dev_t dev = MKDEV(DUMMY_MAJOR_NUMBER, 0); register_chrdev_region(dev_t dev, unsigned int count , char *name);

cdev_init(struct cdev *cdev, struct file_operations *fops); cdev_add(strcut cdev *cdev, dev_t num, unsigned int count);

dev_t dev = MKDEV(DUMMY_MAJOR_NUMBER, 0); register_chrdev_region(dev_t dev, unsigned int count , char *name);

cdev_init(struct cdev *cdev, struct file_operations *fops); cdev_add(strcut cdev *cdev, dev_t num, unsigned int count);

cdev_del(&my_cdev); unregister_chrdev_region(MKDEV(DUMMY_MAJOR_NUMBER,0),128);

cdev_del(&my_cdev); unregister_chrdev_region(MKDEV(DUMMY_MAJOR_NUMBER,0),128);

Page 58: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Computer Engineering Research Lab, EECS, KAIST

Device Driver Dummy_device code ( a sample)

#define DUMMY_MAJOR_NUMBER 254 int dummy_open(struct inode *, struct file *); int dummy_release(struct inode *, struct file *); ssize_t dummy_read(struct file *, char *, size_t, loff_t *); ssize_t dummy_write(struct file *, char *, size_t, loff_t *); /* file operation structure */ static struct file_operations dummy_fops = {         .open =         dummy_open,         .read =         dummy_read,         .write =        dummy_write,         .release =      dummy_release, }; char devicename[20]; static struct cdev my_cdev;

#define DUMMY_MAJOR_NUMBER 254 int dummy_open(struct inode *, struct file *); int dummy_release(struct inode *, struct file *); ssize_t dummy_read(struct file *, char *, size_t, loff_t *); ssize_t dummy_write(struct file *, char *, size_t, loff_t *); /* file operation structure */ static struct file_operations dummy_fops = {         .open =         dummy_open,         .read =         dummy_read,         .write =        dummy_write,         .release =      dummy_release, }; char devicename[20]; static struct cdev my_cdev;

/* init module - register module */ static int __init dummy_init(void) {         dev_t dev = MKDEV(DUMMY_MAJOR_NUMBER, 0);         printk("init module\n");         strcpy(devicename, "Dummy_Driver");         register_chrdev_region(dev, 128, devicename);         cdev_init(&my_cdev, &dummy_fops);         cdev_add(&my_cdev, dev, 128);         return 0; }/* cleanup module - unregister module */ static void __exit dummy_exit(void) {         printk("Clean Up Module\n");         cdev_del(&my_cdev);         unregister_chrdev_region(MKDEV(DUMMY_MAJOR_NUMBER,0),128); } …module_init(dummy_init); module_exit(dummy_exit);

/* init module - register module */ static int __init dummy_init(void) {         dev_t dev = MKDEV(DUMMY_MAJOR_NUMBER, 0);         printk("init module\n");         strcpy(devicename, "Dummy_Driver");         register_chrdev_region(dev, 128, devicename);         cdev_init(&my_cdev, &dummy_fops);         cdev_add(&my_cdev, dev, 128);         return 0; }/* cleanup module - unregister module */ static void __exit dummy_exit(void) {         printk("Clean Up Module\n");         cdev_del(&my_cdev);         unregister_chrdev_region(MKDEV(DUMMY_MAJOR_NUMBER,0),128); } …module_init(dummy_init); module_exit(dummy_exit);

Page 59: 1 1 Nov. 24, 2015 Kyu Ho Park Lecture 11 Time Handling,GPIO and I/O Systems

Computer Engineering Research Lab, EECS, KAIST

Application Program

        fd = open("/dev/DUMMY_DEVICE", O_RDWR);         if ( fd <= 0 ) {                 printf("Devic File Open Fail!\n");                 exit(0);         }

        buf[0] = 0x12;         write(fd,buf,1);         read(fd,buf,1);         printf("%x\n",buf[0]);         close(fd);         return 0;

        fd = open("/dev/DUMMY_DEVICE", O_RDWR);         if ( fd <= 0 ) {                 printf("Devic File Open Fail!\n");                 exit(0);         }

        buf[0] = 0x12;         write(fd,buf,1);         read(fd,buf,1);         printf("%x\n",buf[0]);         close(fd);         return 0;