Use RTLinux to develop embedded applications

Source: Internet
Author: User
For Chinese engineers, using real-time Linux to develop embedded applications is one of the difficulties they face. This article takes RTLinux as an example and discusses it with RTAI, although the two implementation methods differ in syntax details, they work in the same way. Therefore, the content described here is applicable to both of them.

In the process of communication between real-time tasks and user processes, some real-time applications can run smoothly in the background without any user interface. However, more and more real-time applications require a user interface and other system functions, such as file operations or networking. All these functions must run in the user space. The problem is that user space operations are non-deterministic and incompatible with real-time operations.

Fortunately, real-time Linux has a mechanism that can reduce real-time and non-real-time operations in time. This mechanism is represented by a driver called real-time FIFO. When insmod inserts the rtl_fifo.o driver into the Linux kernel, the driver registers itself as part of RTLinux and becomes a Linux driver. Once the Linux kernel is inserted, real-time Linux FIFO can be used for user space processes and real-time tasks.

Before going into the details of real-time FIFO, let's review some parts of the real-time application structure (figure 1 ). An effective embedded application design method is to separate the real-time part from the inherent non-real-time functions (table 1 ). If any part of an application, such as the user interface, graphics, database, or network, requires only soft real-time performance, it is best to write this part into the user space. Then, only the part that must meet the timing requirements is written as a real-time task.

Note that the latest version of RTLinux (PSC, portable Signal Encoding) and RTAI (LXRT, Linux real-time extension) has adopted a method that can execute soft and hard real-time tasks in user space.

Any hard real-time task is run under the control of RTLinux. Generally, this task can execute periodic tasks, handle interruptions, and communicate with the driver of the I/O device, to collect or output analog and digital information. When a real-time task tells a process that an event will occur, it sends the message to the real-time FIFO. Each FIFO transmits data in one direction: from real-time tasks to user space, or vice versa. Therefore, two FIFO is required for bidirectional communication. Any read or write operations on the real-time task side are non-module operations, so rtf_put () and rtf_get () are immediately returned, regardless of the FIFO status.

From the application side, FIFO is like a regular file. By default, the RTLinux installer creates 64 real-time FIFO nodes in the/dev directory. If necessary, you must create a new node. For example, to create/dev/rtf80, use the following command:

======================================
Mknod c 150 80;
Chmod 0666/dev/rtf80
======================================

150 is the number of real-time FIFO masters, and 80 is the number of rtf80.

From the perspective of user processes, real-time FIFO can perform standard file operations. From the perspective of real-time tasks, FIFO has two communication modes: directly calling the RTLinux FIFO function, or using FIFO as an RTLinux device driver, and using open (), close () read () and write () operations. To use FIFO as a device driver, you must set the configuration variable CONFIG_RTL_POSIX_IO in rtl_conf.h to 1.

Rtf_create_handler () can be used to set the handler function. Each time a Linux Process reads or writes a FIFO, The rtl_fifo driver calls this handler. It should be noted that the handler resides in the Linux kernel. Therefore, when Linux needs to be called, it is safe to make any kernel call from the handler. The best way to communicate between the processing program and real-time tasks is to use the flag or thread synchronization function. Finally, the FIFO driver must configure the kernel memory. Therefore, rtf_create () in real-time threads should not be called. Instead, you can call the rtf_create () function in init_module () and the rtf_destroy () function in cleanup_module.

For example, list 1 shows the real-time part of a simple data collection application that uses two FIFO. Both FIFO instances are created in init_module () and granted to minor numbers as 1 and 2. Before rtf_create (minor, size) is called, the program calls rtf_destroy (minor) when the FIFO has been created ). In this case, another module is not called during development. Call rtf_create_handler (ID, & pd_do_aout) to register the Real-Time FIFO data collection simulation output function pd_do_aout (). Note that the Real-Time Thread pp_thread_ep () is created because it is periodic and Its interval is 1/100 seconds.

After each periodic thread obtains control of the system, it calls rtf_put (ID, dataptr, size) to insert data into the first-in-first-out with minor number 2. In a Linux Process, open/dev/rtf2 and read and display the collected data from the real-time FIFO. This process also enables/dev/rtf1 to write data to other real-time FIFO instances. When you move the screen slider to change the analog output voltage, the process writes a new value to the FIFO. RTLinux calls the pd_do_aout () processing program, and then pd_do_aout () obtains the value from the FIFO using rtf_get (), and calls the actual hardware driver to set the voltage of the analog output. As you can see, real-time tasks and user processes use FIFO asynchronously.

Memory sharing between tasks

FIFO provides a convenient mechanism for the connection between user processes and real-time tasks, but it is more appropriate to use them as message queues. For example, a real-time thread can use FIFO to record the test results, and then the user process can read the results and store them into database files.

