📄 picoos.h
字号:
#if (DOX==0) && (HZ <= 1000)
#define MS(msec) (((UINT_t)(msec)<(1000/HZ)) ? \
((UINT_t)1) : ((UINT_t)((1L*HZ*(UINT_t)(msec))/1000)))
#else
#define MS(msec) ((UINT_t)((1L*HZ*(UINT_t)(msec))/1000))
#endif
/*---------------------------------------------------------------------------
* DATA TYPES
*-------------------------------------------------------------------------*/
/** @brief Signed machine variable type.
* This variable type is the fastest for
* the target architecture.
* @sa UVAR_t
*/
typedef signed MVAR_t VAR_t;
/** @brief Unsigned machine variable type.
* This variable type is the fastest for
* the target architecture.
* @sa VAR_t
*/
typedef unsigned MVAR_t UVAR_t;
#ifndef MINT_t
#define MINT_t int
#endif
/** @brief Signed integer.
*
* The bit size can be changed by the user
* by defining MINT_t to something other than @e int
* in the port configuration file.
* This integer type is used by the operating system e.g.
* for semaphore counters and timer.
* @sa UINT_t
*/
typedef signed MINT_t INT_t;
/** @brief Unsigned integer.
*
* The bit size can be changed by the user
* by defining MINT_t to something other than @e int
* in the pico]OS configuration file.
* This integer type is used by the operating system e.g.
* for semaphore counters and timer.
* @sa INT_t
*/
typedef unsigned MINT_t UINT_t;
#ifndef MPTR_t
#define MPTR_t long
#endif
/** @brief Memory pointer type.
*
* This variable type is an integer with the width
* of the address lines of memory architecure. The bit width
* is equal to the width of a void-pointer.
* This variable type is needed by the operating system for
* lossless typecasting of void pointers to integers.
* ::MPTR_t is a define that is set in the port configuration
* file. When ::MPTR_t is not set, it defaults to @e long.
* @sa MPTR_t
*/
typedef unsigned MPTR_t MEMPTR_t;
#if (DOX!=0) || (POSCFG_FEATURE_LARGEJIFFIES == 0)
/** @brief Signed type of ::JIF_t.
* @sa JIF_t
*/
typedef VAR_t SJIF_t;
/** @brief Timer counter type. Can be ::UVAR_t or ::UINT_t.
* @sa SJIF_t
*/
typedef UVAR_t JIF_t;
#else
typedef INT_t SJIF_t;
typedef UINT_t JIF_t;
#endif
/** @brief Generic function pointer.
* @param arg optional argument, can be NULL if not used.
*/
typedef void (*POSTASKFUNC_t)(void* arg);
/** @brief Software interrupt callback function pointer.
*
* The parameter @e arg is the value that was dropped
* in the call to ::posSoftInt.
* @sa posSoftInt
*/
typedef void (*POSINTFUNC_t)(UVAR_t arg);
#if (DOX!=0) ||(POSCFG_FEATURE_IDLETASKHOOK != 0)
/** @brief Idle task function pointer */
typedef void (*POSIDLEFUNC_t)(void);
#endif
/* forward declarations (just dummies) */
struct POSSEMA;
struct POSMUTEX;
struct POSFLAG;
struct POSTIMER;
/** @brief Handle to a semaphore object.
* @sa posSemaCreate, posSemaGet, posSemaWait, posSemaSignal
*/
typedef struct POSSEMA *POSSEMA_t;
/** @brief Handle to a mutex object.
* @sa posMutexCreate, posMutexLock, posMutexTryLock, posMutexUnlock
*/
typedef struct POSMUTEX *POSMUTEX_t;
/** @brief Handle to a flag object.
* @sa posFlagCreate, posFlagDestroy, posFlagGet, posFlagSet
*/
typedef struct POSFLAG *POSFLAG_t;
/** @brief Handle to a timer object.
* @sa posTimerCreate, posTimerDestroy, posTimerSet, posTimerStart
*/
typedef struct POSTIMER *POSTIMER_t;
/** @brief Atomic variable.
* @sa posAtomicGet, posAtomicSet, posAtomicAdd, posAtomicSub
*/
typedef volatile INT_t POSATOMIC_t;
#if (DOX!=0) || (POSCFG_FEATURE_LISTS != 0)
struct POSLIST;
struct POSLISTHEAD {
struct POSLIST* volatile prev;
struct POSLIST* volatile next;
POSSEMA_t volatile sema;
UVAR_t volatile flag;
#if POSCFG_FEATURE_LISTLEN != 0
UINT_t volatile length;
#endif
};
struct POSLIST {
struct POSLIST* volatile prev;
struct POSLIST* volatile next;
#if POSCFG_FEATURE_LISTLEN != 0
struct POSLISTHEAD* volatile head;
#endif
};
/** @brief List variable.
* This variable type is used as running variable of a list or as list link.
* @sa POSLISTHEAD_t, posListInit, posListTerm, posListAdd, posListGet
*/
typedef struct POSLIST POSLIST_t;
/** @brief List variable.
* This variable defines the head of a list.
* @sa POSLIST_t, posListInit, posListTerm, posListAdd, posListGet
*/
typedef struct POSLISTHEAD POSLISTHEAD_t;
#endif
/** @brief Task environment structure.
*
* Most members of this structure are private, and are hidden from the user.
* The user can add its own members to the structure. For this purpose the
* user must define the macro ::POS_USERTASKDATA in the pico]OS
* configuration file. Here is an example of this macro:@n
*
* @code
* #define POS_USERTASKDATA \
* void *stackptr; \
* unsigned short stack[FIXED_STACK_SIZE]; \
* int errno;
* @endcode
*
* Note that the stackptr variable is required by most of the architecture
* ports. The stack array is an example of how to include the stack frame
* into the task environment structure (e.g. when ::POSCFG_TASKSTACKTYPE
* is defined to 2).
*/
typedef struct POSTASK *POSTASK_t; /* forward declaration */
/*---------------------------------------------------------------------------
* DEFINITIONS FOR GENERIC "findbit" FUNCTION (file fbit_gen.c)
*-------------------------------------------------------------------------*/
#ifndef POSCFG_FBIT_USE_LUTABLE
#define POSCFG_FBIT_USE_LUTABLE 0
#endif
#if (POSCFG_FBIT_USE_LUTABLE > 1) && (POSCFG_ROUNDROBIN == 0)
#undef POSCFG_FBIT_USE_LUTABLE
#define POSCFG_FBIT_USE_LUTABLE 1
#endif
#ifndef FINDBIT
#if POSCFG_FBIT_USE_LUTABLE == 1
#if POSCFG_ROUNDROBIN == 0
#ifndef _FBIT_GEN_C
extern VAR_t const p_pos_fbittbl[256];
#endif
#define FINDBIT(x) p_pos_fbittbl[x]
#else
UVAR_t p_pos_findbit(const UVAR_t bitfield, UVAR_t rrOffset);
#define FINDBIT(x, o) p_pos_findbit(x, o)
#endif
#elif POSCFG_FBIT_USE_LUTABLE == 2
#ifndef _FBIT_GEN_C
extern VAR_t const p_pos_fbittbl_rr[8][256];
#endif
#define FINDBIT(x, o) p_pos_fbittbl_rr[o][x]
#endif
#endif /* !FINDBIT */
/*---------------------------------------------------------------------------
* GLOBAL VARIABLES
*-------------------------------------------------------------------------*/
/** @brief Global task variable.
* This variable points to the environment structure of the currently
* active task.
* @note Only the context switch functions ::p_pos_softContextSwitch,
* ::p_pos_intContextSwitch and ::p_pos_startFirstContext
* need to access this variable.
* @sa posNextTask_g
*/
POSEXTERN volatile POSTASK_t posCurrentTask_g;
/** @brief Global task variable.
* This variable points to the environment structure of the next task
* that shall be scheduled.
* @note The context switch functions ::p_pos_softContextSwitch and
* ::p_pos_intContextSwitch must copy the content of this variable
* into the ::posCurrentTask_g variable.
* @sa posCurrentTask_g
*/
POSEXTERN volatile POSTASK_t posNextTask_g;
/** @brief Global flag variable.
* This variable is nonzero when the CPU is currently executing an
* interrupt service routine.
* @note Only the architecture specific ISR functions need to access
* this variable.
*/
#ifndef _POSCORE_C
POSEXTERN volatile UVAR_t posInInterrupt_g;
#else
POSEXTERN volatile UVAR_t posInInterrupt_g = 1;
#endif
/** @brief Global flag variable.
* This variable is nonzero when the operating system is initialized
* and running.
* @note Only the architecture specific ISR functions need to access
* this variable.
*/
#ifndef _POSCORE_C
POSEXTERN volatile UVAR_t posRunning_g;
#else
POSEXTERN volatile UVAR_t posRunning_g = 0;
#endif
#if DOX!=0
/** @brief Unix style error variable.
* This variable is global for the currently runnig task.
* @note ::POSCFG_FEATURE_ERRNO must be set to 1 to enable this variable.
* @sa POSCFG_FEATURE_ERRNO, E_OK
*/
VAR_t errno;
#endif
#if POSCFG_FEATURE_ERRNO != 0
#ifdef errno
#undef errno
#endif
POSEXTERN VAR_t* _errno_p(void);
#define errno (*_errno_p())
#endif
/*---------------------------------------------------------------------------
* PROTOTYPES OF INTERNAL FUNCTIONS
*-------------------------------------------------------------------------*/
/** @defgroup port pico]OS Porting Information
* @ingroup intro
* <h3>General Information</h3>
* <h4>Choose the best type of stack management</h4>
* The operating system can be easily ported to other architectures,
* it can be ported to very small 8 bit architectures with low memory
* and to 32 bit architectures with lots of memory. To keep the
* porting as simple as possible, there are only a couple of functions
* that must be adapted to the architecute.
* Before you start porting the operating system to your architecture,
* you must choose a stack management type. You have the choice
* between:@n
*
* ::POSCFG_TASKSTACKTYPE <b>= 0</b>@n
* The stack memory is provided by the user. This is the best choice for
* very small architectures with low memory.@n
*
* ::POSCFG_TASKSTACKTYPE <b>= 1</b>@n
* The stack memory is dynamically allocated by the architecture dependent
* code of the operating system. The size of the stack frame is variable
* and can be choosen by the user who creates the task. This is the best
* choice for big architectures with lots of memory.@n
*
* ::POSCFG_TASKSTACKTYPE <b>= 2</b>@n
* The stack memory is dynamically allocated by the architecture dependent
* code of the operating system. The size of the stack frame is fixed and
* can not be changed by the user. This may be an alternative to type 0,
* it is a little bit more user friendly.@n
*
* Here is a list of the functions that are architecture specific and
* must be ported:@n
* ::p_pos_initTask, ::p_pos_startFirstContext, ::p_pos_softContextSwitch,
* ::p_pos_intContextSwitch.@n
*
* If you choose ::POSCFG_TASKSTACKTYPE <b>= 2</b> or <b>3</b>, you must
* also provide the function ::p_pos_freeStack.@n@n@n
*
* <h4>Get more speed with optimized "findbit" function</h4>
* If your application is critical in performance, you may also provide
* an assembler version of the function "findbit".
* There are two different function prototypes possible. The simple
* prototype for the standard scheduling scheme
* (::POSCFG_ROUNDROBIN <b>= 0</b>) is@n
*
* <b>UVAR_t ::p_pos_findbit(const UVAR_t bitfield);</b>
*
* The prototype for a findbit function that supports round robin
* scheduling (::POSCFG_ROUNDROBIN <b>= 1</b>) is@n
*
* <b>UVAR_t ::p_pos_findbit(const UVAR_t bitfield, UVAR_t rrOffset);</b>@n
*
* The function gets a bitfield as input, and returns the number of the
* right most set bit (that is the number of the first lsb that is set).
* If round robin is enabled, the function takes an offset as second
* parameter. The offset is the position where the function starts to
* search the first set bit. The function scans the bitfield always from
* right to left, starting with the bit denoted by the offset. The bitfield
* is seen as circle, when the rightmost bit is not set the function
* must continue scanning the leftmost bit (wrap around), so all bits
* of the field are scanned.@n
* It is possible to implement the findbit mechanism as look up table.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -