
Lineo: Introduction to Real-time Linux ... Day 3 Table of Contents 1 The Proc File System . 1 1.1 The Proc File System . 1 1.2 Creating a Proc Entry . 2 1.3 Creating a Proc Directory Entry . 3 1.4 Lab: Adding a Proc inerface to the FIFO example . 3 2 Real-time Interrupts . 4 2.1 Interrupt Handlers . 4 2.2 Interrupt Handler Arguments . 4 2.2.1 Interrupt Setup . 4 2.2.2 Interrupt Service . 4 2.3 Real-time Interrupts . 5 2.4 Real Time and Linux Interrupt Handlers . 6 2.4.1 Exercise 3.0: Interrupts and Their Latencies . 7 2.4.2 Information . 7 2.4.3 Assignment . 7 2.4.4 Tips . 7 2.4.5 Interrupt Latency example . 7 2.5 Lab: Servo Interrupt Latency . 10 3 Real-time Floating Point . 11 3.1 Floating Point . 11 3.2 Exercise: Floating-point Numbers in Real-Time . 11 3.2.1 Information . 11 3.2.2 Assignment . 11 3.2.3 Tips . 11 3.3 Lab: Servo Floating-Point . 12 4 Real-time User Code . 13 4.1 LXRT: Linux Real-time . 13 4.2 "Hard" Real Time versus "Soft" Real Time . 13 4.3 LXRT Object Name Space . 13 4.4 LXRT Mailboxes and Semaphores . 14 4.5 Hard Real-time from User Space . 14 4.6 Exercise 3.0: Real-time in User Space with LXRT . 14 4.6.1 Instructions . 14 4.6.2 Assignment . 14 4.6.3 Tips . 15 4.6.4 LXRT ( User Space Real Time) example . 15 4.7 Lab: Servo LXRT Lab . 17 5 Real Time POSIX . 18 5.1 POSIX Introduction . 18 5.2 Posix Threads and Processes . 19 5.2.1 Posix API . 19 5.3 RTAI 1.6 Problem . 20 5.4 POSIX Mutexes . 22 5.4.1 Exercise: Protecting Critical Regions with Mutexes . 22 5.4.2 Information . 22 5.4.3Lineo Assignment . Education. Services. 22 - i - 5.4.4 Tips . 23 5.4.5 Mutex Example . 23 5.5 Lab: POSIX Mutex Lab . 29 5.6 Exercise 3.4: Real-time with POSIX functions . 29 5.6.1 Information . 29 5.6.2 Assignment . 30 5.6.3 Tips . 30 5.6.4 RTAI POSIX Example . 30 5.7 Lab: Servo Posix Lab . 33 5.8 POSIX Message Queues . 34 5.8.1 POSIX Message Queue API . 34 6 Coding Standards . 35 6.1 Linux Kernel Coding Style . 35 6.1.1 Indentation . 35 6.1.2 Placing Braces . 35 6.1.3 Naming . 36 6.1.4 Functions . 37 6.1.5 Commenting . 37 6.1.6 You’ve made a mess of it . 37 7 Real Time Code Structure . 39 7.1 Real-time Design Overview . 39 7.2 Real-time Abstraction and Simulation . 40 7.2.1 Abstraction . 40 7.2.2 Simulation . 40 8 Combined Real Time Driver . 41 8.1 What We Are Trying to Do . 41 8.2 The Data Section . 42 8.3 The Fifo Section . 42 8.4 The Control Section . 42 8.5 The Driver Section . 42 8.6 The User Section(s) . 42 8.7 The Proc Section . 43 8.8 The IRQ Section . 43 8.9 Overall Summary . 43 9 Real Time - Futher Information . 44 9.1 Instructions on how to use the RTAI CVS tree . 44 9.1.1 Accessing the repository . 44 9.1.2 Updating the local tree . 44 9.1.3 Using the new Makefiles: . 44 Lineo Education Services - ii - Lineo: Introduction to Real-time Linux ... Day 3 1 The Proc File System 1 The Proc File System 1.1 The Proc File System The proc file system provides a means of quick access to core kernel data. A simple access method is provided which can be used in user tasks. The basic Proc file system is shown: dr-xr-xr-x 3 root root 0 August 25 15:23 1 dr-xr-xr-x 3 root root 0 August 25 15:23 2 dr-xr-xr-x 3 root root 0 August 25 15:23 3 dr-xr-xr-x 3 bin root 0 August 25 15:23 303 dr-xr-xr-x 3 nobody nobody 0 August 25 15:23 416 dr-xr-xr-x 3 daemon daemon 0 August 25 15:23 434 dr-xr-xr-x 3 xfs xsf 0 August 25 15:23 636 dr-xr-xr-x 4 root root 0 August 25 15:23 bus -r--r--r-- 1 root root 0 August 25 15:23 cmdline -r--r--r-- 1 root root 0 August 25 15:23 cpuinfo -r--r--r-- 1 root root 0 August 25 15:23 devices -r--r--r-- 1 root root 0 August 25 15:23 filesystems dr-xr-xr-x 2 root root 0 August 25 15:23 fs dr-xr-xr-x 4 root root 0 August 25 15:23 ide -r--r--r-- 1 root root 0 August 25 15:23 interrupts -r--r--r-- 1 root root 0 August 25 15:23 ioports Lineo Education Services - 1 - 1.2 Creating a Proc Entry 1.2 Creating a Proc Entry The code for generating the data seen in a proc entry is shown here: #include <linux/proc_fs.h> RTIME start_time = 0; int rt_servo_proc_read (char *buf, char **start, off_t offset, int count, int *eof , void * data) { RTIME elapsed; int i; char * sp; int len = 0; /* write up to 4096 bytes to buf return bytes written in len */ elapsed = rt_get_time_ns() - start_time; len = sprintf (buf, "Servo proc time: %d\n", (int) elapsed); /* * if we had more channels for (i = 0; i < N_CHANS; i++) { sp = &buf[len]; len += sprintf (sp, "Channel %d:, position = %d ns, \n", i, channel[i].position); } */ sp = &buf[len]; i = 0; len += sprintf (sp, "Channel %d:, position = %d ns, \n", i, position); return len; } Lineo Education Services - 2 - Lineo: Introduction to Real-time Linux ... Day 3 1.3 Creating a Proc Directory Entry 1.3 Creating a Proc Directory Entry This will create the rt_servo proc directory entry at the proc root: /* add this in init_module */ proc_rt_servo = create_proc_entry("rt_servo", 0, 0); proc_rt_servo->get_info = rt_servo_proc_read; /* add this in cleanup_module */ remove_proc_entry("rt_servo", &proc_root); 1.4 Lab: Adding a Proc inerface to the FIFO example cd /$HOME/ClassLabs/Servo/proc cp /mnt/train/code/ClassLabs/Servo/proc/* ./ Edit servoproc.c to add the items listed above. make insmod servoproc.o cd /proc. *Note that there is now an entry called "rt_servo." cat /proc/rt_servo Lineo Education Services - 3 - 2 Real-time Interrupts 2 Real-time Interrupts 2.1 Interrupt Handlers The standard way of using interrupts in Linux is to "wake up" a task that is waiting for some resource that is being provided by the system generating the interrupt. A process blocks through a call to interruptible_sleep_on(). A hardware interrupt occurs. The corresponding interrupt handler then executes the wake_up_interruptible() function. Like the device driver, an interrupt handler must be "registered" by a call to request_irq(). This establishes the link between the interrupt handler and the hardware IRQ. 2.2 Interrupt Handler Arguments 2.2.1 Interrupt Setup int request_irq( unsigned int irq_num, void (*handler)(int, void * , struct pt_regs *), unsigned long irq_flags, const char * device, void * dev_id) 2.2.2 Interrupt Service void service_irq( unsigned int irq_num, void * dev_id, struct pt_regs *) irq_flags: A set of flags used to define the handler’s behavior. Lineo Education Services - 4 - Lineo: Introduction to Real-time Linux ... Day 3 2.3 Real-time Interrupts SA_INTERRUPT. When set, run with interrupts disabled. SA_SHIRQ. When set, this is a shared interrupt. In the case of a shared interrupt all the drivers registered for that interrupt are called in the order in which they were registered. The code that services the interrupt handlers follows: // extract from /usr/src/linux/arch/i386/kernel/irq.c do { status |= action->flags; action->handler(irq, action->dev_id, regs); action = action->next; } while (action); 2.3 Real-time Interrupts A group of flags introduced by RTAI are used to detect the state of the system. We are running either a real-time task or a normal Linux task. void rt_switch_to_linux(int cpuid) { TRACE_RTAI_SWITCHTO_LINUX(cpuid); set_bit(cpuid, &global.used_by_linux); processor[cpuid].intr_flag = processor[cpuid].linux_intr_flag; } void rt_switch_to_real_time(int cpuid) { TRACE_RTAI_SWITCHTO_RT(cpuid); processor[cpuid].linux_intr_flag = processor[cpuid].intr_flag; processor[cpuid].intr_flag = 0; clear_bit(cpuid, &global.used_by_linux); } When an interrupt is serviced, it is passed to a dispatch_global_irq routine. The logic here is as follows: Lineo Education Services - 5 - 2.4 Real Time and Linux Interrupt Handlers If you have a global interrupt assigned (by a real-time task), then use it. Otherwise set_bit(irq, &(global.pending_irqs)); If you are running Linux, use linux_sti() to trigger the interrupt service. // extract from linux_sti() rt_spin_lock_irq(&(global.data_lock)); if ((irq = global.pending_irqs & ~global.activ_irqs)) { irq = ffnz(irq); set_bit(irq, &global.activ_irqs); clear_bit(irq, &global.pending_irqs); rt_spin_unlock_irq(&(global.data_lock)); cpu->intr_flag = 0; do_linux_irq(global_vector[irq]); clear_bit(irq, &global.activ_irqs); cpu->intr_flag = intr_enabled; } else { rt_spin_unlock_irq(&(global.data_lock)); } 2.4 Real Time and Linux Interrupt Handlers You can chain a Linux interrupt after a real time interrupt rt_pend_linux_irq(7) - will trigger a Linux irq Claim the IRQ using request_irq(7,irq_handler,0,"servo",NULL); Look at the code in /$HOME/ClassLabs/Servo/irq/servoirq2.c: Lineo Education Services - 6 - Lineo: Introduction to Real-time Linux ... Day 3 2.4.1 Exercise 3.0: Interrupts and Their Latencies 2.4.1 Exercise 3.0: Interrupts and Their Latencies 2.4.2 Information While building the previously proposed architecture, the signal source line DATA7 (Pin 9) short-circuited with the interrupt input /ACK (Pin 10) of the parallel port.
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages47 Page
-
File Size-