Many data collection applications involve a large amount of data between the kernel and user space. Linux Kernel v. 2.2.x does not provide any mechanism for data sharing in these spaces, but Version V. 2.4.0 is expected to include the kiobuf structure. To solve this problem, RTLinux includes the mbuff driver. The driver can use vmalloc () to allocate the named memory area of the virtual kernel memory. It uses the memory allocation and page locking techniques to demonstrate the frame-grabber (bttv frame capture) in most Linux systems) the driver is the same.

More specifically, mbuff locks the virtual memory page by page to the actual physical memory page. Any real-time or kernel task or user process can access the memory at any time. By locking the virtual memory page to the physical memory page, mbuff can ensure that the allocated page permanently resides in the physical memory without page errors. In other words, when real-time or kernel processes access the allocated memory, it ensures that vmm is not called. Note: during real-time task execution, any call to vmm will cause the system to stop freezing the execution of the standard kernel in Linux. If you want to access a virtual storage page that is not in the physical Ram, a normal Linux kernel driver may cause a system failure.

Because mbuff is a Linux driver, its functions can be implemented through the device node/dev/mbuff. This node displays several entry points, including MMAP () that maps the kernel space address to the user space (). It can also be controlled by the Input Point IOCTL. However, there is no need for complex structures and direct call of IOCTL. On the contrary, mbuff can provide a package for IOCTL () calls, and only two simple functions can be called to configure and release shared storage buffers.

Of course, the mbuff driver cannot be called from a real-time task, because the virtual memory allocation function called by the driver itself is an operation of uncertainty. The time required to allocate shared memory depends on the memory capacity of the primary system, CPU speed, disk drive performance, and the existing status of memory allocation. Therefore, shared memory can only be allocated from the Linux kernel side of the module, for example, from init_module () or an IOCTL () request.

How much memory can a shared buffer allocate? If it is not a heavy-duty server or graphics application, we recommend that you retain at least 8 MB of storage space for Linux. To achieve optimized configurations, you can measure the performance of real-time applications while limiting the memory size to determine how much storage space is needed.

List 2 shows how to access shared memory from the perspective of real-time tasks and user processes. The kernel module uses the same feature set as the user task. Of course, to use insmod mbuff. o, you must also place it in the Linux kernel. For example, mbuff_alloc ("buf_name", size) can allocate the symbol name buf_name to a buffer, while mbuff_free ("buf_name", mbuf) can release it.

When mbuff_alloc () with the symbolic buffer name is called for the first time, mbuff executes the actual memory allocation. When this function is called again from the kernel module or user process, it simply adds the usage count and returns the pointer to the existing buffer. Each call to mbuff_free () reduces the number of calls until it is zero. Then, mbuff allocates a buffer with a signed name. This method obtains a pointer to the same shared buffer from Multiple kernel modules and user processes, thus solving the problem. It also ensures that the shared buffer remains valid until the last application releases it. Please note that the real-time kernel or the actual buf1 configuration executed by the user process depends on who gets control first.

There is also a "stupid" way to share memory between real-time applications, kernel modules, and user applications. This method is acceptable for embedded applications. For example, if the PC has 128 mb ram, you can add the Line Search Path = "mem = 120 m" to the lilo. conf file (List 3 ). Linux only uses 2.3 MB of memory when Linux kernel and RTLinux are started. The OS does not need the remaining 8 MB memory (the physical address is 0x7F00000 to 0x7FFFFFF), but is reserved for sharing various tasks running under the OS. To obtain the memory address from the user process and access the reserved memory, you must use O_RDWR access mode to open the/dev/mem driver, and then use mmap () to retain the memory (list 4 ). From the real-time module or the kernel driver side, you must use ioremap (0x7F00000, 0x100000) to obtain the 8 MB (0x100000 bytes) reserved memory.

This method has advantages and disadvantages. You can neither reserve the ownership of the memory nor obtain control by reading or writing. The mechanism for correctly configuring and releasing a large amount of memory has not yet been released. In addition, no matter whether the real-time process is required or not, the memory cannot be used by Linux.

Perhaps the only application of the stupid Memory sharing method is a small embedded system tailored for specific applications, because mbuff drivers can be discarded for miniaturization.

Interrupted

RTLinux has two types of interruptions: Hard interrupt and Soft Interrupt. Soft Interrupt is a conventional Linux kernel interrupt. Its advantage is that it can be called without restrictions using the Linux kernel. This type of interrupt is useful as the second part of hard Interrupt Processing (see article 5 for more details about Interrupt Processing in Linux ).

Hardware (Real-Time) interruption is the prerequisite for installing Real-Time Linux. To install the interrupt handler, call rtl_request_irq (...) and call rtl_free_irq () to release it. Depending on different systems, the latency of hard (or real-time) interruptions in Real-Time Linux is 15 μs. A fast processor has a good latency. If you want to process the same device IRQ in a real-time processor and a general Linux driver, you must set an IRQ for each hard interrupt.

List 5 describes how to install the real-time interrupt handler. In RTLinux, IRQ is disabled when the Real-Time Interrupt Processing Program is executed. Note that the Code must call rtl_hard_enable_irq () before exiting the real-time interrupt handler to re-enable the interrupt.

