Menu

Home

Pharos Team
There is a newer version of this page. You can find it here.

Welcome to Pharos!

Pharos is a Real-Time Operating System designed for secure systems. This means that applications run in user mode and cannot access the memory space outside its limits (otherwise an exception will be triggered by the hardware MMU/MPU) and must execute within configurable time limits. See a quick presentation on https://www.slideshare.net/RTOSPharos/pharos-105989016
Pharos is available in open-source and under an Apache 2.0 license. This means that you can freely use on your public/private domain projects as you wish, free of cost.

We designed Pharos to provide to support mixed-criticality applications. In essence:

  • applications are divided into partitions
  • each partition contains a set of threads
  • threads run in user mode
  • partitions cannot access the memory area of each other (unless configured to be able to do so)
  • each thread can be configured to have a maximum execution time

In other words, you could have an airbag and infotainement systems running under the same CPU and Pharos will guarantee that the low critical systems interference with the highly critical is under your applications defined limits. For example, the infotainment code will not be able to corrupt the memory area of the airbag. Furthermore, the infotainment could have high priority threads (to provide quick user response) and still Pharos can ensure that the lower priority but highly critical airbag threads will run, no matter what the high priority threads code. We refer this feature as thread execution temporal monitoring.

Pharos divides the application into partitions, where each partition is composed by threads, semaphores, message queues, etc. Each partition threads can synchronize/communicate with each other using the standard OS features. Each thread can be:

  • periodic
  • sporadic
  • aperiodic

The periodic and sporadic threads have included a maximum time for each job to execute (should correspond to their WCET) and a deadline. If the thread attempts to take more time to execute, Pharos will notify the partition and stop the thread (and resume it when the period or the MIT as elapsed). If the thread deadline is reached, Pharos will call an error handler so that the application detects the fault.

While a periodic thread is easy to understand, a native support for a sporadic thread might be unknow to most users. Basically, a sporadic thread has the same propreties as a periodic thread except instead of a period it has a MIT (minimum inter-arrival time). A sporadic thread can be activated at any time by a Pharos event, semaphore, message queue, etc. But the thread will be executed respecting its MIT: there must be a minimum time interval between two consecutive activations of the thread. This is similar to a periodic thread instead of a fixed period, there is a minimum "period".
The application defines which type of sporadic thread it wants, based on events, message queues, semaphores, etc. The entry point of the thread corresponds to a function that executes a job (hence there is no need for an infinite loop inside periodic or sporadic threads). The sporadic thread function will receive an argument corresponding to its type. For example, if it is activated by a message queue, it will get a message sent; if it is activated by an event, it will get the event sent and so on.

Aperiodic threads, by definition, do not have a maximum time (WCET) nor a deadline. However, since Pharos 2.0.0, aperiodic threads can also have a WCET and an associated "period" by which the application can limit its execution time. That is, each aperiodic thread has a budget that is replenished at each period. If the thread tries to execute more budget than configured (more time than it is supposed to), Pharos will stop the thread until the next period.

Using this method the lower priority threads can have a garantee that the higher priority threads will relinquish the CPU and so they will have time to execute (as long as the application configured the maximum execution times of the higher priority threads appropriately).

A partition can also communicate and synchronize with other partitions through:

  • message queue - data is copied from one partition to another (slow for big messages)
  • channel - data is sent from one partition to another simply by managing the MMU/MPU (very fast for big messages)
  • resource - used to ensure mutual exclusion. Uses internally a semaphore with priority ceiling algorithm and the calling thread can only execute the mutual exclusion code if it has enough time to fully complete it.

One inovation that Pharos brings (to the best of our knowledge) is the introduction of filters for inter-partition objects. Inter-partition objects are not new themselves, but the way Pharos implements them and the way the application can use them is new (to the best of our knowledge). This mechanism is needed in multiple applications that have a resource (in the abstract sense of the word) that is used by multiple partitions but must be controlled. For example, a CAN driver can be used to transmit/receive messages from any partition. However, it should not be overloaded with messages from a faulty partition. Pharos introduces a filter function that is invoked before the message is transmitted (to the message queue or channel) or the resource accessed. It is run in the context of the calling thread but with memory permissions and stack of the partition being invoked. For example, suppose partitions A, B and C can send messages to a message queue of partition Z, but partition D cannot send messages to this queue. The code executed in filter for the message queue will have the same memory permissions as partition Z and will run with a stack in partition Z. However Pharos will still account for the time taken in executing the filter to the calling thread. This means that a faulty thread can only damage its own execution time and this will have no impact on partition Z (or any other partition). In this case, the filter code that will check if the message being sent is from partition D and if so, rejects it. The application is free to create more complex filters, such as limit the number of messages per second being sent, reject messages if the CAN queue is approaching its limits, etc.

Multicore is supported in AMP fashion on the ARM Cortex-A53 (raspberry pi 3). This means that each core can be viewed as running its own separate Pharos. Partitions are allocated to one core, including its threads, semaphores, queues, etc. There can be no inter-core communication through Pharos and the only way for one core to communicate with another is through the shared memory (there are some thoughts to increase the multicore functionality, stay tuned).

Version 1.6.0 has just been released with a port to STM32F469I-DISCO (https://www.st.com/en/evaluation-tools/32f469idiscovery.html). This board from ST has a STM32F469NIH6 CPU, running at 180 MHz, 64 KiB CCM SRAM (extremely fast SRAM), 320 KiB SRAM, 4 KiB Backup SRAM, 128 Mbit SDRAM, 2 MiB Flash and more. This is the first port that Pharos is ported to that has more than one type of memory. Pharos has been extended in such a way that an application can easily select the memory type where it wants part (or all) of its memory.

The full list of currently supported CPUs is:

  • ARM926EJ-S (armv5)
  • Cortex-R5 (armv7-R)
  • Cortex-M4 (armv7-M)
  • Cortex-A53 (armv8-A)

Pharos is a quite recent RTOS, hence common features (such as TCP/IP) and CPU ports (e.g. RISC-V x86, PowerPC, SPARC) will still need to be performed. However, it is throughly tested (> 120 KLOC of tests) and follows a strict quality procedure.

The next release (3.2.0) is focusing on preparing the Pharos API to in the future, support the ARINC 653 APEX API.

Support is available. Please make use of the Ticket system if you found a bug, use the Discussions to place questions or contact us at rtos.pharos@outlook.com.

Project Members:


MongoDB Logo MongoDB