System Calls

System Call Format

μT-Kernel adopts C as the standard high-level language, and standardizes interfaces for system call execution from C language routines.

The method for interfacing with the assembly language shall be implementation-dependent. Calling by means of a C language interface is recommended even when an assembly language is used. In this way, portability is assured for programs written in assembly language even if the OS changes, so long as the CPU is the same.

The following common rules are established for system call interfaces.

The implementation of the system call interface is not standardized, and is implementation-dependent. For example, we can use C language macros, inline functions, inline assembly language description, etc.

Among C language interfaces for system calls, those which pass parameters using a packet or pointer have CONST modifier attached to explicitly indicate that μT-Kernel does not overwrite a parameter referred to by the pointer.

CONST is intended to be the C language const modifier equivalent. This alias for const is used so that the compiler check can be disabled by using #define macro function when any program that does not support const modifier mixes in.

Specific usage of CONST is as follows: Details, however, depend on the development environment.

  1. Include the following descriptions in the common include file:

    
/* If TKERNEL_CHECK_CONST definition exists, enable the check for const */
    #ifdef TKERNEL_CHECK_CONST
    #define CONST const
    #else
    #define CONST
    #endif
    
  2. Describe a function definition or system call definition in the program by using CONST.

    Example 1. Description Example of CONST

    
tk_cre_tsk( CONST T_CTSK *pk_ctsk );
    foo_bar( CONST void *buf );
    

In μT-Kernel 3.0 or later, it is strongly recommended that CONST is used explicitly in a program and the check for const is enabled in the configuration.

APIs Possible from Task-Independent Portion

The following system calls of μT-Kernel/OS can be issued from a task-independent portion and in dispatch disabled state:

System call nameSummary description
tk_sta_tsk Start Task
tk_ref_tsk Reference Task Status
tk_wup_tsk Wakeup Task
tk_rel_wai Release Wait
tk_sus_tsk Suspend Task
tk_sig_tev Signal Task Event
tk_sig_sem Signal Semaphore
tk_set_flg Set Event Flag
tk_sta_cyc Start Cyclic Handler
tk_stp_cyc Stop Cyclic Handler
tk_ref_cyc Reference Cyclic Handler Status
tk_ref_cyc_u Reference Cyclic Handler Status (Microseconds)
tk_sta_alm Start Alarm Handler
tk_sta_alm_u Start Alarm Handler (Microseconds)
tk_stp_alm Stop Alarm Handler
tk_ref_alm Reference Alarm Handler Status
tk_ref_alm_u Reference Alarm Handler Status (Microseconds)
tk_ret_int Return from Interrupt Handler (can be issued only from an interrupt handler written in an assembly language)
tk_rot_rdq Rotate Ready Queue
tk_get_tid Get Task Identifier
tk_ref_sys Reference System Status

The following APIs of μT-Kernel/SM can be issued from a task-independent portion and in dispatch disabled state:

API nameSummary description
DI Disable External Interrupts
EI Enable External Interrupts
isDI Get Interrupt Disable Status
SetCpuIntLevel Set CPU Interrupt Mask Level
GetCpuIntLevel Get CPU Interrupt Mask Level
EnableInt Enable Interrupts
DisableInt Disable Interrupts
ClearInt Clear Interrupt
EndOfInt Issue EOI to Interrupt Controller
CheckInt Check Interrupt
SetIntMode Set Interrupt Mode
SetCtrlIntLevel Set Interrupt Controller Interrupt Mask Level
GetCtrlIntLevel Get Interrupt Controller Interrupt Mask Level
out_b Write to I/O Port (in Bytes)
out_h Write to I/O Port (in Half-words)
out_w Write to I/O Port (in Words)
out_d Write to I/O Port (in Double-words)
in_b Read from I/O Port (in Bytes)
in_h Read from I/O Port (in Half-words)
in_w Read from I/O Port (in Words)
in_d Read from I/O Port (in Double-words)
WaitUsec Micro Wait (Microseconds)
WaitNsec Micro Wait (Nanoseconds)
SetOBJNAME Set Object Name

All system calls of μT-Kernel/DS can be issued from a task-independent portion and in dispatch disabled state.

Whether system calls or APIs other than those above can be issued from a task-independent portion or in dispatch disabled state is implementation-dependent.

Restricting System Call Invocation

