MaRTE OS Misc utilities

Similar documents
MaRTE-OS: Minimal Real-Time Operating System for Embedded Applications

Chapter 13: I/O Systems

Chapter 13: I/O Systems

Module 12: I/O Systems

TIP675-SW-82. Linux Device Driver. 48 TTL I/O Lines with Interrupts Version 1.2.x. User Manual. Issue November 2013

Assignment 2 Group 5 Simon Gerber Systems Group Dept. Computer Science ETH Zurich - Switzerland

The Embedded I/O Company TIP700-SW-82 Linux Device Driver User Manual TEWS TECHNOLOGIES GmbH TEWS TECHNOLOGIES LLC

Asynchronous Events on Linux

Section 3: File I/O, JSON, Generics. Meghan Cowan

Chapter 13: I/O Systems

Chapter 13: I/O Systems. Chapter 13: I/O Systems. Objectives. I/O Hardware. A Typical PC Bus Structure. Device I/O Port Locations on PCs (partial)

CSE 333 SECTION 3. POSIX I/O Functions

Advcan QNX Driver User Manual V1.02

MaRTE OS FAT16 Filesystem

10. I/O System Library

CSE 410: Systems Programming

Threads. Threads (continued)

Migrating Linux Device Drivers to a Microkernel POSIX RTOS: A Case Study. David Donohoe Senior Software Developer QNX Software Systems

EECS 3221 Operating System Fundamentals

EECS 3221 Operating System Fundamentals

Module 12: I/O Systems

Operating Systems 2010/2011

Experiment 6 The Real World Interface

TPMC901-SW-95. QNX4 - Neutrino Device Driver. User Manual. The Embedded I/O Company. 6/4/2 Channel Extended CAN-Bus PMC

MaRTE OS: Practical view

SA30228 / CVE

Objectives. Chapter 2: Operating-System Structures. 2.1 Operating System Services

NOTE: Debug and DebugSingle are the only MPI library configurations that will produce trace output.

NPTEL Course Jan K. Gopinath Indian Institute of Science

NPTEL Course Jan K. Gopinath Indian Institute of Science

I/O AND DEVICE HANDLING Operating Systems Design Euiseong Seo

ECE 650 Systems Programming & Engineering. Spring 2018

pthreads CS449 Fall 2017

I/O Systems. 04/16/2007 CSCI 315 Operating Systems Design 1

CS 33. Shells and Files. CS33 Intro to Computer Systems XX 1 Copyright 2017 Thomas W. Doeppner. All rights reserved.

Device-Functionality Progression

Chapter 12: I/O Systems. I/O Hardware

CMSC 216 Introduction to Computer Systems Lecture 17 Process Control and System-Level I/O

The control of I/O devices is a major concern for OS designers

COSC Operating Systems Design, Fall Lecture Note: Unnamed Pipe and Shared Memory. Unnamed Pipes

Operating Systems 2010/2011

OS COMPONENTS OVERVIEW OF UNIX FILE I/O. CS124 Operating Systems Fall , Lecture 2

Processes. Johan Montelius KTH

Embedded Systems. 5. Operating Systems. Lothar Thiele. Computer Engineering and Networks Laboratory

CSC 271 Software I: Utilities and Internals

A process. the stack

To obtain the current global trace mask, call meitraceget(...). To modify the global trace mask, call meitraceset(...).

C Programming. Course Outline. C Programming. Code: MBD101. Duration: 10 Hours. Prerequisites:

Operating Systems (2INC0) 2018/19. Introduction (01) Dr. Tanir Ozcelebi. Courtesy of Prof. Dr. Johan Lukkien. System Architecture and Networking Group

CSE 333 SECTION 3. POSIX I/O Functions

File Descriptors and Piping

Kernel Modules. Kartik Gopalan

Module 11: I/O Systems

Chapter 13: I/O Systems

Linux Device Drivers Interrupt Requests

Input/Output Systems

Unix File and I/O. Outline. Storing Information. File Systems. (USP Chapters 4 and 5) Instructor: Dr. Tongping Liu

TIP670-SW-95. QNX-Neutrino Device Driver. User Manual. The Embedded I/O Company. Digital I/O. Version 1.0.x. Issue August 2008.

User-Space Debugging Simplifies Driver Development

MaRTE OS: Overview and Linux Version

Operating Systems. Lecture 06. System Calls (Exec, Open, Read, Write) Inter-process Communication in Unix/Linux (PIPE), Use of PIPE on command line

CSE 4/521 Introduction to Operating Systems. Lecture 24 I/O Systems (Overview, Application I/O Interface, Kernel I/O Subsystem) Summer 2018

