⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 picoos.h

📁 picoos源码。The RTOS and the TCP/IP stack will be built automatically.
💻 H
📖 第 1 页 / 共 5 页
字号:
 * 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 + -