Göm meny

TSEA81 - Datorteknik och realtidssystem

Notera att dessa sidor enbart finns i engelsk version

TSEA81 - Computer Engineering and Real-time Systems

Assignment 6 : Realtime Linux

Introduction

In this assignment, a real-time program should be developed where a high-priority and a low-priority task should cooperate.

The purpose of the assignment is to provide skills and knowledge for implementation of a real-time program using Linux, executing in an embedded system.

Requirements

In the lab skeleton assignment6_20231218.tar.gz, which you can download at the course webpage, you will find a program which should, but does not, fulfill the following specifications:

  • The program should call read_sample() every millisecond with as little variation in timing as possible. The samples should be stored in an array which contains 256 elements.
  • The program should call do_work() for every 256:th call to read_sample(). do_work() should write out all 256 stored sampled using a call to write_sample().
  • The program should be protected against the behavior of other non-realtime threads and processes in the system and should also be protected against out-of-memory situations.

Your task

Unfortunately the program, as written, will not fulfill the specifications above. First of all, it is not protected against the behavior of other programs. (See the lecture notes for the lecture on real-time tasks in Linux for how to do this, particularly the discussion about how to set a thread to real-time priority and how to lock the memory a program has allocated/will allocate.) Secondly, the call to do_work() takes so long that the deadlines for the calls to read_sample() will be missed for a number of iterations after do_work() is called.

Your task is to modify the program so that the specifications are fulfilled. Here are some hints on what to do:

  • Run the original program and understand its behavior. To analyze the behavior, a Matlab script (analyze.m) and a Python program (analyze.py) is included in the lab skeleton. Use one or the other. To use the Python program you may have to load the module prog/anaconda first:
    module add prog/anaconda  
    ./analyze.py
    
    Try to make it fail even harder by running other tasks on the Linux computer at the same time (e.g., reloading 20 tabs in the webbrowser at the same time, running the elevator from assignment 5 at the same time, etc, or using the program disturb.c). Compile and start as follows:
    make disturb
    ./disturb 60
    
    This will start 60 disturb processes running for a short while, so at the same time start the lab application in another terminal window. That way the disturb processes are running when the lab application starts to take samples.
  • Protect the program from other programs running on the same system by using pthread_setschedparam and mlockall() as appropriate (see the lecture notes about real-time programming in Linux).
  • Split maintask() into two threads (sampletask() and doworktask() for example). One thread should be responsible for sampling data at regular intervals using read_sample(), the other should be responsible for running do_work() whenever enough data has been written into the sample_buffer. Hint: You need to take steps to ensure that data used by do_work() is not overwritten while do_work() is running (for example by using two sample_buffers instead of one). You shouldn't change anything that has to do with the delay function in do_work().
  • You should not need to modify do_work(). (If you still feel the need for this, please discuss this with the lab assistants.)
  • It might be easier to see what's wrong with the sampled data by initially using a periodic waveform, like a sawtooth signal. You can use the program create_saw.c to create sawtooth data (data_saw.raw) and replace the data.raw file with data_saw.raw (rename data.raw to data_orig.raw for later use). When you think that you understand the problem and have a solution change back to data.raw again. Compile and run create_saw like this:
    make create_saw
    ./create_saw
    

Known Limitations

The computers in Muxen 1 and 2 are configured to allow for some real-time related operations that are not normally permitted to users on a Linux system. For example, the computers have been configured to allow a user to set the scheduling class of a thread/process to one of the real-time scheduling classes (SCHED_FIFO or SCHED_RR). However, the maximum priority you are allowed to set using the pthread_setschedparam call is 10.

The computers in Muxen 1 and 2 have also been reconfigured to allow you to lock up to 16384 KiB of memory using the mlock() or mlockall() command. This should be enough for the application you want to run in this assignment as the application needs about 12 megabytes of memory (About 4 megabytes for the data buffers in samples.c and about 8 megabyte for the standard libraries that are required and a couple of kilobytes for everything in lab.c) However, it turns out that the standard stack size for a newly created thread is about 8 megabytes. That is, as soon as a new thread is created, the required memory size will exceed the maximum allowed limit.

However, it is possible to change the default stacksize for a newly allocated process by using the pthread_attr_setstacksize() function as seen in the lab skeleton.

You can test the first part of this lab (i.e., the division of maintask() into sampletask() and doworktask()) in any ISY computer lab. However, you need to be in Muxen 1 or 2 to set any real-time priorities.


Informationsansvarig: Kent Palmkvist
Senast uppdaterad: 2023-12-18