Outline. OS Interface to Devices. System Input/Output. CSCI 4061 Introduction to Operating Systems. System I/O and Files. Instructor: Abhishek Chandra

CS 326 Operating Systems C Programming. Greg Benson Department of Computer Science University of San Francisco

CMPSC 311- Introduction to Systems Programming Module: Input/Output

Files and the Filesystems. Linux Files

Chapter 13: I/O Systems

Hyo-bong Son Computer Systems Laboratory Sungkyunkwan University

Chapter 2: System Structures

Sistemi in Tempo Reale

Input / Output. Kevin Webb Swarthmore College April 12, 2018

Lecture 13 Input/Output (I/O) Systems (chapter 13)

CSE 120. Overview. July 27, Day 8 Input/Output. Instructor: Neil Rhodes. Hardware. Hardware. Hardware

Socket programming in C

Silberschatz and Galvin Chapter 12

Computer Systems A Programmer s Perspective 1 (Beta Draft)

File Systems. Jinkyu Jeong Computer Systems Laboratory Sungkyunkwan University

Chapter 12: I/O Systems

Chapter 13: I/O Systems

Chapter 12: I/O Systems. Operating System Concepts Essentials 8 th Edition

TIP570-SW-95 QNX-Neutrino Device Driver TIP570 16/8 Channel 12 Bit ADC and 8 Channel 12 Bit DAC on SBS PCI40 Carrier

OCF for resource-constrained environments

Thread. Disclaimer: some slides are adopted from the book authors slides with permission 1

CS 134. Operating Systems. April 8, 2013 Lecture 20. Input/Output. Instructor: Neil Rhodes. Monday, April 7, 14

CS 201. Files and I/O. Gerson Robboy Portland State University

Last Class: OS and Computer Architecture. Last Class: OS and Computer Architecture

1. Overview This project will help you understand address spaces and virtual memory management.

CISC2200 Threads Spring 2015

I/O Systems. Amir H. Payberah. Amirkabir University of Technology (Tehran Polytechnic)

Important Dates. October 27 th Homework 2 Due. October 29 th Midterm

Chp1 Introduction. Introduction. Objective. Logging In. Shell. Briefly describe services provided by various versions of the UNIX operating system.

Chapter 13: I/O Systems

C Programming Review CSC 4320/6320

TDRV010-SW-95. QNX6 - Neutrino Device Driver. Isolated 2x CAN Bus. Version 1.0.x. User Manual. Issue September 2016

Embedded Systems Programming - PA8001

Chapter 13: I/O Systems

SmartHeap for Multi-Core

Files and Directories Filesystems from a user s perspective

Embedded System Design

CS 453: Operating Systems Programming Project 5 (100 points) Linux Device Driver

Transcription:

MaRTE OS Misc utilities Daniel Sangorrin daniel.sangorrin@{unican.es, gmail.com} rev 0.1: 2008-5-12 1. Circular Memory Buffer This is a generic software component that allows the user to write some data in a buffer. This data is supposed to be extracted periodically. Otherwise, in case of overflow the old data will be overwritten. Mutual exclusion is provided through the use of a Mutex. The component has been developed to serve as a basis for a logging user application. The following files compose this component: circular_memory_buffer.[h, c]: this is the module that implements the functionality of circular memory buffers. Its interface is very simple and consists on the following functions: int membuffer_init(membuffer_t *mbuff, int capacity, int ceiling); int membuffer_write(membuffer_t *mbuff, const void *data, int len); int membuffer_read(membuffer_t *mbuff, void *data, int len); int membuffer_destroy(membuffer_t *mbuff); membuffer_driver.[h, c]: this is the implementation of the driver interface required by the operating system (MaRTE OS). Internally, the driver just makes the appropiate calls to the circular_memory_buffer interface. In the header file, a constant for the capacity of the memory buffer and the ceiling of the internal mutex can be set by the user of the driver. #define MBUFFER_SIZE 100000 #define MBUFFER_CEILING 98 int membuffer_driver_create(); ssize_t membuffer_driver_read (int file_descriptor, void *buffer, size_t bytes); ssize_t membuffer_driver_write (int file_descriptor, void *buffer, size_t bytes); int membuffer_driver_remove(); membuffer_driver_import.ads: this is just the Ada spec file that imports the previous functions to Ada, pragma Import (C, Create, "membuffer_driver_xxx"), so it can be inserted in the MaRTE OS drivers table. test_circular_memory_buffer.c: a test for the circular memory buffer. This test uses directly the interface of the module not the driver. For example: err = membuffer_init(&mbuff, BUFFER_CAPACITY, BUFFER_CEILING);