There are two problems that affect calling the Linux kernel function directly from the real-time interrupt handler: the kernel prohibits all interruptions and does not define the execution content. It should also be noted that floating point operations cannot be performed here. Using Real-Time Interrupt handlers to control thread execution is a good way to avoid these problems. In this example, the pthread_wakeup_np () function is used to wake up a real-time thread. The interrupt handler can handle real-time work, and the rest will be handled by this thread.

Advantages of SMP Structure

Real-Time Linux supports multi-processor architecture. The symmetric multi-processor (SMP) structure uses an advanced programmable interrupt controller (APIC). Pentium-level processors all have local APIC on chip, which can transmit interruptions to local processors. SMP (or even single-processor motherboard) has an I/O APIC that collects interrupt requests from peripherals and sends them to the local APIC. The old 8259 PIC is slow, and the number of Interrupt vectors processed is insufficient, which forces the device to share the interrupt, making the Interrupt Processing slower. However, APIC can solve these problems. By setting a specific IRQ for each device request, the system can reduce the interruption delay, and APIC can also accelerate code synchronization.

Real-Time Linux can make full use of APIC. In the SMP system, the real-time scheduler uses APIC instead of an outdated 8254 chip for timing allocation. Due to PC compatibility, 8254 is located on each ISA bus, and each call to a re-programming device occupies a processor cycle. A 2.5 MHz CPU wastes hundreds of processor cycles to wait for an 8 MHz timer (about μs ). The APIC operates at the bus frequency and can immediately perform all timer operations, this means that a higher periodic frequency must be obtained on the amp machine using the local APIC clock (the dual-P-III-500 CPU can run periodic real-time threads at KHz without significant performance loss ).

Real-Time Linux can execute multiple processing tasks well, which implements separate processes for each CPU. Call pthread_create () to create a thread that runs on an existing CPU. You can also use pthread_attr_setcpu_np () to allocate the thread to a specific CPU to change the thread attributes. Before calling this function, you must first initialize the thread attributes.

RTLinux v. 3 includes the reserve_cpu function, which allows you to reserve a CPU on the SMP platform for use in RTLinux. It runs on the 2.4x kernel, and rtai has almost the same features.

If you want to assign a task to a specific CPU, pay attention to the "pset" Scheme (http://isunix.it.ilstu.edu/thockin/pset ). This kernel can be used to assign an SMP processor to a user application, or even call a processor dedicated to real-time tasks from a Linux processor group.

Synchronization Element

In early Real-Time Linux, no synchronization primitive exists. Currently, POSIX-type flag, mutex, and signal are available in the latest real-time Linux version. Although there are still problems with using these synchronization elements in real-time design, it makes sense to synchronize or use signals to represent real-time tasks and user applications. However, this requires software developers to have superb skills, this issue is beyond the scope of this article.

The best way to quickly learn synchronization functions such as pthread_mutex_init (), pthread_mutex_trylock (), pthread_mutex_unlock (), and merge () is to view./examples/mutex. C. Note that the./examples/mutex/sema_test.c file is a good start point for learning the flag.

Development Direction of Real-Time Linux

Like Linux, real-time Linux is still evolving. More features and features are added for each new version. Real-Time Linux is moving towards a better POSIX 1003. X is evolving towards implementation. The latest features include real-time support, mutex, signal, flag, real-time memory management, and extended SMP support for user space processes. If you have not determined which real-time system is used for the next project, download a Real-Time Linux version. In fact, Linux is already a mature OS and has a real-time extended version. It is one of the best choices for embedded applications.

Dr. Alex Ivchenko is the R & D Engineering Manager of the united electronics industry company and one of the major developers of the company's powerdaq II series PCI data collection board. Recently, he has compiled Linux drivers for the series of cards. You can contact him by email aivchenko@ueidaq.com.

References:

Ivchenko, A. "Real-Time Linux," embedded systems programming, May 2001, p. 35.

Marsh, David. "understand Linux Device Drivers," Test & Measurement world, choose l 15,200 0.

Johnson, M. K. and e.w. troan. Linux application development. Reading, MA: Addison Wesley Longman, 1998.

Mantegazza, P ., e. bianchi, L. dozio, S. papacharalambous, S. hughes, and D. beal. "rtai: Real-time application interface. an Introduction to rtai for deterministic and preemptive real-time behavior for Linux, "Linux Journal, limit l 2000.

RTLinux Website: www.rtlinux.org and www.rtlinux.com. The file and source code can be downloaded from the file. Reading the RTLinux declaration by Victor yodaiken is also a good start point.

Rtai Website: www.rtai.org

Other driver materials come from the "Linux document project" (www.linuxdoc.org), especially David A. rusling's Linux kernel and Michael K. Johnson (khg.redhat.com) Linux kernel hacker guide. Finally, we recommend that you keep yourself updated with the latest kernel www.kernelnotes.org ).
Author: Alex Ivchenko

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.