The protection levels at which a system call is invokable can be restricted. In this case, if a system call is issued from a task (task portion) running at lower privilege than the specified protection level, the error code E_OACV is returned.

Extended SVC calling cannot be restricted.

If, for example,issuing a system call from a level with lower privilege than level 1 is prohibited, system calls cannot be made from tasks running at protection levels 2 and 3. Tasks running at those levels will only be able to make extended SVC calls, and are programmed using subsystem functions only.

This kind of restriction is used when μT-Kernel is combined with middleware that offers process management function and other functions, to prevent tasks (as part of user process, etc.) that use the functions of such middleware (process management, etc.) from directly accessing μT-Kernel functions. It allows μT-Kernel to be used as a micro-kernel. The idea is that the user process cannot control the micro-kernel directly via available process API, and only the middleware can control the micro-kernel directly.

The protection level restriction on system call invocation is set using the system configuration information management functions. (see the Section called System Configuration Information Management Functions in the Chapter called μT-Kernel/SM Functions).

Modifying a Parameter Packet Format

Some parameters passed to system calls use packet format. The packet format parameters are of two kinds, either input parameters passing information to a system call (e.g., T_CTSK) or output parameters returning information from a system call (e.g., T_RTSK).

Additional information that is implementation-dependent can be added to a parameter packet. When implementation-dependent information is added, it must be positioned after the standard defined information. It is permitted to delete only parameters that are declared ineffective by the service profile, and other parameters shall not be deleted. It is not allowed, however, to change the data types and order of information defined in the standard specification.

When implementation-dependent information is added to a packet of input information passed to a system call (T_CTSK, etc.), if the system call is invoked while this additional information is not yet initialized (memory content is indeterminate), the system call must still function normally.

Ordinarily a flag indicating that valid values are set in the additional information is defined in the implementation-dependent area of attribute flag included in the standard specification. When that flag is set (1), the additional information is to be used; and when the flag is not set (0), the additional information is not initialized (memory content is indeterminate) and the default values are to be used instead.

The reason for this specification is to make sure we can run the same application program merely by recompiling, irrespective of whether implementation dependent function extension is added to an implementation of the specification.

NotePorting Guideline
 

A care must be taken now for parameter packet initialization since the parameter may be deleted by declaring it to be ineffective by service profile. For example, it is not recommended to initialize T_CTSK structure in the following manner from the viewpoint f portability.


T_CTSK  ctsk = {
        NULL,
        TA_HLNG|TA_RNG0|TA_USERBUF,
        task,
        10,
        2048,
        "",
        buf
};

Instead, it is recommended to perform initialization using the syntax specified in ISO/IEC 9899:1999 as follows.


T_CTSK  ctsk = {
        .exinf   = NULL,
        .tskatr  = TA_HLNG|TA_RNG0|TA_USERBUF,
        .task    = task,
        .itskpri = 10,
        .stksz   = 2048,
        .bufptr  = buf
};

Function Codes

Function codes are numbers assigned to each system call and used to identify the system call.

The system call function codes are not specified here but are to be defined in implementation.

See tk_def_ssy on extended SVC function codes.

Error Codes

System call return codes are in principle to be signed integers. When an error occurs, a negative error code is returned; and if processing is completed normally, E_OK (= 0) or a positive value is returned. The meaning of returned values in the case of normal completion is specified individually for each system call. An exception to this principle is that there are some system calls that do not return when called. A system call that does not return is declared in the C language interface as having no return code (i.e., a void type function).

An error code consists of the main error code and sub error code. The low 16 bits of the error code are the sub error code, and the remaining high bits are the main error code. Main error codes are classified into error classes based on the necessity of their detection, the circumstances in which they occur and other factors.


#define MERCD(er)       ( (ER)(er) >> 16 )    /* main error code */
#define SERCD(er)       ( (H)(er) )           /* sub error code */
#define ERCD(mer, ser)  ( (ER)(mer) << 16 | (ER)(UH)(ser) )

Note that, in an environment where ER is 16-bit data type, sub error code can be omitted and main error code can be returned as the error code. In this case, SERCD macro shall not be defined.


#define MERCD(er)       ( (ER)(er) )    /* main error code */
#define ERCD(mer, ser)  ( (ER)(mer) )

NoteRelated Service Profile Items
 

Only when the service profile items below are set to be effective, the error code contains sub error code, and SERCD macro is supported.

TK_SUPPORT_SERCD Support of sub error code

Timeout

