📄 picoos.h
字号:
* For this purpose you can define the macro @b FINDBIT. Please see the
* header file picoos.h (search for the word ::POSCFG_FBIT_USE_LUTABLE)
* and the source file fbit_gen.c for details.@n
*
* @n<h3>Assembler Functions</h3>
* Unfortunately, not the whole operating system can be written in C.
* The platform port must be written in assembly language. I tried to
* keep the assembly part of the RTOS as small as possible. But there
* are three assembly functions left, that are needed for doing
* the context switching:@n
*
* - ::p_pos_startFirstContext
* - ::p_pos_softContextSwitch
* - ::p_pos_intContextSwitch
*
* The operating system requires also a timer interrupt that is used
* to cut the task execution time into slices. Hardware interrupts
* must comply with some conventions to be compatible to pico]OS.
* So the fourth thing you need to write in assember is a framework
* for hardware interrupts.@n
*
* The diagram shows the assembler functions in logical structure.
* At the left side I have drawn a normal interrupt service routine
* for reference.@n@n@n
*
* <p><img src="../pic/portfc1.png" align="middle" border=0></p>@n
*
* The context switching (multitasking) is done by simply swaping the
* stack frame when an interrupt service routine (eg. the timer interrupt)
* is left. But it must also be possible for a task to give of processing
* time without the need of an interrupt.
* This is done by the function ::p_pos_softContextSwitch
* at the right side in the diagram. Since this function is not called
* by a processor interrupt, it must build up an ISR compatible
* stack frame by itself. Note that the second part of this function is
* equal to the function ::p_pos_intContextSwitch, so the function must be
* terminated by an return-from-interrupt instruction, even if the
* function was called from a C-routine.@n
*
* For completeness, the next diagram shows at its left side how
* the function ::p_pos_startFirstContext works. Again, this function
* looks like the lower part of the funtion ::p_pos_intContextSwitch
* in the diagram above. In the middle you can see how the timer
* interrupt routine must look like.@n@n@n
*
* <p><img src="../pic/portfc2.png" align="middle" border=0></p>@n
*
* There is a special interrupt handling needed when interrupts are
* interruptable on your system. To prevent a deadlock situation (that
* is, an ISR would be called again and again until the stack flows over),
* a counting flag variable is exported by pico]OS: ::posInInterrupt_g.
* This variable contains the value zero if no interrupt is running yet.
* And only if no other interrupt is running, the ISR must save the
* stack pointer to the task environment structure where ::posCurrentTask_g
* points to. This behaviour is shown at the right side in the
* diagram above.@n
*
* Note that interrupt service routines need some stack space to be
* able to do their work - in the discussed configuration every ISR
* would take some stack memory from the stack frame of the currently
* active task. But this may be a problem at platforms that are low
* on memory - it would be to expensive to increase every tasks stack
* frame by the count of bytes an ISR would need. In this case, you can
* set up a special stackframe that is only used by interrupt service
* routines. The diagram below shows the small changes to the ISRs
* discussed above. But attention - this method is only applicable on
* platforms where interrupts can not interrupt each other.@n@n@n
*
* <p><img src="../pic/portfc3.png" align="middle" border=0></p>@n
*
* @{
*/
/* findbit function or macro definition */
#if (DOX!=0) || (POSCFG_ROUNDROBIN == 0)
#ifdef FINDBIT
#define POS_FINDBIT(bf) FINDBIT(bf, 0)
#define POS_FINDBIT_EX(bf, ofs) FINDBIT(bf, 0)
#else /* FINDBIT */
POSFROMEXT UVAR_t p_pos_findbit(const UVAR_t bitfield); /* arch_c.c */
#define POS_FINDBIT(bf) p_pos_findbit(bf)
#define POS_FINDBIT_EX(bf, ofs) p_pos_findbit(bf)
#endif /* FINDBIT */
#else /* POSCFG_ROUNDROBIN */
#ifdef FINDBIT
#define POS_FINDBIT(bf) FINDBIT(bf, 0)
#define POS_FINDBIT_EX(bf, ofs) FINDBIT(bf, ofs)
#else /* FINDBIT */
POSFROMEXT UVAR_t p_pos_findbit(const UVAR_t bitfield, UVAR_t rrOffset); /* arch_c.c */
#define POS_FINDBIT(bf) p_pos_findbit(bf, 0)
#define POS_FINDBIT_EX(bf, ofs) p_pos_findbit(bf, ofs)
#endif /* FINDBIT */
#endif /* POSCFG_ROUNDROBIN */
#if DOX!=0
/**
* Bit finding function.
* This function is called by the operating system to find the
* first set bit in a bitfield. See the file fbit_gen.c for an example.
* @param bitfield This is the bitfield that shall be scanned.
* @return the number of the first set bit (scanning begins with the lsb).
* @note ::POSCFG_ROUNDROBIN <b>must be defined to 0</b>
* to have this format of the function compiled in.
*/
POSFROMEXT UVAR_t p_pos_findbit(const UVAR_t bitfield);
/**
* Bit finding function.
* This function is called by the operating system to find the
* first set bit in a bitfield. See the file fbit_gen.c for an example.
* @param bitfield This is the bitfield that shall be scanned.
* @param rrOffset Offset into the bitfield. Scanning begins here.
* @return the number of the first set bit (scanning begins with the lsb).
* @note ::POSCFG_ROUNDROBIN <b>must be defined to 1</b>
* to have this format of the function compiled in.
*/
POSFROMEXT UVAR_t p_pos_findbit(const UVAR_t bitfield, UVAR_t rrOffset);
#endif
#if (DOX!=0) || (POSCFG_CALLINITARCH != 0)
/**
* Architecture port initialization.
* This function is called from the ::posInit function to initialize
* the architecture specific part of the operating system.
* @note ::POSCFG_CALLINITARCH must be defined to 1
* when ::posInit shall call this function.@n
* This function is not part of the pico]OS. It must be
* provided by the user, since it is architecture specific.@n
* A timer interrupt should be initialized in the funcion
* ::p_pos_startFirstContext.
*/
POSFROMEXT void p_pos_initArch(void);
#endif
#if (DOX!=0) || (POSCFG_TASKSTACKTYPE == 0)
/**
* Task initialization function.
* This function is called by the operating system to
* initialize the stack frame of a new task.
* See the available port source files for an
* example on how to write this function.
* @param task pointer to the task environment structure.
* @param stackstart pointer to the start of the stack memory.
* @param funcptr pointer to the first function that shall
* be executed by the new task.
* @param funcarg argument that should be passed to the
* first function.
* @note ::POSCFG_TASKSTACKTYPE <b>must be defined to 0</b>
* to have this format of the function compiled in.@n
* This function is not part of the pico]OS. It must be
* provided by the user, since it is architecture specific.@n
* The processor interrupts are disabled when this function
* is called.
*/
POSFROMEXT void p_pos_initTask(POSTASK_t task, void *stackstart,
POSTASKFUNC_t funcptr,
void *funcarg); /* arch_c.c */
#endif
#if (DOX!=0) || (POSCFG_TASKSTACKTYPE == 1)
/**
* Task initialization function.
* This function is called by the operating system to
* initialize the stack frame of a new task.
* See the available port source files for an
* example on how to write this function.
* @param task pointer to the task environment structure.
* @param stacksize size of the stack memory for the new task.
* The stack memory may be allocated
* dynamically from within this function.
* @param funcptr pointer to the first function that shall
* be executed by the new task.
* @param funcarg argument that should be passed to the
* first function.
* @return zero on success. A negative value should be returned
* to denote an error (e.g. out of stack memory).
* @note ::POSCFG_TASKSTACKTYPE <b>must be defined to 1</b>
* to have this format of the function compiled in.@n
* This function is not part of the pico]OS. It must be
* provided by the user, since it is architecture specific.@n
* The processor interrupts are disabled when this function
* is called.
* @sa p_pos_freeStack
*/
POSFROMEXT VAR_t p_pos_initTask(POSTASK_t task, UINT_t stacksize,
POSTASKFUNC_t funcptr,
void *funcarg); /* arch_c.c */
/*
* Stack free function.
* This function is called by the operating system to
* free a stack frame that was set up by the function
* ::p_pos_initTask.
* See the available port source files for an
* example on how to write this function.
* @param task pointer to the task environment structure.
* @note ::POSCFG_TASKSTACKTYPE <b>must be defined to 1 or 2</b>
* to have this format of the function compiled in.@n
* This function is not part of the pico]OS. It must be
* provided by the user, since it is architecture specific.@n
* The processor interrupts are disabled when this function
* is called; but the processor may still write some bytes to
* the stack frame after this function was called and before
* the interrupts are enabled again.
* @sa p_pos_initTask
*/
POSFROMEXT void p_pos_freeStack(POSTASK_t task);/* arch_c.c */
#endif
#if (DOX!=0) || (POSCFG_TASKSTACKTYPE == 2)
/**
* Task initialization function.
* This function is called by the operating system to
* initialize the stack frame of a new task.
* This function is responsible to allocate the stack memory and
* to store the pointer of the stack frame into the task environment.
* See the available port source files for an
* example on how to write this function.
* @param task pointer to the task environment structure.
* @param funcptr pointer to the first function that shall
* be executed by the new task.
* @param funcarg argument that should be passed to the
* first function.
* @return zero on success. A negative value should be returned
* to denote an error (e.g. out of stack memory).
* @note ::POSCFG_TASKSTACKTYPE <b>must be defined to 2</b>
* to have this format of the function compiled in.@n
* This function is not part of the pico]OS. It must be
* provided by the user, since it is architecture specific.@n
* The processor interrupts are disabled when this function
* is called.
* @sa p_pos_freeStack
*/
POSFROMEXT VAR_t p_pos_initTask(POSTASK_t task, POSTASKFUNC_t funcptr,
void *funcarg); /* arch_c.c */
/**
* Stack free function.
* This function is called by the operating system to
* free a stack frame that was set up by the function
* ::p_pos_initTask.
* See the available port source files for an
* example on how to write this function.
* @param task pointer to the task environment structure.
* @note ::POSCFG_TASKSTACKTYPE <b>must be defined to 1 or 2</b>
* to have this format of the function compiled in.@n
* This function is not part of the pico]OS. It must be
* provided by the user, since it is architecture specific.@n
* The processor interrupts are disabled when this function
* is called.
* @sa p_pos_initTask
*/
POSFROMEXT void p_pos_freeStack(POSTASK_t task);/* arch_c.c */
#endif
/**
* Context switch function.
* This function is called by the operating system to
* start the multitasking. The function has
* to restore the first context from stack memory.
* See the available port source files for an
* example on how to write this function.
* @note This function is not part of the pico]OS. It must be
* provided by the user, since it is architecture specific.@n
* The processor interrupts are disabled when this function
* is called.
* @sa p_pos_softContextSwitch, p_pos_intContextSwitch
*/
POSFROMEXT void p_pos_startFirstContext(void); /* arch_c.c */
/**
* Context switch function.
* This function is called by the operating system to
* initiate a software context switch. This function has then to
* save all volatile processor registers to stack memory, switch
* the context variable and restore the new context from
* stack memory. See the available port source files for an
* example on how to write this function.
* @note This function is not part of the pico]OS. It must be
* provided by the user, since it is architecture specific.@n
* The processor interrupts are disabled when this function
* is called.
* @sa p_pos_intContextSwitch, p_pos_startFirstContext
*/
POSFROMEXT void p_pos_softContextSwitch(void); /* arch_c.c */
/**
* Context switch function.
* This function is called by the operating system to initiate a
* context switch from interrupt level. This function has then
* to switch the context variable and restore the new context
* from stack memory. See the available port source files for an
* example on how to write this function.
* @note This function is not part of the pico]OS. It must be
* provided by the user, since it is architecture specific.
* The processor interrupts are disabled when this function
* is called.
* @sa p_pos_softContextSwitch, p_pos_startFirstContext
*/
POSFROMEXT void p_pos_intContextSwitch(void); /* arch_c.c */
/**
* Interrupt control function.
* This function must be called from an interrupt service routine
* to show the operating system that an ISR is currently running.
* This function must be called first before other operating system
* functions can be called from within the ISR.
* @sa c_pos_intExit, c_pos_timerInterrupt
*/
POSEXTERN void c_pos_intEnter(void); /* picoos.c */
/**
* Interrupt control function.
* This function must be called from an interrupt service routine
* to show the operating system that the ISR is going to complete its
* work and no operating system functions will be called any more
* from within the ISR.
* @sa c_pos_intEnter, c_pos_timerInterrupt
*/
POSEXTERN void c_pos_intExit(void); /* picoos.c */
/**
* Timer interrupt control function.
* This function must be called periodically from within a timer
* interrupt service routine. The whole system timing is derived
* from this timer interrupt.@n
*
* A timer ISR could look like this:@n
*
* @code
* PUSH ALL; // push all registers to stack@n
*
* if (posInInterrupt_g == 0)
* saveStackptrToCurrentTaskEnv();
*
* c_pos_intEnter();
* c_pos_timerInterrupt();
* c_pos_intExit();
*
* PULL ALL; // pull all registers from stack@n
* RETI; // return from interrupt@n
* @endcode
*
* @note Any other ISR looks like this, only the function
* ::c_pos_timerInterrupt is replaced by an user function.@n
* Dependent on the platform port, it can be necessary to
* evaluate the variable ::posRunning_g to ensure that the
* timer interrupt is not triggered when the OS is not yet
* running.@n
* To avoid this race condintions, it is better to initialize
* the timer interrupt in the function ::p_pos_startFirstContext.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -