Des Autom Embed Syst (2006) 10:209–227 DOI 10.1007/s10617-006-9725-1
RTOS modeling in SystemC for real-time embedded SW simulation: A POSIX model H. Posadas · J. A. Adamez · E. Villar · F. Blasco · F. Escuder
C
Springer Science + Business Media, LLC 2006
Abstract SystemC is committed to support the requirements for an integrated, HW/SW codesign flow, thus allowing the development of complex, multiprocessing, Systems-on Chip (MpSoC). To make this possible, efficient modeling and simulation methodologies for RealTime, Embedded (RT/E) SW in SystemC have to be developed, so that the designer can verify and refine the application SW together with the rest of the elements of the platform. Accurate modeling of the application SW requires an accurate model of the RTOS. Nevertheless, low-level, dynamic timing characteristics of the RTOS such as time-slicing, priority-based preemptive scheduling, interrupts and exceptions do not have a direct implementation in SystemC. In this paper, techniques are proposed to accurately model the detailed RTOS functionality on top of the SystemC execution kernel. The model allows timed-simulation and refinement of the RT/E SW code in SystemC. The simulation technology has been applied to the development of a high-level, POSIX simulation library in SystemC. The library allows the designer a fast, sufficiently accurate, timed simulation of the application SW running on top of POSIX. As most current RTOSs support this standard, the library is portable to different development frameworks. The library provides the required infrastructure for a complete, H. Posadas () . J. A. Adamez . E. Villar TEISA Department, E.T.S.I. Industriales y Telecom, University of Cantabria, Avda. Los Castros s/n, 39005 Santander, Spain e-mail:
[email protected] J. A. Adamez e-mail:
[email protected] E. Villar e-mail:
[email protected] F. Blasco . F. Escuder DS2, Robert Darwin 2, Parque Tecnol´ogico, Paterna, Spain e-mail:
[email protected] F. Escuder e-mail:
[email protected] Springer
210
H. Posadas et al.
multiprocessing, HW/SW co-simulation environment at different abstraction levels using SystemC. Keywords SystemC . Performance analysis . Embedded software . RTOS . POSIX
1 Introduction Microelectronic technology improvement towards increasingly complex Systems-on-Chip (SoC) demands a parallel improvement in the corresponding design technologies. Among the different cost components, embedded software development can account for 80% of embedded-system development costs [15]. In this context, there is a clear need for new methodologies improving the design efficiency of RT/E SW on complex Systems-on Chip (SoC) platforms. Moreover, currently, the SoC is routinely multiprocessor (MpSoC), containing several microprocessors and DSPs running different RT/E SW functions [17]. RT/E SW on MpSoC has a stronger interaction with the rest of the system and harder constraints (cost, timing, power, etc.) than SW on general-purpose platforms. Thus, specific SW development tools are required [16]. SystemC is a standard C++ class library that has proven to be an effective framework for complex system design [13, 20]. SystemC provides the HW and SW design teams with a common framework to develop an executable specification of the system. Transaction-Level Modeling (TLM) in SystemC has become a widely-used standard in industrial embedded system design flows [8]. Although the language has proven to support efficient generation of the embedded SW including interface drivers and the RTOS [11], the SystemC kernel does not support direct simulation of many RTOS concurrency and synchronization features such as time-slicing and priority-based preemption. As a consequence, it is essential to improve the modeling capability of embedded SW in SystemC with appropriate libraries, so that the designer can execute and optimize the application SW together with the rest of the elements of the platform [21]. Accurate modeling of the application SW requires an accurate model of the RTOS [9, 10, 12, 22, 24, 26–28,]. RTOS modeling must take into account the timing characteristics of the RTOS dynamic behavior (time-slicing, preemption, priority-based scheduling, timers, etc.). System specification languages such as SpecC [7] or SystemC [10, 22, 28] have proven to provide a useful HW/SW co-simulation platform. Nevertheless, the use of these languages requires an adequate use of the underlying simulation kernel in order to correctly model the task scheduling policies implemented by the RTOS. Moreover, the detailed modeling of the temporal behavior of the RTOS requires the integration of a dynamic SW execution time estimation technique [23, 24]. In this paper, the application of SystemC to model the RT/E SW taking into account the detailed RTOS dynamic features is discussed. Techniques to accurately model the RTOS functionality on-top of the SystemC execution kernel are proposed. This model allows timed simulation and refinement of the embedded SW code in SystemC. This makes it possible to cosimulate SW and HW components efficiently over the same simulation kernel. The simulation technology has been applied to the development of a high-level, POSIX simulation library in SystemC. The library allows the designer a fast, sufficiently accurate, timed simulation of the application SW running on top of POSIX [14]. As most current RTOSs support this standard, the library is portable to different development frameworks. The library provides the required infrastructure for a complete, multiprocessing, HW/SW co-simulation environment at different abstraction levels using SystemC. Springer
RTOS modeling in SystemC for real-time embedded SW simulation: A POSIX model
211
The structure of the paper is as follows. In the next section, an analysis of the state of the art is done to highlight the contribution of the paper. In Section 3, the application of SystemC for RTOS modeling is presented. The dynamic, time annotation technique required for the modeling of the detailed RTOS dynamic features is discussed in Section 4. In Section 5, the extension of the proposed methodology to HW/SW co-simulation is briefly discussed. Then, in Section 6, the application of the RTOS modeling technology to POSIX simulation is described. Experimental results are provided in Section 7. In Section 8, the main conclusions of the work are presented. Finally, the forecast future work is outlined. 2 Related work Most RTOS vendors provide a simulator of their OS as part of the SW development kit. The RTOS simulator allows development and emulation of the application code on the host without having to develop the actual SW (and HW) prototypes [1, 5]. As the simulation relies on the host operating system scheduling it cannot be timing accurate. The simulation is untimed. Moreover, commercial RTOS simulators are based on proprietary languages and do not support HW/SW co-simulation. RT level co-simulation including the microprocessors running the application code in memory can ensure, with a high degree of reliability, the correctness of the design [3]. Nevertheless, it is unfeasible for design refinement of complex systems due to its excessive host execution time. SW simulation using cycle-accurate Instruction-Set Simulators (ISS) only alleviates the problem. Most of the currently available co-simulation commercial tools are based on this technology. SystemC has been used to develop multiprocessor, co-simulation frameworks [2, 27]. Fast HW/SW co-simulation can be achieved by directly executing the code in an adequate SW-HDL co-simulation environment. C-VHDL (or Verilog) environments can be developed [18]. Most commercial HDL simulators support the execution of external C functions for this purpose. Nevertheless, using this approach the SW execution time is very difficult to model. In most cases, a fixed amount of time is allocated to each SW call. In many cases, the SW is considered to be executed in zero-time. On the other hand, SystemC has been used for very abstract modeling of the RTOS. The system is conceived as a collection of tasks and the model allows analysis of the effect of a certain scheduling policy. The functionality is not exercised [19]. Achieving both fast HW/SW co-simulation and enough accuracy requires SW simulation running on a model of the RTOS in a system-level language (SLL) such as SpecC [7, 26] or SystemC [9, 10, 22]. SLLs provide the required co-simulation framework and, at the same time, allow abstraction of the RTOS. These techniques can be applied as soon as the application code is available, avoiding costly design iterations. Of course, the improvement in execution time comes at the cost of lower accuracy. Several approaches have been proposed. The RTOS model can use specific APIs including the most important functions found in any RTOS [7, 10], wrappers [28] or an implementation-specific model of each channel [22]. As none of these techniques use the functions of any specific RTOS, the simulation methodology does not directly support the refinement of the original specification into compilable code except by the inclusion of the RTOS model itself in the loop [7]. Moreover, the code has to be modified with specific RTOS modeling functions in order to simulate the application code using the RTOS [7, 28]. Reuse of legacy code or COTS components is not possible if this external code makes use of RTOS functions. Only by direct modeling of a specific RTOS is it possible to use the same code for both simulation and implementation. As a consequence, refinement is made easier [9, 12, 24]. Springer
212
H. Posadas et al.
Timed simulation of the application code including the RTOS is made possible by introducing ‘wait’ statements [7, 9, 10, 12, 22, 26–28]. High accuracy can only be achieved by diminishing the granularity, which requires increasing the number of ‘wait’ statements introduced. Nevertheless, as the ‘wait’ statements are introduced at certain static predetermined points, low-level dynamic timing characteristics of the RTOS such as time-slicing, preemptive scheduling, interrupts and exceptions are very difficult to model. Adding the time the task has been preempted by the RTOS kernel to the estimated time in each wait statement would correctly set the finishing time of the corresponding piece of code [10]. However, asynchronous communications such as accesses to peripherals and global variables would be modeled incorrectly [23, 24]. A SystemC library called PERFidy was developed for system-level, timed simulation and performance analysis. The execution time estimation is carried out dynamically at the same time as the timed simulation, thus avoiding any additional design step [22]. An extension of the timed-simulation methodology used in PERFidy was proposed in order to allow the timed simulation of the embedded SW in SystemC including the effects of the RTOS [23, 24]. Although the SystemC 2.0 simulation kernel executes processes following a non-preemptive scheduling policy without priorities, the proposed simulation methodology is able to model preemption as well as different scheduling policies based on priorities. The place in the application code where the task (process or thread) has to be preempted can be dynamically decided based on the detailed estimation of the SW execution time provided by PERFidy. As a consequence, the low-level, dynamic characteristics of the RTOS can be efficiently modeled. Nevertheless, the RTOS simulation methodology proposed could integrate any dynamic execution time estimation technique. In order to ensure independence from any specific RTOS, the simulation methodology supports POSIX, thus ensuring wide portability. In this way, the proposed extension, called PERFidiX (http://www.teisa.unican.es/perfidix) supports very early performance analysis of the system specification as well as the impact of the decisions taken during the refinement-based design methodology shown in Fig. 1. Integration of legacy code and/or COTS components using POSIX functions is also supported [24].
Fig. 1 Refinement-based, system design methodology Springer
RTOS modeling in SystemC for real-time embedded SW simulation: A POSIX model Fig. 2 Proposed RTOS model structure
213
Application SW Task 1
...
Task n
Specific API
RTOS model Specific API implementation Generic RTOS kernel model TIME MANAGER
Time Estimation Tool
SystemC
Based on previous work, in this paper, a general analysis of the actual capabilities of SystemC for accurate modeling and timed simulation of the embedded SW running on a certain platform is presented. Static insertion of wait statements in the code used in previously proposed techniques presents the limitations commented above. Accurate modeling of the RTOS effects requires overcoming these limitations. To achieve this goal, a dynamic execution time estimation technique is needed. The technique used in this paper is PERFidy. Details of the implementation of the proposed RTOS modeling approach in a POSIX API model are provided showing it feasibility. The corresponding SystemC library and user interface, PERFidiX, is described.
3 RTOS modeling in SystemC To make the RTOS model as general as possible, the structure shown in Fig. 2 is proposed. The model is developed in two different parts. The lowest part is a generic RTOS kernel model that provides the general features required to model any specific RTOS. Over this kernel, the implementations of the particular RTOS features and the API functions have been carried out. Nevertheless, the kernel model is open and can support any other RTOS API functions. However, as it has been pointed out above, the implementation of the detailed timing RTOS features is not possible without dynamic time information. Therefore, the time manager between the underlying SystemC kernel and the RTOS model shown in Fig. 2 is required. This manager transforms the untimed SW simulation into a timed simulation, and provides the RTOS model with the required timing information. The time manager requires an external time estimation tool to operate properly. In this work, the PERFidy [22] technology has been used. Nevertheless, any other dynamic estimation technique could be used. 3.1 RTOS model implementation To model the RTOS services three methods have been found. The first method uses the underlying host OS functions. These features are basically those that do not interfere with the RTOS kernel. Mathematical functions, string management, etc., do not produce scheduling, communication or synchronization effects. Thus, the functions of the underlying host RTOS Springer
214
H. Posadas et al.
can be used to model them. To include the timing cost, these functions will be wrapped into new functions that will consider the time the function will take in the final processor. The second method is to model the corresponding functionality over the SystemC kernel. This method has to be used for most of the RTOS features. Parallelism, scheduling, communication, synchronization and timing features require a complete implementation over SystemC [23]. It is important to note that the “pthread” library of the host OS (e.g. Linux) cannot be used to simulate the scheduling characteristics of the SW components in SystemC. SC THREADs are the SystemC features used to model concurrency. Every SW task can be modeled with an independent SC THREAD. The SystemC kernel can use the pthreads of the underlying OS to model the SC THREADs. However, the characteristics of the simulated tasks cannot be modeled using the host pthread characteristics. For instance, two host threads are never ready at the same time in a SystemC simulation. The kernel decides which thread runs and, when it stops, decides the next running thread. Thus, host OS scheduling capabilities have no effect and synchronization facilities cannot be used. The decision about which thread to run next does not depend on the OS pthread characteristics, it depends only on the information managed by the SystemC kernel. Furthermore, if a host thread is blocked, the whole simulation is blocked indefinitely. That is because the kernel only resumes another thread when the current one is stopped in a SystemC blocking function, not in an OS function (e.g. a pthread mutex). Another reason is that underlying OS timing facilities (timeouts, sleeps, . . . ) depend on the simulation time, not on the execution time expected on the target platform. Finally, those RTOS features that are strongly platform dependent form the last group. These features use the HW drivers and require their code to be simulated. Thus, they cannot be provided in a generic way, and, as a consequence, they will not be covered in this work. 3.2 Generic RTOS kernel model In order to ensure generality, the development of a generic RTOS kernel model is required. This kernel model has to provide all the underlying features needed to emulate the API functions of most of the RTOSs commonly used. The first element that the generic RTOS model has to provide is a method to provide concurrency. In general, RT/E SW implies several execution flows. They will be called tasks in the following. Tasks will be modeled using the SystemC SC THREAD macro. The next RTOS feature to be modeled is the scheduling policy of the concurrent tasks. Although SystemC provides concurrency capabilities, it does not provide scheduling features. There is no way to control the execution order of the tasks. The simulation kernel decides this without considering any external indication. To solve this problem all tasks are blocked. Then, the RTOS scheduler decides each time which task has to execute (one for each microprocessor in the target platform), and unblocks it. As a consequence, the RTOS model controls the process execution order. To do that, the generic RTOS kernel model is based on defining seven different states for each execution flow (Fig. 3). This graph is similar to the graph commonly used in UNIX systems. The seven states are: – User (U): It executes the user code. – SuperUser (SU): It executes in kernel mode. The code executed is an operating system function or an interrupt handler. This state is required to model some RTOSs in which the execution mode has to be known. Furthermore, the time annotation technique proposed below uses it. Springer
RTOS modeling in SystemC for real-time embedded SW simulation: A POSIX model
215
User mode Interruptions and System calls
SuperUser mode
Zombie
Blocked
Scheduler execution and context switch (optional)
Waiting
Ready
Created
Process scheduled
Fig. 3 States of a task and the possible transitions
– Waiting (W): It is ready to execute in User mode but it does not have the processor. It is reached when the task returns from SU state but another task with higher priority has been resumed and takes the processor. Then the previous task waits for the processor in this state. – Blocked (B): It is blocked in an operating system call. – Ready (R): It is ready to continue the execution of an operating system routine. – Zombie (Z): The task has died but its associated data may be required by another task, so the resources cannot be released. – Created (C): It has been created but it is not in the Ready state yet. The possible transitions between states are shown in the diagram in Fig. 3. The current task executes the scheduler when it moves from SuperUser state to another state. A new scheduler call is required when a task goes to the Zombie state (it finishes), to the Blocked state, or to the Waiting state. In fact, the scheduler is a function that decides which among all tasks in ready or waiting state (ready and waiting for the processor) has the highest priority. If there is more than one task with the same priority, the first one in the list is selected. Furthermore, to model it in a generic way, a two-level scheduler is required. Control flows (threads) can be divided in groups to compete for the processor with the rest of the groups of the system. Once the first scheduler has decided which group will take the processor, the second scheduler decides which thread of this group will execute. This can be used, for example, to model the POSIX “process scope” feature. The scheduling model has to implement the procedure deciding when the current task releases the processor. Two options are possible. The first option is that the task only releases the processor at system calls or interruptions. The case of system calls is resolved internally in the system call code changing the task state. However, interruptions have to be considered together with time annotations and will be controlled within the time manager (Section 4). The other possibility for releasing the processor is that the current task itself decides to do it Springer
216
H. Posadas et al.
in the middle of the user code. This can be done by defining a time slice that limits the time the task can use the processor. This also depends on the time manager (Section 4). It is interesting to note that a blocked task can only be resumed when the current task is in SuperUser state. To continue the user code execution, the current task goes through Waiting state and then the scheduler is executed. Thus, preemption is tackled automatically. The last element modeled is the tic-timer. The tic-timer is modeled using a specific SC THREAD. This thread is implemented as an infinite loop. For each iteration, first, there is a “wait” statement that models the tic-timer period. When the wait returns, it means that an interruption occurs. In fact, not only periodic tic-timers can be modeled. The period value can be modified dynamically. An execution time cost can be assigned to these interruptions to model their effect in the target platform. Although the tic-timer can be modeled by simply using the SC THREADs of the system tasks, when all tasks are blocked, it would be difficult to decide the SystemC thread that has to manage the tic-timer interruption. Furthermore, modeling the tic-timer with a specific SC THREAD gives higher flexibility. This flexibility is required to ensure the generality of the RTOS kernel model. Depending on this tic-timer, the system clock has been defined. This clock updates its value each time the interruption raises. From this clock new clocks can be created. Two methods have been defined to create new clocks. New clocks can be created defining initial values. The original clock starts with zero value. New clocks can also be created assigning a condition to update the clock value in the tic-timer interruptions. Depending on these clocks, timers can be defined. These timers execute a user-defined function when the corresponding clock reaches a specified value. 3.3 Modeling of specific RTOS features Modeling of a specific RTOS can use the task states and scheduling capabilities proposed above. In fact, most RTOS functions are based on task state transitions. The first transition, between User and SuperUser mode, is done automatically at system calls and interruptions. System calls are specified in SW code, but modeling external interruptions requires specific annotation techniques. Hence, interruptions will be presented in Section 4. At system calls, the first operation of the RTOS API functions is to change the state from User to SuperUser. The last operation is to move the state from SuperUser to Waiting state. During the system call, the task can also be blocked or finished by simply calling the function to move the current task from SuperUser state to Blocked or Zombie state. This allows the modeling of all blocking channels, sleeps, signals, timeouts, and rest of the RTOS elements that modify the task states. Every feature that wants to unblock a blocked task can do so by calling the RTOS kernel function to change the target task from Blocked to Ready state. To model the specific target RTOS scheduler, the capabilities of the generic model can be used. This requires two parts: defining the task selection method and the processor release procedure. First, the method by which the scheduler decides the task that will take the processor has to be modeled. The generic kernel selection model is based on priorities and the order in the ready list. Thus, monitoring the priorities assigned to each task and monitoring when each task is inserted in the ready list, every selection method can be modeled. Therefore, different scheduling policies can be modeled. For example, to model an “Earliest Deadline First (EDF)” policy, the task priority values have to depend on the deadline of each task at that moment. Furthermore, the exit procedure has to be monitored. Common RTOS scheduling policies only voluntarily deliver the control to the OS when they depend on time slices, such Springer
RTOS modeling in SystemC for real-time embedded SW simulation: A POSIX model
217
as Round-Robin or Sporadic-Server policies. The time slice technique is modeled on the generic RTOS kernel model. Thus, defining the correct time slice interval, these policies can be modeled. Summarizing, only three basic SystemC elements are required to model the RTOS. The SC THREAD macro is used to model concurrency. Scheduling, communication and synchronization are controlled with the “wait” and “notify” SystemC functions inside the RTOS system calls. As a result, SystemC simulation models a RTOS without requiring any modification of the original SystemC library. This characteristic means the RTOS modeling library is very portable among different SystemC implementations and compatible with future versions of the SystemC standard.
4 Time annotation in RTOS modeling As commented above, a time manager has to be inserted between the RTOS model and the SystemC kernel to obtain a timed simulation. This model receives the time estimation tool information and places the adequate “wait” calls to annotate the time, at the same time as providing the RTOS model with the facilities it requires for RTOS timing management. 4.1 Timed simulation granularity To perform an exact timed simulation, a “wait” statement with the corresponding exact platform execution time would need to be placed next to each instruction. However, this produces very slow simulations because the SystemC scheduler runs once for each source code instruction executed. In order to improve the simulation efficiency, the time manager execution has to be based on the division of the source code into larger pieces called “segments”. During segment simulation, execution time can be estimated. These results are used in this work to annotate the complete segment execution time in the SystemC simulation. Thus, execution time estimations are used to model SW in a timed simulation. To obtain a correct simulation, one segment has to be the fragment of code executed in a single User state stage. With this definition, communication points are controlled. If only one task executes from the segment start time to the segment end, the communication order in that segment only depends on the order of communication instructions at the source code. Thus, during the segment execution, the timed SW model is correct because the communication instruction order is maintained. When dealing with a set of concurrent tasks, the execution order of segments in each task has to be controlled. If simulation order is the same as in target platform execution, simulation would be correct. Thus, adequately modeling synchronization, SW timed simulation can be used for refining the system-level code to obtain a correct SW component. The result is that there is no difference between placing a “wait” statement for each instruction and placing only one “wait” at the end of the segment with the total amount of execution time. Thus, the SystemC kernel is executed only once for each segment. As a result, this solution is much more efficient than using multiple waits because the overhead produced is much lower. However, this segment definition is hard to use because during source code execution it is not always possible to know when the task should change its state. For instance, as a consequence of an external interrupt. Thus, a new concept of segment is required. In the original definition a segment finishes when a task moves to SuperUser state. This means that it finishes at system calls and interruptions. Interruptions are difficult to manage during code simulation. However, system calls are part of the source code and so are automatically Springer
218
H. Posadas et al.
managed. Thus, the segment can be initially redefined as each piece of code between two consecutive system calls. Therefore, only preemption caused by interruptions requires specific management. The simulation will be correct if interruptions are also adequately modeled. Interruptions cause automatic changes in the current task execution state. Current task state changes from User to SuperUser. Thus, to continue the execution of the user code, the task has to be re-scheduled. The consequence is that due to interruptions, preemptions can occur and the task execution order is modified. However, the most important consequence is that the access order to global variables from the preemptor and preempted tasks can be modified. Thus, functional results can be wrong. Summarizing, the code is executed in segments. To simulate a segment, it is executed and, at the same time, the corresponding execution time has to be estimated. To obtain the execution time estimations any dynamic estimation tool can be used. Nevertheless, a tool that does not require manual modification in the source code is recommended to maintain the original code. In this work, PERFidy has been used. This tool automatically substitutes the original C data types by C++ classes, where each operator is overloaded. These overloaded operators have the same functionality and, in addition, perform the time estimation taking into account the estimated cost of the corresponding operation. The segment is finished in two ways: with a time limit and until the next system call or communication point. That is, when the current segment reaches the execution time limit, or a system call is executed the segment is finished. The method used is explained in more detailed in the next section. 4.2 Using segments for timed SW simulation During user code execution the estimation tool calculates the estimated total time cost of the current segment. To do this, the simulation tool adds the execution time cost of each executed instruction to the time cost of the previous instructions. Furthermore, at each instruction, the tool sends this time cost to the time manager. When the current task makes a system call and moves to SuperUser state, the RTOS model informs the time manager that the current segment has finished. Then, the time manager annotates the estimation provided by the estimation tool with a SystemC “wait” statement. Finally, when the “wait” function returns, the time manager returns the control to the RTOS model and the system call functionality is executed. The time cost of the function call is also annotated adding it to the segment time estimation. This solution produces exact simulations if there are no interruptions. To model interruptions correctly, tic-timer and HW component interruptions have to be managed. Tic-timer interruptions are predictable, and thus can be tackled considering the simulation time. However, HW interruptions require the use of a special annotation technique. The proposed solution can be explained better with a simple example (see Fig. 4). In this example there are two SW tasks. The first task contains the computation and the second task is in charge of communications with HW components. In fact, task 2 waits for HW interruptions to load HW information. If the interruptions are not produced before a variable amount of time a timeout expires and new values are generated by default. For communication between these two tasks, a global variable is used. At the beginning of the simulation, task 2 is blocked waiting for a HW interruption with a 25-μs timeout. Thus, task 1 starts. At 25 μs the timeout expires and task 2 executes and stores a value in the global variable. Once task 2 is blocked again waiting for a HW interruption, task 1 continues. At T = 65 μs, an external interruption raises, and task 2 Springer
RTOS modeling in SystemC for real-time embedded SW simulation: A POSIX model
219
Fig. 4 Common timed simulation and Tic-timer management
executes. After that, task 2 is blocked again and task 1 continues. The complete execution of task 1 is estimated to require 75 μs in the target platform, and each execution of task 2 takes 10 μs. As proposed before, the segment is estimated, and then, annotated. However, HW interruption always raises during the time annotation (the “wait” function call). This means that the segment has already been completely executed, but it should be stopped at the interruption. In fact the task can be preempted and, as a result, the last part of the segment may have been simulated in an incorrect time. The interrupt management and a possible preemption cannot be simulated until the “wait” function returns. To solve this problem, first, predictable interruptions should be analyzed. In some cases, such as the Tic-Timer interruption, it is well known when the interruption is going to raise. Then, the remaining time until the next interruption raises can be calculated at the beginning of each segment by the time manager. Thus, the time manager can predict the interruption and automatically finish and annotate the current segment. With this solution, “timers”, “timeouts” or “sleeps” can be correctly modeled, as shown in Fig. 4. This solution is also used to model policies that define time slices. In this case, the RTOS model informs the time manager that the current segment has to finish when the time slice ends. When the estimation tool detects that the time limit has been reached, a wait statement has to be automatically executed. To do that, a dynamic estimation tool has to be used. It has to estimate the execution time of the instructions at the same time they are executed. In this way, the execution time of the current instruction is added to the total segment execution time and, when the limit is exceeded, the wait statement is executed. However, for non-predictable interruptions the solution is more complex. The current segment has to be divided when an interruption is raised, but it has been executed before annotation. To model it correctly, two considerations are required: the wait functions have to follow the real execution and the access order to global variables has to be ensured. The proposed solution is to execute the complete segment, estimate its cost and make the Springer
220
H. Posadas et al.
annotations in two steps: one until the interruption and the rest when the task is re-scheduled after the interruption. First, the “wait” function used to annotate the code is modified. When an external event is received, the wait call is interrupted. The model calculates the amount of time that is left to annotate it in the second step. Then, it changes the task state to SuperUser mode to execute the interrupt handler. Once the interrupt handler finishes, the state is changed to Waiting state and the scheduler is executed. In the second step, when the task is scheduled again, the task waits the time that is left from the previous segment estimation, and the execution continues normally. This solves the error of modeling processor assignments during this time, but the solution is not complete. The segment is completely executed before the interruption, and if a communication is done in the middle of the segment, “read after write”, “write after read” or “write after write” errors can occur. Communication using channels, as message queues does not present any problem, because they are system calls and they cannot be in the middle of a segment; in fact they are always the segment borders. However, accesses to global variables are done during segment execution and, therefore, an error (always less than the tic-timer period) may be introduced. To solve this problem, several options were proposed in [23]. The best one was to transform global variables into channels. The new channel has the same behavior as a common variable, but each read and write access makes the current segment finish. Thus, the access is done at the beginning of a new segment, and therefore, at the exact temporal point. As a consequence, the order in the accesses from different tasks is correctly modeled. The corresponding effect on the same example used in Fig. 4 is shown in Fig. 5. Nevertheless, transforming global variables into channels would require a modification in the source code, (at least for global variables declared as pointers). As a consequence, although it can be done automatically with a simple parser, the advantage provided by direct use of the original source code would be lost.
Fig. 5 Correct simulation and code modification required Springer
RTOS modeling in SystemC for real-time embedded SW simulation: A POSIX model
221
5 Hardware-software communication This work is not oriented to HW/SW communication. However, HW interruptions and, in general I/O communications are important issues in RTOS modeling. I/O communication facilities are system calls, so they can be modeled over the generic RTOS kernel. When they are called, the task state changes to SU state. If it is a synchronized access and the task has to wait, it is moved into Blocked state. When the access is possible, it changes to Ready state and waits until it is scheduled. Finally, when the access finishes, the task state goes to Waiting state. To model interruptions the generic RTOS kernel model provides two elements. The first one is a new function, “void raise interruption (int Int number)”, that allows sending interruptions from the HW platform to the RTOS. The second one is the possibility of assigning a user code as a handler of each interruption. 6 POSIX modeling POSIX is probably the most common standard API. There are many RTOSs supporting this interface, and covering a wide range of processor application areas, including embedded systems. As a consequence, POSIX was selected to implement the proposed RTOS model [24]. The POSIX standard covers a wide range of system facilities. Concurrency, scheduling, timing, communication and synchronization are the main features of every RTOS and, thus, in particular of a POSIX RTOS. Most part of the functions related to these features has been modeled. In fact about 180 POSIX functions have been developed. The remaining POSIX features have been supported using some of the underlying OS functions (e.g. linux). 6.1 Concurrency and scheduling To provide concurrency, POSIX defines the parallelism among different tasks using processes and threads. Processes are the elements that control the resources that the system assigns for the correct execution of the code, and threads are the elements in charge of executing this code. This means that all processes must have at least one thread, and each thread must be associated to a process. They can be modeled using the concurrency features provided by the generic RTOS kernel model. Threads can be modeled with a high accuracy, but modeling processes is more restrictive. Management of process related information (pids, children processes, groups, . . . ), scopes, priorities and policies, signals or channel accesses (attached/detached) are some of the elements modeled. However, some elements related to different memory spaces or paging, have not been modeled. Regarding scheduling, POSIX defines the scheduling level, the policy and the priority of each thread and process. First, in a POSIX RTOS, each process competes with the rest to take control of the processor. However, when a new thread is created it is decided whether this thread will compete with the rest of processes of the system (“system scope”) or if it will only compete with the rest of threads of this process when the process obtains the processor (“process scope”). In this implementation both possibilities have been modeled using the two-level scheduler defined in the generic kernel model. Furthermore, several scheduling policies have been defined: SCHED FIFO, SCHED RR (Round-Robin), SCHED SS (Sporadic Server), and SCHED OTHER, which does not have real- time characteristics and depends on the “nice” parameter. All of them can be modeled with the generic kernel. The selection of the new task by the scheduler is done depending on process and thread priorities. Springer
222
H. Posadas et al.
To model the exit procedure, the FIFO policy only releases the processor for a system call or an interruption, so no specific management is required. To model RR and SS policies, the time slice technique has been used. 6.2 Communication and synchronization The POSIX standard defines several mechanisms for communication and synchronization. Apart from shared variables, there are mutexes, conditional variables, message queues, semaphores, sockets, streams, signals, etc. Timing facilities are based on timers and realtime clocks. Additionally, file systems and memory management are also included Mutexes, conditional variables, spinlocks, rwlocks, semaphores or message queues use the kernel facilities to block or resume tasks, generate signals or implement timeouts. Once the different task states in the generic kernel are modeled, these facilities can easily be modeled. First, the task enters the SuperUser state. Here, blocking channels can make the task change its state to Blocked or can unblock another task stopped because of this channel (see Section 3.3). Finally, the task returns to User state to continue the user code execution or waits for the scheduler if the processor is busy. POSIX signals can also be used to synchronize and, even, to communicate tasks. To model POSIX signals, the POSIX model is in charge of saving the information when a signal is sent to a task. If the task is waiting for the signal in a “sigwait” function, the task is unblocked and continues in a similar way as the previous channels. If not, when the task is scheduled, the signal handler is executed at the correct state (SuperUser or User for user-defined handlers). 6.3 Timing facilities Timing features use the task states and the tic-timer control from the generic kernel model. POSIX defines several clocks. The real-time clock and the monotonic clock are modeled defining an initial value with respect to the original clock. POSIX also defines that there has to be one clock for each processor and one for each thread. These clocks are created defining as a condition that they only be updated when the corresponding thread or process is running. To model sleeps and timeouts, the task is moved to the Blocked state in the same way used to model synchronization channels. When the RTOS function is called the state is changed to SuperUser state. When the function returns, the task goes to User state through Waiting state. Furthermore, to block the task and wait for the required time, the Blocked state is used. To unblock the task, a generic kernel timer is used. This timer moves the corresponding task to Ready state at the indicated time. POSIX timers are modeled using the generic kernel timers, and the POSIX signal control explained above. These elements cannot be modeled using temporal “wait” statements directly. In real RTOS, these features do not execute at the exact specified time, but in the closest tic-timer interruption. 6.4 Other facilities Some other kinds of facilities are also part of a POSIX compliant OS. For instance, mathematical functions, string management functions, and functions for I/O, memory management or file management can be also included. Springer
RTOS modeling in SystemC for real-time embedded SW simulation: A POSIX model SystemC wrapper
#define RESOURCE PROC_1
Original SW code
int main(){
SC_MODULE(sw_code){ // class sw_code: ... {
pthread_t p1; pthread_attr_t attr;
pthread_mutex_t mutex; GLOBAL_VA R(int, glob_var); int main(){ ... } void func_1{…} void func_2{…}
pthread_attr_init(&attr); sch_param.sched_policy = SCHED_FIFO; sch_param.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; pthread_attr_setschedparam(&attr,&sch_param);
SC_CTOR(sw_code){ SC_THREAD(main); }
pthread_create(&p1,&attr,func_1,NULL); pthread_mutex_lock(&mutex); func_2(); pthread_mutex_unlock(&mutex); pthread_join(p1,&st1); pthread_mutex_destroy(&mutex); exit(0);
} int sc_main(){ sw_code pr1; start(-1); }
223
}
Fig. 6 POSIX interface: Example of use in SystemC
For some kind of facilities, such as mathematics and string management, the functions of the underlying OS can be used. Only the execution time on the target platform has to be added. Thus, the generic RTOS model does not required any extension in this area. For other features, such as I/O, memory management or file management, the model depends on the designer requirements. If the designer wants to model the real effect of HW peripherals that are involved in these features, specific models for each target platform, including specific drivers, are required. Thus, the generic model cannot cover them. However, if only the corresponding SW functionality is required, the underlying OS features can be used. It should be noted, that it is not possible to use the underlying OS blocking functions. To model them, it is necessary to use the non-blocking corresponding ones and model task blocking by using the generic RTOS model states. So, for instance, to block the task if data are not ready, the task should be moved into “Blocked” state. 6.5 POSIX Interface: Example of use To introduce a POSIX-based code in the SystemC simulation, very few new code lines are required. A simple example is used to illustrate this. The code of the example does not have any special purpose, except to show the use of the POSIX implementation described before. As can be seen in Fig. 6, only a very simple SystemC wrapper is required to simulate the components in SystemC. The simulation code is the same as the original SW code. Only the global variable type has been modified. The wrapper starts by defining a resource in which the module will be executed initially. To do this, the value PROC 1 is associated to the RESOURCE, indicating that the component will run on processor 1. Then, the module definition starts. Firstly, a mutex and a global variable are declared. This mutex will be used for task synchronization and the variable to share information between the tasks. After that, the functions “main”, “func 1” and “func 2” are declared. Finally, the module constructor is placed and a SC THREAD is created. This SC THREAD will be used as virtual processor for the “main” task. Finally the main function Springer
224
H. Posadas et al.
Fig. 7 View of PERFidiX graphic interface
of SystemC, “sc main”, is located. The code of the function “main” can be seen on the right of Fig. 6. It is standard C code with POSIX functions. This SystemC component is simulated together with the POSIX modeling library and the time estimation obtained with [22] to create a timed simulation. The use of SystemC also enables the simulation together with the SW component system-level descriptions or HW components, to model the whole system. The conclusion is that the design can be deeply refined using the whole simulation of HW and SW components. PERFidiX provides a graphic interface that helps the designer to visualize the system execution. The tool provides information about the behavior of the system, in terms of state change waveforms of each task over time, CPU utilization, the percentage of time each process is in each state, etc. Capture points can also be placed in the code to obtain the values that certain variables have at certain points. These values can also be displayed together with the task state change waveforms. An example can be seen in Fig. 7. 7 Results The POSIX modeling library has been evaluated in a complex case study, the standard EN 301 245 vocoder, for GSM applications of the ETSI [6]. The original model of the standard, with a sequential structure has over 13,500 lines of code. This code has been divided into nine concurrent tasks, which are synchronized and scheduled using the functions of a POSIX-compliant operating system. The execution time of the SW code has been estimated using PERFidy [22]. This tool provides a dynamic estimation of each code segment. These Springer
RTOS modeling in SystemC for real-time embedded SW simulation: A POSIX model Table 1 Simulation times using POSIX modeling and temporal estimation
225
Simulation type
SystemC
POSIX model
Overhead
Time(msec)
1,060
1,120
6%
estimations are automatically annotated in the simulation when transitions from U to SU state are done. At this time, kernel time execution is also included in the simulation. First, the overhead produced by the inclusion of the library in the SystemC simulation is analyzed. A comparison between the simulation time with and without the library is made. As shown in Table 1, the inclusion of the POSIX library in the SystemC simulation produces an overhead of 6% with respect to the simulation of the same example with PERFidy over SystemC. The PERFidy simulation provides the time estimations but does not model the RTOS. The overhead of the estimation tool has to be considered apart from the RTOS model. In the case of PERFidiX, the overhead related to the operator overloading results in simulation times in the range between the ISS simulation time and the original source code simulation time [22]. Therefore, the SystemC simulation is more realistic when including the RTOS model than when the basic SystemC kernel is used alone. Task execution order is more adequately modeled when considering the target RTOS scheduling capabilities. Analyzing the results provided by the graphic interface, it can be verified that the simulation is closer to the real execution. Apart from this benefit, the RTOS model also improves the time estimation obtained by the independent estimation tool. Firstly, the SW code modeled when considering the RTOS is the same as the one used for the implementation. However, when simulating the original SystemC specification, communication and synchronization functions are used. These functions have not yet been implemented using the target RTOS features. Therefore, the code modeled is not exactly the same as the final one. As a consequence, the time estimations obtained without the RTOS model include additional errors. Furthermore, the correct modeling of the task execution order also improves the time estimations. For example, task execution order becomes especially important when modeling communications based on polling techniques. If the task in charge of the polling has a high priority, a lot of accesses to the polled variable can be expected. However, if the priority is very low, the number of pollings is smaller. If the simulation does not include a RTOS model, the number of pollings cannot be monitored and the resulting time estimations also contain additional errors. The effect of the RTOS model on the estimation tool results can be analyzed in Table 2. Time estimation values have been obtained with and without the RTOS model, and they have been compared with the execution time measured it the target platform [4]. As can be seen, the errors obtained when considering the RTOS effect are smaller than the results when simulating directly over the SystemC kernel. To verify the POSIX compliance, the Open POSIX Test Suite v1.5 [25] has been used. This test suite proposes about 2,000 tests to check the correct implementation of the POSIX standard. The result is that more than the 70% of the proposed functionality has been implemented and operates correctly. Some features for memory management, shared memory, I/O and other platform dependent facilities have not been modeled and will be considered in future work. Springer
226 Table 2 Errors in the execution time estimation with and without the RTOS model
H. Posadas et al.
Task
SCS (%)
PP (%)
pre filtering homing frame test frame lsp func frame int tol fun subframe coder fun serializer fun vad comp fun CN encoder fun sid encoding fun RTOS
3.45 13.67 4.51 6.17 3.04 6.72 9.36 7.45 12.18 3.94
2.41 0.88 0.45 3.56 0.23 6.36 3.34 5.33 7.29 1.84
8 Conclusions and future work In this work, the use of SystemC for RTOS modeling has been studied. As a conclusion, SystemC has proven to be a powerful language for efficiently simulating the detailed, low-level, dynamic timing characteristics of the RTOS such as time-slicing, priority-based preemptive scheduling, interrupts and exceptions. This is possible even with the current version of the language without modifying the standard simulation kernel. The need for a dynamic time estimation tool linked to the RTOS model through a time manager has been highlighted. Based on the proposed simulation technology, a RTOS simulation modeling library for RT/E timed simulation has been developed. The main advantage of the proposed technology over other similar techniques is that it avoids the complex, three-step process of estimating the execution times, annotating them in the appropriate points of the code and simulating. In this case, a time manager that does this automatically has been proposed. This manager uses the execution time estimations from an independent estimation tool and produces a timed simulation. This technology was proven to be effective using PERFidy, a SystemC performance analysis library, as an external time estimation tool. The RTOS model supports POSIX. The model implements all the concurrency, communication and synchronization functionality required by the standard. Using two widely used standards, POSIX and SystemC, full portability is ensured. The new library, called PERFidiX, supports refinement of the original SystemC specification by optimizing the code including POSIX functions so that a directly compilable code is developed. In future work, the main area to be tackled is HW/SW communication. To communicate the SW code with the HW resources, a generic way to easily integrate specific predefined drivers in the simulation with the RTOS model will be defined. Furthermore, it will allow modeling those POSIX functions that are completely platform dependent. To achieve this objective, a tight integration of HW/SW interfaces has to be defined, including the HW interfaces, bus models and RTOS facilities that control direct HW access. Acknowledgments This work has been partially funded by the ITEA MERCED project and the Spanish TEC2005-03301 project.
References 1. AXLOG, information available in http://www.axlog.fr. 2. Benini, L., D. Bertozzi, D. Bruni, N. Drago, F. Fummi, and M. Ponzino. SystemC cosimulation and Emulation of multiprocessor SoC design. In IEEE Computer, April 2003. Springer
RTOS modeling in SystemC for real-time embedded SW simulation: A POSIX model
227
3. Bergeron, J. Writing Testbenches: Functional Verification of HDL Models. Springer, 2003. 4. Bolado, M., H. Posadas, J. Castillo, P. Huerta, C. S´anchez, P. S´anchez, H. Fouren, and F. Blasco. Platform Based on Open-Source Cores for Industrial Applications. In Proceedings of the Design, Automation and Test Conference, IEEE, 2004. 5. ENEA OSE Soft Kernel Environment, available in http://www.ose.com/products. 6. EN 301.245, ETSI, December, 1997. 7. Gerstlauer, A., H. Yu, and D. Gajski. RTOS Modeling for System-Level Design. In A.A. Jerraya, S. Yoo, D. Verkest, and N. When (eds.), Embedded Software for SoC. Springer, 2003. 8. Ghenassia, F. (ed.) Transaction-Level Modeling with SystemC. Springer, 2005. 9. Hassan, M.A., K. Sakanushi, Y. Takeuchi, and M. Imai. RTK-Spec TRON: A Simulation Model of an ITRON Based RTOS Kernel in SystemC. In Proceedings of the Design, Automation and Test Conference, IEEE, 2005. 10. He, Z., A. Mok, and C. Peng. Timed RTOS Modeling for Embedded System Design. In Proceedings of the Real Time and Embedded Technology and Applications Symposium, IEEE, 2005. 11. Herrera, F., V. Fern´andez, P. S´anchez, and E. Villar. Embedded Software Generation from SystemC for Platform-Based Design. In W. M¨uller, W. Rosenstiel, and W. Ruf (eds.), SystemC: Methodologies and Applications. Springer, 2003. 12. Honda, S., T. Wakabayashi, H. Tomiyama, and H. Takada. RTOS-centric HW/SW Cosimulator for Embedded System Design. In Proceedings of CoDes-ISSS’04, ACM, 2004. 13. IEEE, IEEE ratifies SystemC 2.1 Standard for System-Level chip design, http://standards.ieee.org/ announcements/pr p1666.html. 14. IEEE, Information technology-Portable Operating System Interface, IEEE Std 1003.1, 2004. 15. ITRS, International Technology Roadmap for Semiconductors: 2005 Edition, http://www.itrs.net/ Common/2005ITRS/Home2005.htm. 16. Jerraya, A.A., S. Yoo, D. Verkest, and N. When (eds.). Embedded Software for SoC. Springer, 2003. 17. A.A. Jerraya and W. Wolf (eds.). Multiprocessor Systems-on Chip. Morgan Kaufmann, 2005. 18. Liem, C., F. Nacabal, C. Valderrama, P. Paulin, and A. Jerraya. System-on-a-Chip Cosimulation and Compilation. Design & Test of Computers, April-June, IEEE, 1997. 19. Madsen, J., K. Virk, and M. Gonzales. Abstract RTOS Modeling for Multiprocessor System on Chip. In Proceedings of the International Symposium on System-on Chip, IEEE, 2003. 20. M¨uller, W., W. Rosenstiel, and J. Ruf (eds.). SystemC: Methodologies and Applications. Springer, 2003. 21. Posadas, H., F. Herrera, V. Fern´andez, P. S´anchez, E. Villar, and F. Blasco. Single Source Design Environment for Embedded Systems Based on SystemC. Design Automation for Embedded Systems, N.9, Springer, 2004. 22. Posadas, H., F. Herrera, P. S´anchez, E. Villar, and F. Blasco. System-level Performance Analysis in SystemC. In Proceedings of the Design, Automation and Test Conference, IEEE, 2004. 23. Posadas, H., E. Villar, and F. Blasco. Real-Time Operating System Modeling in SystemC for HW/SW co-simulation. In Proceedings of DCIS, IST, Lisbon, 2005. ´ 24. Posadas, H., J. Adamez, P. S´anchez, E. Villar, and F. Blasco. POSIX modeling in SystemC. In Proceedings of the Asian, South-Pacific Design, Automation Conference, IEEE, 2006. 25. Open POSIX test suite. www.sourceforge.net/. 26. Tomiyama, H., Y. Cao, and K. Murakami. Modeling Fixed-Priority Preemptive Multi-Task Systems in SpecC. In Proceedings of the 10th Workshop on System And System Integration of Mixed Technologies (SASIMI’01), IEEE, 2001. 27. Yi, Y., D. Kim, and S. Ha. Fast and Time-Accurate Cosimulation with OS Scheduler Modeling. Design Automation of Embedded Systems, N.8. Springer, 2003. 28. Yoo, S., G. Nicolescu, LG. Gauthier, and A.A. Jerraya. Automatic Generation of fast Timed Simulation Models for Operating Systems in SoC Design. In Proceedings of the Design, Automation and Test Conference, IEEE, 2002.
Springer