Real-Time Applications with RTLinux
Task 1 can be easily implemented using the POSIX interface. Listing 1 shows the structure as it would be implemented in RTLinux.
#include <rtl.h>
#include <time.h>
#include <pthread.h>
#define TASK_PERIOD 100000
/* 100 microseconds period */
#define TASK_PRIORITY 1
/* priority assigned to task */
pthread_t thread;
void * task_one(void *arg) {
struct sched_param p;
p . sched_priority = TASK_PRIORITY;
pthread_setschedparam (pthread_self(),
SCHED_FIFO,
&p);
pthread_make_periodic_np (pthread_self(),
gethrtime(),
TASK_PERIOD);
/* startup controller
initialization routine
goes here */
.
.
.
while (1) {
pthread_wait_np();
/* periodic controller
routines go here */
.
.
.
}
return 0;
}
int init_module(void) {
pthread_create (&thread, NULL, task_one, 0);
pthread_setfp_np(&thread,TRUE);
return 0;
}
void cleanup_module(void) {
pthread_cancel (thread);
pthread_setfp_np(&thread,FALSE);
pthread_join (thread, NULL);
}
Here, the init_module() and cleanup_module() functions can be seen as the RTLinux equivalent of the main() function in user-level C programs. Upon startup, the init_module() function is called. This function then immediately tells the scheduler to create a new thread--where the function task_one() comprises the body of the thread--and sets up permissions to enable floating point calculations. Likewise, when the program is stopped, the cleanup_module() function is executed, which in turn stops the thread from further execution, removes permissions to use the floating point unit and quits.
The thread itself can be separated into three segments--initialization, periodic and shutdown--which are represented in the code, respectively, by the segments prior to, inside and after the ``while'' loop.
First, during initialization, we establish the attributes for this particular thread. We specify the scheduler type to use (SCHED_FIFO), the priority and the frequency at which the thread will be called by the scheduler, and we perform all tasks necessary to initialize our controller.
Next, during the periodic segment, we first encounter the call to pthread_wait_np(), which causes the thread to block until the scheduler calls it again. Thus, the thread will execute the entire contents of the while loop once per execution cycle. Note that in this particular example the shutdown part of our code will never execute, since there is no provision in our example code to exit the while loop. Instead, it will be terminated immediately upon execution of the cleanup_module().
There are several ways of implementing this second task. In what follows, we shall focus on two: an Interrupt Service Routine running within RTLinux, and a signal handler running within a user-level Linux task.
To run Task 2 as an Interrupt Service Routine (ISR), we need to add the following to the code for Task 1 above (assuming that we are using IRQ 7):
#define IRQ 7<\n>
unsigned int example_isr(unsigned int, struct pt_regs *);
unsigned int example_isr(unsigned int irq_number, struct pt_regs *p)
{
/* insert non FP dependent
calculations here */
.
.
rtl_hard_enable_irq(IRQ);
return(0);
}
However, in order to tell RTLinux to associate example_isr() to IRQ 7, we must use the rtl_request_irq() and rtl_hard_enable() functions in init_module():
rtl_request_irq(IRQ, example_isr);<\n>
/* <-- I/O IRQ initialization
routines go here --> */
rtl_hard_enable_irq(IRQ);
And we must of course clean up after ourselves, so we add the
following to cleanup_module():
rtl_hard_disable_irq(IRQ);<\n> rtl_free_irq(IRQ);The problem becomes more interesting for the implementation of the third task. The thread for Task 3 is created in much the same way as was done for Task 1, however we now use our aforementioned ISR to trigger the first execution of Task 3. The subsequent 15 executions of Task 3 have a period, P, that is dependent on the interarrival times, T, of IRQ 7 as P=T/(16+1). But that's getting beyond the scope of the present discussion.
An even more interesting example of the rich RTLinux programming API can be seen with an alternative approach to the development of Task 2. Suppose that instead of executing Task 2 within RTLinux, we instead would like to execute it in Linux itself. For example, let's say that we now want to combine the functionality of Tasks 2 and 4: We want to plot a point to the screen each time that the rotor rotates once about its axis. We can write an application in Linux that first intercepts IRQ 7 and then plot the spin speed to the screen.
Our user-level Linux program would use the rtlinux_sigaction() function--first introduced in RTLinux V3.0--to first identify a handler within our program that would be executed each time that IRQ 7 is triggered.
Today’s modular x86 servers are compute-centric, designed as a least common denominator to support a wide range of IT workloads. Those generic, virtualized IT workloads have much different resource optimization requirements than hyperscale and cloud applications. They have resulted in a “one size fits all” enterprise IT architecture that is not optimized for a specific set of IT workloads, and especially not emerging hyperscale workloads, such as web applications, big data, and object storage. In this report, you will learn how shifting the focus from traditional compute-centric IT architectures to an innovative disaggregated fabric-based architecture can optimize and scale your data center.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
| Non-Linux FOSS: Seashore | May 10, 2013 |
| Trying to Tame the Tablet | May 08, 2013 |
| Dart: a New Web Programming Experience | May 07, 2013 |
- RSS Feeds
- New Products
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Drupal Is a Framework: Why Everyone Needs to Understand This
- A Topic for Discussion - Open Source Feature-Richness?
- Home, My Backup Data Center
- New Products
- Trying to Tame the Tablet
- Developer Poll
- Paranoid Penguin - Building a Secure Squid Web Proxy, Part IV



3 hours 24 min ago
7 hours 37 min ago
10 hours 10 min ago
14 hours 49 min ago
17 hours 12 min ago
1 day 10 hours ago
1 day 12 hours ago
1 day 13 hours ago
1 day 14 hours ago
1 day 14 hours ago