A system call that may enter WAITING state has a timeout function. If processing is not completed by the time the specified timeout interval has elapsed, the processing is canceled and the system call returns error code E_TMOUT.

In accordance with the principle that there should be no side-effects from calling a system call if that system call returns an error code, the calling of a system call that times out should in principle result in no change in system state. An exception to this is when the functioning of the system call is such that it cannot return to its original state if processing is canceled. This is indicated in the system call description.

If the timeout interval is set to 0, a system call does not enter even when a situation arises in which it would ordinarily go to WAITING state. In other words, a system call with timeout set to 0 when it is invoked has no possibility of entering WAITING state. Invoking a system call with timeout set to 0 is called polling; i.e., a system call that performs polling has no chance of entering WAITING state.

The descriptions of individual system calls as a rule describe the behavior when there is no timeout (in other words, when an eternal wait occurs). Even if the system call description states that the system call "enters WAITING state" or "is put in WAITING state," if a timeout is set and that time interval elapses before processing is completed, the WAITING state is released and the system call returns error code E_TMOUT. In the case of polling, the system call returns E_TMOUT without entering WAITING state.

Timeout (TMO and TMO_U types) is given as a positive integer, or as TMO_POL=0 for polling, or as TMO_FEVR (= -1) for eternal wait. If a timeout interval is set, the timeout processing must be guaranteed to take place after the specified interval from the system call issuing has elapsed.

NoteAdditional Notes
 

Since a system call that performs polling does not enter WAITING state, there is no change in the precedence of the task calling it.

In a general implementation, when the timeout is set to 1, timeout processing takes place on the second timer interrupt (sometimes called "time tick") after a system call is invoked. Since a timeout of 0 cannot be specified (0 being allocated to TMO_POL ), in this kind of implementation timeout does not occur on the initial timer interrupt after the system call is invoked.

Relative Time and System Time

When the time of an event occurrence is specified relative to another time, such as the time when a system call was invoked, relative time (RELTIM or RELTIM_U type) is used. If relative time is used to specify event occurrence time, it is necessary to guarantee that the event processing will take place after the specified time has elapsed from the time base. Relative time (RELTIM or RELTIM_U type) is also used for e.g. event occurrence. In such cases the method of interpreting the specified relative time is determined for each case. When time is specified as an absolute value, system time (SYSTIM or SYSTIM_U type) is used. The μT-Kernel provides a function for setting system time, but even if the system time is changed using this function, there is no change in the real world time (actual time) at which an event occurs that was specified using relative time. What changes is the system time at which an event occurs that was specified as relative time.

SYSTIM: System time

Time base 1 millisecond, 64-bit signed integer


typedef struct systim {
        W       hi;     /* High 32 bits */
        UW      lo;     /* Low 32 bits */
} SYSTIM;
SYSTIM_U: System time

Time base 1 microsecond, 64-bit signed integer


typedef D       SYSTIM_U;       /* 64-bit */
RELTIM: Relative time

Time base 1 millisecond, 32-bit unsigned integer (UW)


typedef UW      RELTIM;
RELTIM_U: Relative time

Time base 1 microsecond, 64-bit unsigned (UD) integer


typedef UD      RELTIM_U;       /* Relative time in microseconds with 64-bit integer */
TMO: Timeout time

Time base 1 millisecond, 32-bit signed integer (W)


typedef W       TMO;

Eternal wait can be specified as TMO_FEVR (= -1).

TMO_U timeout period

Time base 1 microsecond, 64-bit signed (D) integer


typedef D       TMO_U;          /* Timeout in microseconds with 64-bit integer */

Eternal wait can be specified as TMO_FEVR (= -1).

NoteRelated Service Profile Items
 

TMO_U, RELTIM_U, and SYSTEM_U dealing with date and relative time in microsecond resolution are guaranteed to be usable only when the following service profile items are set to be effective.

TK_SUPPORT_USEC Support of microsecond

NoteAdditional Notes
 

Timeout or other such processing must be guaranteed to occur after the time specified as RELTIM, RELTIM_U, TMO, or TMO_U has elapsed. For example, if the timer interrupt interval is 1 ms and a timeout of 1 ms is specified, timeout occurs on the second timer interrupt after system call invocation. (The first timer interrupt does not exceed 1 ms.)

When a system time (SYSTIM_U) value that may overflow internally in kernel is specified as an argument, the system call behavior is undefined.