test_membuffer_driver.c: a test for the memory buffer driver. This file tests the driver so it goes through the MaRTE OS filesystem. Therefore it uses a POSIX interface (Note, that the driver can also be used from Ada or C++ programs as the bindings are provided by MaRTE OS), like this: fd = open( /dev/membuffer, O_RDWR); count = write(fd, buff, nbytes); count = read(fd, buff, BUFFER_LENGTH); In the figures X and X we can see a graph showing the dependences of the module. The most important is pthread.h which is used for the internal mutex. fig X. circular_memory_buffer module include graph fig X. membuffer_driver include graph 2. Logger This is a software component that allows its users to retrieve data from the membuffer driver previously described and log it in a certain device, being that device a file in a disk, an ethernet card, a serial port, a wireless card (useful to retrieve data from equipment that is difficult to access) or the console for example. The component is composed of the following files: logger.[h, c]: so far the logger has a simple interface that allows the user to either create a periodic thread that logs data periodicallly or log manually the data when the user wants. The constant MAX_BYTES_TO_READ defines how many bytes are read from the buffer (at the maximum) in each period or in each call to a manual log. #define MAX_BYTES_TO_READ 1000 enum log_device_id_t { LOG_CONSOLE = 0, LOG_ETHERNET = 1... other devices };

int logger_init(enum log_device_id_t dev); int logger_thread_create(struct timespec *period); int logger_manual_call(void); In the figure X we see the dependences of this module. Most of them are the typical POSIX header files. We use timespec_operations.h to operate on timespec values in the periodic thread and the headers to use the ethernet driver. In the future, support for other devices can be added easily by fulfilling a simple internal interface of two functions: int (*init)(void); int (*log_data)(int nbytes); fig X. logger include graph test_logger.c: test for the logger that creates a logger thread and then writes some data to the memory buffer with a certain period. This data should be read by the logger and sent to the appropiate device (ethernet, disk,...) test_logger_manual.c: like the previous test but instead of creating a logging thread here we will use a manual trigger (a keyboard press event) for the logging. linux_eth_receive_log.[h, c]: when we use LOG_ETHERNET as the logging device, the logger sends a set of ethernet frames with a broadcast address and a certain protocol number not allocated for other protocols. This module is a Linux program that uses raw sockets to receive those frames and write them to a log file. This log file can be then readed and treated with powerful Linux applications.

fig X. Linux ethernet logger include graph In the figure X we see the dependences of the Linux ethernet logger. The most important is the use of raw ethernet sockets. 3. Console switcher So far we have two interesting components, one to put data bytes in a buffer and the other one to log those bytes into a specific device at a certain time (which can be periodic). Now, an interesting feature from the user point of view would be to send character strings (messages) to be logged. This is useful for debugging purposes for example. In order to give this functionality to the framework we have created a console_switcher driver that allows the user to change the console device dynamically so the messages printed to the console (i.e: with a printf) are redirected to the current device (the default device would be the normal console). The component is composed of the following files:

console_switcher.[h, c]: the implementation of the console_switcher driver. It provides the functions required by the MaRTE OS filesystem to be inserted and then used from the POSIX interface (printf). In order to change to a different console a non standard ioctl option is used. We provide some simple macros to do that for us: void SERIAL_CONSOLE_INIT(void); void STANDARD_CONSOLE_INIT(void); void MEMBUFFER_CONSOLE_INIT(void); fig X. console switcher include graph In the figure X we see the dependences of the console switcher module. The most important ones are each of the console devices currently supported (text_console, serial port and membuffer). test_console_switcher_membuffer.c: test for switching between the console and the memory buffer. It also uses the logger to retrieve the written messages and log them to a given device. console_switcher_ioctl.ads: ioctl constants to use it from the Ada language console_switcher_import.ads: import the driver functions to Ada to insert them in MaRTE OS's drivers table. 4. Time measurement library So far, the framework we are describing is capable of redirecting printf messages to the memory buffer where they will wait to be logged at a safer time to a specific device (typically by sending them to a Linux host). Now we are going to go one step further in order to provide the feature of timestamping points of code that we will call trace points. This timestamps will be stored internally as efficiently as possible and at a safe time they will be flushed to the membuffer driver (with any additional information) so they can be logged (ie send them to a Linux host) and analyzed. We have created two time measurement libraries that have different features and might be helpful in different situations: POSIX time measurement library:

This library is based on the POSIX function clock_gettime(). Its main good points are that, as a POSIX based library, it is portable (among operating systems and hardware platforms) and it allows the user to make measures on different kinds of clocks (for example, it is useful to know how much time has elapsed on a thread CPU time clock). On the other hand, it has a slight overhead that must be taken into account because it has to go through the POSIX interface and uses timespecs. The interface is quite simple so far, and it is intended to do begin end time measurements: int time_measure_posix_create(const char *name, clockid_t clock_id, time_measure_id_t *id); int time_measure_posix_begin(time_measure_id_t id); int time_measure_posix_end(time_measure_id_t id); fig X. console switcher include graph In the figure X we see the dependences of the module. The most important are time.h, where the function gettime is declared, and fcntl.h and unistd.h that allows the module to open the memory buffer driver to store the measures whenever time_measure_posix_end is called. The component is composed of the following files. time_measurement_posix.[h, c]: the time measurement implementation based on POSIX test_time_measurement_posix_load.c: test for the time_measurement_posix module that measures the time taken to eat some time. test_time_measurement_posix_ethernet.c: test for the time_measurement_posix module and ethernet. We get N measures of a packet go return trip and then we log them manually. HWTIME time measurement library: This library tries to avoid the overheads of using timespecs and the POSIX interface and reads and stores hardware timestamps (i.e for intel pentiums the rdtsc instruction gives the processor cycles). Its interface is a bit different to the previous one. We can't choose a CPU clock timer, only absolute timestamps can be taken. Also, it is not oriented to begin end time measurements but to take measures of certain source code points (tracepoints). This is especially useful when we have a

execution path and we want to know where is the bottleneck because we just have to put some tracepoints and then performe substractions between the timestamps. The downside of this library is that it is not directly portable (although minor changes should be necessary, just the way to get the hardware time and the frequency typically). In the current implementation there are two main dependencies: #define rdtscll(val) \ asm volatile ("rdtsc" : "=A" (val)) extern hwtime_t hardware_interface get_hwclock_frequency (); The component is composed of the following files: time_measurement_hwtime.[h, c]: the library implementation. Its interface is as follows: #define MX_TRACE_POINTS 20 #define MX_TRACE_POINT_CHARS 50 #define MX_TIMESTAMPS_PER_ID 1000 typedef unsigned int trace_point_id_t; // 0.. MX_TRACE_POINTS 1 int time_measure_hwtime_init(trace_point_id_t id, const char *name); void inline time_measure_hwtime_set_timestamp(trace_point_id_t id); int time_measure_hwtime_write_membuffer(trace_point_id_t id); test_time_measurement_hwtime_load.c: test for the time_measurement_hwtime module that measures the time taken to eat some time. test_time_measurement_hwtime_ethernet.c: test for the time_measurement_hwtime module and ethernet. We get N measures of a packet go return trip and then we log them manually. So far we have our own way to format the log messages, but it may be desirable in the future to adapt them to support several analysis tools. We plan to study the difficulty of adapting them to tools like QNX TimeDoctor 1, Rapita's tools 2, KIWI 3, a task inspector tool that exists for MaRTE OS 4. For the moment, to make the analysis of the measures we are just using simple customized scripts written in Perl to parse the log messages and then copy the measures in an OpenOffice spreadsheet to extract a histogram ( FREQUENCY(Data;Bin) + Ctrl Shift Enter), max, min and average values, variance, etc. 5. RT EP Wireshark plug in This is a plug in for the Wireshark sniffer in order to monitor the RT EP protocol. The sniffer will be helpful to explain the number of messages transmitted in each transaction and therefore to check that the sum of the lower level message timings explain the timing measures of the high level measures (i.e the time to negotiate a transaction). The plug in is in a directory inside the RT EP protocol directory (x86_arch/drivers/rtep) and it contains the installation instructions. 1 http://sourceforge.net/projects/timedoctor 2 http://www.rapitasystems.com/ 3 http://rtportal.upv.es/apps/kiwi/ 4 http://marte.unican.es

6. Linux linked lists The file 'x86_arch/include/misc/linux_list.h' contains code extracted from the Linux kernel that implements double linked lists. See http://kernelnewbies.org/faq/linkedlists This linked lists are very useful to link the same elements in different lists. 7. Freelist The file 'x86_arch/include/misc/freelist.h' contains the interface to the freelists which is an interesting data structure that implements a sinly linked list that is used to find free cells in some external table. Parallel to the external table, there is a table of indexes organized as a singly linked list; it is the free list. A separate index, free_cell, indicates which is the first element of the sibly linked list. The list is terminated with an index of 1. A typical example of use is to have a pool of preallocated structures (in an array) and provide the user with an identifier (the position in that pool) which can be allocated and deallocated in O(1) time by using the freelist linked list. int freelist_init(freelist_t *list, int size); int freelist_alloc(freelist_t *list); int freelist_free(freelist_t *list, int cell); Check the file test_freelist.c to see an example.