| |||
| Home > Angel > Angel in operation > Angel task management | |||
All Angel operations are controlled by Angel task management. Angel task management:
assigns task priorities and schedules tasks accordingly
controls the Angel environment processor mode.
Angel task management requires control of the processor mode. This can impose restrictions on using Angel with an RTOS. Refer to Using Angel with an RTOS for more information.
Angel assigns task priorities to tasks under its control. Angel ensures that its tasks have priority over any application task. Angel takes control of the execution environment by installing exception handlers at system initialization. The exception handlers enable Angel to check for commands from the debugger and process application semihosting requests.
Angel will not function correctly if your application or RTOS interferes with the execution of the interrupt, SWI or Data Abort exception handlers. Refer to Chaining exception handlers for more information.
When an exception occurs, Angel either processes it completely
as part of the exception handler processing, or calls Angel_SerialiseTask() to
schedule a task. For example:
When an Angel SWI occurs, Angel determines whether the SWI is a simple SWI that can be processed immediately, such as the EnterSVC SWI, or a complex SWI that requires access to the host communication system, and therefore to the serializer. Refer to Angel C library support SWIs for more information.
When an IRQ occurs, the Angel PID port determines whether or not the IRQ signals the receipt of a complete ADP packet. If it does, Angel task management is called to control the packet decode operation. Refer to Example of Angel processing: a simple IRQ for more information. Other Angel ports can make other choices for IRQ processing, provided the relevant task is eventually run.
The task management code maintains two values that relate to priority:
The
task type indicates type of task being performed. For example, the
application task is of type TP_Application, and Angel
tasks are usually TP_AngelCallback. The task
type labels a task for the lifetime of the task.
The task priority is initially derived from the task type, but thereafter it is independent. Actual priority is indicated in two ways:
in the value of a variable in the task structure
in the relative position of the task structure in the task queue.
The task priority of the application task changes when an application SWI is processed, to ensure correct interleaving of processing.
Table 13.1 shows the relative task priorities used by Angel.
Table 13.1. Task priorities
| Priority | Task | Description |
|---|---|---|
| Highest | AngelWantLock | High priority callback. |
AngelCallBack | Callbacks for Angel. | |
ApplCallBack | Callbacks for the user application. | |
Application | The user application. | |
AngelInit | Boot task. Emits boot message on reset and then exits. | |
| Lowest | IdleLoop |
Angel task management is implemented through the following top-level functions:
Angel_SerialiseTask()
Angel_NewTask()
Angel_QueueCallback()
Angel_BlockApplication()
Angel_NextTask()
Angel_Yield()
Angel_Wait()
Angel_Signal()
Angel_TaskID().
Some of these functions call other Angel functions not documented
here. The functions are described in brief below. For full implementation
details, refer to the source code in serlock.h, serlock.c,
and serlasm.s.
In most cases this function is the entrance function to Angel
task management. The only tasks that are not a result of a call
to Angel_SerialiseTask() are the boot task,
the idle task, and the application. These are all created at startup.
When an exception occurs, Angel_SerialiseTask() cleans
up the exception handler context and calls Angel_NewTask() to
create a new high priority task. It must be entered in a privileged mode.
Angel_NewTask() is the core task creation
function. It is called by Angel_SerialiseTask() to
create task contexts.
This function:
queues a callback
specifies the priority of the callback
specifies up to four arguments to the callback.
The callback executes when all tasks of a higher priority have completed. Table 13.1 shows relative task priorities.
This function is called to allow or disallow execution of
the application task. The application task remains queued, but is
not executed. If Angel is processing an application SWI when Angel_BlockApplication() is
called, the block might be delayed until just before the SWI returns.
This is not a function, in that it is not called directly. Angel_NextTask() is
executed when a task returns from its main function. This is done
by setting the link register to point to Angel_NextTask() on
function entry.
The Angel_NextTask() routine:
enters Supervisor mode
disables interrupts
calls Angel_SelectNextTask() to
select the first task in the task queue that has not been blocked
and run it.
This is a yield function for polled devices. It can be called either:
by the application
by Angel while waiting for communications on a polled device
within processor-bound loops such as the idle loop.
Angel_Yield() uses the same serialization
mechanism as IRQ interrupts. Like an IRQ, it can be called from
either User or Supervisor mode and returns cleanly to either mode. If
it is called from User mode it calls the Angel_EnterSVC SWI to enter
Supervisor mode, and then disables interrupts.
Angel_Wait() works in conjunction with Angel_Signal() to
enable a task to wait for a predetermined event or events to occur
before continuing execution. When AngelWait() is
called, the task is blocked unless the predetermined event has already
been signalled with AngelSignal().
AngelWait() is called with an event mask.
The event mask denotes events that will result in the task continuing
execution. If more than one bit is set, any one of the events corresponding
to those bits will unblock the task. The task remains blocked until
some other task calls Angel_Signal() with one
or more of the event mask bits set. The meaning of the event mask
must be agreed beforehand by the routines.
If AngelWait() is called with a zero
event mask, execution continues normally.
Angel_Signal() works in conjunction with Angel_Wait().
This function sends an event to a task that is now waiting for it,
or will in the future wait for it:
If
the task is blocked, Angel_Signal() assumes
that the task is waiting and subtracts the new signals from the
signals the task was waiting for. The task is unblocked if the event
corresponds to any of the event bits defined when the task called Angel_Wait().
If the task is running, Angel_Signal() assumes
that the task will call Angel_Wait() at some
time in the future. The signals are marked in the task signalWaiting member.
Angel_Signal() takes a task ID that identifies
a current task, and signals the task that the event has occurred.
See the description of Angel_Wait() for more
information on event bits. The task ID for the calling task is returned
by the Angel_TaskID() macro. The task must
write its task ID to a shared memory location if an external task
is to signal it.