Assignment A: Coding Schedulers
In this assignment you will be implementing and testing several schedulers for a real-time system on actual hardware (STM32F4DISCOVERY).
You will use Zephyr RTOS to implement RM (rate-monotonic), EDF (earliest-deadline-first) and FP (fixed priority) aperiodic schedulers. RM, EDF and FP servers are scheduling algorithms discussed in the Lecture 5, Lecture 6, and Lecture 9 respectively. In this assignment you will put this theory into practice. The resulting schedules must then be plotted and analyzed by using a logic analyzer.
Learning Objectives
Considering the learning objectives of the course, this assignment (partially) focuses on the following:
- Discuss advantages and disadvantages of different scheduling policies for a given platform or system
- Identify (reverse engineer) parameters of a scheduling scheme or a task set from output traces of the system
- Evaluate the scheduling overheads of a given implementation (in the lab)
- Implement event-based scheduling policies on a given microcontroller (in the lab)
Submission Information
Deadline: 7th December 2024 23:59 (week 4)
The assignment is submitted by pushing to the main
branch of this repository.
The last commit before the deadline will be considered your submission.
We recommend frequently committing in order to prevent losing progression. Please note that you cannot directly commit to the main branch. You need to make a merge request between a different branch and main.
The report should be submitted as a .pdf
, in the root of the main branch your GitLab repository. Use a maximum of 6 pages for your report (A4, standard font size, single-column, including images). The filename should be formatted as: assignment_a_report_group_X.pdf
where X
is your group number. Inside the report you should specify your names and student numbers. Use the following template for the report: RTS_assignment-a-template
Following your assignment's submission, the TAs might conduct oral checks about the assignment. For example, you might be asked to change parts of the code or explain the report. There will be a follow up announcement with more information.
Using the console
For this assignment, you can use the built-in Zephyr console and use Zephyr's printk
that works exactly the same way as printf
from the standard C library. Ensure that printk
is not called in a interrupt routine, it can cause unpredicted behaviour.
When you want to debug, you just have to uncomment the CONSOLE_ENABLED
macro in main.c
. Be aware that initialization will block untill you don't connect the computer to the console.
WARNING: The use of print statements will mess up the scheduling timings. When measuring with the logic analyzer, be sure that you don't call any print statement.
Assignment questions
I. Understanding the System
Let's take a look at the system you will be working with for this assignment. The scheduler functions are found in scheduler.c
. It is already set up with a simple
scheduler example
and a task set tasks
in main.c
. New tasks can be added to the schedule by using the spawn_task
function which takes an execution time (ms), period (ms) and a GPIO pin. This task should execute for the given time
every period, during which it sets the pin to high. The available pins are listed in gpio.h
.
-
(2 points) Is the
example
scheduler a real-time scheduler? Justify your answer. -
(1 points) Calculate the hyper-period of
TASK_SET_1
inmain.c
. -
(2 points) Design two new non-trivial task sets with at least 3 tasks with a maximum hyper-period of 120ms.
- One with a processor utilization factor of 1 -
TASK_SET_2
- One with a processor utilization factor over 1 -
TASK_SET_3
Calculate and report the processor utilization factors for both task sets and document these in your report. Note that you will be using these later on in the assignment, so do not make them too difficult.
- One with a processor utilization factor of 1 -
Clarification: Non-trivial task set is a task set where all tasks have an execution time greater than 1 ms, and there are no repeated tasks: tasks with the same period and execution time.
Your main.c should resemble this snippet:
#ifdef TASK_SET_1
//Task set provided
#elifdef TASK_SET_2
//Non-trivial task set, U = 1
#elifdef TASK_SET_3
//Non-trivial task set, U > 1
#elifdef APERIODIC_TASKS
// Periodic task set provided in question IV
// Aperiodic tasks you define based on the requirements in question IV
#endif
You can switch which task set is active by changing #define TASK_SET_1
(at the top of the file) to the task set of your choice. I.e. #define TASK_SET_2
for task set 2 and #define TASK_SET_3
for task set 3
Important:
- At any point in time, only one of these defines must be present
- Note that the code supports a maximum of 8 tasks.
II. Implementing a Rate Monotonic Scheduler
In scheduler.c
, implement a rate monotonic scheduler in the rate_monotonic
function. The scheduling algorithm should
schedule the first pending task with the shortest period.
Some points about helping you implement this:
- To select the scheduler, change the
SchedulerType
argument passed to therun_scheduler()
function. - The
rate_monotonic
function should select the next task to be executed based on the scheduling algorithm, which in this case is the first pending task with the shortest period, this is done with theset_active_task
function. When there are no pending tasks,set_idle
needs to be called. - The
rate_monotonic
function is invoked when a task is finished or when it has delayed itself. It should delay itself until a higher priority task is ready (preemption of the current running task) or until there is a task ready to be scheduled when there were no tasks running. This delay should be calculated and ak_timeout_t
struct containing the delay time needs to be returned. Learn more about kernel timing here: Kernel Timing. Some of the functions/macros that you might find useful areK_MSEC
,K_USEC
,sys_timepoint_calc
,sys_timepoint_timeout
andk_uptime_get
. - For the following questions you are expected to add fields to the
Task
struct given inscheduler_impl.h
in order for you to make a rate monotonic scheduler. - Check the Zephyr kernel API reference for more information. We recommend looking at the pages about the threads and system_clock APIs.
- (12 points) Implement a rate monotonic scheduler in the function
rate_monotonic
inscheduler.c
. Briefly explain how it works and mention what fields you added to theTask
struct. Report the output of the logic analyzer for the given task set inmain.c
. Verify that the scheduler works correctly. - (4 points) Measure the overhead of your RM scheduler with the given task set in
main.c
and calculate the percentage of the hyperperiod that is spent on this overhead. What actions does the scheduler need to do during this time? - (5 points) Explain what overloading is and how your rate monotonic scheduler handles it. Use the given task set in
main.c
with a processor utilization < 1, and the two task sets that you made in question 3 (U = 1 and U > 1). Compare and report how the task sets with their different utilizations (U < 1, U > 1) behave. Now use the task set with U = 1. How does this task set's behaviour differ from what is expected in theory?
Clarification: You dont need to handle over-load just continue running the algorithm. We want you to analyse what happens when the scheduler is over-loaded
III. Implementing an Earliest Deadline First Scheduler
In scheduler.c
, implement the earliest deadline first scheduler in the earliest_deadline_first
function.
This scheduling algorithm should schedule the first pending task with the earliest nearing deadline.
Similar points about implementing this:
- Change the
schedule
function to call theearliest_deadline_first
scheduler. The function should perform similar actions as described in therate_monotonic
function, but it should schedule with the EDF algorithm. - Add necessary fields to the
Task
struct in order for you to make an earliest deadline first scheduler. - Use the
set_active_task
function to select the task to execute. In this case that should be the first pending task with the earliest nearing deadline.
- (10 points) Implement an earliest deadline first scheduler in the function
earliest_deadline_first
inscheduler.c
. Briefly explain how it works and mention what fields you added to theTask
struct. Report the output of the logic analyzer for the given task set inmain.c
. Verify that the scheduler works correctly. - (4 points) How does your EDF scheduler handle overloading? Is this better or worse than RM? Discuss. Perform the same analysis like you did in question 6.
IV. Implement Fixed Priority Servers
Fixed Priority Servers are scheduling algorithms for hybrid task-set with both periodic tasks and aperiodic jobs. In this section you will be designing 3 aperiodic jobs with varing periods. These jobs will be mapped to the switches SW 1
, SW 2
and SW 3
and will spawn when you press the user_button
on the board. Once you have the 3 aperiodic jobs you will implement 2 scheduling schemes, using your EDF implementation, implemented in Question 7.
For the periodic tasks, use the below task-set with your EDF implementation.
Task | Execution Time (ms) | Period (ms) |
---|---|---|
Task1 | 2 | 20 |
Task2 | 10 | 40 |
Task3 | 20 | 60 |
-
(6 points) Schedule it Immediately: Aperiodic Jobs have the highest priority.
- Design 3 jobs that satisfy below requirements. Justify how the jobs satisfies the requirements in the report:
- Job should never make a periodic task miss it's deadline, regardless of when it is spawned.
- Job should always make atleast 1 periodic task miss it's deadline in a hyper-period.
- Write a scheduler to implement this algorithm.
- Note: Aperiodic tasks have highest priority when the scheduler is called, not when they spawn.
- Calculate the
Response time
for all the jobs, when all the periodic tasks and the job spawn at the same time. - Detect when a periodic task misses it's deadline, set the Orange LED (
D7
/leds[8]
) when a deadline is missed.
- Design 3 jobs that satisfy below requirements. Justify how the jobs satisfies the requirements in the report:
-
(4 points) Background Scheduling: Any spawned aperiodic job has the least priority.
- Write a scheduler with this algorithm using the jobs create in
Question 9
- Calculate the
Response time
for all the jobs, when all the periodic tasks and the job spawn at the same time. - Between the 2 algorithms when are the aperiodic jobs preempted and why?
- Give 2 examples where you would use
Schedule it Immediately
and when you would useBackground Scheduling
with justification.
- Write a scheduler with this algorithm using the jobs create in