Process management functions
[Pre-emptive, soft real-time scheduler]

This group of functions is responsible for the handling of processes. More...

Data Structures

struct  BX_PROC
 Process descriptor object. More...

Enumerations

enum  BX_PROT { BX_PROT_NORM = 0, BX_PROT_COOP = 1, BX_PROT_IRQD = 2, BX_PROT_FIQD = 3 }
 

Process protection levels.

More...

Functions

int BX_ProcNice (int prio)
 Change the priority of the caller.
int BX_ProcProtLower (BX_PROT prot)
 Lowers the protection level of the caller.
int BX_ProcProtRaise (BX_PROT prot)
 Raises the caller's protection level.
BX_PROCBX_ProcSelf (void)
 Returns the caller's process descriptor.
int BX_ProcSpawn (BX_PROC *proc, BX_PROC_FUNC func, void *parm, int *stack, unsigned int prio, BX_PROT prot)
 Creates a new process.

Detailed Description

This group of functions is responsible for the handling of processes.

Processes have two attributes. One is their priority. It is simply a number, assigned by you. The kernel selects the process with the highest priority to run. There is no timeslicing between identical priority processes, if a process starts to run, it is let to run until it goes to wait or a higher priority process becomes active.
A process actually has two priorities assigned to it. One is the number that you set as its priority. It is called its real priority. However, it is possible that the kernel temporarily raises the priority of a process through the priority ceiling or priority inheritance mechanism. That elevated priority is called the effective priority. When the kernel selects the process to run, it looks at the effective priority of the processes.

The other attribute is the process' protection level. It indicates what can interrupt the process. Four levels are defined.


Enumeration Type Documentation

enum BX_PROT

Process protection levels.

Enumerator:
BX_PROT_NORM 

Normal, not protected, preemptable mode.

BX_PROT_COOP 

Cooperative mode, suspend only when requested.

BX_PROT_IRQD 

IRQ disabled mode, no preemption or suspension.

BX_PROT_FIQD 

IRQ and FIQ disabled, no preemption or suspension.


Function Documentation

int BX_ProcNice ( int  prio  ) 

Change the priority of the caller.

The real priority of the caller will be set to the given value. If the priority is higher than the current effective priority of the caller, then the effective priority will be elevated to the new level. If the new priority is lower than the effective priority of the caller, then the effective priority will be adjusted, subject to priority ceiling and priority inheritance rules. If the requested priority is higher than BX_MAX_PRIO, then it will be limited to that value.

Parameters:
prio The requested new priority. If this value is negative, then no priority change is performed but the current real priority is returned.
Return values:
BX_ERR_CONTEXT The function was not called from an user context
>=0 The previous real priority of the caller
Attention:
This function should not be called from an ISR or delayed ISR. This function does not suspend the caller but can cause a context switch as a result of the priority change.
int BX_ProcProtLower ( BX_PROT  prot  ) 

Lowers the protection level of the caller.

The function lowers the protection level of the caller if the caller was at a level higher than the parameter. If the caller's protection level is already at or below the parameter, the function does not change the caller's protection level. If the function is called from an ISR, then the protection level can not be lowered below BX_PROT_IRQD, if called from a soft ISR then the level can not be lowered below BX_PROT_COOP, or, if the kernel disabled interrupts due to the event queue being over the watermak, below BX_PROT_IRQD. If the requested level is out of the allowed boundaries, then it will be changed to be between the boundaries.

Parameters:
prot The required new protection level
Returns:
The protection level before the call
Attention:
This function does not suspend the caller but can cause a context switch as a result of the priority change.
Note:
If called from a soft ISR with a parameter of BX_PROT_COOP, it may not actually enable the IRQ level interrupt if the kernel's event queue is over the watermark. Therefore, in a soft IRQ handler, even if you know that an IRQ is pending, you should not expect it to be accepted immediately after this call.
int BX_ProcProtRaise ( BX_PROT  prot  ) 

Raises the caller's protection level.

