RT_FIFO, Device driver.

Slides:



Advertisements
Similar presentations
Introduction to Sockets Jan Why do we need sockets? Provides an abstraction for interprocess communication.
Advertisements

Memory Management in Linux Anand Sivasubramaniam.
DEVICE DRIVER VINOD KAMATH CS691X PROJECT WORK. Introduction How to write/install device drivers Systems, Kernel Programming Character, Block and Network.
Linux device-driver issues
Linux Device Drivers & Project3 preview CSC345. Project 3 Preview Write a device driver for a pseudo stack device Idea from
B LOCK D RIVERS Ted Baker Andy Wang CIS 4930 / COP 5641.
Lecture 101 Lecture 10: Kernel Modules and Device Drivers ECE 412: Microcomputer Laboratory.
Device Drivers. Linux Device Drivers Linux supports three types of hardware device: character, block and network –character devices: R/W without buffering.
Device Drivers cs423, Fall 2007 Klara Nahrstedt/Sam King 6/6/20141.
Sogang University Advanced Operating Systems (Linux Device Drivers) Advanced Operating Systems (Linux Device Drivers) Sang Gue Oh, Ph.D.
Lecture for Lab 3, Exp1 of EE505 (Developing Device Driver) T.A. Chulmin Kim CoreLab. Mar, 11, 2011 [XenSchedulerPaper_Hotcloud-commits] r21 - /
Computer System Laboratory
Inter-Process Communication: Message Passing Tore Larsen Slides by T. Plagemann, Pål Halvorsen, Kai Li, and Andrew S. Tanenbaum.
2006/1/201IGEL Co.,Ltd. / Renesas Solution Corp. Studies on User Level Device Driver in Embedded Environment ( Progress Report ) Katsuya Matsubara IGEL.
USERSPACE I/O Reporter: R 張凱富.
The OS kernel: Implementing processes and Threads Kernel Definitions and Objects Queue Structures Threads Implementing Processes and Threads Implementing.
File and I/O system calls int open(const char* path, int flags, mode_t modes) int creat(const char *path, mode_t mode) ssize_t read(int fd, void *buf,
Module R2 Overview. Process queues As processes enter the system and transition from state to state, they are stored queues. There may be many different.
CSC 660: Advanced Operating SystemsSlide #1 CSC 660: Advanced OS Memory Management.
Using VMX within Linux We explore the feasibility of executing ROM-BIOS code within the Linux x86_64 kernel.
I/O Multiplexing The role of the ‘poll()’ method in Linux device-driver operations.
Embedded Systems Programming Writing Device Drivers.
63 UQC152H3 Advanced OS Writing a Device Driver. 64 The SCULL Device Driver Simple Character Utility for Loading Localities 6 devices types –Scull-03.
Chapter 3 Buffer Cache TOPICS UNIX system Architecture Buffer Cache
Device Drivers In Linux © Gregory Kesden Fall 2000.
Data Structures in the Kernel Sarah Diesburg COP 5641.
M. Muztaba Fuad Advanced Operating System Project Device Drivers.
Loadable Kernel Modules Dzintars Lepešs The University of Latvia.
Kernel module programming Nezer J. Zaidenberg. reference This guide is built on top of The Linux Kernel Module Programming Guide The guide is available.
Operating System Program 5 I/O System DMA Device Driver.
OPERATING SYSTEM OVERVIEW. Contents Basic hardware elements.
Real-time Systems Lab, Computer Science and Engineering, ASU Linux Input Systems (ESP – Fall 2014) Computer Science & Engineering Department Arizona State.
1-1 Embedded Network Interface (ENI) API Concepts Shared RAM vs. FIFO modes ENI API’s.
Sogang University Advanced Operating Systems (Linux Module Programming) Sang Gue Oh, Ph.D.
An Effective Method to Control Interrupt Handler for Data Race Detection Makoto Higashi †, Tetsuo Yamamoto ‡, Yasuhiro Hayase †, Takashi Ishio † and Katsuro.
Kernel Modules. Kernel Module Pieces of code that can be loaded and unloaded into the kernel upon demand. Compiled as an independent program With appropriate.
Sogang University Advanced Operating Systems (Enhanced Device Driver Operations) Advanced Operating Systems (Enhanced Device Driver Operations) Sang Gue.
Linux for Real Time applications in accelerator control systems Linux for control systems Andreas Steinbacher
K ERNEL D EVELOPMENT CSC585 Class Project Dawn Nelson December 2009.
Thread Implementations; MUTEX Reference on thread implementation –text: Tanenbaum ch. 2.2 Reference on mutual exclusion (MUTEX) –text: Tanenbaum ch
LOGO System Call. Introduction System call is the mechanism used by an application program to request service from the OS. Users use it to communicate.
Linux Device Driver 2009/04/08. Reference Book Another Reference Book Embedded Linux Primer: A Practical, Real-World Approach By Christopher Hallinan.
Interfacing Device Drivers with the Kernel
B LOCK L AYER S UBSYSTEM Linux Kernel Programming CIS 4930/COP 5641.
Lab 12 Department of Computer Science and Information Engineering National Taiwan University Lab12 – Driver 2014/12/16 1 /21.
COMP 3438 – Part I - Lecture 5 Character Device Drivers
ICOM Noack Linux I/O structure Device special files Device switch tables and fops How the kernel finds a device Parts of a device driver or module.
1 The File System. 2 Linux File System Linux supports 15 file systems –ext, ext2, xia, minix, umsdos, msdos, vfat, proc, smb, ncp, iso9660, sysv, hpfs,
MINIX Presented by: Clinton Morse, Joseph Paetz, Theresa Sullivan, and Angela Volk.
Finish up OS topics Group plans. Today Finish up and review Linux device driver stuff – Walk example again – See how it all goes together – Discuss talking.
Lecture 3 Module Programming and Device Driver (Homework#1 included) Kyu Ho Park Sept. 15, 2015.
File table: a list of opened files Each entry contains: – Index: file descriptors – Pointer to the file in memory – Access mode File descriptor is a positive.
1 COMP 3500 Introduction to Operating Systems Project 4 – Processes and System Calls Part 4: Managing File System State Dr. Xiao Qin Auburn University.
A simple control application with Real Time Linux Peter Wurmsdobler Real Time Systems Lab Jong-Koo, Lim Paper Survey.
File System Design David E. Culler CS162 – Operating Systems and Systems Programming Lecture 23 October 22, 2014 Reading: A&D a HW 4 out Proj 2 out.
Device Driver_Skeleton
Introduction to Developing Embedded Linux Device Drivers
Chapter 3 Buffer Cache TOPICS UNIX system Architecture Buffer Cache
Linux Kernel Development - Robert Love
Final Project: ThreadOS File System
CSNB334 Advanced Operating Systems 4
Linux Kernel Driver.
CSCI 315 Operating Systems Design
Introduction to Linux Device Drivers
Making Virtual Memory Real: The Linux-x86-64 way
Practical Session 11 File Systems & Midterm 2013
I/O Systems I/O Hardware Application I/O Interface
Computer System Laboratory
Loadable Kernel Modules
Mr. M. D. Jamadar Assistant Professor
Presentation transcript:

RT_FIFO, Device driver

Outline Introduction of RT_FIFOs Device driver RT_FIFO Example

Intro. of RT_FIFOs(1) The RT_FIFO is a mechanism, implemented as a character device, to communicate between realtime tasks and ordinary Linux processes. RT FIFO User Process RT Process RT FIFO

Intro. of RT_FIFOs(2) In the real-time task interface, read/write must be atomic and non-blocking. In Linux user processes, see RT_FIFOs as ordinary character devices

Requirements of a device driver Compile gcc –DMODULE –D__KERNEL__ -o dst src Code Setup file_opreation structure Register_chrdev / register_blkdev / misc_register in init_module

Linux file_ops structure struct file_operations { int (*seek) (struct inode *, struct file *, off_t, int); int (*read) (struct inode *, struct file *, char, int); int (*write) (struct inode *, struct file *, off_t, int); int (*readdir) (struct inode *, struct file *, struct dirent *, int); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); int (*select) (struct inode *, struct file *, int , select_table *); int (*mmap) (struct inode *, struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*release) (struct inode *, struct file *); int (*fsync) (struct inode *, struct file *); int (*fasync) (struct inode *, struct file *, int); int (*check_media_change) (struct inode *, struct file *); int (*revalidate) (dev_t dev); }

register_chrdev int register_chrdev(unsigned int major, const char * name, struct file_operations *fops){ if (major == 0) { write_lock(&chrdevs_lock); for (major = MAX_CHRDEV-1; major > 0; major--) { if (chrdevs[major].fops == NULL) { chrdevs[major].name = name; chrdevs[major].fops = fops; write_unlock(&chrdevs_lock); return major; } return -EBUSY; if (major >= MAX_CHRDEV) return -EINVAL; ………………………………………………… return 0;

Init_module int init_module(void){ if (register_chrdev (MAJOR, “name”, &fops)){ printk (“%s: unable to get major %d\n", name, MAJOR); return -EIO; } return 0; void cleanup_module(void){ unregister_chrdev(MAJOR, “name");

RT_FIFO Install RT_FIFO module FIFO structure & file_ops Real-time part Non-real-time part

RT_FIFO init_module Flow register_chrdev == 0 yes no get_soft_irq Irq > 0 no yes rtl_register_chrdev == 0 yes no return 0 unregister_chrdev

RT_FIFO init_module int init_module(void){ int ret; ret = rtf_init(); if (ret < 0) return ret; #ifdef CONFIG_RTL_POSIX_IO if (rtl_register_chrdev (RTF_MAJOR, "rtf", &rtl_fifo_fops)) { printk ("RT-FIFO: unable to get RTLinux major %d\n", RTF_MAJOR); rtf_uninit(); return -EIO; } #endif return 0; void cleanup_module(void){ rtl_unregister_chrdev(RTF_MAJOR, "rtf"); Install non-real-time device driver Install real-time device driver

rtf_init(); int rtf_init (void){ int irq = -1, i; if (register_chrdev (RTF_MAJOR, "rtf", &rtf_fops)) { printk ("RT-FIFO: unable to get major %d\n", RTF_MAJOR); return -EIO; } irq = rtl_get_soft_irq (fifo_irq_handler, "RTLinux FIFO"); if (irq > 0) { rtl_fifo_irq = irq; } else { unregister_chrdev (RTF_MAJOR, "rtf"); printk ("Can't get an irq for rt fifos"); return 0;

RT_FIFO Install RT_FIFO module FIFO structure & file_ops Real-time part Non-real-time part

Struct rt_fifo_struct int allocated; int bidirectional; int user_open; struct task_struct *opener; char *base; int bufsize; int start; int len; spinlock_t fifo_spinlock; int (*user_handler) (unsigned int fifo); int (*rt_handler) (unsigned int fifo); int (*user_ioctl)(unsigned int fifo, unsigned int cmd, unsigned long arg); struct module *creator; struct wait_queue *wait; };

rtl_file_ops structure struct rtl_file_operations { loff_t (*llseek) (struct rtl_file *, loff_t, int); ssize_t (*read) (struct rtl_file *, char *, size_t, loff_t *); ssize_t (*write) (struct rtl_file *, const char *, size_t, loff_t *); int (*ioctl) (struct rtl_file *, unsigned int, unsigned long); int (*mmap) (struct rtl_file *, void *start, size_t length, int prot , int flags, off_t offset, caddr_t *result); int (*open) (struct rtl_file *); int (*release) (struct rtl_file *); };

Linux file_ops structure struct file_operations { int (*seek) (struct inode *, struct file *, off_t, int); int (*read) (struct inode *, struct file *, char, int); int (*write) (struct inode *, struct file *, off_t, int); int (*readdir) (struct inode *, struct file *, struct dirent *, int); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); int (*select) (struct inode *, struct file *, int , select_table *); int (*mmap) (struct inode *, struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*release) (struct inode *, struct file *); int (*fsync) (struct inode *, struct file *); int (*fasync) (struct inode *, struct file *, int); int (*check_media_change) (struct inode *, struct file *); int (*revalidate) (dev_t dev); }

RT_FIFO Install RT_FIFO module FIFO structure & file_ops Real-time part Non-real-time part

rtl_fifo_fops cont. static struct rtl_file_operations rtl_fifo_fops = { NULL, // llseek rtl_rtf_read, // read rtl_rtf_write, // write rtl_rtf_ioctl, // ioctl NULL, // mmap rtl_rtf_open, // open rtl_rtf_release // release };

rtl_rtf_open & rtl_rtf_release static int rtl_rtf_open (struct rtl_file *filp){ if (!(filp->f_flags & O_NONBLOCK)) { return -EACCES; } if( (filp->f_flags & O_CREAT) && !RTF_ALLOCATED(filp->f_minor)){ __rtf_create(filp->f_minor, RTF_DEFAULT_SIZE, &__this_module); if(!RTF_ALLOCATED(filp->f_minor)){ return -EUNATCH; return 0; better be calling from Linux and not RT mode unless there are preallocted fifos still static int rtl_rtf_release (struct rtl_file *filp){ int minor = filp->f_minor; char *old = RTF_BASE(minor); if (RTF_ALLOCATED(minor) && old && find_prealloc(old)) { rtf_destroy(minor); } return 0;

rtl_rtf_read  rtf_get int rtf_get(unsigned int minor, void *buf, int count){ int chars = 0, size = 0, read = 0; char *pipebuf; rtl_spin_lock_irqsave(&RTF_SPIN(minor), interrupt_state); while (count > 0 && (size = RTF_LEN(minor))) { ………read circular queue…… count -= chars; memcpy(buf, pipebuf, chars); buf += chars; } rtl_spin_unlock_irqrestore(&RTF_SPIN(minor), interrupt_state); if(*RTF_RT_HANDLER(minor)){ (*RTF_RT_HANDLER(minor))(minor); if (RTF_USER_OPEN(minor)) { fifo_wake_sleepers(minor); return read;

rtl_rtf_write  rtf_put int rtf_put(unsigned int minor, void *buf, int count){ int chars = 0, free = 0, written = 0; char *pipebuf; rtl_spin_lock_irqsave(&RTF_SPIN(minor), interrupt_state); if (RTF_FREE(minor) < count) { rtl_spin_unlock_irqrestore(&RTF_SPIN(minor), interrupt_state); return -ENOSPC; } while (count > 0 && (free = RTF_FREE(minor))) { ………write circular queue…… memcpy(pipebuf, buf, chars); buf += chars; if((*RTF_RT_HANDLER(minor))) (*RTF_RT_HANDLER(minor))(minor); if (RTF_USER_OPEN(minor)) fifo_wake_sleepers(minor - (RTF_BI(minor) < 0)); return written;

rtl_rtf_ioctl static int rtl_rtf_ioctl (struct rtl_file *filp, unsigned int req, unsigned long arg){ int minor = RTL_MINOR_FROM_FILEPTR(filp); if (!RTF_ALLOCATED(minor)) { return -EINVAL; } if (req == RTF_SETSIZE) { if (rtf_resize(minor, arg) < 0) { } else { return 0;

RT_FIFO Install RT_FIFO module FIFO structure & file_ops Real-time part Non-real-time part

rtf_fops cont. static struct file_operations rtf_fops = { llseek: rtf_llseek, read: rtf_read, write: rtf_write, poll: rtf_poll, ioctl: rtf_ioctl, open: rtf_open, release: rtf_release, };

rtf_open& rtf_release static int rtf_open(struct inode *inode, struct file *filp){ unsigned int minor = MINOR(inode->i_rdev); RTF_OPENER(minor) = current; RTF_USER_OPEN(minor)++; if (RTF_ADDR(minor)->creator) { __MOD_INC_USE_COUNT(RTF_ADDR(minor)->creator); } return 0; static int rtf_release(struct inode *inode, struct file *file){ unsigned int minor = MINOR(inode->i_rdev); RTF_USER_OPEN(minor)--; if (RTF_ADDR(minor)->creator) { __MOD_DEC_USE_COUNT(RTF_ADDR(minor)->creator); } return 0;

rtf_read Block until data available copy fifo content to user space static ssize_t rtf_read(struct file *filp, char *buf, size_t count, loff_t* ppos){ ………………………………….. minor = minor + RTF_BI(minor); if…………… while (RTF_EMPTY(minor) ) { if (signal_pending(current)) return -ERESTARTSYS; fifo_setup_sleep(minor); interruptible_sleep_on_timeout(&RTF_WAIT(minor), RTL_FIFO_TIMEOUT); } while (count > 0 && (size = RTF_LEN(minor))) { ……read from queue…… copy_to_user(buf, pipebuf, chars); rtl_spin_lock_irqsave(&RTF_SPIN(minor), interrupt_state); RTF_START(minor) += chars; RTF_START(minor) = RTF_WRAP(minor, RTF_START(minor)); RTF_LEN(minor) -= chars; rtl_spin_unlock_irqrestore(&RTF_SPIN(minor), interrupt_state); if (read) { if((*RTF_HANDLER(minor))){ ………………………… Block until data available copy fifo content to user space

rtf_write Block until able to write if……………… copy buffer to fifo static ssize_t rtf_write(struct file *filp, const char *buf, size_t count, loff_t* ppos) { …………………… while (count > 0) { while (RTF_FREE(minor) < free) { if…………………… fifo_setup_sleep(minor); interruptible_sleep_on_timeout(&RTF_WAIT(minor), RTL_FIFO_TIMEOUT); } while (count > 0 && (free = RTF_FREE(minor))) { ………..write to queue…… rtl_spin_lock_irqsave(&RTF_SPIN(minor), interrupt_state); pipebuf = RTF_BASE(minor) + RTF_END(minor); copy_from_user(pipebuf, buf, chars); RTF_LEN(minor) += chars; rtl_spin_unlock_irqrestore(&RTF_SPIN(minor), interrupt_state); free = 1; if……………… return result; return written; Block until able to write copy buffer to fifo

Example(rt_np) pthread_t thread; void * start_routine(void *arg){ struct sched_param p; int status; p . sched_priority = 1; pthread_setschedparam (pthread_self(), SCHED_FIFO, &p); pthread_make_periodic_np (pthread_self(), gethrtime(), 10000000); while (1){ sprintf(buf, “[%d]\n“),; status = rtf_put(0, buf, 1024); pthread_wait_np(); } return 0; int init_module(void) { rtf_create(0, 1024*1024); return pthread_create (&thread, NULL, start_routine, 0); void cleanup_module(void) { rtf_destroy(0); pthread_delete_np (thread);

Result (rt_np) [root@rtlinux rtlinux]# insmod fifo.o Run a user application [root@rtlinux root]# lsmod Module Size Used by Tainted: P fifo 2148 1 rtl_sched 30368 0 [fifo] rtl_fifo 10784 0 [fifo] rtl_posixio 8052 0 [rtl_fifo] rtl_time 7084 0 [fifo rtl_sched rtl_posixio] rtl 21200 0 [rtl_sched rtl_fifo rtl_posixio rtl_time] mbuff 8684 0 (unused)

Example(rt_posixio) int fd; pthread_t thread; void * start_routine(void *arg){ struct sched_param p; int status, i=0; p.sched_priority = 1; pthread_setschedparam (pthread_self(), SCHED_FIFO, &p); pthread_make_periodic_np (pthread_self(), gethrtime(), 10000000); while (1){ sprintf(buf, "[%d] fd = %d\n“, i++, fd); status = write(fd, buf, 1024); pthread_wait_np(); } return 0; int init_module(void) { fd = open("/dev/rtf10", O_NONBLOCK | O_CREAT ); if(fd) return -1; return pthread_create (&thread, NULL, start_routine, 0); void cleanup_module(void) { close(fd); pthread_delete_np (thread);

Result(rt_posixio) [root@rtlinux rtlinux]# insmod fifo_test.o Run a user application [root@rtlinux include]# lsmod Module Size Used by Tainted: P fifo_test 2564 0 (unused) fifo 2148 0 (unused) rtl_sched 30368 0 [fifo_test fifo] rtl_fifo 10784 2 [fifo] rtl_posixio 8052 0 [fifo_test rtl_fifo] rtl_time 7084 0 [fifo_test fifo rtl_sched rtl_posixio] rtl 21200 0 [rtl_sched rtl_fifo rtl_posixio rtl_time] mbuff 8684 0 (unused)