Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
OSE Epsilon
ARM Kernel
ARM Kernel
Reference Manual
Copyright
Copyright 2005 by Enea Embedded Technology. All rights reserved. No part of this publication may be reproduced, transmitted, stored in a retrieval system, or translated into any language or computer language, in any form or by any means, electronic, mechanical, optical, chemical or otherwise, without the prior written permission of Enea Embedded Technology. If, however, your only means of access is electronic, permission to print one paper hardcopy is hereby granted. The software described in this document is furnished under a licence agreement or a non-disclosure agreement. The software may be used or copied only in accordance with terms of agreement.
Disclaimer
Enea Embedded Technology makes no representations or warranties with respect to the contents hereof and specifically disclaims any implied warranties of merchantability or fitness for any particular purpose. Further, Enea Embedded Technology reserves the right to revise this publication and to make changes from time to time in the contents hereof without obligation to Enea Embedded Technology to notify any person of such revision or changes.
ARM Kernel
Trademarks
OSE is a registered trademark of Enea Embedded Technology.
Contents
1 Introduction 2 System Call Summary 3 System Calls
3.1 3.2 3.3 3.4 3.5 3.6 3.7 Data Type Definitions 12 Basic System Calls 13 Advanced System Calls 13 System Calls for Link handler 14 System Calls for Semaphores 14 System Calls for Fast Semaphores 14 System Calls 15
5 7 11
4 Timing Specification
61 65
ARM Kernel
5 User Interface
5.1 Header and Include Files 66 5.2 Data Types 67
6 Error Messages
6.1 Run-Time Error Messages 70 6.2 Configuration Error Messages 76
69
7 Reserved Words
79
Contents 3
ARM Kernel
4 Contents
1 Introduction
OSE Epsilon for ARM is a fast, compact, real-time operating system for the ARM (Thumb) line of microprocessors from ARM Ltd. The purpose of this Reference Manual is to give the reader a good understanding of the different mechanisms in OSE. It contains also the system call summary, a detailed description of every system call, specification of data types and an error message guide. This manual is intended for users not familiar with real-time programming as well as experienced users and is intended for application developers. This manual contains reference information for ARM Kernel, described in:
System Call Summary on page 7 gives a system call summary. System Calls on page 11 is a detailed description of every system call in C. Timing Specification on page 61 indicates the timing of all system calls User Interface on page 65 defines the user interface with header files and data types. Error Messages on page 69is the Error Message Guide for run-time and configuration error messages. Reserved Words on page 79 is a description of reserved words. Document Revisions on page 83 is the document revision history.
ARM Kernel
Introduction 5
ARM Kernel
6 Introduction
Description ADD_TICKS adds a specified number of ticks to the system tick counter. ADDRESSEE finds addressee of signal directed to process in another CPU. ALLOC reserves memory for a user process. ALLOC_NIL reserves memory for a user process. ALLOC_NIL works like ALLOC with the exception that memory shortage causes return of a NIL pointer. COND_HALT conditionally calls the power off handler, depending on the number of ticks remaining before the next scheduled time-out event. CREATE_SEM creates a dynamic semaphore structure. CURRENT_PROCESS returns the process ID of the currently running process. DELAY suspends execution of the calling process for the requested number of system ticks. ERROR collects error information and is called by any user process detecting an error condition. FLUSH removes signals of the requested senders from the signal queue of the designated process. FREE_BUF returns memory from a user process to the system. GET_FSEM reads the current value of a fast semaphore. GET_SEM reads the current value of a semaphore. GET_PRI returns the current priority level of a prioritized process. GET_TICKS returns current system clock tick count.
ARM Kernel
create_sem (p. 22) current_process (p. 23) delay (p. 24) error (p. 25) flush (p. 26) free_buf (p. 28) get_fsem (p. 29) get_sem (p. 30) get_pri (p. 31) get_ticks (p. 32)
Description KILL_SEM returns a semaphore created by create_sem to the pool. POWER_FAIL is used in case of power failure and it causes the present environment to be saved in order to be restored after a warm start. RECEIVE searches the signal queue of the calling process for one or more desired signals. RECEIVE_ALL_BUT searches the signal queue in the same manner as RECEIVE but with reversed logic. Any signal is received except the signals specified in the array. RECEIVE_FSEM waits for either a signal, a fast semaphore, or a time-out. RECEIVE_W_TMO searches the signal queue of the calling process for one or more desired signals with a selectable timeout. RESTORE enters the calling process as owner and addressee of the buffer. SEND moves a buffer from the sending process to the signal queue of the receiving process. SENDER obtains the process number of the process which sent a buffer. SEND_W_S sends signals exactly like SEND, but the sender of the buffer may be set to any process ID. SET_FSEM assigns a value to a fast semaphore. SET_PRI sets a new priority level for the calling process. SIGNAL_FSEM signals a fast semaphore for the specified process. SIGNAL_SEM increments the value of the specified semaphore and releases the first process waiting at the semaphore. SIGSIZE obtains the size of a buffer. START causes a stopped process to resume execution as soon as no process of higher priority is running.
ARM Kernel
restore (p. 43) send (p. 45) sender (p. 47) send_w_s (p. 48) set_fsem (p. 50) set_pri (p. 51) signal_fsem (p. 52) signal_sem (p. 53) sigsize (p. 54) start (p. 55)
Description STOP suspends execution of the required process until it is started using the START system call. WAIT_FSEM waits on a fast semaphore. WAIT_SEM waits at the specified semaphore structure. WAKE_UP informs an interrupt process of how it was invoked.
For more information, see System Calls on page 11. For a description of the system calls in Assembler, see System Calls in Assembler on page 85.
ARM Kernel
Reference Manual / 4.6
ARM Kernel
10 System Call Summary
3 System Calls
System calls are calls to the operating system to use its services. This chapter explains how to use system calls by processes written in C. The declarations needed to use the OSE Epsilon for ARM System Calls are present in the header files supplied with OSE Epsilon for ARM, i.e. in the files ose.h and ose_i.h. Only the union SIGNAL declaration must be added. For each call, the syntax of the call is given, followed by an example. The "&"-operator must be used to provide addresses to pointers to buffers. Such pointers are named buf_ptr in the syntax definitions. The C interface protects registers required by the C compiler. System functions can detect user errors. If the Illuminator System Level Debugger is running, it will report such errors. In an actual system, you may wish to write a small error handler procedure to display errors if some display device is available. (For details, refer to the ARM Kernel Users Guide.) Use lower case letters in system call names when calling from processes written in C.
ARM Kernel
See:
Data Type Definitions on page 12 Basic System Calls on page 13 Advanced System Calls on page 13 System Calls for Link handler on page 14 System Calls for Semaphores on page 14 System Calls for Fast Semaphores on page 14 System Calls on page 15
System Calls 11
ARM Kernel
The member PROCESS f and PROCESS b are of no interest to applications. Init to NULL.
alloc (p. 18) delay (p. 24) error (p. 25) free_buf (p. 28) receive (p. 35) receive_w_tmo (p. 41) send (p. 45) sender (p. 47)
ARM Kernel
(p. 15) alloc_nil (p. 20) cond_halt (p. 21) current_process (p. 23) get_pri (p. 31) get_ticks (p. 32) power_fail (p. 34) receive_all_but (p. 37) receive_fsem (p. 39) set_pri (p. 51) sigsize (p. 54) start (p. 55) stop (p. 56) wake_up (p. 59)
addressee (p. 16) flush (p. 26) restore (p. 43) send_w_s (p. 48)
create_sem (p. 22) get_sem (p. 30) kill_sem (p. 33) signal_sem (p. 53) wait_sem (p. 58)
ARM Kernel
get_fsem (p. 29) set_fsem (p. 50) signal_fsem (p. 52) wait_fsem (p. 57)
Adds a specified number of ticks to the system tick counter. ticks None. The number of ticks to advance the system tick counter.
add_ticks adds a specified number of ticks to the system tick counter. This system call is intended to make corrections to the system time after the system has been powered down or halted for a while, i.e. in power-on handler at hot start. There are several types of behaviour associated with the system ticks. Only some of these are updated by calling add_ticks.
ARM Kernel
Timer interrupts:
No, not updated
The other mechanisms will not be updated. If any time-outs or delays were scheduled to expire during the time that was skipped over by calling add_ticks, those delays and time-outs will expire at a later time. This can be avoided by never adding more ticks than the number of ticks indicated by the cond_halt mechanism.
System Calls 15
addressee
Syntax PROCESS addressee (union SIGNAL **sig);
Finds addressee of signal directed to process in another CPU. Addressee examines a signal buffer to find out to which process the buffer was originally sent by the sender. sig A pointer to a pointer to a signal buffer.
General This system call is intended for link handlers. addressee returns the ID of the process to which the signal was sent. When a signal is sent, OSE tags the buffer with the specified receiver process ID. This is normally the same process that eventually receives the buffer. Therefore addressee returns the ID of the current process most of the time. When a signal is sent to a process which does not exist in this CPU, OSE redirects the signal to a link handler. From this point, the addressee of the buffer is no longer the same as the receiving process, and OSE will not alter the addressee of the buffer until it has been restored with the restore system call. This mechanism enables a link handler to pass the buffer on to other link handler processes using the send_w_s call, without losing the original addressee of the buffer.
ARM Kernel
16 System Calls
Example
#include "ose.h" static const SIGSELECT any_sig[] = {0}; union SIGNAL { SIGSELECT sig_no; }; OS_PROCESS(my_process) { union SIGNAL *sig; PROCESS addr; for(;;) { sig = receive((SIGSELECT *) any_sig); addr = addressee(&sig); if(addr == current_process ()) { /* The signal was sent directly to this process */ } else { /* Signal was sent to another process*/ } } }
ARM Kernel
Reference Manual / 4.6
System Calls 17
alloc
Syntax union SIGNAL *alloc (OSBUFSIZE size, SIGSELECT signo);
Description Parameters
Reserves memory for a user process. size signo The requested size of the buffer. The signal number will be placed in the allocated buffer.
Return Value
General This system call is used to reserve memory. The caller must state the amount of memory required and also furnish a value to be inserted in the first halfword of the buffer. The first halfword is used for signal identification when buffers contain signals. It is not illegal to use signal number zero (0) and $8000, but it is not advised, since in the debugger is using these signal numbers. 0 is used to indicate any signal and $8000 is used to signal process swaps. It is an error to try to allocate a buffer of size 0 (zero).
ARM Kernel
The maximum buffer size is stated in the configuration file (osarm.con). Alloc will select one of the eight fixed memory sizes chosen when the system was generated. The size selected will always be large enough to accommodate the requested number of bytes. Each buffer is preceded by a 12 byte administration block which is used by OSE Epsilon for ARM. Users generally need not care about the administration block. When the system starts, all memory available for buffers is located in the buffer pool. As users allocate buffers, they are removed from the buffer pool and handed over to users. When users return buffers to the system they are stored in lists for returned buffers. They never again return to the buffer pool. If such returned buffers are available, as is almost always the case, alloc will allocate them first. This allocation scheme ensures consistent allocation times and that the memory can never be fragmented, i.e. split up into many small sections, too small to use. If no used buffers of the requested size are available and the system pool does not contain enough memory to allocate the requested buffer, a fatal error is reported. This occurs even if a buffer of a larger size than the closest fit is available. Note that the actual buffer may be larger than requested since the buffersizes are fixed.Process number of the sending process is valid only after the buffer has been sent. Four more bytes are used at the end of the buffer if the debug option is used when configuring the system.
18 System Calls
Example
#include "ose.h" #define THIRD 3 /* struct Third /* { /* SIGSELECT sig_no;/* }; union SIGNAL { SIGSELECT sig_no; struct Third third; }; OS_PROCESS(my_process) { union SIGNAL *sig; extern PROCESS proc_;/* Process ID for process "proc" */ for(;;) { sig = alloc(sizeof(struct third),THIRD); send(&sig,proc_); delay(100); } } These declarations */ are preferably made */ in a .sig-file which*/ should be included. */
ARM Kernel
Reference Manual / 4.6
System Calls 19
alloc_nil
Syntax union SIGNAL *alloc_nil (OSBUFSIZE size, SIGSELEC signo);
Description Parameters
Reserves memory for a user process. alloc_nil works like alloc with the exception that memory shortage causes return of a NIL pointer. size signo The requested size of the buffer. The signal number will be placed in the allocated buffer.
Return Value
A pointer to the allocated buffer if the alloc_nil call was successful. If there was a memory shortage a NIL pointer will be returned.
General Alloc_nil works like alloc with the exception that memory shortage is treated differently. Alloc_nil returns a NIL pointer in case of memory shortage. Note that designing a system where memory shortage is not a fatal error is much more complicated than designing a system that always expects to have enough memory. It would be necessary to always expect memory shortage when allocating a memory buffer and provide a non fatal alternative action for every instance where memory is allocated. Otherwise memory shortage caused by large memory consumption in one part of the system could cause a fatal failure to allocate memory in another part of the system. Because of these difficulties, using alloc_nil in a system should only be done after careful design analysis. An alternative design approach is often preferable. E.g. if a small portion of the system is expected to consume an undetermined amount of memory, it is probably easier to design a mechanism that limits memory consumption in those areas, than dealing with the system-wide problem of expecting memory shortage. It is however possible to use alloc_nil safely in a limited part of a system if some special conditions are met, by doing 'tricks' with the memory allocation system. The 'trick' is to use alloc_nil only on some of the 8 available buffer sizes, and to create enough buffers of the other sizes at system start. The drawback of this approach is that the flexibility is lost and a thorough analysis of the memory use in the system must be performed.
ARM Kernel
20 System Calls
cond_halt
Syntax void cond_halt (OSTICKS min_ticks);
cond_halt conditionally calls the power off handler, depending on the number of ticks remaining before the next scheduled time-out event. min_ticks None. The threshold number of ticks until next time-out event for calling the power off handler.
General Cond_halt finds out the number of ticks until the next scheduled time-out event. If this is more or equal to the min_ticks value, the power off handler is called. The time-out events considered only include time outs created by the system calls delay, receive_w_tmo and receive_fsem. Other timing related events such as rescheduling of background processes and calling timer interrupt processes do not affect cond_halt.
ARM Kernel
The power off handler is called with information about the number of ticks until the next time-out event. It can use this information to set up a hardware timer for a matching delay time, and then power down or halt the processor. See Configuring OSE Epsilon for ARM, Power off handler for details. The min_ticks value is useful if powering down or halting for very short periods of time should be avoided. That can be the case if the power required to start and stop the system is not negligible. The min_ticks parameter should be set high enough to prevent power down cycles that are shorter than break-even. A min_ticks parameter of 0 will always cause the power off handler to be called. cond_halt is normally called from a background process. This will cause the system to save power when there is no work to be done. Note that the power_down system call is not equivalent to a cond_halt call with a min_ticks parameter of 0. Even though the power off handler will be called in both cases, information about the number of ticks before the next time-out event will only be sent to the handler if called through cond_halt.
System Calls 21
create_sem
Syntax Description SEMAPHORE *create_sem (OSSEMVAL init_val); Creates a dynamic semaphore structure and initializes it to the value specified in initial_val. The initial value must be zero or a positive value. Typical values are 0 and 1. The semaphore is dynamically allocated from the current pool. It may be returned to the pool when it is no longer in use by calling kill_sem. Parameters Return Value General init_val The initial value of the created semaphore.
It is the user's responsibility to ensure that the semaphore is not killed while it is still in use. The semaphore is dynamically allocated from the current pool. It may be returned to the pool when it is no longer in use by calling kill_sem.
ARM Kernel
Semaphores may also be statically defined by simply declaring a static semaphore structure in the program and initializing it. Such semaphores can not be killed. Semaphore structures contain three fields. The first must be initialized to the initial (positive) value of the semaphore. The second and third fields must be initialized to zero, and are required for internal use by the kernel. The three fields of a semaphore structure are named "value", "f" and "b" respectively. The value field is of type OSSEMVAL. The types of the other fields are implementationspecific. This applies only for static semaphores. Example
#include "ose.h" OS_PROCESS(my_process) { SEMAPHORE *sem; for(;;) { /* Code */ sem = create_sem (1) /* Code */ } }
22 System Calls
current_process
Syntax PROCESS current_process (void);
The call current_process returns the process ID of the currently running process, i.e. the ID of the caller. None. Returns the process ID of the calling process.
General This call is used by any process which needs to obtain its own process ID. For example a library function may be interested in from which process it was called. Example
#include "ose.h" OS_PROCESS(my_process) { PROCESS proc_; for(;;) { /* Code */ proc_ = current_process(); /* Code */ } }
ARM Kernel
Reference Manual / 4.6
System Calls 23
delay
Syntax void delay (OSTIME time);
The call delay suspends execution of the calling process for the requested number of system ticks. time None. The number of system ticks the delay is to last.
General This system call is used when a process needs to suspend execution for a time. OSE guarantees that the process is kept waiting for at least the requested time minus one system tick. The actual waiting time may always be longer than the requested, since other processes of higher priority may run for an indeterminate time. Delay can not be called from an interrupt process since an interrupt process can never be swapped out. Example
ARM Kernel
#include "ose.h" OS_PROCESS(my_process) { for(;;) { turn_on_lamp(); /* fictive function */ delay(10); turn_off_lamp(); /* fictive function */ delay(10); } }
24 System Calls
error
Syntax void error (OSERRCODE my_info);
collects error information and is called by any user process detecting an error condition. my_info None. The error number to be passed to the error handler.
General This system call is used by processes detecting an error condition. The operating system also uses error to report errors. The caller may provide information about the error. It is not necessary to provide information on process number and error location, since this is automatically provided by error. Errors detected by OSE are always fatal and the system can not continue execution; a restart is necessary.
ARM Kernel
The user may provide an error handler to handle detected errors. Such a handler may log the error on a printer, show it on a display, send it on a serial link etc. It will use whatever output devices present in the system. (For details, see 10.9 Writing an Error Handler). If no error handler is present or if an error handler returns from an error detected by OSE, the system enters an infinite loop. If an error handler returns from a user reported error, control is returned to the process calling error. Interrupts are disabled while an error handler is executing. You are not allowed to use system calls in the error handler except:
addressee current_process get_fsem get_sem get_pri get_ticks sender sigsize wake_up
System Calls 25
flush
Syntax void flush (PROCESS *psel, PROCESS pid);
Description
Removes signals from the requested senders from the signal queue of the designated process. The flush call throws away all signals sent by any of a set of processes specified in psel, from the signal queue of the process specified in pid. The psel parameter is an array of process ID's. The first location contains the number of valid entries in the rest of the array.
Parameters
psel pid
A pointer to an array of processes to flush signals from. The process ID of the receiving process.
Return Value
None.
General flush is intended for communications software only. The first parameter to flush is a pointer to a RAM array of senders. flush removes every signal from any of the senders from the signal queue of the process in the second parameter. Signals from senders not in the array remain in the queue. The removed signals are freed by flush. The psel array must be built in run-time since process identities are unknown at compile time. The first location in psel contains the number of entries in the rest of the array. Since the PROCESS type may not be compatible to an integer, the count should be cast to the PROCESS type when building psel. Ex: psel[0] = (PROCESS) 1; It is illegal to flush the queue of an interrupt process or timer-interrupt process. It is also illegal to call flush from an interrupt or timer-interrupt process. flush uses start/stop internally to stop processes while their queues are flushed. If flush must be re-entrant (may be called from several processes), the semaphores option is also required.
ARM Kernel
26 System Calls
Example
#include "ose.h" extern PROCESS proc1_; extern PROCESS proc2_; OS_PROCESS(my_process) { PROCESS flush_array[2]; flush_array[0] = (PROCESS) 1; flush_array[1] = proc1_; for (;;) { /* Code */ flush (flush_array, proc2_); /* Throws away all */ /* signals sent */ /* from proc1 to proc2*/ /* Code */ } }
ARM Kernel
Reference Manual / 4.6
System Calls 27
free_buf
Syntax void free_buf (union SIGNAL **sig);
Returns memory from a user process to the system. sig None. A pointer to a pointer to the signal buffer to free.
General free_buf is used to return memory which is no longer needed. Only memory allocated using alloc may be returned using free_buf. Memory which has been returned can be used by other processes. If you send a signal buffer to another process it is the responsibility of the receiving process to free the buffer. It is an error for the sending process to try to do so. Example
#include "ose.h"
ARM Kernel
static const SIGSELECT any_sig[] = {0}; union SIGNAL { SIGSELECT sig_no; } OS_PROCESS(my_process) { union SIGNAL *sig; for(;;) { /* Code */ sig = receive((SIGSELECT *) any_sig); /* Code */ free_buf(&sig); } }
28 System Calls
get_fsem
Syntax OSFSEMVAL get_fsem (PROCESS pid);
Reads the current value of a fast semaphore. pid The ID of the process which owns the desired semaphore.
General get_fsem is used to read the current value of a fast semaphore. An interrupt process may for example test a semaphore for overflow before calling signal_fsem. Example
#include "ose.h" OS_PROCESS(my_process) { OSFSEMVAL fsemvalue; for(;;) { /* Code */ fsemvalue = get_fsem(current_process()); /*Code */ } }
ARM Kernel
Reference Manual / 4.6
System Calls 29
get_sem
Syntax Description Parameters Return Value General get_sem is used to read the current value of a semaphore. Example #include "ose.h" extern SEMAPHORE *sem; OS_PROCESS(my_process) { OSSEMVAL semvalue; for(;;) { /* Code */ semvalue = get_sem (sem); if(semvalue == 5) { /* Code */ } else { /* Code */ } } } OSSEMVAL get_sem (SEMAPHORE *sem); Reads the current value of a semaphore. sem A pointer to the specified semaphore
ARM Kernel
30 System Calls
get_pri
Syntax PRIO get_pri (PROCESS pid);
Returns the current priority level of a prioritized process. pid The ID of the specified process.
General get_pri is used to find out the priority of a prioritized process. The call does not work for any other kind of process. Example
#include "ose.h" OS_PROCESS(my_process) { PRIO prio; for(;;) { prio = get_pri(current_process()); if(prio != 31) { set_pri(++prio); } else { set_pri(0); } delay(100); } }
ARM Kernel
Reference Manual / 4.6
System Calls 31
get_ticks
Syntax OSTICKS get_ticks (void);
Returns current system clock tick count. None. System time in tick.
General get_ticks is used to find out the current value of the system clock. The system clock is set to zero at system start. It is subsequently incremented at each system tick. Example
#include "ose.h" OS_PROCESS(my_process) { long tick; for(;;) { /* Code */ tick = get_ticks(); /* Code */ } }
ARM Kernel
32 System Calls
kill_sem
Syntax Description Parameters Return Value General void kill_sem (SEMAPHORE *sem); Returns a semaphore created by create_sem to the pool. sem None. A pointer to the semaphore
ARM Kernel
Reference Manual / 4.6
System Calls 33
power_fail
Syntax Description Parameters Return value void power_fail (void); Used in case of power failure and it causes the present environment to be saved in order to be restored after a warm start. None. None.
General This call is used in systems where memory contents remain undisturbed in case of temporary power failures. When the power fails, any process may call power_fail. If called from a prioritized or background process, power_fail will swap out the current process and then call the user supplied power off handler to shut down the power source and wait for a restart. If called from an interrupt or timer-interrupt process, power_fail will return immediately to the calling interrupt process. When the interrupt is done, OSE Epsilon for ARM will swap out the current process and then call the user supplied power off handler. The power off handler is declared in osarm.con. When power returns, after reset, the user supplied power on handler is called to determine if memory contents are valid for a warm start or if a cold start is necessary. The power on handler is also declared in osarm.con. If power_fail was called from a prioritized or background process the caller "returns" from power_fail when power is restored and execution may continue where it was interrupted by the power failure. If power_fail was called from interrupt, execution continues at the prioritized or background process which was interrupted by the interrupt which called power_fail. A power off handler may calculate a memory checksum and leave it in memory for the power on handler. A power on handler may recalculate the checksum and allow a warm start if memory remains unharmed. I/O ports must also be initialised to the state that was present when power_fail was called. (This is a major issue which must be carefully considered.)
ARM Kernel
34 System Calls
receive
Syntax union SIGNAL *receive (SIGSELECT *sigsel);
Description
Searches the signal queue of the calling process for one or more desired signals. If a desired signal is found, it is removed from the queue and handed over to the calling process. sigsel Pointer to an array of the signal numbers to receive.
Returns a pointer to the received signal buffer. This buffer is owned by the caller from that moment.
General Receive will search the signal queue of the calling process for the requested signal(s). The first signal in the queue to match any of the required signals will be received. Sigsel points to an array containing a list of signal numbers to be received. Receive returns to the caller when a signal matching any of the specified signal numbers is found.
ARM Kernel
The first position in sigsel contains the number of entries in the list that follows. If the number of entries is zero, any signal number is accepted. When called from an interrupt or timer-interrupt process, receive always returns immediately. If no requested signal was immediately available in the signal queue, NIL is returned. This works in a manner similar to receive_w_tmo with a 0 timeout. (Note that receive_w_tmo is not available to interrupt and timer-interrupt processes.) If the signal queue is empty or none of the requested signals is available in the queue the process will be swapped out and another process allowed to run. As more signals arrive, the process will run again in order to scan the queue. Only when one of the required signals has arrived will the process return from the call to receive. A signal in a signal queue will never be scanned more than once during one call to receive. Receive During Interrupt It is permitted for an interrupt or timer-interrupt process to receive signals. If none of the required signals is present in the queue the interrupt process will return from the call to receive and a NIL-pointer is provided. An interrupt process must always be able to handle the case that receive may not return any signal.
System Calls 35
Example
#include "ose.h" #define THIRD 3 struct Third { SIGSELECT sig_no; }; #define FIFTH 5 struct Fifth { SIGSELECT sig_no; }; union SIGNAL { /* /* /* /* These declarations */ are preferably made */ in a .sig-file which*/ is included. */
/* /* /* /*
ARM Kernel
A union SIGNAL declaration */ must include a signal */ number and the signal */ structures of the signals */ that will be used. It must */ be present in every */ application using signals */
}; static const SIGSELECT any_sig[] = {0}; OS_PROCESS(my_process) { union SIGNAL *sig; for(;;) { sig = receive((SIGSELECT *) any_sig); switch(sig->sig_no) { case THIRD: /* Code */ break; case FIFTH: /* Code */ break; default: /* Code */ } free_buf(&sig); } }
36 System Calls
receive_all_but
Syntax Description Parameters Return Value union SIGNAL *receive_all_but (SIGSELECT *signotsel); Searches the signal queue in the same manner as receive but with reversed logic. Any signal is received except the signals specified in the array. signotsel Pointer to an array of the signal numbers not to receive.
Returns a pointer to the received signal buffer. This buffer is owned by the caller from that moment.
General Receive will search the signal queue of the calling process for all signal(s) excluding the ones defined in signotsel. The first signal in the queue to match any of the required signals will be received. Sigsel points to an array containing a list of signal numbers to be received. Receive returns to the caller when a signal not matching any of the specified signal numbers is found.
ARM Kernel
The first position in sigsel contains the number of entries in the list that follows. If the number of entries is zero, any signal number is accepted. When called from an interrupt or timer-interrupt process, receive always returns immediately. If no requested signal was immediately available in the signal queue, NIL is returned. This works in a manner similar to receive_w_tmo with a 0 timeout. (Note that receive_w_tmo is not available to interrupt and timer-interrupt processes.) If the signal queue is empty or none of the requested signals is available in the queue the process will be swapped out and another process allowed to run. As more signals arrive, the process will run again in order to scan the queue. Only when one of the required signals has arrived will the process return from the call to receive. A signal in a signal queue will never be scanned more than once during one call to receive. Receive During Interrupt It is permitted for an interrupt or timer-interrupt process to receive signals. If none of the required signals is present in the queue the interrupt process will return from the call to receive and a NIL-pointer is provided. An interrupt process must always be able to handle the case that receive may not return any signal.
System Calls 37
Example
#include "ose.h" #define FIRST 1 struct First { SIGSELECT sig_no; }; #define THIRD 3 struct Third { SIGSELECT sig_no; }; union SIGNAL { SIGSELECT sig_no; struct First first; struct Third third; }; static const SIGSELECT exclude_sig[] = {1,FIRST}; OS_PROCESS(my_process) { union SIGNAL *sig; for(;;) { sig = receive_all_but ((SIGSELECT *) exclude_sig); switch(sig->sig_no) { case THIRD: /* Code */ break; default: /* Code */ } free_buf(&sig); } }
ARM Kernel
38 System Calls
receive_fsem
Syntax union SIGNAL *receive (OSTICKS timeout, SIGSELECT *sigsel OSFSEMVAL semvalue);
Description
waits for either a signal, a fast semaphore, or a time-out. If the signal was already available, or the fast semaphore had already been signalled, the call will return immediately. The time-out is optional: it can either be set to 0 causing a check for signal or fast semaphore. It can also be set to -1, resulting in an infinite time-out.
Parameters
timeout
The time which will elapse before returning if none of the wanted signals turn up and the fast semaphore is not signalled. The time may be almost one system time shorter and many system ticks longer if other processes of higher priority requests the CPU. 0 is legal and forces return without any delay, i.e. checking if either a desired signal is available, or if the fast semaphore had already been signalled. -1 indicates an infinite time-out, preventing return because of time-out. Pointer to an array of the signal numbers to receive. Requested number of time to wait on the fast semaphore. This is usually 1.
ARM Kernel
Returns a pointer to the received signal buffer. This buffer is owned by the caller from that moment.
Receive_fsem combines wait_fsem with receive_w_tmo. It receives signals and times out in exactly the same manner as receive_w_tmo. Additionally it waits for fast semaphores much like wait_fsem. The return value indicates which type of event caused the call to return. The fast semaphore associated with the calling process is decreased by semvalue on entry to receive_fsem. The call will return immediately if the fast semaphore is still positive, i.e. if the fast semaphore had been signalled at least semvalue time before the call to receive_fsem. The call can return because of fast semaphore signalling as soon as the fast semaphore is positive. If the call returns because of another event than the fast semaphore, the fast semaphore is increased by semvalue before the call returns. This insures that no fast semaphore event is missed even if there are several simultaneous events. Receive_fsem will receive signals in exactly the same manner as receive. All signals will remain in the signal queue if a return is caused by fast semaphore signalling or a time-out. The time to wait is given in the type OSTICKS. Timeouts of 0 ticks return immediately. Timeouts set to 1 expire at the next system tick, that is after 0-1 system tick. Time-outs of 0 ticks return immediately after checking. Time-outs set to 1 expire at the next system tick, that is after 0-1 system tick. It is also possible to avoid time-outs altogether by using a time to wait value of -1.
System Calls 39
Several events may appear to occur simultaneously, e.g. if a wanted signal is sent to the process and the fast semaphore is signalled during execution of higher or equal priority processes. It cannot be known which of several simultaneous events will cause receive_fsem to return. The following is however guaranteed:
When return is caused by a signal, the first wanted signal in the signal queue will be returned. The return value will not indicate a time-out if a signal arrives or the fast semaphore is signalled within he specified time. If the fast semaphore had been signalled enough time before the entry to the call, the return value will be OS_RCV_FSEM.
Receive_fsem cannot be called from an interrupt process since an interrupt process can never wait for any event except interrupts. Example
#include "ose.h" static const SIGSELECT any_sig[] = {0};
ARM Kernel
union SIGNAL { SIGSELECT sig_no; }; OS_PROCESS(my_process) { union SIGNAL *sig; for(;;) { /* Wait for any signal in 10 ticks time */ sig = receive_fsem ((OSTICKS) 10, any_sig, 1); If (my_signal_p == NIL) { /* Timeout has occurred */ } else if (my_signal_p == (-1)) { /* Semaphore count became zero */ } else { /* A signal was received */ } } }
40 System Calls
receive_w_tmo
Syntax union SIGNAL *receive (OSTICKS timeout, SIGSELECT *sigsel);
Description
Searches the signal queue of the calling process for one or more desired signals. If a desired signal is found, it is removed from the queue and handed over to the calling process. If none of the desired signals arrive within the specified time, receive_w_tmo returns a NIL-pointer. timeout The time which will elapse beforereceive_w_tmo returns, if none of the wanted signals turns up. The time may be almost one system time shorter and many system ticks longer if other processes of higher priority requests the CPU. 0 is legal and forces return without any delay. Pointer to an array of the signal numbers to receive.
Parameters
Returns a pointer to the received signal buffer. This buffer is owned by the caller from that moment.
ARM Kernel
Receive_w_tmo will receive signals in exactly the same manner as receive. However, if after the specified time none of the required signals have appeared, the call to receive_w_tmo returns with a NIL-pointer. The time to wait is given in the type OSTICKS. Timeouts of 0 ticks return immediately. Timeouts set to 1 expire at the next system tick, that is after 0-1 system tick. Receive_w_tmo can not be called from an interrupt process since an interrupt process can never wait for a signal. It is guaranteed that if a signal arrives within the specified time the calling process will get that signal. If, however, a signal arrives slightly after the time has elapsed the process may get it anyway. This is due to the fact that if a process of higher priority runs, the process calling receive_w_tmo may not get the opportunity to scan the queue until after the timeout has occurred.
System Calls 41
Example
#include "ose.h" static const SIGSELECT any_sig[] = {0}; union SIGNAL { SIGSELECT sig_no; }; OS_PROCESS(my_process) { union SIGNAL *sig; for(;;) { /* Wait for any signal in 10 ticks time */ sig = receive_w_tmo((OSTICKS) 10, any_sig); /* Check if a signal was received. If no signal was * received in 10 ms time the receive_w_tmo() sys * call will return NIL. */ if (sig != NIL) { /* Code */ free_buf(&sig); } else { /* Code */ } } }
ARM Kernel
42 System Calls
restore
Syntax void restore (union SIGNAL *sig);
Description Parameter
Enters the calling process as owner and addressee of the buffer. sig The pointer to the buffer to restore. Caution: This call has an unusual parameter systax (pointer to the buffer and not pointer to the pointer to the buffer).
Return Value
None.
General When a signal is sent to an external process, send will use a special buffer format when forwarding the buffer to the link handler. The link handler cannot return such buffers directly to the system; they must be re formatted. restore re formats such buffers. Any attempt to free an unrestored buffer may cause a system crash. When the DEBUG-option is used, every buffer possessed by a user process is owned by that process. When the buffer is sent/received owner is changed. Any attempt by a process to send/free a buffer it does not own is an error. If a buffer is taken over by another process without using send/receive, that process must call restore in order to be acknowledged as the new owner of the buffer. It can then be freed/sent in the ordinary manner.
ARM Kernel
Reference Manual / 4.6
System Calls 43
Example
#include "ose.h" static const SIGSELECT any_sig[] = {0}; union SIGNAL { SIGSELECT sig_no; }; OS_PROCESS(my_linkhandler) { union SIGNAL *sig; for(;;) { /* Code */ sig = receive((SIGSELECT *) any_sig); if(addressee(&sig) != current_process()) { restore(sig); /* Code */ } free_buf(&sig); } }
ARM Kernel
44 System Calls
send
Syntax void send (union SIGNAL **sig, PROCESS to);
Description Parameters
Moves a buffer from the sending process to the signal queue of the receiving process. sig to A pointer to a pointer to a signal buffer. The ID of the process the signal will be sent to. In order to send a signal to a process you must have the address to the process. To obtain the address, simply add an underscore to the name of the process, then declare it as an external process. The process names are those that you specified in the osarm.con file when you configured your system.
None.
ARM Kernel
Send transfers control of a signal buffer from the sending process to the receiving process, the addressee. Each process has one, and only one, queue for signals sent to the process. Buffers are entered at the end of the signal queue of the receiving process. The sending process can no longer access the buffer. If the receiving process is of higher priority than the sending process, the sending process will be swapped out and the receiving process will be swapped in. Before sending a buffer, it must be allocated using alloc. It is also possible to send a buffer which has been received from receive. Sending Signals To Another CPU This is done in exactly the same manner as when you send a signal to an internal process. However, you must provide the address yourself. Addresses to internal processes range from 1 to the number of processes you have. Before you can send signals to an external processor you will need to obtain or write a link handler for the physical link you intend to use. External process must have numbers in the range 0x0100 to 0xFF00, e.g. the low byte must be zero.
System Calls 45
Example
#include "ose.h" #define FORTH 4 /* struct forth /* { /* SIGSELECT sig_no;/* char data; }; extern PROCESS proc_; union SIGNAL { SIGSELECT sig_no; struct Forth forth; }; These declarations */ are preferably made */ in a .sig-file which */ is included. */
ARM Kernel
OS_PROCESS(my_process) { union SIGNAL *sig; for(;;) { sig = alloc(sizeof(struct forth), FORTH); sig->forth.data =x; send(&sig,proc_); /* Code */ } }
46 System Calls
sender
Syntax PROCESS sender (union SIGNAL **sig);
Obtains the process ID of the process which sent a buffer. sig A pointer to a pointer to a signal buffer.
Returns the process ID of the sender or zero if the signal was never sent.
General Sender is used to find out who sent a signal. You must have the pointer to a buffer before you may call sender, i.e. if you have sent the buffer to another process or freed it, it is too late to find out who sent it. Example
#include "ose.h" static const SIGSELECT any_sig[] = {0};
ARM Kernel
union SIGNAL { SIGSELECT sig_no; }; OS_PROCESS(my_process) { union SIGNAL *sig; for(;;) { sig = receive((SIGSELECT *) any_sig); /* Code */ send(&sig, sender(&sig)); } }
System Calls 47
send_w_s
Syntax void send_w_s (union SIGNAL **sig, PROCESS from, PROCESS to);
Description Parameters
Sends signals exactly like SEND, but the sender of the buffer may be set to any process ID. sig from to A pointer to a pointer to a signal buffer The ID of the process specified as sender. The ID of the process the signal will be sent to.
Return Value
None.
General The regular send system call always enters the calling process as sender in the buffer. if this is not desired, send_w_s performs a regular send but enters the specified process as the sender in the buffer. This might be useful to a link handler. Suppose that a signal comes to the link handler on the physical link. Once received by the link handler, the link handler may want to send the signal to the destination process. When doing that the link handler may enter the sending global process on the other side of the physical link as the sender of the signal. If the link handler was to use the regular send, the link handler would become sender, making it impossible for the receiving process to find out which process originally sent the signal. If a system has several link handlers, the process declared as LINKHANDLER will still have to forward signals from send to other link handlers. In this case send_w_s might be used, thus preserving the original senders. Note: External processes are numbered from 0x0100 to 0xFF00, i.e. the low byte must be zero.
ARM Kernel
48 System Calls
Example
#include "ose.h" #define FIFTH 5 struct fifth { SIGSELECT sig_no; }; extern PROCESS proc1_; extern PROCESS proc2_; union SIGNAL { SIGSELECT sig_no; }; OS_PROCESS(my_process) { union SIGNAL *sig; for(;;) { sig = alloc(sizeof(struct fifth), FIFTH); /* send a signal to proc2 specifying proc1 as sender */ send_w_s(&sig, proc1_, proc2_); /* Code */ } } /* /* /* /* These declarations */ are preferably made */ in a .sig-file which */ is included. */
ARM Kernel
Reference Manual / 4.6
System Calls 49
set_fsem
Syntax void set_fsem (OSFSEMVAL val, PROCESS pid);
Description Parameters
Assigns a value to a fast semaphore. val pid The initial value of the fast semaphore. Process ID of the process which owns the fast semaphore whose value is set.
Return Value
None.
General This system call is used to initialise the value of a fast semaphore before normal operation begins. A fast semaphore can not be referenced until it has been initialized. It is therefore wise to have processes initialize only their own fast semaphores. Example
ARM Kernel
#include "ose.h" extern PROCESS proc_; OS_PROCESS(my_process) { for(;;) { set_fsem((OSSEMVAL) 1, proc_); /* Code */ } }
50 System Calls
set_pri
Syntax void set_pri (OSPRIORITY newpri);
Sets a new priority level for the calling process. newpri None. The desired new priority for the calling process.
General Set_pri is used to modify the priority level of the calling process. The call only works for prioritized processes. The call will cause a context switch if the new priority is lower or equal to the priority of another process. (Calling set_pri with the same priority as the current priority will force a context switch to the next ready process, if there are other ready processes at the same priority.) Example
#include "ose.h" OS_PROCESS(my_process) { OSPRIORITY org_prio; OSPRIORITY prio; for(;;) { org_prio = get_pri(current_process()); prio = set_pri(31); if(prio == org_prio && org_prio == 31) { /* Code, priority could not be set */ } else { /* Code */ /* Reset the original priority */ prio = set_pri(org_prio); } } }
ARM Kernel
Reference Manual / 4.6
System Calls 51
signal_fsem
Syntax void signal_fsem (PROCESS pid);
Signals a fast semaphore for the specified process. pid None. The ID of the process which owns the desired semaphore.
General The fast semaphore for the specified process is incremented. If it becomes zero, the process waiting at the semaphore is made ready. Example
#include "ose.h" extern PROCESS proc_; OS_PROCESS(my_process) { for(;;) { /* Code */ signal_fsem(proc_); /* Code */ } }
ARM Kernel
52 System Calls
signal_sem
Syntax Description Parameters Return Value General void signal_sem (SEMAPHORE *sem); increments the value of the specified semaphore and releases the first process waiting at the semaphore. sem None. A pointer to the semaphore to be signaled.
It is illegal to cause a semaphore to wrap from high positive numbers to a negative value. Example
#include "ose.h" extern SEMAPHORE *sem; OS_PROCESS(my_process) { for(;;) { /* Code */ signal_sem(sem); /* Code */ } }
ARM Kernel
Reference Manual / 4.6
System Calls 53
sigsize
Syntax OSBUFSIZE sigsize (union SIGNAL **sig);
Examines a signal buffer and reports the size that was requested when the buffer was allocated. sig A pointer to a pointer to a signal buffer.
Returns the number of bytes requested when the buffer was allocated
General Sigsize is used to find the size that was requested from alloc when a buffer was first allocated. You must have the pointer to a buffer before you may call sigsize, i.e. if you have sent the buffer to another process or freed it, it is too late to find out the size. Example
#include "ose.h"
ARM Kernel
static const SIGSELECT any_sig[] = {0}; union SIGNAL { SIGSELECT sig_no; }; OS_PROCESS(my_process) { union SIGNAL *sig; union SIGNAL *sig2; OSBUFSIZE size; for(;;) { sig = receive((SIGSELECT *) any_sig); size = sigsize(&sig); sig2 = alloc(size,sig->sig_no); /* Code */ } }
54 System Calls
start
Syntax void start (PROCESS pid);
Causes a stopped process to resume execution as soon as no process of higher priority is running. pid None. The ID of the process which is to be started. For details on process names, refer to the section on send.
General Start is used to start a process which has been stopped using stop. If the process currently running is of lower priority than the started process, the current process will be swapped out and the stopped process will be allowed to run. Only when all calls to stop a process have been matched by the same number of calls to start the process will it be allowed to start. It is an error to start a process which is not stopped.
ARM Kernel
Example
#include "ose.h" extern PROCESS proc_; OS_PROCESS(my_process) { for(;;) { stop(proc_); /* Code */ start(proc_); } }
System Calls 55
stop
Syntax void stop (PROCESS pid);
suspends execution of the required process until it is started using the start system call. pid None. The ID of the process which is to be stopped. For details on process names, refer to the section on send.
General Stop is used to stop a process. The process will not again be allowed to run until all processes which have stopped the process have again ordered it started using start. It is an error to start a process which has not been stopped. A stopped process will not require CPU execution time. The stop function should be used with caution. If the currently running process is stopped, another process will be allowed to run. Stop During Delay If a process has been stopped while waiting for a delay to expire, the delay timer will continue to count. If the process is again started before the delay has expired the delay will continue and the process will not be allowed to run until the delay is finished. If, on the other hand, the delay has expired while the process was stopped, the process will be allowed to run as soon as it is started. Provided, of course, that no process of higher priority is running. Stop During receive_w_tmo If a process which was stopped during RECEIVE_W_TMO is started before the timeout is expired and the process has not received any required signal, execution of RECEIVE_W_TMO will continue as if the process had never been stopped. Example
#include "ose.h" extern PROCESS proc_; OS_PROCESS(my_process) { for(;;) { stop(proc_); /* Code */ start(proc_); } }
ARM Kernel
56 System Calls
wait_fsem
Syntax void wait_fsem (OSFSEMVAL count);
waits on a fast semaphore. count None. The number to decrease the fast semaphore with. Requested number of times to wait on the fast semaphore.
General Wait_fsem waits at the fast semaphore associated to the calling process. The semaphore is decreased by the requested amount. If the result becomes negative, the calling process is suspended until the semaphore again becomes positive or zero. This occurs when some other process has signalled the semaphore a sufficient number of times. Example
#include "ose.h" OS_PROCESS(my_process) { for(;;) { /* Code */ wait_fsem((OSFSEMVAL) 1); /* Code */ } }
ARM Kernel
Reference Manual / 4.6
System Calls 57
wait_sem
Syntax Description void wait_sem (SEMAPHORE *sem); Waits at the specified semaphore structure. The semaphore value is decremented. If the result is negative, the caller is suspended and queued at the end of the semaphore queue. Each time some other process signals the semaphore, the value is incremented and the first process queued at the semaphore is released Parameters Return Value General sem None. A pointer to the semaphore.
ARM Kernel
58 System Calls
wake_up
Syntax int wake_up (void);
Description
An interrupt process can be invoked in two ways; either by a hardware interrupt or by a software event. In both cases the interrupt process is invoked with interrupts disabled up to and including the hardware priority assigned to the interrupt process. The wake_up system call informs the interrupt process of the way in which it was invoked. This is useful because receive calls are fairly expensive and can often not be afforded at each hardware interrupt. Software events that cause interrupt processes to be invoked are signal transmissions to an interrupt process. This system call can be disabled by a configuration entry in osarm.con.
None. Returns 0 (zero) if the interrupt process was invoked by a hardware interrupt. Returns 1 (one) if the interrupt process was invoked by a signal sent to it. The signal is ready to be fetched with a receive call. Returns 2 if the interrupt process was invoked in response to a signal_fsem call issued by some other process. (The value of the fast semaphore is not important and can not be read with the get_fsem system call.) If called by a process of a type other than an interrupt process, the wake_up function returns 1 (one).
ARM Kernel
Reference Manual / 4.6
System Calls 59
Example
#include "ose.h" union SIGNAL { SIGSELECT sig_no; }; OS_PROCESS(my_interrupt_process) { static const SIGSELECT all[] = {0}; union SIGNAL *sig; switch(wake_up()) { case 0: /* hardware interrupt invoked the interrupt * process */ break; case 1: /* A signal sent to this process caused the wake_up */ sig = receive((SIGSELECT *)all); free_buf(&sig); break; case 2: /*signal_fsem() on this process caused the wake_up */ break; default: /* this is an error */ }
ARM Kernel
60 System Calls
4 Timing Specification
The execution times stated assume a ARM7TDMI processor running with a clock frequency of 20 MHz (OSE Epsilon for ARM in internal ROM, no wait states and external nonmultiplexed databus), and that the system has been configured for fast execution with no debug options selected. In some cases, when execution time has not been considered critical and execution time varies from time to time, the execution time is given as "roughly".
Table 2: Timing specification for ARM Kernel System Call Processor cycles Time in microseconds (ARM7TDMI, 20 MHz no waitstates)
ADDRESSEE
2 10
ARM Kernel
ALLOC
ALLOC
11
ALLOC_NIL
11 Allocating buffers for the first time is slightly more expensive than reallocating a used buffer. If this time is crucial you may wish to preallocate buffers at system start. 12
ALLOC_NIL
COND_HALT CURRENT_PROCESS
7 1
Timing Specification 61
Table 2: Timing specification for ARM Kernel System Call DELAY Processor cycles 5 Delay of zero. Time in microseconds (ARM7TDMI, 20 MHz no waitstates) 1 For other delays, the delay may be up to almost one system tick shorter, depending on when the next system tick occurs. 11 5 19
121 Delay of > zero. 53 Jump into errorhandler. 185 Varies with the number of signals removed from, and present in the queue. Add 130 cycles per wanted signal. 71 15 9 138 If the first signal in the queue is the required one and only one signal is required. 158 If the first signal in the queue is the required one and only one signal is required. 138 If the first signal in the queue is the required one and only one signal is required.
ARM Kernel
7 2 1 14
RECEIVE_ALL_BUT
16
RECEIVE_FSEM
14
62 Timing Specification
Table 2: Timing specification for ARM Kernel System Call RECEIVE_W_TMO Processor cycles 171 If the first signal in the queue is the required one and only one signal is required. Timeout = 0 46 To restore any buffer. 32 To restore the smallest available buffer. 100 100 12 14 52 64 If the semaphore value was non negative (no task switch takes place). 12 70 87 58 If the semaphore becomes negative, the dispatch time has to be added. 177 Process switch 17 Time in microseconds (ARM7TDMI, 20 MHz no waitstates)
RESTORE RESTORE
5 3
ARM Kernel
10 10 1 1 5 6
1 7 9 6
DISPATCH
18
Timing Specification 63
ARM Kernel
64 Timing Specification
5 User Interface
The user interface to OSE is defined in a number of C header and assembler include files, which should be included in an OSE application. These files are not affected by OSE kernel and interface library reconfiguration, even if the headers are sometimes produced by a configuration program. Header behaviour may be affected by manifest constants defined at compile time. In particular, the OS_DEBUG constant affects debugger support. Headers conform to ANSI recommendations, i.e. they use ANSI prototypes and may be included any number of times in any order. Internal OSE symbols begin with the string "zz" or "ZZ". Such symbols along with the names of all system calls, types, tags of enumerated types, macros and manifest constants are reserved by OSE. Many types begin with the letters "OS" or "ose_", so it is wise to avoid such symbols when writing an application. For more information, see Header and Include Files on page 66 and Data Types on page 67.
ARM Kernel
Reference Manual / 4.6
User Interface 65
ose.h Contains variable and code address declarations to be included in prioritized and background processes written in C. ose_i.h Contains variable and code address declarations to be included in timerinterrupt and interrupt processes written in C and declared as OS_INT in the OSE Configuration entry. ose_usr.h Contains variable and code address declarations to be included in prioritized and background processes written in C and running in USR mode. osarm.anc Contains variable and code address declarations to be included in prioritized and background processes written in assembly. osarmi.anc Contains variable and code address declarations to be included in timer interrupt and interrupt processes written in assembly. It is written in assembly.
ARM Kernel
All types except unions, structures and the SEMAPHORE type, which is a typedef for the semaphore structure, are simple types. This means that in an application variables of these types can be compared safely against each other for numerical equality. The types OSSEMVAL and OSFSEMVAL are signed. Other types are unsigned. When writing an application it is necessary to declare the "union SIGNAL" type and this must be done after including the ose.h header file. All signals that are used in a file must be part of the union signal declaration in that particular file.
ARM Kernel
The sig_no variable must always be part of the union. Signal structures may also be included if they are used, preferably declared in a header file which is included. The signal structure must contain the signal number but it may also contain other variables. A declaration of a signal structure can look as follows:
#define FIRST 1 struct First { SIGSELECT sig_no; /* Here, other data can be declared if desirable for instance: char data; */ };
Data Types 67
union SIGNAL A signal structure SIGSELECT A signal number PROCESS A process ID OSBUFSIZE The number of bytes in a signal OSFSEMVAL A fast semaphore value OSSEMVAL A semaphore value OSERRCODE Information passed to error() OSTICKS Used by delay() and similar
ARM Kernel
68 Data Types
6 Error Messages
Error messages are described in:
For an explanation of the error information and how to write an error handler, see the ARM Kernel Users Guide.
ARM Kernel
Reference Manual / 4.6
Error Messages 69
Table 3: Run-time Error Messages for ARM Kernel Error code (hex) 01 Error Attempt to allocate larger buffer than the largest size specified at system configuration. 8 buffersizes were specified in the osarm.con file before you generated the system you are running. The designated process has tried to allocate a buffer which is larger than the largest of the buffersizes. The memory pool was empty when the designated process tried to allocate memory. You must allocate more memory to the memory pool or your processes must use less memory. There is also the possibility that one or more processes fail to return memory to the system. The designated process called FREE providing a NIL-pointer. The process has called RECEIVE during interrupt and failed to observe that a NILpointer was returned. It may also have called RECEIVE_W_TMO and then failed to note that a NIL-pointer was returned. The designated process tried to free a buffer which did not have the number of the process. There are two known explanations for this:
The process which allocated or received the buffer turned it over to another process using a public variable to transfer the buffer. If such is the case, you should read Buffer Transfer in Building a System. It details how to transfer buffers without using SEND. The designated process has two or more pointers to the same buffer. It then used one pointer to send/free the buffer, whereupon it used another pointer to free the same buffer. Use only one pointer to each buffer.
ARM Kernel
02
03
04
Table 3: Run-time Error Messages for ARM Kernel Error code (hex) 05 Error The designated process called SEND_W_S providing a NIL-pointer. The process may have called RECEIVE or ALLOC during interrupt and failed to observe that a NIL-pointer was returned. It may also have called RECEIVE_W_TMO and then failed to note that a NIL-pointer was returned. This error may also indicate that a buffer was sent twice or freed before it was sent. The designated process called SEND providing a NIL-pointer. The process may have called RECEIVE during interrupt and failed to observe that a NIL-pointer was returned. It may also have called RECEIVE_W_TMO and then failed to note that a NIL-pointer was returned. The designated process tried to send a buffer which the process did not have. This error only occurs when the BUFFER_CHECK option has been turned off. Since buffer check is not active, there is very little information available. This could actually be any of the errors 9, 21, 22, 25, 26 or 28. Refer to these for further information. Attempt to send a signal to a non-existent process. The designated process tried to send a buffer which did not have the number of the process. There are two known explanations for this:
The process which allocated or received the buffer turned it over to another process using a public variable to transfer the buffer. If such is the case, you should read Buffer Transfer in Building a system. It details how to transfer buffers without using SEND. The designated process has two or more pointers to the same buffer. It has used one pointer to send/free the buffer, whereupon it used another pointer to send the same buffer. Use only one pointer to each buffer.
06
07
ARM Kernel
08 09
0A 0D 0E 0F 10
The designated process called SENDER providing an illegal pointer. The process has probably already sent the buffer or it may have freed the buffer. Attempt to start process 0. Processes are numbered from 1. Attempt to start an unknown process. Attempt to stop process 0. Processes are numbered from 1. Attempt to stop an unknown process.
Table 3: Run-time Error Messages for ARM Kernel Error code (hex) 11 Error The designated process tried to free a buffer which the process did not have. This error only occurs when the BUFFER_CHECK option has been turned off. Since buffer check is not active, there is very little information available. This could actually be any of the errors 4, 21, 22, 25, 26 or 28. Refer to these for further information. Attempt to send signal with illegal sender. The designated process is using system call SEND_W_S and tried to send a buffer which did not have the number of the process. There are two known explanations for this:
The process which allocated or received the buffer turned it over to another process using a public variable to transfer the buffer. If such is the case, you should read Buffer Transfer in Building a System on transferring buffers. It details how to transfer buffers without using SEND. The designated process has two or more pointers to the same buffer. It has used one pointer to send/free the buffer, whereupon it used another pointer to send the same buffer. Use only one pointer to each buffer.
12 13
ARM Kernel
14
The designated process is using system call SEND_W_S and tried to send a buffer which the process did not have. This error only occurs when the BUFFER_CHECK option has been turned off. Since buffer check is not active, there is very little information available. This could actually be any of the errors 9, 21, 22, 25, 26 or 28. Refer to these for further information. Stack underflow. Interrupt stack overflow. Too many variables has been allocated or the procedure calls have too deep nesting. The designated process is probably the one which has blown the stack. Stack overflow. Too many variables has been allocated or the procedure calls have too deep nesting. The designated process is probably the one which has blown the stack.
1D 1E
1F
Table 3: Run-time Error Messages for ARM Kernel Error code (hex) 21 Error SEND/SEND_W_S/RECEIVE/FREE_BUF/RESTORE found a buffer whose administration block and/or identity codes were ruined. The pointer to the buffer pointed inside the pool. When searching backwards from this buffer OSE Epsilon for ARM was unable to find any correct buffer. Either this buffer was first in the pool or else the buffer pool was corrupted from the indicated address and backwards, i. e. in the direction of decreasing addresses. SEND/SEND_W_S/RECEIVE/FREE_BUF/RESTORE found a pointer which did not point inside the buffer pool. The pointer may have been uninitialised or perhaps ALLOC was never called? A process has terminated. It is always illegal for a prioritized or background process to terminate. You may have forgotten to jump to the beginning of the process or you may have POPed too much data from the stack. Illegal attempt to start a process. The designated process tried to start a process which was already started. Each stop of a process must be matched by an equal number of starts. It is illegal to start a process which is not stopped. SEND/SEND_W_S/RECEIVE/FREE_BUF/RESTORE found a buffer whose administration block and/or identity codes were ruined. However, the real problem could not be found. SEND/SEND_W_S/RECEIVE/FREE_BUF/RESTORE found a buffer whose administration block and/or identity codes were ruined. The pointer to the buffer pointed inside the pool. When searching backwards from this buffer OSE Epsilon for ARM found a buffer whose administration block and ID-codes were correct. It is suspected that the process which owns this buffer is responsible for the memory disruption. The process has probably written beyond the end of the buffer the process has allocated. Use signal number and other information of the buffer to locate the code of the process which has caused the error. The designated process called GET_PRI providing a non-existent process.
22
23
ARM Kernel
24
25
26
27
Table 3: Run-time Error Messages for ARM Kernel Error code (hex) 28 Error RECEIVE has encountered a pointer which points outside the allocated part of the buffer pool. This is often an indication of major memory corruption. This error may also result if some process overwrites buffers in the queue which RECEIVE tries to traverse. Use the POOL analyse function of the debugger to check for this type of error. Memory corruption. Queueheads for returned buffers have been damaged. ALLOC has found a pointer in a queuehead that does not point inside the pool. An attempt was made to start an interrupt process. An attempt was made to stop an interrupt process. An attempt was made to restore the NIL pointer. An attempt was made to restore a pointer which points outside the allocated part of the buffer pool. RESTORE failed in determining buffer size, probably due to a damaged buffer. SET_PRI with illegal priority argument. POWER_FAIL was called but no power on routine has been declared. SIGSIZE was called with the NIL pointer as a parameter. The process has probably already sent the buffer or it may have freed the buffer. SET_PRI was called from an interrupt/timer-interrupt process or from a background process. DELAY was called from an interrupt process. Interrupt processes and timer-interrupt processes may not call DELAY. Stack overflow in interrupt process stack. Probably due to overusage by some interrupt process. Stack overflow in temporary stack. Stack underflow in temporary stack. An attempt was made to create more than one link handler.
29
2C 2D
ARM Kernel
2E 2F 30 31 32 33 34 35 37 38 39 3A
Table 3: Run-time Error Messages for ARM Kernel Error code (hex) 3B Error During system start a process descriptor that contained an unknown process type was encountered. This is either an indication of heavy ROM corruption or a CPU crash. An attempt was made to free an unrestored buffer. A buffer must be restored before it is freed if its addressee does not equal current process. This occurs when OSE has redirected a buffer with an unknown destination process to a link handler. Illegal buffersize found, when an attempt was made to kill signal. Call to GET_FSEM with an illegal PID. Call to SET_FSEM with an illegal PID. Call to SET_FSEM with an illegal semaphore value. Call to WAIT_FSEM with an illegal semaphore value. Call to SIGNAL_FSEM with an illegal PID. ADDRESSEE was called with the NIL pointer as a parameter. The process has probably already sent the buffer or it may have freed the buffer. POWER_FAIL was called but no power off routine has been declared. Stack overflow in second interrupt stack. Stack underflow in second interrupt stack.
41
44 45 46
ARM Kernel
47 48 49 55 56 57 58
Table 4: Configuration Error Messages for ARM Kernel Error code 1 Error ILLEGAL PARAMETER. An erroneous parameter has been given to an configuration entry. Check the parameters of the named configuration entry. The manual section on configuration describes exactly which parameters are legal. DECLARATION DISORDER. Configuration entries was given a wrong order. If you fail to locate the trouble, copy the original configuration file and re-enter your selections. ILLEGAL INTERVAL. A timer-interrupt process was declared with an illegal interval between calls to the timer-interrupt process, or a background process was declared with an illegal timeslice. Legal values are in the range 1..255. INTERRUPT DECLARED TWICE. The designated interrupt source was used more than once or the interrupt source does not exist. Each interrupt can have at most one interrupt process. Check the section on system configuration to see which interrupt sources are available. Also check that you have selected the intended CPU-type. POOL TOO SMALL. The pool must be at least 48 bytes. BUFFERSIZE ALIGNEMENT. Buffer sizes must be multiples of 4. BUFFERSIZE DISORDER. Buffer sizes must be selected in ascending order, that is the smallest buffersize first, then the next larger, then the next larger and finally the largest. BUFFERSIZE OUT OF RANGE. The largest buffer size possible is poolsize minus 24 bytes. The smallest size is 2 bytes. TOO MANY PROCESSES. The total number of processes may never exceed 127. ILLEGAL PRIORITY. The priority must be between 0 and 31. SEND HANDLER REQUIRES DEBUG. A send handler cannot be selected unless DEBUG is set to either YES in osarm.con.
Reference Manual / 4.6
ARM Kernel
10
11 12 21
22 27 28 39
Table 4: Configuration Error Messages for ARM Kernel Error code 40 41 Error TO MANY START HANDLERS. The maximum number of start handlers is 128. ILLEGAL TIME SLICE. Zero is not allowed as time slice or init value.
ARM Kernel
Reference Manual / 4.6
ARM Kernel
78 Configuration Error Messages
7 Reserved Words
A number of words are used as identifiers by OSE. These words must never be used as identifiers in your programs. Any conflicts will be accurately reported by the compiler/ assembler or the linker. A further restriction is that processes may not be named in conflict with any symbol used locally within OSE. If you keep getting assembler errors on duplicate symbols you must rename the process in conflict. Avoid using symbols beginning with "zz" or "ZZ" since these are extensively used by the operating system and debugger. The most interesting of these symbols are listed below. Words reserved as identifiers by OSE.
ARM Kernel
ADDRESSEE, COND_HALT CURRENT_PROCESS FLUSH GET_SEM GET_TICKS OSBUFSIZE OSERRCODE OSTIME OS_INT_PROCESS PROCESS RECEIVE_FSM RESTORE SEND_W_S SET_PRI SIGSELECT STOP WAIT_FSEM addressee current_process flush get_sem power_fail restore sender signal_sem stop wait_sem
ALLOC CREATE_SEM DELAY FREE_BUF GET_PRI KILL_SEM OSDEBUG OSFSEMVAL OS_PROCESS, OS_INT_PROCESS32 Q_ERR RECEIVE_W_TMO SEMAPHORE SENDER, SIGNAL_FSEM SIGSIZE SYSTEM_TICK WAIT_SEM alloc delay free_buf get_ticks receive send set_fsem sigsize wait_fsem wake_up
ALLOC_NIL ERROR, ERR_MSG GET_FSEM NILOSARM OSEOSE_I OSSEMVAL OS_PROCESS32 POWER_FAIL RECEIVE RECEIVE_ALL_BUT SEND SET_FSEM SIGNAL_SEM START TIMER_ENTRY WAKE_UP create_sem error get_fsem kill_sem receive_w_tmo send_w_s signal_fsem start wait_sem
Reserved Words 79
ARM Kernel
80 Reserved Words
Index
Symbols
System Calls on page 15 ADD_TICKS add_ticks ADDRESSEE addressee ALLOC alloc ALLOC_NIL alloc_nil Buffer Structure BUFFERSIZE ALIGNEMENT BUFFERSIZE DISORDER BUFFERSIZE OUT OF RANGE COND_HALT cond_halt Configuration Error Messages CREATE_SEM create_sem CURRENT_PROCESS current_process Data Type Definitions Data Types DECLARATION DISORDER DELAY delay DISPATCH ERR_MSG ERROR error Error Messages Execution time Fast semaphore Fatal error FLUSH flush FREE_BUF free_buf 11
A
7, 14, 86 15 61, 87 16 61, 88 18 61, 90 20
B
88 76 76 76
ARM Kernel
C
61, 92 21 76 14, 93 22 61, 94 23
D
12 67 76 62, 95 24 63
E
70 62, 96 25 69 61
F
7, 29 25, 96 62, 98 26 62, 100 28
Index 81
G
GET_FSEM get_fsem GET_PRI get_pri GET_SEM GET_TICKS get_ticks Header ILLEGAL INTERVAL ILLEGAL PARAMETER ILLEGAL PRIORITY ILLEGAL TIME SLICE Include Files INTERRUPT DECLARED TWICE 15, 62, 101 29 15, 102 31 103 62, 104 32
H
66
I
76 76 76 77 66 76
ARM Kernel
KILL_SEM kill_sem Memory Shortage NIL-pointer osarm.anc osarm.con osarm.s osarmi.anc ose.h ose_i.h POOL TOO SMALL POWER_FAIL power_fail Process Q_ERR RECEIVE receive Receive During Interrupt RECEIVE_ALL_BUT receive_all_but RECEIVE_FSEM receive_fsem RECEIVE_W_TMO
105 33
M
88
N
35, 37, 107, 109
O
66 76 76 66 66 66
P
76 106 34 67
Q
70
R
62, 107 35 35, 37, 107, 109 62, 109 37 62, 111 39 63, 114
Index 82
S
SEND 63, 117 send 45 SEND HANDLER REQUIRES DEBUG 76 63, 119 SEND_W_S send_w_s 48 63, 118 SENDER 47 sender Sending Signals To Another CPU 45, 117 63, 121 SET_FSEM 50 set_fsem SET_PRI 63, 122 51 set_pri 8, 35, 107 Signal queue SIGNAL_FSEM 63, 123 52 signal_fsem 124 SIGNAL_SEM signal_sem 53 67 SIGSELECT 63, 125 SIGSIZE sigsize 54 9, 14, 63, 126, 127 START 55 start STOP 55, 63, 126, 127 56 stop 56, 127 Stop During Delay Suspend 7, 24, 95 7, 11, 85 System Call 7 System Call Summary System Calls in Assembler 85 11 System Calls in C
ARM Kernel
T
Tick Timing Specification TO MANY START HANDLERS TOO MANY PROCESSES union SIGNAL User Interface WAIT_FSEM 7, 32, 104 61 77 76
U
67 65
W
63, 128
Index 83
57 129 58 130 59
ARM Kernel
Reference Manual / 4.6
Index 84
ARM Kernel
Reference Manual / 4.6
ADD_TICKS Description
CALL
R0 None.
ADD_TICKS adds a specified number of ticks to the system tick counter. This system call is intended to make corrections to the system time after the system has been powered down or halted for a while, i.e. in power-on handler at hot start. There are several types of behaviour associated with the system ticks. Only some of these are updated by calling ADD_TICKS.
ARM Kernel
Return value from GET_TICKS: Yes, updated Time when delays and time-outs expire: Yes, updated, if no time-outs are skipped Timer interrupts: No, not updated Scheduling of background processes: No, not updated The other mechanisms will not be updated. If any time-outs or delays were scheduled to expire during the time that was skipped over by calling ADD_TICKS, those delays and time-outs will expire at a later time. This can be avoided by never adding more ticks than the number of ticks indicated by the COND-HALT mechanism. Example
MOV BL R0,#20 ADD_TICKS
ADDRESSEE Description
CALL
R0 R0
The pointer to the buffer whose addressee is requested. A half_word variable where the addressee of the buffer will be put.
This system call is intended for link handlers. ADDRESSEE returns the ID of the process to which the signal was sent. When a signal is sent, OSE tags the buffer with the specified receiver process ID. This is normally the same process that eventually receives the buffer. Therefore ADDRESSEE returns the ID of the current process most of the time.
ARM Kernel
When a signal is sent to a process which does not exist in this CPU, OSE redirects the signal to a link handler. From this point, the addressee of the buffer is no longer the same as the receiving process, and OSE will not alter the addressee of the buffer until it has been restored with the RESTORE system call. This mechanism enables a link handler to pass the buffer on to other link handler processes using the SEND_W_S call, without losing the original addressee of the buffer. Example
LDR BL STRH R0,=MY_SIGNAL_P ADDRESSEE R0,[...,#DEST_PID]
ALLOC Description
CALL
Input
R0 R1
The desired size of the allocated buffer. The size is in the range 1 to the largest buffer size stated in osarm.con. A halfword value which will be placed in the first halfword of the buffer. If you do not intend to use the buffer for a signal you may wish to use a dummy value. The pointer to the allocated buffer.
Output General
R0
ARM Kernel
This system call is used to reserve memory. The caller must state the amount of memory required and also furnish a value to be inserted in the first halfword of the buffer. The first halfword is used for signal identification when buffers contain signals. It is not illegal to use signal number zero (0) and $8000, but it is not advised, since in the debugger is using these signal numbers. 0 is used to indicate any signal and $8000 is used to signal process swaps. It is an error to try to allocate a buffer of size 0 (zero). The maximum buffer size is stated in the configuration file (osarm.con). ALLOC will select one of the eight fixed memory sizes chosen when the system was generated. The size selected will always be large enough to accommodate the requested number of bytes. Each buffer is preceded by a 12 byte administration block which is used by OSE Epsilon for ARM. Users generally need not care about the administration block. When the system starts, all memory available for buffers is located in the buffer pool. As users allocate buffers, they are removed from the buffer pool and handed over to users. When users return buffers to the system they are stored in lists for returned buffers. They never again return to the buffer pool. If such returned buffers are available, as is almost always the case, ALLOC will allocate them first. This allocation scheme ensures consistent allocation times and that the memory can never be fragmented, i.e. split up into many small sections, too small to use. Memory Shortage If no used buffers of the requested size are available and the system pool does not contain enough memory to allocate the requested buffer, a fatal error is reported. This occurs even if a buffer of a larger size than the closest fit is available. Buffer Structure NOTE that the actual buffer may be larger than requested since the buffersizes are fixed.Process number of the sending process is valid only after the buffer has been
sent. Four more bytes are used at the end of the buffer if the debug option is used when configuring the system. Example
LDR LDR BL STR R0,=MY_SIGNAL_SIZE R1,=MY_SIGNAL_ID ALLOC R0,[...,MY_SIGNAL_P]
; It may be convenient to save the pointer ; immediately after ALLOC, since you will ; need it when calling SEND or FREE.
ARM Kernel
Reference Manual / 4.6
ALLOC_NIL Description ALLOC_NIL reserves memory for a user process. ALLOC_NIL works like ALLOC with the exception that memory shortage causes return of a NIL pointer.
BL ALLOC_NIL
CALL
Input
R0 R1
The desired size of the allocated buffer. The size is in the range 1 to the largest buffer size stated in osarm.con. A halfword value which will be placed in the first halfword of the buffer. If you do not intend to use the buffer for a signal you may wish to use a dummy value. The pointer to the allocate buffer, or NIL if no buffer could be allocated.
Output General
R0
ARM Kernel
ALLOC_NIL works like ALLOC with the exception that memory shortage is treated differently. ALLOC_NIL returns a NIL pointer in case of memory shortage. Note that designing a system where memory shortage is not a fatal error is much more complicated than designing a system that always expects to have enough memory. It would be necessary to always expect memory shortage when allocating a memory buffer and provide a non fatal alternative action for every instance where memory is allocated. Otherwise memory shortage caused by large memory consumption in one part of the system could cause a fatal failure to allocate memory in another part of the system. Because of these difficulties, using ALLOC_NIL in a system should only be done after careful design analysis. An alternative design approach is often preferable. E.g. if a small portion of the system is expected to consume an undetermined amount of memory, it is probably easier to design a mechanism that limits memory consumption in those areas, than dealing with the system-wide problem of expecting memory shortage. It is however possible to use ALLOC_NIL safely in a limited part of a system if some special conditions are met, by doing 'tricks' with the memory allocation system. The 'trick' is to use ALLOC_NIL only on some of the 8 available buffer sizes, and to create enough buffers of the other sizes at system start. The drawback of this approach is that the flexibility is lost and a thorough analysis of the memory use in the system must be performed.
Example
LDR LDR BL STR R0,=MY_SIGNAL_SIZE R1,=MY_SIGNAL_ID ALLOC_NIL R0,[...,MY_SIGNAL_P]
ARM Kernel
Reference Manual / 4.6
COND_HALT Description COND_HALT conditionally calls the power off handler, depending on the number of ticks remaining before the next scheduled time-out event.
BL COND_HALT
CALL
R0 None.
The threshold number of ticks until next time-out event for calling the power off handler.
COND_HALT finds out the number of ticks until the next scheduled time-out event. If this is more or equal to the min_ticks value, the power off handler is called.
ARM Kernel
The time-out events considered only include time outs created by the system calls DELAY, RECEIVE_W_TMO and RECEIVE_FSEM. Other timing related events such as rescheduling of background processes and calling timer interrupt processes do not affect COND_HALT. The power off handler is called with information about the number of ticks until the next time-out event. It can use this information to set up a hardware timer for a matching delay time, and then power down or halt the processor. See Configuring OSE Epsilon for ARM, Power off handler for details. The min_ticks value is useful if powering down or halting for very short periods of time should be avoided. That can be the case if the power required to start and stop the system is not negligible. The min_ticks parameter should be set high enough to prevent power down cycles that are shorter than break-even. A min_ticks parameter of 0 will always cause the power off handler to be called. COND_HALT is normally called from a background process. This will cause the system to save power when there is no work to be done. Note that the POWER_DOWN system call is not equivalent to a COND_HALT call with a min_ticks parameter of 0. Even though the power off handler will be called in both cases, information about the number of ticks before the next timeout event will only be sent to the handler if called through COND_HALT. Example
MOV BL R0,#2 COND_HALT
CREATE_SEM Description CREATE_SEM creates a dynamic semaphore structure and initializes it to the value specified in initial_val. The initial value must be zero or a positive value. Typical values are 0 and 1. The semaphore is dynamically allocated from the current pool. It may be returned to the pool when it is no longer in use by calling kill_sem.
CALL BL CREATE_SEM
R0 R0
It is the user's responsibility to ensure that the semaphore is not killed while it is still in use.
ARM Kernel
Reference Manual / 4.6
CURRENT_PROCESS Description
CALL
CURRENT_PROCESS returns the process ID of the currently running process, i.e. the ID of the caller.
BL CURRENT_PROCESS process = current_process();
This call is used by any process which needs to obtain its own process ID. For example a library function may be interested in from which process it was called. Example
BL CURRENT_PROCESS R0,[...,#WHOAMI_]
ARM Kernel
STRH
DELAY Description
CALL
DELAY suspends execution of the calling process for the requested number of system ticks.
BL DELAY
2
The number of system ticks the delay is to last (word value, 32 bit).
R0 None.
This system call is used when a process needs to suspend execution for a time. OSE guarantees that the process is kept waiting for at least the requested time minus one system tick. The actual waiting time may always be longer than the requested, since other processes of higher priority may run for an indeterminate time.
ARM Kernel
DELAY can not be called from an interrupt process since an interrupt process can never be swapped out.
ERROR Description
CALL
ERROR collects error information and is called by any user process detecting an error condition.
BL ERROR
R0 None.
This system call is used by processes detecting an error condition. The operating system also uses ERROR to report errors. The caller may provide information about the error. It is not necessary to provide information on process number and error location, since this is automatically provided by ERROR.
ARM Kernel
Errors detected by OSE are always fatal and the system can not continue execution; a restart is necessary. The user may provide an error handler to handle detected errors. Such a handler may log the error on a printer, show it on a display, send it on a serial link etc. It will use whatever output devices present in the system (for details, see chapter 8.13 Writing an Error Handler, of the OSE Epsilon for ARM Users Guide). If no error handler is present or if an error handler returns from an error detected by OSE, the system enters an infinite loop. If an error handler returns from a user reported error, control is returned to the process calling error. Interrupts are disabled while an error handler is executing. You are not allowed to use system calls in the error handler except:
Example
96 System Calls in Assembler Reference Manual / 4.6
LDR BL
R0,=ERROR_CODE ERROR
ARM Kernel
Reference Manual / 4.6
FLUSH Description
CALL
FLUSH removes signals from the requested senders from the signal queue of the designated process.
BL FLUSH
Input
R0
An array of halfwords in memory where senders process numbers are stored. The first halfword of the array is equal to the number of senders to flush. The process number of the process whose signal queue is to be flushed.
ARM Kernel
FLUSH is intended for communications software only. The first parameter to flush is a pointer to a RAM array of senders. FLUSH removes every signal from any of the senders from the signal queue of the process in the second parameter. Signals from senders not in the array remain in the queue. The removed signals are freed by FLUSH. It is illegal to flush the queue of an interrupt process or timer-interrupt process. It is also illegal to call FLUSH from an interrupt or timer-interrupt process. FLUSH uses START/STOP internally to stop processes while their queues are flushed. If FLUSH must be re-entrant (may be called from several processes), the semaphores option is also required. (For details, see Configuring OSE Epsilon for ARM.) Example
LDR MOV STRH ADD R1,[R4,#MY_ARRAY] R0,#3 R0,[R1] R1,#2
R1,#2
ARM Kernel
Reference Manual / 4.6
FREE_BUF Description
CALL
R0 None.
FREE_BUF is used to return memory which is no longer needed. Only memory allocated using ALLOC may be returned using FREE_BUF. Memory which has been returned can be used by other processes. If you send a signal buffer to another process it is the responsibility of the receiving process to free the buffer. It is an error for the sending process to try to do so. Example
ARM Kernel
LDR BL
R0,=MY_SIGNAL_P FREE_BUF
GET_FSEM Description
CALL
R0 R0
The ID of the process which owns the desired semaphore. The current value of the fast semaphore.
GET_FSEM is used to read the current value of a fast semaphore. An interrupt process may for example test a semaphore for overflow before calling SIGNAL_FSEM. Example
LDR R0,=sl_driver__ ; use 2x underscore for ; ASM call
ARM Kernel
BL STRH
GET_FSEM R0,[...,#FSEM_VALUE]
GET_PRI Description
CALL
R0 R0
GET_PRI is used to find out the priority of a prioritized process. The call does not work for any other kind of process. Example
BL CURRENT_PROCESS ; R0 = process identity ; of this process BL GET_PRI R0,[...,#PRIO]
ARM Kernel
STR
GET_SEM Description
CALL
R0 R0
ARM Kernel
Reference Manual / 4.6
GET_TICKS Description
CALL
None. R0 A word variable where the current system ticks will be put.
GET_TICKS is used to find out the current value of the system clock. The system clock is set to zero at system start. It is subsequently incremented at each system tick. Example
BL GET_TICKS R0,[...,#TICKS]
ARM Kernel
STR
KILL_SEM Description
CALL
R0 None.
Make sure no process is using the semaphore when it is killed. You have to own the semaphore before you can kill it.
ARM Kernel
Reference Manual / 4.6
POWER_FAIL Description POWER_FAIL is used in case of power failure and it causes the present environment to be saved in order to be restored after a warm start.
BL POWER_FAIL
CALL
None. None.
This call is used in systems where memory contents remain undisturbed in case of temporary power failures. When the power fails, any process may call POWER_FAIL. If called from a prioritized or background process, POWER_FAIL will swap out the current process and then call the user supplied power off handler to shut down the power source and wait for a restart. If called from an interrupt or timer-interrupt process, POWER_FAIL will return immediately to the calling interrupt process. When the interrupt is done, OSE Epsilon for ARM will swap out the current process and then call the user supplied power off handler. The power off handler is declared in osarm.con. When power returns, after reset, the user supplied power on handler is called to determine if memory contents are valid for a warm start or if a cold start is necessary. The power on handler is also declared in osarm.con. If POWER_FAIL was called from a prioritized or background process the caller "returns" from POWER_FAIL when power is restored and execution may continue where it was interrupted by the power failure. If POWER_FAIL was called from interrupt, execution continues at the prioritized or background process which was interrupted by the interrupt which called POWER_FAIL. A power off handler may calculate a memory checksum and leave it in memory for the power on handler. A power on handler may recalculate the checksum and allow a warm start if memory remains unharmed. I/O ports must also be initialised to the state that was present when POWER_FAIL was called. (This is a major issue which must be carefully considered.) Example
BL POWER_FAIL
ARM Kernel
RECEIVE Description RECEIVE searches the signal queue of the calling process for one or more desired signals. If a desired signal is found, it is removed from the queue and handed over to the calling process.
BL RECEIVE
CALL
R0 R0
RECEIVE will search the signal queue of the calling process for the requested signal(s). The first signal in the queue to match any of the required signals will be received. Signals not specified in this particular receive will remain in the queue. Each process has only one signal queue.
ARM Kernel
The number of signals to search for must be stated. If that number is 0 (zero), then any signal found in the queue will be received. If the signal queue is empty or none of the requested signals is available in the queue the process will be swapped out and another process allowed to run. As more signals arrive, the process will run again in order to scan the queue. Only when one of the required signals has arrived will the process return from the call to RECEIVE. A signal in a signal queue will never be scanned more than once during one call to RECEIVE. Receive During Interrupt It is permitted for an interrupt or timer-interrupt process to receive signals. If none of the required signals is present in the queue the interrupt process will return from the call to RECEIVE and a NIL-pointer is provided. An interrupt process must always be able to handle the case that RECEIVE may not return any signal.
Example
WANTED_SIGNALS: DCW DCW DCW DCW 3 SIG_1 SIG_2 SIG_3
LDR BL STR
ARM Kernel
108 System Calls in Assembler
RECEIVE_ALL_BUT Description RECEIVE_ALL_BUT searches the signal queue in the same manner as RECEIVE but with reversed logic. Any signal is received except the signals specified in the array.
BL RECEIVE_ALL_BUT
CALL
R0 R0
RECEIVE will search the signal queue of the calling process for the requested signal(s) excluding the signals defined in input parameter R0. The first signal in the queue to match any of the required signals will be received. Signals not specified in this particular receive will remain in the queue. Each process has only one signal queue.
ARM Kernel
The number of signals to search for must be stated. If that number is 0 (zero), then any signal found in the queue will be received. If the signal queue is empty or none of the requested signals is available in the queue the process will be swapped out and another process allowed to run. As more signals arrive, the process will run again in order to scan the queue. Only when one of the required signals has arrived will the process return from the call to RECEIVE. A signal in a signal queue will never be scanned more than once during one call to RECEIVE. Receive During Interrupt It is permitted for an interrupt or timer-interrupt process to receive signals. If none of the required signals is present in the queue the interrupt process will return from the call to RECEIVE and a NIL-pointer is provided. An interrupt process must always be able to handle the case that RECEIVE may not return any signal.
Example
UNWANTED_SIGNALS: DCW DCW DCW DCW 3 SIG_1 SIG_2 SIG_3
LDR BL STR
ARM Kernel
110 System Calls in Assembler
RECEIVE_FSEM Description RECEIVE_FSEM waits for either a signal, a fast semaphore, or a timeout. If the signal was already available, or the fast semaphore had already been signalled, the call will return immediately. The time-out is optional: it can either be set to 0 causing a check for signal or fast semaphore. It can also be set to -1, resulting in an infinite time-out.
CALL BL RECEIVE_FSEM
Input
R0
ARM Kernel
The time which will elapse before returning if none of the wanted signals turn up and the fast semaphore is not signalled. The time may be almost one system time shorter and many system ticks longer if other processes of higher priority requests the CPU. 0 is legal and forces return without any delay, i.e. checking if either a desired signal is available, or if the fast semaphore had already been signalled. -1 indicates an infinite time-out, preventing return because of time-out. An array of signals to receive. Requested number of time to wait on the fast semaphore. This is usually 1. A pointer to the received signal.
R1 R2 Output General R0
RECEIVE_FSEM combines WAIT_FSEM with RECEIVE_W_TMO. It receives signals and times out in exactly the same manner as RECEIVE_W_TMO. Additionally it waits for fast semaphores much like WAIT_FSEM. The return value indicates which type of event caused the call to return. The fast semaphore associated with the calling process is decreased by semvalue on entry to RECEIVE_FSEM. The call will return immediately if the fast semaphore is still positive, i.e. if the fast semaphore had been signalled at least semvalue time before the call to RECEIVE_FSEM. The call can return because of fast semaphore signalling as soon as the fast semaphore is positive. If the call returns because of another event than the fast semaphore, the fast semaphore is increased by semvalue before the call returns. This insures that no fast semaphore event is missed even if there are several simultaneous events. RECEIVE_FSEM will receive signals in exactly the same manner as RECEIVE. All signals will remain in the signal queue if a return is caused by fast semaphore signalling or a time-out.
The time to wait is given in system ticks. The maximum value is 4294967295 ticks. If this time is not sufficient, RECEIVE_FSEM may be called several times inside a loop. (See System Timer in Configuring OSE Epsilon for ARM for details on the system tick.) Time-outs of 0 ticks return immediately after checking. Timeouts set to 1 expire at the next system tick, that is after 0-1 system tick. It is also possible to avoid time-outs altogether by using a time to wait value of -1. Several events may appear to occur simultaneously, e.g. if a wanted signal is sent to the process and the fast semaphore is signalled during execution of higher or equal priority processes. It cannot be known which of several simultaneous events will cause RECEIVE_FSEM to return. The following is however guaranteed:
When return is caused by a signal, the first wanted signal in the signal queue will be returned. The return value will not indicate a time-out if a signal arrives or the fast semaphore is signalled within he specified time. If the fast semaphore had been signalled enough time before the entry to the call, the return value will be OS_RCV_FSEM.
ARM Kernel
RECEIVE_FSEM cannot be called from an interrupt process since an interrupt process can never wait for any event except interrupts.
Example
WANTED_SIGNALS: DCW DCW DCW DCW 3 SIG_1 SIG_2 SIG_3
R0,#17 R1, (R4,#WANTED_SIGNALS) R2,#1 RECEIVE_FSEM R1,#NIL R0, R1 TIMEOUT R1,#-1 R0,R1 FAST_SEMAPHORE R0, (...,#MY_SIGNAL_P) . ; A signal was found
ARM Kernel
RECEIVE_W_TMO Description RECEIVE_W_TMO searches the signal queue of the calling process for one or more desired signals. If a desired signal is found, it is removed from the queue and handed over to the calling process. If none of the desired signals arrive within the specified time, RECEIVE_W_TMO returns a NIL-pointer.
BL RECEIVE_W_TMO
CALL
Input
R0
The time which will elapse before RECEIVE_W_TMO returns, if none of the wanted signals turns up. The time may be almost one system time shorter and many system ticks longer if other processes of higher priority requests the CPU. 0 is legal and forces return without any delay. An array of signals to receive. A pointer to the received signal.
R1
ARM Kernel
Output General
R0
RECEIVE_W_TMO will receive signals in exactly the same manner as RECEIVE. However, if after the specified time none of the required signals have appeared, the call to RECEIVE_W_TMO returns with a NIL-pointer. The time to wait is given in system ticks. The maximum value is 4294967295 ticks. If this time is not sufficient, RECEIVE_W_TMO may be called several times inside a loop. (See System Timer in Configuring OSE Epsilon for ARM, for details on the system tick.) Timeouts of 0 ticks return immediately. Timeouts set to 1 expire at the next system tick, that is after 0-1 system tick. RECEIVE_W_TMO can not be called from an interrupt process since an interrupt process can never wait for a signal. It is guaranteed that if a signal arrives within the specified time the calling process will get that signal. If, however, a signal arrives slightly after the time has elapsed the process may get it anyway. This is due to the fact that if a process of higher priority runs, the process calling RECEIVE_W_TMO may not get the opportunity to scan the queue until after the timeout has occurred.
Example
WANTED_SIGNALS: DCW DCW DCW DCW 3 SIG_1 SIG_2 SIG_3
ARM Kernel
RESTORE Description
CALL
RESTORE enters the calling process as owner and addressee of the buffer.
BL RESTORE
R0 None.
When a signal is sent to an external process, SEND will use a special buffer format when forwarding the buffer to the link handler. The link handler cannot return such buffers directly to the system; they must be re formatted. RESTORE re formats such buffers. Any attempt to free an unrestored buffer may cause a system crash. When the DEBUG-option is used, every buffer possessed by a user process is owned by that process. When the buffer is sent/received owner is changed. Any attempt by a process to send/free a buffer it does not own is an error. If a buffer is taken over by another process without using SEND/RECEIVE, that process must call RESTORE in order to be acknowledged as the new owner of the buffer. It can then be freed/sent in the ordinary manner. Example
; This example assumes that a pointer ; pointing to the buffer's signal number ; is located in location MY_PTR.
ARM Kernel
LDR LDR BL
SEND Description
CALL
SEND moves a buffer from the sending process to the signal queue of the receiving process.
BL SEND
2
The pointer to the buffer to send. The process to which the signals is to be sent.
Input
R0 R1
Output General
None.
SEND transfers control of a signal buffer from the sending process to the receiving process, the addressee. Each process has one, and only one, queue for signals sent to the process. Buffers are entered at the end of the signal queue of the receiving process. The sending process can no longer access the buffer.
ARM Kernel
If the receiving process is of higher priority than the sending process, the sending process will be swapped out and the receiving process will be swapped in. Before sending a buffer, it must be allocated using ALLOC. It is also possible to send a buffer which has been received from RECEIVE. In order to send a signal to a process you must have the address to the process. To obtain the address, simply add an underscore to the name of the process, then declare it as an external process. The process names are those that you specified in the osarm.con file when you configured your system. Sending Signals To Another CPU This is done in exactly the same manner as when you send a signal to an internal process. However, you must provide the address yourself. Addresses to internal processes range from 1 to the number of processes you have. Before you can send signals to an external processor you will need to obtain or write a link handler for the physical link you intend to use. Example
IMPORT LDR LDR BL my_addressee_ R1,=my_addressee__ R0,=my_signal_p SEND
SENDER Description
CALL
SENDER obtains the process number of the process which sent a buffer.
BL SENDER
R0 R0
The pointer to the buffer whose sender is requested. A halfword variable where the address to the sender will be put.
SENDER is used to find out who sent a signal. You must have the pointer to a buffer before you may call SENDER, i.e. if you have sent the buffer to another process or freed it, it is too late to find out who sent it. Example
LDR R0,=MY_SIGNAL_P SENDER R0,[...,#WHO_WAS_IT]
ARM Kernel
BL STRH
SEND_W_S Description
CALL
SEND_W_S sends signals exactly like SEND, but the sender of the buffer may be set to any process ID.
BL SEND_W_S
Input
R0 R1 R2
The pointer to the buffer to send. The simulated sender of the signal. The receiver will see this process if SENDER is called. The process to which the signal is to be sent.
Output General
None.
ARM Kernel
The regular SEND system call always enters the calling process as sender in the buffer. If this is not desired, SEND_W_S performs a regular SEND but enters the specified process as the sender in the buffer. This might be useful to a link handler. Suppose that a signal comes to the link handler on the physical link. Once received by the link handler, the link handler may want to send the signal to the destination process. When doing that the link handler may enter the sending global process on the other side of the physical link as the sender of the signal. If the link handler was to use the regular SEND, the link handler would become sender, making it impossible for the receiving process to find out which process originally sent the signal. If a system has several link handlers, the process named LINKHANDLER will still have to forward signals from SEND to other link handlers. In this case SEND_W_S might be used, thus preserving the original senders. Note: External processes are numbered from 0x0100 to 0xFF00, i.e. the low byte must be zero.
Example
IMPORT IMPORT LDR LDR LDR my_sender__ my_addressee__ R1,=my_sender__ R2,=my_addressee__ R0,=my_signal_p
; Assuming that a pointer to ; the buffer to send is stored ; in location buf_ptr. BL SEND_W_S
ARM Kernel
120 System Calls in Assembler
SET_FSEM Description
CALL
Input
R0 R1
Requested value of the fast semaphore. Process ID of the process which owns the fast semaphore whose value is set.
Output General
None.
This system call is used to initialise the value of a fast semaphore before normal operation begins. A fast semaphore can not be referenced until it has been initialized. It is therefore wise to have processes initialize only their own fast semaphores.
ARM Kernel
Example
LDR LDR BL R0,=SEM_VALUE R1,=some_process__ SET_FSEM
SET_PRI Description
CALL
R0 R0
The desired new priority for the calling process. The resulting priority of the calling process.
SET_PRI is used to modify the priority level of the calling process. The call only works for prioritized processes. The call will cause a context switch if the new priority is lower or equal to the priority of another process. (Calling SET_PRI with the same priority as the current priority will force a context switch to the next ready process, if there are other ready processes at the same priority.) Example
ARM Kernel
LD BL STR
SIGNAL_FSEM Description
CALL
R0 None.
The fast semaphore for the specified process is incremented. If it becomes zero, the process waiting at the semaphore is made ready. Example
LDR BL R0,=some_process__ SIGNAL_FSEM
ARM Kernel
Reference Manual / 4.6
SIGNAL_SEM Description
CALL
SIGNAL_SEM increments the value of the specified semaphore and releases the first process waiting at the semaphore.
BL SIGNAL_SEM
R0 None.
It is illegal to cause a semaphore to wrap from high positive numbers to a negative value.
ARM Kernel
124 System Calls in Assembler
SIGSIZE Description
CALL
R0 R0
The pointer to the buffer whose size is requested. A halfword variable where the size of the buffer will be put.
SIGSIZE is used to find the size that was requested from ALLOC when a buffer was first allocated. You must have the pointer to a buffer before you may call SIGSIZE, i.e. if you have sent the buffer to another process or freed it, it is too late to find out the size. Example
ARM Kernel
LDR BL STR
START Description
CALL
START causes a stopped process to become ready. It resumes execution as soon as no process of equal or higher priority is running.
BL START
R0 None.
The name of the process which is to be started. For details on process names, refer to the section on SEND.
START is used to start a process which has been stopped using STOP. If the process currently running is of lower priority than the started process, the current process will be swapped out and the stopped process will be allowed to run. Only when all calls to stop a process have been matched by the same number of calls to start the process will it be allowed to start. It is an error to start a process which is not stopped. Example
LDR BL R0,=MY_PROCESS__ START
ARM Kernel
STOP Description
CALL
STOP suspends execution of the required process until it is started using the START system call.
BL STOP
2
The name of the process which is to be stopped. For details on process names, refer to the section on SEND.
R0 None.
STOP is used to stop a process. The process will not again be allowed to run until all processes which have stopped the process have again ordered it started using START. It is an error to start a process which has not been stopped. A stopped process will not require CPU execution time. The STOP function should be used with caution.
ARM Kernel
If the currently running process is stopped, another process will be allowed to run. Stop During Delay If a process has been stopped while waiting for a delay to expire, the delay timer will continue to count. If the process is again started before the delay has expired the delay will continue and the process will not be allowed to run until the delay is finished. If, on the other hand, the delay has expired while the process was stopped, the process will be allowed to run as soon as it is started. Provided, of course, that no process of higher priority is running. Stop During receive_w_tmo If a process which was stopped during RECEIVE_W_TMO is started before the timeout is expired and the process has not received any required signal, execution of RECEIVE_W_TMO will continue as if the process had never been stopped. Example
LDR BL R0,=MY_PROCESS__ STOP
WAIT_FSEM Description
CALL
R0 None.
The number of times the semaphore must be signalled before the process becomes ready.
WAIT_FSEM waits at the fast semaphore associated to the calling process. The semaphore is decreased by the requested amount. If the result becomes negative, the calling process is suspended until the semaphore again becomes positive or zero. This occurs when some other process has signalled the semaphore a sufficient number of times.
ARM Kernel
Example
LDR BL R0,=17 WAIT_FSEM
WAIT_SEM Description WAIT_SEM waits at the specified semaphore structure. The semaphore value is decremented. If the result is negative, the caller is suspended and queued at the end of the semaphore queue. Each time some other process signals the semaphore, the value is incremented and the first process queued at the semaphore is released.
CALL BL WAIT_SEM
R0 None.
ARM Kernel
Reference Manual / 4.6
WAKE_UP Description WAKE_UP checks if an interrupt or timer interrupt process was activated by hardware or by OSE. This system call can be disabled by a configuration entry in osarm.con.
CALL BL WAKE_UP
Input Output
None. R0 Source of interrupt: 0 Invoked by hardware interrupt 1 Invoked by signal send to this process 2 Invoked by a SIGNAL_FSEM to this process. This irrespective of the actual FSEM value. GET_FSEM gives no real value.
ARM Kernel
130 System Calls in Assembler