The parameter is one of the defined protection levels. If the current protection level is is lower than the one specified by the parameter, then the caller's protection level will be elevated to the desired level. If the requested level is less than or equal to the current protection level, then the function does nothing. In any case, the function returns the protection level before the call. This function can be called from interrupt service routines as well as soft interrupts. A real ISR is always at least at level BX_PROT_IRQD, a soft interrupt is at least at level BX_PROT_COOP (even though soft interrupts can not call kernel functions that would suspend them). The function's intended usage, when called from ISR-s or soft interrupts is to protect a short bit of code from FIQs or IRQs. It should be noted that in an ISR, especially if you are in ARM mode, it is quite faster to disable the FIQ by a call to BX_FiqDisable() call than calling this function. This, in an ISR the two fragments below have the same semantics, although the second is more efficient:

    void my_isr( void )
    {
    int     old_status;

        ... do something ...
        // now we must protect ourselves from FIQs
        old_status = BX_ProcProtRaise( BX_PROT_FIQD );
        // Do the protected bits
        ... we're protected ...
        BX_ProcProtLower( old_status );
    }

    void my_isr( void )
    {
    int     old_status;

        ... do something ...
        // now we must protect ourselves from FIQs
        old_status = BX_FiqDisable();
        // Do the protected bits
        ... we're protected ...
        BX_FiqRestore( old_status );
    }

However, the same is not true for functions that can be called from ISRs as well as from soft interrupts or user code. In that case the efficient approach of directly manipulating the processor's status register is not sufficient because the kernel is not notified about the status change. This then can result in lost kernel events, context switching a process while the interrupt is disabled and other very hard to debug problems. Therefore, it is advised that if you are not absolutely certain that the code fragment that needs FIQ protection will never, ever be called from a context other than a real IRQ ISR, use the BX_ProcProtRaise() and BX_ProcProtLower() mechanism. If you are sure that the fragment is only executed within an IRQ ISR, then it is more efficient to use the BX_FiqDisable() and BX_FiqRestore() functions. Note that the latter function pair does not check if the caller is an IRQ ISR or not (the check is omitted for efficincy) and thus you need to be careful with them.

Parameters:
prot The desired protection level
Returns:
The protection level before the call
BX_PROC * BX_ProcSelf ( void   ) 

Returns the caller's process descriptor.

The function, if called from a user process, returns the process descriptor of the caller. If it is called from an interrupt context, either a real interrupt or a delayed interrupt, it returns NULL.

Returns:
The process descriptor of the caller or NULL if the call is from an interrupt context.
int BX_ProcSpawn ( BX_PROC proc,
BX_PROC_FUNC  func,
void *  parm,
int *  stack,
unsigned int  prio,
BX_PROT  prot 
)

Creates a new process.

Parameters:
proc Pointer to a process descriptor that will hold the internal state of the newly created process.
func Pointer to a function returning void and receiving a void pointer. This function will be the entry point of the new process. This function must not return, if it does, the system will crash.
parm The parameter that will be passed to the function.
stack The initial stack pointer for the new process. It must be aligned on a 32-bit word boundary. If you use and unsigned int array, declared like stk[S_SIZE] then you should pass a pointer to just behind the last element of the array. That is, you should pass stk+S_SIZE. If you pass an incorrect stack pointer, the system will crash. It goes without saying that the stack areas for processes must be distinct, even if you start the same function for different processes. Do not laugh. I've seen it done.
prio The initial priority of the process, between BX_PRIO_MIN (least important) and BX_PRIO_MAX (most important). If the parameter is out of these bounds, it will be cropped.
prot The initial protection level of the process. If the level passed is higher than BX_PROT_FIQD, then it will be set to BX_PROT_FIQD.
Return values:
>0 Success
BX_ERR_CONTEXT The function was called from an ISR context.
Attention:
This function should not be called from an ISR or delayed ISR. This function does not suspend the caller but can cause a context switch if a higher priority process is created by the call.
Generated on Mon Aug 16 09:50:08 2010 by  doxygen 1.6.3