Task synchronization functions achieve synchronization among tasks by direct manipulation of task states. They include functions for task sleep and wakeup, for canceling wakeup requests, for forcibly releasing task WAITING state, for changing a task state to SUSPENDED state, for delaying execution of the invoking task, and for disabling task WAITING state.
Wakeup requests for a task are queued. That is, when it is attempted to wake up a task that is not sleeping, the wakeup request is remembered, and the next time the task is to go to a sleep state (waiting for wakeup), it does not enter that state. The queuing of task wakeup requests is realized by having the task keep a task wakeup request queuing count. When the task is started, this count is cleared to 0.
Suspend requests for a task are nested. That is, if it is attempted to suspend a task already in SUSPENDED state (including WAITING-SUSPENDED state), the request is remembered, and later when it is attempted to resume the task in SUSPENDED state (including WAITING-SUSPENDED state), it is not resumed. The nesting of suspend requests is realized by having the task keep a suspend request nesting count. When the task is started, this count is cleared to 0.
E_OK | Normal completion |
E_PAR | Parameter error (tmout ≦ (-2)) |
E_RLWAI | Waiting state released (tk_rel_wai received in waiting state) |
E_DISWAI | Wait released due to disabling of wait |
E_TMOUT | Polling failed or timeout |
E_CTX | Context error (issued from task-independent portion, or in dispatch disabled state) |
Changes the state of the invoking task from RUNNING state to sleep state (WAITING state for tk_wup_tsk). Note if the wakeup requests for the invoking task are queued, i.e., the wakeup request queuing count of the invoking task is 1 or more, the count is decremented by 1, and the execution is continued without moving the invoking task to the waiting state.
If tk_wup_tsk is issued for the invoking task before the time specified in tmout
has elapsed, this system call completes normally. If timeout occurs before tk_wup_tsk is issued, the timeout error code E_TMOUT is returned. Specifying
tmout
= TMO_FEVR (= -1) means eternal wait. In this case, the task stays in waiting state until tk_wup_tsk is issued.
Since tk_slp_tsk is a system call that puts the invoking task into the waiting state, tk_slp_tsk can never be nested. It is possible, however, for another task to issue tk_sus_tsk for a task that was put in the waiting state by tk_slp_tsk. In this case the task goes to WAITING-SUSPENDED state.
For simply delaying a task, tk_dly_tsk should be used rather than tk_slp_tsk.
The task sleep function is intended for use by applications and as a rule should not be used by middleware. The reason is as follows.
Attempting to achieve synchronization by putting a task to sleep in two or more places would cause confusion, leading to mis-operation. For example, if sleep were used by both an application and middleware for synchronization, a wakeup request might arise in the application while middleware has a task sleeping. In such a situation, normal operation would not be possible in either the application or middleware.
In this manner, proper task synchronization is not possible if it is not clear where the wait for wakeup originated. Task sleep is often used as a simple means of task synchronization. Applications should be able to use it freely, which means as a rule it should not be used by middleware.
E_OK | Normal completion |
E_PAR | Parameter error (tmout_u ≦ (-2)) |
E_RLWAI | Waiting state released (tk_rel_wai received in waiting state) |
E_DISWAI | Wait released due to disabling of wait |
E_TMOUT | Polling failed or timeout |
E_CTX | Context error (issued from task-independent portion, or in dispatch disabled state) |
Only when all the service profile items below are set to be effective, this system call can be used.
This system call takes 64-bit tmout_u
in microseconds instead of the parameter tmout
of tk_slp_tsk.
The specification of this system call is same as that of tk_slp_tsk, except that the parameter is replaced with tmout_u
. For more details, see the description of tk_slp_tsk.
E_OK | Normal completion |
E_ID | Invalid ID number (tskid is invalid or cannot be used) |
E_NOEXS | Object does not exist (the task specified in tskid does not exist) |
E_OBJ | Invalid object state (called for the invoking task or for a task in DORMANT state) |
E_QOVR | Queuing or nesting overflow (too many queued wakeup requests in wupcnt ) |
If the task specified in tskid
has been put in WAITING state by tk_slp_tsk, this system call releases the WAITING state.
This system call cannot be called for the invoking task. If the invoking task is specified, error code E_OBJ is returned.
If the target task has not called tk_slp_tsk and is not in WAITING state, the wakeup request by tk_wup_tsk is queued. That is, the calling of tk_wup_tsk for the target task is recorded, then when tk_slp_tsk is called after that, the task does not go to WAITING state. This is what is meant by queuing of wakeup requests.
The queuing of wakeup requests works as follows. Each task keeps a wakeup request queuing count (wupcnt
) in its TCB. Its initial value (when tk_sta_tsk is executed) is 0. When tk_wup_tsk is issued for a task not sleeping (not in WAITING state), the count is incremented by 1; but each time tk_slp_tsk is executed, the count is decremented by 1. When tk_slp_tsk is executed for a task whose wakeup queuing count is 0, the queuing count is not made negative but rather the task goes to WAITING state.
It is always possible to queue tk_wup_tsk at least one time (wupcnt
= 1), but the maximum queuing count ( wupcnt
) is implementation-dependent and its maximum value is defined by serviced profile item, TK_WAKEUP_MAXCNT. In other words, issuing tk_wup_tsk once for a task not in WAITING state does not return an error, but whether an error is returned for the second or subsequent call of tk_wup_tsk is implementation-dependent.
When calling tk_wup_tsk causes wupcnt
to exceed the allowed maximum value, error code E_QOVR is returned.
Passes in the return value the wakeup request queuing count (wupcnt
) for the task specified in tskid
, at the same time canceling all wakeup requests. That is, this system call clears the wakeup request queuing count (wupcnt
) to 0 for the specified task.
The invoking task can be specified by setting tskid
= TSK_SELF = 0. Note, however, that when tskid
= TSK_SELF = 0 is specified in a system call issued from a task-independent portion, error code E_ID is returned.
This system call can be used to determine whether the processing was completed within the allotted time when processing is performed that involves cyclic wakeup of a task. Before processing of a prior wakeup request is completed and tk_slp_tsk is called by the waken up task, the task monitoring this task calls tk_can_wup. If wupcnt
in the return parameter is 1 or above, this means the previous wakeup request was not processed within the allotted time. Measure can then be taken accordingly to compensate for the delay.
E_OK | Normal completion |
E_ID | Invalid ID number (tskid is invalid or cannot be used) |
E_NOEXS | Object does not exist (the task specified in tskid does not exist) |
E_OBJ | Invalid object state (called for a task not in WAITING state (including when called for the invoking task, or for a task in DORMANT state)) |
If the task specified in tskid
is in some kind of waiting state (not including SUSPENDED state), forcibly releases that state.
To the task whose WAITING state was released by tk_rel_wai, the error code E_RLWAI is returned. At this time, the target task is guaranteed to be released from its wait state without the allocation of the waited resource (without the wait release conditions being met).
Wait release requests are not queued by tk_rel_wai. That is, if the task specified in tskid
is already in WAITING state, the WAITING state is cleared; but if it is not in WAITING state when this system call is issued, error code E_OBJ is returned to the caller. Likewise, error code E_OBJ is returned when this system call is issued specifying the invoking task.
The tk_rel_wai system call does not release a SUSPENDED state. If tk_rel_wai is issued for a task in WAITING-SUSPENDED state, the task goes to SUSPENDED state. If it is necessary to release SUSPENDED state, the separate system call tk_rsm_tsk or tk_frsm_tsk is used.
The states of the target task when tk_rel_wai is called and the results of its execution in each state are shown in Table 3.
Table 3. Target Task State and Execution Result (tk_rel_wai)
Target Task State | tk_rel_waiercd Return Value | (processing) |
---|---|---|
Run state (RUNNING or READY) (not for invoking task) | E_OBJ | No operation |
Running state (RUNNING) (invoking task) | E_OBJ | No operation |
Waiting state (WAITING) | E_OK | Wait released/release wait |
Suspended state (SUSPENDED) | E_OBJ | No operation |
Waiting-suspended state (WAITING-SUSPENDED) | E_OK | Goes to SUSPENDED state |
Dormant state (DORMANT) | E_OBJ | No operation |
Non-existent state (NON-EXISTENT) | E_NOEXS | No operation |
A function similar to timeout can be realized by using an alarm handler or the like to issue this system call after a given task has been in WAITING state for a set time.
The main differences between tk_rel_wai and tk_wup_tsk are the following.
Whereas tk_wup_tsk releases only WAITING state effected by tk_slp_tsk, tk_rel_wai releases also WAITING state caused by other factors (tk_wai_flg, tk_wai_sem, tk_rcv_mbx, tk_get_mpl, tk_dly_tsk, etc.).
Seen from the task in WAITING state, release of the WAITING state by tk_wup_tsk returns a Normal completion (E_OK), whereas release by tk_rel_wai returns an error code (E_RLWAI).
Wakeup requests by tk_wup_tsk are queued if tk_slp_tsk has not yet been executed. If tk_rel_wai is issued for a task not in WAITING state, error code E_OBJ is returned.
E_OK | Normal completion |
E_ID | Invalid ID number (tskid is invalid or cannot be used) |
E_NOEXS | Object does not exist (the task specified in tskid does not exist) |
E_OBJ | Invalid object state (called for the invoking task or for a task in DORMANT state) |
E_CTX | A task in RUNNING state was specified in dispatch disabled state |
E_QOVR | Queuing or nesting overflow (too many nested requests in suscnt ) |
Puts the task specified in tskid
in SUSPENDED state and interrupts execution by the task.
SUSPENDED state is released by issuing system call tk_rsm_tsk or tk_frsm_tsk.
If tk_sus_tsk is called for a task already in WAITING state, the state goes to a combination of WAITING state and SUSPENDED state (WAITING-SUSPENDED state) after the execution of tk_sus_tsk. Thereafter when the task wait release conditions are met, the task goes to SUSPENDED state. If tk_rsm_tsk is issued for the task in WAITING-SUSPENDED state, the task state reverts to WAITING state. (See Figure 1 in the Section called Task States in the Chapter called μT-Kernel Concepts).
Since SUSPENDED state means task interruption by a system call issued by another task, this system call cannot be issued for the invoking task. If the invoking task is specified, error code E_OBJ is returned.
When this system call is issued from a task-independent portion, if a task in RUNNING state is specified while dispatching is disabled, error code E_CTX is returned.
If tk_sus_tsk is issued more than once for the same task, the task is put in nested SUSPENDED state. This is called nesting of suspend requests. In this case, the task reverts to its original state only when tk_rsm_tsk has been issued for the same number of times as tk_sus_tsk (suscnt
). Accordingly, nesting of the pair of system calls tk_sus_tsk and tk_rsm_tsk is possible.
The nesting feature of suspend requests (issuing tk_sus_tsk two or more times for the same task) and upper limits on nesting count are implementation-dependent.
If tk_sus_tsk is issued multiple times in a system that does not allow suspend request nesting, or if the nesting count exceeds the allowed limit, error code E_QOVR is returned.
When a task is in WAITING state for resource acquisition (semaphore wait, etc.) and is also in SUSPENDED state, the resource allocation (semaphore allocation, etc.) takes place under the same conditions as when the task is not in SUSPENDED state. Resource allocation is not delayed by the SUSPENDED state, and there is no change whatsoever in the priority of resource allocation or release from WAITING state. In this way SUSPENDED state is in an orthogonal relation with other processing and task states.
In order to delay resource allocation to a task in SUSPENDED state (temporarily lowering its priority), the user can employ tk_sus_tsk and tk_rsm_tsk in combination with tk_chg_pri.
Task suspension is intended only for very limited uses closely related to the OS, such as breakpoint processing in a debugger. As a rule it should not be used in ordinary applications or in middleware. The reason is as follows.
Task suspension takes place regardless of the target task running state. If, for example, a task is put in SUSPENDED state while it is calling a middleware function, the task will be stopped in the course of middleware internal processing. In some cases middleware performs resource management or other mutual exclusion control. If a task stops inside middleware while it has resources allocated, other tasks may not be able to use that middleware. This situation can cause chain reactions, with other tasks stopping and leading to system-wide deadlock.
For this reason a task must not be stopped without knowing its status (what it is doing at the time), and ordinary tasks should not use the task suspension function.
E_OK | Normal completion |
E_ID | Invalid ID number (tskid is invalid or cannot be used) |
E_NOEXS | Object does not exist (the task specified in tskid does not exist) |
E_OBJ | Invalid object state (the specified task is not in SUSPENDED state (including when this system call specifies the invoking task or a task in DORMANT state)) |
Releases the SUSPENDED state of the task specified in tskid
. If the target task was earlier put in SUSPENDED state by the tk_sus_tsk system call, this system call releases that SUSPENDED state and resumes the task execution.
When the target task is in a combined WAITING state and SUSPENDED state (WAITING-SUSPENDED state), executing tk_rsm_tsk releases only the SUSPENDED state, putting the task in WAITING state (see Figure 1 in the Section called Task States in the Chapter called μT-Kernel Concepts).
This system call cannot be called for the invoking task. If the invoking task is specified, error code E_OBJ is returned.
Executing tk_rsm_tsk once clears only one nested suspend request (suscnt
). If tk_sus_tsk was issued more than once for the target task (suscnt
≧ 2), the target task remains in SUSPENDED state even after tk_rsm_tsk is executed.
After a task in RUNNING state or READY state is put in SUSPENDED state by tk_sus_tsk and then resumed by tk_rsm_tsk or tk_frsm_tsk, the task has the lowest precedence among tasks of the same priority.
When, for example, the following system calls are executed for tasks A and B of the same priority, the result is as indicated below.
tk_sta_tsk (tskid=task_A, stacd_A); tk_sta_tsk (tskid=task_B, stacd_B); /* By the rule of FCFS, precedence becomes task_A → task_B. */ tk_sus_tsk (tskid=task_A); tk_rsm_tsk (tskid=task_A); /* In this case precedence becomes task_B → task_A. */
E_OK | Normal completion |
E_ID | Invalid ID number (tskid is invalid or cannot be used) |
E_NOEXS | Object does not exist (the task specified in tskid does not exist) |
E_OBJ | Invalid object state (the specified task is not in SUSPENDED state (including when this system call specifies the invoking task or a task in DORMANT state)) |
Releases the SUSPENDED state of the task specified in tskid
. If the target task was earlier put in SUSPENDED state by the tk_sus_tsk system call, this system call releases that SUSPENDED state and resumes the task execution.
When the target task is in a combined WAITING state and SUSPENDED state (WAITING-SUSPENDED state), executing tk_frsm_tsk releases only the SUSPENDED state, putting the task in WAITING state (see Figure 1 in the Section called Task States in the Chapter called μT-Kernel Concepts).
This system call cannot be called for the invoking task. If the invoking task is specified, error code E_OBJ is returned.
Executing tk_frsm_tsk once clears all the nested suspend requests (suscnt
) (suscnt
= 0). Therefore, all suspend requests are released (suscnt
is cleared to 0) even if tk_sus_tsk was issued more than once (suscnt
≧ 2). The SUSPENDED state is always cleared, and unless the task was in the WAITING-SUSPENDED state, its execution resumes.
After a task in RUNNING state or READY state is put in SUSPENDED state by tk_sus_tsk and then resumed by tk_rsm_tsk or tk_frsm_tsk, the task has the lowest precedence among tasks of the same priority.
When, for example, the following system calls are executed for tasks A and B of the same priority, the result is as indicated below.
tk_sta_tsk (tskid=task_A, stacd_A); tk_sta_tsk (tskid=task_B, stacd_B); /* By the rule of FCFS, precedence becomes task_A → task_B. */ tk_sus_tsk (tskid=task_A); tk_frsm_tsk (tskid=task_A); /* In this case precedence becomes task_B → task_A. */
E_OK | Normal completion |
E_PAR | Parameter error (dlytim is invalid) |
E_CTX | Context error (issued from task-independent portion, or in dispatch disabled state) |
E_RLWAI | Waiting state released (tk_rel_wai received in waiting state) |
E_DISWAI | Wait released due to disabling of wait |
Temporarily stops execution of the invoking task and waits for time dlytim
to elapse.
The state while the task waits for the delay time to elapse is a WAITING state and is subject to release by tk_rel_wai.
If the task issuing this system call goes to SUSPENDED state or WAITING-SUSPENDED state while it is waiting for the delay time to elapse, the elapsed time continues to be counted in the SUSPENDED state.
The time unit for dlytim
(time unit) is the same as that for system time (= 1 ms).
This system call differs from tk_slp_tsk in that normal completion, not an error code, is returned when the specified delay time elapses. Moreover, the wait is not released even if tk_wup_tsk is executed during the delay time. The only way to terminate tk_dly_tsk before the delay time elapses is by calling tk_ter_tsk or tk_rel_wai.
E_OK | Normal completion |
E_PAR | Parameter error (dlytim_u is invalid) |
E_CTX | Context error (issued from task-independent portion, or in dispatch disabled state) |
E_RLWAI | Waiting state released (tk_rel_wai received in waiting state) |
E_DISWAI | Wait released due to disabling of wait |
Only when all the service profile items below are set to be effective, this system call can be used.
This system call takes 64-bit dlytim_u
in microseconds instead of the parameter dlytim
of tk_dly_tsk.
The specification of this system call is same as that of tk_dly_tsk, except that the parameter is replaced with dlytim_u
. For more details, see the description of tk_dly_tsk.
Only when all the service profile items below are set to be effective, this system call can be used.
Sends the task event specified in tskevt
to the task specified in tskid
.
There are eight task event types stored for each task, specified by numbers 1 to 8.
The task event send count is not saved, only whether the event occurs or not.
The invoking task can be specified by setting tskid
= TSK_SELF = 0. Note, however, that when tskid
= TSK_SELF = 0 is specified in a system call issued from a task-independent portion, error code E_ID is returned.
The task event function is used for task synchronization much like tk_slp_tsk and tk_wup_tsk, but differs from the use of these system calls in the following ways.
The wakeup request (task event) count is not kept.
Wakeup requests can be classified by the eight event types.
Using the same event type for synchronization in two or more places in the same task would cause confusion. Event type allocation should be clearly defined.
The task event function is intended for use in middleware, and as a rule should not be used in ordinary applications. Use of tk_slp_tsk and tk_wup_tsk is recommended for applications.
E_PAR | Parameter error (waiptn or tmout is invalid) |
E_RLWAI | Waiting state released (tk_rel_wai received in waiting state) |
E_DISWAI | Wait released due to disabling of wait |
E_TMOUT | Polling failed or timeout |
E_CTX | Context error (issued from task-independent portion, or in dispatch disabled state) |
Only when all the service profile items below are set to be effective, this system call can be used.
Waits for the occurrence of one of the task events specified in waiptn
. When the wait is released by a task event, the task events specified in waiptn
are cleared (raised task event &= ~waiptn
). The task event status when the wait was released (the state before clearing) is passed in the return code (tevptn
).
The parameters waiptn
and tevptn
consist of logical OR values of the bits for each task event in the form 1 << (task event number -1).
A maximum wait time (timeout) can be set in tmout
. The time unit for tmout
is the same as that for system time (= 1 ms). If the tmout
time elapses before the wait release condition is met (tk_sig_tev is not executed), the system call terminates, returning timeout error code E_TMOUT.
When TMO_POL=0 is set in tmout
, this means 0 was specified as the timeout value, and E_TMOUT is returned without entering WAITING state even if no task event occurs. When TMO_FEVR=(-1) is set in tmout
, this means infinity was specified as the timeout value, and the task continues to wait for a task event without timing out.
E_PAR | Parameter error (waiptn or tmout_u is invalid) |
E_RLWAI | Waiting state released (tk_rel_wai received in waiting state) |
E_DISWAI | Wait released due to disabling of wait |
E_TMOUT | Polling failed or timeout |
E_CTX | Context error (issued from task-independent portion, or in dispatch disabled state) |
Only when all the service profile items below are set to be effective, this system call can be used.
This system call takes 64-bit tmout_u
in microseconds instead of the parameter tmout
of tk_wai_tev.
The specification of this system call is same as that of tk_wai_tev, except that the parameter is replaced with tmout_u
. For more details, see the description of tk_wai_tev.
Only when all the service profile items below are set to be effective, this system call can be used.
Disables waits for the wait factors set in waitmask
by the task specified in tskid
. If the task is already waiting for a factor specified in waitmask
, that wait is released.
waitmask
is specified as the logical OR of any combination of the following wait factors.
#define TTW_SLP 0x00000001 /* Wait caused by sleep */ #define TTW_DLY 0x00000002 /* Wait for task delay */ #define TTW_SEM 0x00000004 /* Wait for semaphore */ #define TTW_FLG 0x00000008 /* Wait for event flag */ #define TTW_MBX 0x00000040 /* Wait for mailbox */ #define TTW_MTX 0x00000080 /* Wait for mutex */ #define TTW_SMBF 0x00000100 /* Wait for message buffer send */ #define TTW_RMBF 0x00000200 /* Wait for message buffer receive */ #define TTW_CAL 0x00000400 /* (reserved) */ #define TTW_ACP 0x00000800 /* (reserved) */ #define TTW_RDV 0x00001000 /* (reserved) */ #define TTW_MPF 0x00002000 /* Wait for fixed-size memory pool */ #define TTW_MPL 0x00004000 /* Wait for variable-size memory pool */ #define TTW_EV1 0x00010000 /* Wait for task event #1 */ #define TTW_EV2 0x00020000 /* Wait for task event #2 */ #define TTW_EV3 0x00040000 /* Wait for task event #3 */ #define TTW_EV4 0x00080000 /* Wait for task event #4 */ #define TTW_EV5 0x00100000 /* Wait for task event #5 */ #define TTW_EV6 0x00200000 /* Wait for task event #6 */ #define TTW_EV7 0x00400000 /* Wait for task event #7 */ #define TTW_EV8 0x00800000 /* Wait for task event #8 */ #define TTX_SVC 0x80000000 /* Extended SVC disabled */
TTX_SVC is a special value disabling not the task wait but the calling of an extended SVC. If TTX_SVC has been set when a task attempts to call an extended SVC, E_DISWAI is returned without calling the extended SVC. This value does not have the effect of terminating an already called extended SVC.
The return value (tskwait
) includes the waiting state of a task as a pattern of concatenated bits (bit width of INT data type - 1) after the waiting states are disabled by tk_dis_wai. If bit width of INT data type is 32, then this value is the same as the value tskwait
returned by tk_ref_tsk. Information concerning TTX_SVC is not returned in tskwait
. A tskwait
value of 0 means the task has not entered WAITING state (or the wait was released). If tskwait
is not 0, this means the task is in WAITING state for a cause other than those disabled in waitmask
. If the bit width of INT data type is less than 32, the information represented by upper bits that will not fit into INT data are not returned. Hence, in this case, even if tskwait
is zero, there is a possibility that the task is waiting for a cause that is not specified in waitmask
.
When a task wait is cleared by tk_dis_wai or the task is prevented from entering WAITING state after this system call has taken effect, E_DISWAI is returned.
When a system call for which there is the possibility of entering the WAITING state is invoked during wait-disabled state, E_DISWAI is returned even if the processing could be performed without waiting. For example, when message buffer space is available and it is possible to send message without entering the WAITING state, and if a message is sent to message buffer (tk_snd_mbf is called), the message is not sent and E_DISWAI is returned.
Disabling of wait that is set during an extended SVC will be cleared automatically upon return from the extended SVC to its caller. It is automatically cleared also when an extended SVC is called, reverting to the original setting upon return from the extended SVC.
Disabling of wait that is set is cleared also when the task reverts to DORMANT state. The setting made while a task is in DORMANT state, however, is valid and the disabling of wait is applied the next time the task is started.
In the case of semaphores and most other objects, TA_NODISWAI can be specified when the object is created. An object created with TA_NODISWAI specified cannot have wait disabled, and rejects any attempt to disable wait by tk_dis_wai.
The invoking task can be specified by setting tskid
= TSK_SELF = 0. Note, however, that when tskid
= TSK_SELF = 0 is specified in a system call issued from a task-independent portion, error code E_ID is returned.
The function to disable wait is provided for aborting the execution of an extended SVC handler in midway, but it is not restricted to that purpose only.
Note that the data type of return value of tk_dis_wai, (tskwait
), is of type INT、and its value range is implementation-dependent, so care must be taken. For example, you can not receive information concerning waiting task events under an implementation on 16-bits CPU. If it is desired to obtain task wait status without regard to the CPU bit width under μT-Kernel, it is necessary to reference tskwait
by invoking tk_ref_tsk. On the other hand, under T-Kernel, INT is defined to be 32 bits or wider, the return value of tk_dis_wai can show all the details of the wait status of a task.
Only when all the service profile items below are set to be effective, this system call can be used.
Releases all disabling of waits set by tk_dis_wai for the task specified in tskid
.
The invoking task can be specified by setting tskid
= TSK_SELF = 0. Note, however, that when tskid
= TSK_SELF = 0 is specified in a system call issued from a task-independent portion, error code E_ID is returned.