00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00244 #ifndef _PICOOS_H
00245 #define _PICOOS_H
00246
00247
00248 #define POS_VER_N 0x0100
00249 #define POS_VER_S "1.0.0"
00250 #define POS_COPYRIGHT "(c) 2004-2006, D.Kuschel"
00251 #define POS_STARTUPSTRING "pico]OS " POS_VER_S " " POS_COPYRIGHT
00252
00253 #ifndef NULL
00254 #define NULL ((void*)0)
00255 #endif
00256
00257 #ifndef DOX
00258 #define DOX 0
00259 #endif
00260 #if DOX==0
00261
00262 #include <port.h>
00263 #include <poscfg.h>
00264
00265
00266
00267
00268
00269
00270
00271
00272 #ifndef MVAR_t
00273 #error MVAR_t not defined
00274 #endif
00275 #ifndef MVAR_BITS
00276 #error MVAR_BITS not defined
00277 #endif
00278 #ifndef POSCFG_ALIGNMENT
00279 #error POSCFG_ALIGNMENT not defined
00280 #endif
00281 #ifndef POSCFG_MAX_PRIO_LEVEL
00282 #error POSCFG_MAX_PRIO_LEVEL not defined
00283 #endif
00284 #ifndef POSCFG_MAX_TASKS
00285 #error POSCFG_MAX_TASKS not defined
00286 #endif
00287 #ifndef POSCFG_MAX_EVENTS
00288 #error POSCFG_MAX_EVENTS not defined
00289 #endif
00290 #ifndef POSCFG_MAX_MESSAGES
00291 #error POSCFG_MAX_MESSAGES not defined
00292 #endif
00293 #ifndef POSCFG_MAX_TIMER
00294 #error POSCFG_MAX_TIMER not defined
00295 #endif
00296 #ifndef POSCFG_SOFT_MTASK
00297 #error POSCFG_SOFT_MTASK not defined
00298 #endif
00299 #ifndef POSCFG_CTXSW_COMBINE
00300 #error POSCFG_CTXSW_COMBINE not defined
00301 #endif
00302 #ifndef POSCFG_REALTIME_PRIO
00303 #error POSCFG_REALTIME_PRIO not defined
00304 #endif
00305 #ifndef POSCFG_ISR_INTERRUPTABLE
00306 #error POSCFG_ISR_INTERRUPTABLE not defined
00307 #endif
00308 #ifndef POSCFG_ROUNDROBIN
00309 #error POSCFG_ROUNDROBIN not defined
00310 #endif
00311 #ifndef POSCFG_TASKS_PER_PRIO
00312 #error POSCFG_TASKS_PER_PRIO not defined
00313 #endif
00314 #ifndef POSCFG_FASTCODE
00315 #error POSCFG_FASTCODE not defined
00316 #endif
00317 #ifndef POSCFG_SMALLCODE
00318 #error POSCFG_SMALLCODE not defined
00319 #endif
00320 #ifndef POSCFG_ARGCHECK
00321 #error POSCFG_ARGCHECK not defined
00322 #endif
00323 #ifndef POSCFG_MSG_MEMORY
00324 #error POSCFG_MSG_MEMORY not defined
00325 #endif
00326 #ifndef POSCFG_MSG_BUFSIZE
00327 #error POSCFG_MSG_BUFSIZE not defined
00328 #endif
00329 #ifndef POSCFG_DYNAMIC_MEMORY
00330 #error POSCFG_DYNAMIC_MEMORY not defined
00331 #endif
00332 #ifndef POSCFG_DYNAMIC_REFILL
00333 #error POSCFG_DYNAMIC_REFILL
00334 #endif
00335 #if POSCFG_DYNAMIC_MEMORY != 0
00336 #ifndef POS_MEM_ALLOC
00337 #error POS_MEM_ALLOC not defined
00338 #endif
00339 #ifndef POS_MEM_ALLOC
00340 #error POS_MEM_ALLOC not defined
00341 #endif
00342 #endif
00343 #ifndef POSCFG_CALLINITARCH
00344 #error POSCFG_CALLINITARCH not defined
00345 #endif
00346 #ifndef POSCFG_LOCK_USEFLAGS
00347 #error POSCFG_LOCK_USEFLAGS not defined
00348 #endif
00349 #if POSCFG_LOCK_USEFLAGS != 0
00350 #ifndef POSCFG_LOCK_FLAGSTYPE
00351 #error POSCFG_LOCK_FLAGSTYPE not defined
00352 #endif
00353 #endif
00354 #ifndef POS_SCHED_LOCK
00355 #error POS_SCHED_LOCK not defined
00356 #endif
00357 #ifndef POS_SCHED_UNLOCK
00358 #error POS_SCHED_UNLOCK not defined
00359 #endif
00360 #ifndef HZ
00361 #error HZ not defined
00362 #endif
00363 #ifndef POSCFG_TASKSTACKTYPE
00364 #error POSCFG_TASKSTACKTYPE not defined
00365 #endif
00366 #ifndef POS_USERTASKDATA
00367 #error POS_USERTASKDATA not defined
00368 #endif
00369 #ifndef POSCFG_FEATURE_YIELD
00370 #error POSCFG_FEATURE_YIELD not defined
00371 #endif
00372 #ifndef POSCFG_FEATURE_SLEEP
00373 #error POSCFG_FEATURE_SLEEP not defined
00374 #endif
00375 #ifndef POSCFG_FEATURE_EXIT
00376 #error POSCFG_FEATURE_EXIT not defined
00377 #endif
00378 #ifndef POSCFG_FEATURE_GETPRIORITY
00379 #error POSCFG_FEATURE_GETPRIORITY not defined
00380 #endif
00381 #ifndef POSCFG_FEATURE_SETPRIORITY
00382 #error POSCFG_FEATURE_SETPRIORITY not defined
00383 #endif
00384 #ifndef POSCFG_FEATURE_SEMAPHORES
00385 #error POSCFG_FEATURE_SEMAPHORES not defined
00386 #endif
00387 #ifndef POSCFG_FEATURE_SEMADESTROY
00388 #error POSCFG_FEATURE_SEMADESTROY not defined
00389 #endif
00390 #ifndef POSCFG_FEATURE_SEMAWAIT
00391 #error POSCFG_FEATURE_SEMAWAIT not defined
00392 #endif
00393 #ifndef POSCFG_FEATURE_MUTEXES
00394 #error POSCFG_FEATURE_MUTEXES not defined
00395 #endif
00396 #ifndef POSCFG_FEATURE_MUTEXDESTROY
00397 #error POSCFG_FEATURE_MUTEXDESTROY not defined
00398 #endif
00399 #ifndef POSCFG_FEATURE_MUTEXTRYLOCK
00400 #error POSCFG_FEATURE_MUTEXTRYLOCK not defined
00401 #endif
00402 #ifndef POSCFG_FEATURE_GETTASK
00403 #error POSCFG_FEATURE_GETTASK not defined
00404 #endif
00405 #ifndef POSCFG_FEATURE_TASKUNUSED
00406 #error POSCFG_FEATURE_TASKUNUSED not defined
00407 #endif
00408 #ifndef POSCFG_FEATURE_MSGBOXES
00409 #error POSCFG_FEATURE_MSGBOXES not defined
00410 #endif
00411 #ifndef POSCFG_FEATURE_MSGWAIT
00412 #error POSCFG_FEATURE_MSGWAIT not defined
00413 #endif
00414 #ifndef POSCFG_FEATURE_INHIBITSCHED
00415 #error POSCFG_FEATURE_INHIBITSCHED not defined
00416 #endif
00417 #ifndef POSCFG_FEATURE_JIFFIES
00418 #error POSCFG_FEATURE_JIFFIES not defined
00419 #endif
00420 #ifndef POSCFG_FEATURE_TIMER
00421 #error POSCFG_FEATURE_TIMER not defined
00422 #endif
00423 #ifndef POSCFG_FEATURE_TIMERDESTROY
00424 #error POSCFG_FEATURE_TIMERDESTROY not defined
00425 #endif
00426 #ifndef POSCFG_FEATURE_TIMERFIRED
00427 #error POSCFG_FEATURE_TIMERFIRED not defined
00428 #endif
00429 #ifndef POSCFG_FEATURE_FLAGS
00430 #error POSCFG_FEATURE_FLAGS not defined
00431 #endif
00432 #ifndef POSCFG_FEATURE_FLAGDESTROY
00433 #error POSCFG_FEATURE_FLAGDESTROY not defined
00434 #endif
00435 #ifndef POSCFG_FEATURE_FLAGWAIT
00436 #error POSCFG_FEATURE_FLAGWAIT not defined
00437 #endif
00438 #ifndef POSCFG_FEATURE_SOFTINTS
00439 #error POSCFG_FEATURE_SOFTINTS not defined
00440 #else
00441 #ifndef POSCFG_FEATURE_SOFTINTDEL
00442 #error POSCFG_FEATURE_SOFTINTDEL not defined
00443 #endif
00444 #ifndef POSCFG_SOFTINTERRUPTS
00445 #error POSCFG_SOFTINTERRUPTS not defined
00446 #endif
00447 #ifndef POSCFG_SOFTINTQUEUELEN
00448 #error POSCFG_SOFTINTQUEUELEN not defined
00449 #endif
00450 #endif
00451 #ifndef POSCFG_FEATURE_IDLETASKHOOK
00452 #error POSCFG_FEATURE_IDLETASKHOOK not defined
00453 #endif
00454 #ifndef POSCFG_FEATURE_ERRNO
00455 #error POSCFG_FEATURE_ERRNO not defined
00456 #endif
00457 #ifndef POSCFG_FEATURE_ATOMICVAR
00458 #error POSCFG_FEATURE_ATOMICVAR not defined
00459 #endif
00460 #ifndef POSCFG_FEATURE_LISTS
00461 #error POSCFG_FEATURE_LISTS not defined
00462 #else
00463 #ifndef POSCFG_FEATURE_LISTJOIN
00464 #error POSCFG_FEATURE_LISTJOIN not defined
00465 #endif
00466 #ifndef POSCFG_FEATURE_LISTLEN
00467 #define POSCFG_FEATURE_LISTLEN 1
00468 #endif
00469 #endif
00470 #ifndef POSCFG_FEATURE_DEBUGHELP
00471 #define POSCFG_FEATURE_DEBUGHELP 0
00472 #endif
00473 #ifdef _DBG
00474 #if POSCFG_FEATURE_DEBUGHELP
00475 #define POS_DEBUGHELP
00476 #endif
00477 #endif
00478
00479
00480 #if (POSCFG_DYNAMIC_MEMORY != 0) && (POSCFG_DYNAMIC_REFILL != 0)
00481 #define SYS_POSTALLOCATE 1
00482 #else
00483 #define SYS_POSTALLOCATE 0
00484 #endif
00485 #if (MVAR_BITS != 8) && (MVAR_BITS != 16) && (MVAR_BITS != 32)
00486 #error MVAR_BITS must be 8, 16 or 32
00487 #endif
00488 #if POSCFG_MAX_PRIO_LEVEL == 0
00489 #error POSCFG_MAX_PRIO_LEVEL must not be zero
00490 #endif
00491 #if (POSCFG_ROUNDROBIN != 0) && (POSCFG_MAX_PRIO_LEVEL > MVAR_BITS)
00492 #error POSCFG_MAX_PRIO_LEVEL must not exceed MVAR_BITS
00493 #endif
00494 #if (POSCFG_ROUNDROBIN == 0) && (POSCFG_MAX_PRIO_LEVEL > (MVAR_BITS*MVAR_BITS))
00495 #error POSCFG_MAX_PRIO_LEVEL must not exceed (MVAR_BITS * MVAR_BITS)
00496 #endif
00497 #if (POSCFG_MAX_TASKS < 2) && (SYS_POSTALLOCATE == 0)
00498 #error POSCFG_MAX_TASKS is less than 2
00499 #endif
00500 #if (POSCFG_MAX_TASKS > (POSCFG_TASKS_PER_PRIO * POSCFG_MAX_PRIO_LEVEL))
00501 #error POSCFG_MAX_TASKS is much to big
00502 #endif
00503 #if (POSCFG_MAX_EVENTS < 1) && (SYS_POSTALLOCATE == 0)
00504 #error POSCFG_MAX_EVENTS must be at least 1
00505 #endif
00506 #if POSCFG_TASKS_PER_PRIO > MVAR_BITS
00507 #error POSCFG_TASKS_PER_PRIO can not exceed MVAR_BITS
00508 #endif
00509 #if (POSCFG_TASKS_PER_PRIO < 2) && (POSCFG_ROUNDROBIN != 0)
00510 #error POSCFG_TASKS_PER_PRIO must be at least 2
00511 #endif
00512 #if (POSCFG_TASKS_PER_PRIO != 1) && (POSCFG_ROUNDROBIN == 0)
00513 #error POSCFG_TASKS_PER_PRIO must be 1 when round robin scheduling is disabled
00514 #endif
00515 #if ((POSCFG_TASKS_PER_PRIO % 3) == 0) || ((POSCFG_TASKS_PER_PRIO % 5) == 0)
00516 #error POSCFG_TASKS_PER_PRIO must be 1/2/4/8/16 or 32
00517 #endif
00518 #if (POSCFG_REALTIME_PRIO >= POSCFG_MAX_PRIO_LEVEL) && (POSCFG_ROUNDROBIN != 0)
00519 #error POSCFG_REALTIME_PRIO must be less than POSCFG_MAX_PRIO_LEVEL
00520 #endif
00521 #if POSCFG_FEATURE_MSGBOXES != 0
00522 #if (POSCFG_MAX_MESSAGES < 2) && (SYS_POSTALLOCATE == 0)
00523 #error POSCFG_MAX_MESSAGES must be at least 2
00524 #endif
00525 #if POSCFG_MSG_BUFSIZE < 1
00526 #error POSCFG_MSG_BUFSIZE must be at least 1
00527 #endif
00528 #endif
00529 #if (POSCFG_FEATURE_TIMER != 0)
00530 #if (POSCFG_MAX_TIMER == 0) && (SYS_POSTALLOCATE == 0)
00531 #error POSCFG_MAX_TIMER must be at least 1
00532 #endif
00533 #endif
00534 #if (POSCFG_TASKSTACKTYPE < 0) || (POSCFG_TASKSTACKTYPE > 2)
00535 #error POSCFG_TASKSTACKTYPE must be 0, 1 or 2
00536 #endif
00537 #if POSCFG_ALIGNMENT == 0
00538 #undef POSCFG_ALIGNMENT
00539 #define POSCFG_ALIGNMENT 1
00540 #else
00541 #if ((POSCFG_ALIGNMENT % 3) == 0) || ((POSCFG_ALIGNMENT % 5) == 0)
00542 #error POSCFG_ALIGNMENT must be 1/2/4/8/16/32/64/128/256 etc.
00543 #endif
00544 #endif
00545 #if POSCFG_FEATURE_SOFTINTS != 0
00546 #if POSCFG_SOFTINTERRUPTS == 0
00547 #error POSCFG_SOFTINTERRUPTS must be greater than 0
00548 #endif
00549 #if POSCFG_SOFTINTQUEUELEN < 2
00550 #error POSCFG_SOFTINTQUEUELEN must be at least 2
00551 #endif
00552 #endif
00553
00554
00555
00556 #ifndef POSCFG_TASKCB_USERSPACE
00557 #define POSCFG_TASKCB_USERSPACE 0
00558 #endif
00559 #if POSCFG_FEATURE_SEMAPHORES == 0
00560 #undef POSCFG_FEATURE_SEMADESTROY
00561 #define POSCFG_FEATURE_SEMADESTROY 0
00562 #endif
00563 #if POSCFG_FEATURE_FLAGS == 0
00564 #undef POSCFG_FEATURE_FLAGDESTROY
00565 #define POSCFG_FEATURE_FLAGDESTROY 0
00566 #endif
00567 #if POSCFG_FEATURE_MUTEXES == 0
00568 #undef POSCFG_FEATURE_MUTEXDESTROY
00569 #define POSCFG_FEATURE_MUTEXDESTROY 0
00570 #else
00571 #if (POSCFG_FEATURE_MUTEXDESTROY != 0) && (POSCFG_FEATURE_SEMADESTROY == 0)
00572 #undef POSCFG_FEATURE_SEMADESTROY
00573 #define POSCFG_FEATURE_SEMADESTROY 1
00574 #endif
00575 #endif
00576 #if (POSCFG_FEATURE_MSGBOXES != 0) && (SYS_POSTALLOCATE == 0)
00577 #define SYS_MSGBOXEVENTS 2
00578 #else
00579 #define SYS_MSGBOXEVENTS 0
00580 #endif
00581 #if (POSCFG_FEATURE_MSGBOXES != 0) && (POSCFG_FEATURE_GETTASK == 0)
00582 #undef POSCFG_FEATURE_GETTASK
00583 #define POSCFG_FEATURE_GETTASK 1
00584 #endif
00585 #if (POSCFG_FEATURE_SEMAWAIT != 0) || (POSCFG_FEATURE_MSGWAIT != 0)
00586 #define SYS_TASKDOUBLELINK 1
00587 #else
00588 #define SYS_TASKDOUBLELINK 0
00589 #endif
00590 #define SYS_EVENTS_USED \
00591 (POSCFG_FEATURE_MUTEXES | POSCFG_FEATURE_MSGBOXES | \
00592 POSCFG_FEATURE_FLAGS | POSCFG_FEATURE_LISTS)
00593 #define SYS_FEATURE_EVENTS (POSCFG_FEATURE_SEMAPHORES | SYS_EVENTS_USED)
00594 #define SYS_FEATURE_EVENTFREE (POSCFG_FEATURE_SEMADESTROY | \
00595 POSCFG_FEATURE_MUTEXDESTROY | POSCFG_FEATURE_FLAGDESTROY | \
00596 POSCFG_FEATURE_LISTS)
00597 #if (POSCFG_FEATURE_MSGBOXES != 0) && (POSCFG_FEATURE_EXIT != 0)
00598 #undef SYS_FEATURE_EVENTFREE
00599 #define SYS_FEATURE_EVENTFREE 1
00600 #endif
00601 #ifndef POSCFG_FEATURE_LARGEJIFFIES
00602 #if MVAR_BITS < 16
00603 #define POSCFG_FEATURE_LARGEJIFFIES 1
00604 #else
00605 #define POSCFG_FEATURE_LARGEJIFFIES 0
00606 #endif
00607 #endif
00608 #endif
00609
00610
00611
00612
00613
00614
00615
00616 #ifdef _POSCORE_C
00617 #define POSEXTERN
00618 #define POSFROMEXT extern
00619 #else
00620 #define POSEXTERN extern
00621 #define POSFROMEXT
00622 #endif
00623
00624 #if POSCFG_ROUNDROBIN == 0
00625 #define SYS_TASKTABSIZE_X MVAR_BITS
00626 #define SYS_TASKTABSIZE_Y ((POSCFG_MAX_PRIO_LEVEL+MVAR_BITS-1)/MVAR_BITS)
00627 #else
00628 #define SYS_TASKTABSIZE_X POSCFG_TASKS_PER_PRIO
00629 #define SYS_TASKTABSIZE_Y POSCFG_MAX_PRIO_LEVEL
00630 #endif
00631
00632 #define SYS_TASKSTATE (POSCFG_FEATURE_TASKUNUSED | POSCFG_FEATURE_MSGBOXES)
00633
00634 #if POSCFG_LOCK_USEFLAGS != 0
00635 #define POS_LOCKFLAGS POSCFG_LOCK_FLAGSTYPE flags
00636 #else
00637 #define POS_LOCKFLAGS do { } while(0)
00638 #endif
00639
00640 #define POSTASKSTATE_UNUSED 0
00641 #define POSTASKSTATE_ZOMBIE 1
00642 #define POSTASKSTATE_ACTIVE 2
00643
00644 #define INFINITE ((UINT_t)~0)
00645
00646
00647
00648
00649
00650
00651
00666 #define E_OK 0
00667
00669 #define E_FAIL 1
00670
00672 #define E_NOMEM 2
00673
00675 #define E_ARG 3
00676
00678 #define E_FORB 4
00679
00681 #define E_NOMORE 5
00682
00684 #define E_NOTFOUND 6
00685
00690
00691
00692
00693
00699 #if (DOX==0) && (HZ <= 1000)
00700 #define MS(msec) (((UINT_t)(msec)<(1000/HZ)) ? \
00701 ((UINT_t)1) : ((UINT_t)((1L*HZ*(UINT_t)(msec))/1000)))
00702 #else
00703 #define MS(msec) ((UINT_t)((1L*HZ*(UINT_t)(msec))/1000))
00704 #endif
00705
00706
00707
00708
00709
00710
00711
00717 typedef signed MVAR_t VAR_t;
00718
00724 typedef unsigned MVAR_t UVAR_t;
00725
00726 #ifndef MINT_t
00727 #define MINT_t int
00728 #endif
00729
00738 typedef signed MINT_t INT_t;
00739
00749 typedef unsigned MINT_t UINT_t;
00750
00751 #ifndef MPTR_t
00752 #define MPTR_t long
00753 #endif
00754
00765 typedef unsigned MPTR_t MEMPTR_t;
00766
00767 #if (DOX!=0) || (POSCFG_FEATURE_LARGEJIFFIES == 0)
00768
00771 typedef VAR_t SJIF_t;
00775 typedef UVAR_t JIF_t;
00776 #else
00777 typedef INT_t SJIF_t;
00778 typedef UINT_t JIF_t;
00779 #endif
00780
00784 typedef void (*POSTASKFUNC_t)(void* arg);
00785
00792 typedef void (*POSINTFUNC_t)(UVAR_t arg);
00793
00794 #if (DOX!=0) ||(POSCFG_FEATURE_IDLETASKHOOK != 0)
00795
00796 typedef void (*POSIDLEFUNC_t)(void);
00797 #endif
00798
00799
00800 struct POSSEMA;
00801 struct POSMUTEX;
00802 struct POSFLAG;
00803 struct POSTIMER;
00804
00808 typedef struct POSSEMA *POSSEMA_t;
00809
00813 typedef struct POSMUTEX *POSMUTEX_t;
00814
00818 typedef struct POSFLAG *POSFLAG_t;
00819
00823 typedef struct POSTIMER *POSTIMER_t;
00824
00828 typedef volatile INT_t POSATOMIC_t;
00829
00830 #if (DOX!=0) || (POSCFG_FEATURE_LISTS != 0)
00831 struct POSLIST;
00832 struct POSLISTHEAD {
00833 struct POSLIST* volatile prev;
00834 struct POSLIST* volatile next;
00835 POSSEMA_t volatile sema;
00836 UVAR_t volatile flag;
00837 #if POSCFG_FEATURE_LISTLEN != 0
00838 UINT_t volatile length;
00839 #endif
00840 };
00841 struct POSLIST {
00842 struct POSLIST* volatile prev;
00843 struct POSLIST* volatile next;
00844 #if POSCFG_FEATURE_LISTLEN != 0
00845 struct POSLISTHEAD* volatile head;
00846 #endif
00847 };
00852 typedef struct POSLIST POSLIST_t;
00857 typedef struct POSLISTHEAD POSLISTHEAD_t;
00858 #endif
00859
00860
00880 typedef struct POSTASK *POSTASK_t;
00881
00882
00883
00884
00885
00886
00887
00888 #ifndef POSCFG_FBIT_USE_LUTABLE
00889 #define POSCFG_FBIT_USE_LUTABLE 0
00890 #endif
00891 #if (POSCFG_FBIT_USE_LUTABLE > 1) && (POSCFG_ROUNDROBIN == 0)
00892 #undef POSCFG_FBIT_USE_LUTABLE
00893 #define POSCFG_FBIT_USE_LUTABLE 1
00894 #endif
00895 #ifndef FINDBIT
00896 #if POSCFG_FBIT_USE_LUTABLE == 1
00897 #if POSCFG_ROUNDROBIN == 0
00898 #ifndef _FBIT_GEN_C
00899 extern VAR_t const p_pos_fbittbl[256];
00900 #endif
00901 #define FINDBIT(x) p_pos_fbittbl[x]
00902 #else
00903 UVAR_t p_pos_findbit(const UVAR_t bitfield, UVAR_t rrOffset);
00904 #define FINDBIT(x, o) p_pos_findbit(x, o)
00905 #endif
00906 #elif POSCFG_FBIT_USE_LUTABLE == 2
00907 #ifndef _FBIT_GEN_C
00908 extern VAR_t const p_pos_fbittbl_rr[8][256];
00909 #endif
00910 #define FINDBIT(x, o) p_pos_fbittbl_rr[o][x]
00911 #endif
00912 #endif
00913
00914
00915
00916
00917
00918
00919
00928 POSEXTERN volatile POSTASK_t posCurrentTask_g;
00929
00938 POSEXTERN volatile POSTASK_t posNextTask_g;
00939
00946 #ifndef _POSCORE_C
00947 POSEXTERN volatile UVAR_t posInInterrupt_g;
00948 #else
00949 POSEXTERN volatile UVAR_t posInInterrupt_g = 1;
00950 #endif
00951
00958 #ifndef _POSCORE_C
00959 POSEXTERN volatile UVAR_t posRunning_g;
00960 #else
00961 POSEXTERN volatile UVAR_t posRunning_g = 0;
00962 #endif
00963
00964
00965 #if DOX!=0
00966
00971 VAR_t errno;
00972 #endif
00973 #if POSCFG_FEATURE_ERRNO != 0
00974 #ifdef errno
00975 #undef errno
00976 #endif
00977 POSEXTERN VAR_t* _errno_p(void);
00978 #define errno (*_errno_p())
00979 #endif
00980
00981
00982
00983
00984
00985
00986
01121
01122 #if (DOX!=0) || (POSCFG_ROUNDROBIN == 0)
01123 #ifdef FINDBIT
01124 #define POS_FINDBIT(bf) FINDBIT(bf, 0)
01125 #define POS_FINDBIT_EX(bf, ofs) FINDBIT(bf, 0)
01126 #else
01127 POSFROMEXT UVAR_t p_pos_findbit(const UVAR_t bitfield);
01128 #define POS_FINDBIT(bf) p_pos_findbit(bf)
01129 #define POS_FINDBIT_EX(bf, ofs) p_pos_findbit(bf)
01130 #endif
01131 #else
01132 #ifdef FINDBIT
01133 #define POS_FINDBIT(bf) FINDBIT(bf, 0)
01134 #define POS_FINDBIT_EX(bf, ofs) FINDBIT(bf, ofs)
01135 #else
01136 POSFROMEXT UVAR_t p_pos_findbit(const UVAR_t bitfield, UVAR_t rrOffset);
01137 #define POS_FINDBIT(bf) p_pos_findbit(bf, 0)
01138 #define POS_FINDBIT_EX(bf, ofs) p_pos_findbit(bf, ofs)
01139 #endif
01140 #endif
01141
01142 #if DOX!=0
01143
01152 POSFROMEXT UVAR_t p_pos_findbit(const UVAR_t bitfield);
01153
01164 POSFROMEXT UVAR_t p_pos_findbit(const UVAR_t bitfield, UVAR_t rrOffset);
01165 #endif
01166
01167 #if (DOX!=0) || (POSCFG_CALLINITARCH != 0)
01168
01179 POSFROMEXT void p_pos_initArch(void);
01180 #endif
01181
01182 #if (DOX!=0) || (POSCFG_TASKSTACKTYPE == 0)
01183
01202 POSFROMEXT void p_pos_initTask(POSTASK_t task, void *stackstart,
01203 POSTASKFUNC_t funcptr,
01204 void *funcarg);
01205 #endif
01206 #if (DOX!=0) || (POSCFG_TASKSTACKTYPE == 1)
01207
01231 POSFROMEXT VAR_t p_pos_initTask(POSTASK_t task, UINT_t stacksize,
01232 POSTASKFUNC_t funcptr,
01233 void *funcarg);
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252 POSFROMEXT void p_pos_freeStack(POSTASK_t task);
01253 #endif
01254
01255 #if (DOX!=0) || (POSCFG_TASKSTACKTYPE == 2)
01256
01279 POSFROMEXT VAR_t p_pos_initTask(POSTASK_t task, POSTASKFUNC_t funcptr,
01280 void *funcarg);
01281
01298 POSFROMEXT void p_pos_freeStack(POSTASK_t task);
01299 #endif
01300
01314 POSFROMEXT void p_pos_startFirstContext(void);
01315
01330 POSFROMEXT void p_pos_softContextSwitch(void);
01331
01345 POSFROMEXT void p_pos_intContextSwitch(void);
01346
01355 POSEXTERN void c_pos_intEnter(void);
01356
01365 POSEXTERN void c_pos_intExit(void);
01366
01399 POSEXTERN void c_pos_timerInterrupt(void);
01400
01405
01406
01407
01408
01414 #if (DOX!=0) || (POSCFG_FEATURE_YIELD != 0)
01415
01423 POSEXTERN void posTaskYield(void);
01424 #endif
01425
01426 #if (DOX!=0) || (POSCFG_FEATURE_SLEEP != 0)
01427
01441 POSEXTERN void posTaskSleep(UINT_t ticks);
01442 #endif
01443
01444 #if (DOX!=0) || (POSCFG_TASKSTACKTYPE == 0)
01445
01461 POSEXTERN POSTASK_t posTaskCreate(POSTASKFUNC_t funcptr, void *funcarg,
01462 VAR_t priority, void *stackstart);
01463
01479 POSEXTERN void posInit(POSTASKFUNC_t firstfunc, void *funcarg, VAR_t priority,
01480 void *stackFirstTask, void *stackIdleTask);
01481 #endif
01482 #if (DOX!=0) || (POSCFG_TASKSTACKTYPE == 1)
01483
01502 POSEXTERN POSTASK_t posTaskCreate(POSTASKFUNC_t funcptr, void *funcarg,
01503 VAR_t priority, UINT_t stacksize);
01504
01520 POSEXTERN void posInit(POSTASKFUNC_t firstfunc, void *funcarg, VAR_t priority,
01521 UINT_t taskStackSize, UINT_t idleStackSize);
01522 #endif
01523 #if (DOX!=0) || (POSCFG_TASKSTACKTYPE == 2)
01524
01540 POSEXTERN POSTASK_t posTaskCreate(POSTASKFUNC_t funcptr, void *funcarg,
01541 VAR_t priority);
01542
01556 POSEXTERN void posInit(POSTASKFUNC_t firstfunc, void *funcarg, VAR_t priority);
01557
01558 #endif
01559
01560
01561 #if (DOX!=0) || (POSCFG_FEATURE_EXIT != 0)
01562
01569 POSEXTERN void posTaskExit(void);
01570 #endif
01571
01572 #if (DOX!=0) || (POSCFG_FEATURE_GETTASK != 0)
01573
01581 POSEXTERN POSTASK_t posTaskGetCurrent(void);
01582 #endif
01583
01584 #if (DOX!=0) || (POSCFG_FEATURE_TASKUNUSED != 0)
01585
01598 POSEXTERN VAR_t posTaskUnused(POSTASK_t taskhandle);
01599 #endif
01600
01601 #if (DOX!=0) || (POSCFG_FEATURE_SETPRIORITY != 0)
01602
01615 POSEXTERN VAR_t posTaskSetPriority(POSTASK_t taskhandle, VAR_t priority);
01616 #endif
01617
01618 #if (DOX!=0) || (POSCFG_FEATURE_GETPRIORITY != 0)
01619
01628 POSEXTERN VAR_t posTaskGetPriority(POSTASK_t taskhandle);
01629 #endif
01630
01631 #if (DOX!=0) || (POSCFG_FEATURE_INHIBITSCHED != 0)
01632
01643 POSEXTERN void posTaskSchedLock(void);
01644
01654 POSEXTERN void posTaskSchedUnlock(void);
01655 #endif
01656
01657 #if (DOX!=0) || (POSCFG_TASKCB_USERSPACE > 0)
01658
01666 POSEXTERN void* posTaskGetUserspace(void);
01667 #endif
01668
01669 #if (DOX!=0) || (POSCFG_FEATURE_IDLETASKHOOK != 0)
01670
01688 POSEXTERN POSIDLEFUNC_t posInstallIdleTaskHook(POSIDLEFUNC_t idlefunc);
01689 #endif
01690
01693
01694
01695 #if (DOX!=0) || (SYS_FEATURE_EVENTS != 0)
01696
01735 POSEXTERN POSSEMA_t posSemaCreate(INT_t initcount);
01736
01737 #if (DOX!=0) || (SYS_FEATURE_EVENTFREE != 0)
01738
01748 POSEXTERN void posSemaDestroy(POSSEMA_t sema);
01749 #endif
01750
01763 #if (DOX!=0) || (POSCFG_SMALLCODE == 0) || (POSCFG_FEATURE_SEMAWAIT == 0)
01764 POSEXTERN VAR_t posSemaGet(POSSEMA_t sema);
01765 #else
01766
01767 #define posSemaGet(sema) posSemaWait(sema, INFINITE)
01768 #endif
01769
01781 POSEXTERN VAR_t posSemaSignal(POSSEMA_t sema);
01782
01783 #if (DOX!=0) || (POSCFG_FEATURE_SEMAWAIT != 0)
01784
01804 POSEXTERN VAR_t posSemaWait(POSSEMA_t sema, UINT_t timeoutticks);
01805 #endif
01806
01807 #endif
01808
01810
01811
01812 #if (DOX!=0) || (POSCFG_FEATURE_MUTEXES != 0)
01813
01834 POSEXTERN POSMUTEX_t posMutexCreate(void);
01835
01836 #if (DOX!=0) || (POSCFG_FEATURE_MUTEXDESTROY != 0)
01837
01847 POSEXTERN void posMutexDestroy(POSMUTEX_t mutex);
01848 #endif
01849
01850 #if (DOX!=0) || (POSCFG_FEATURE_MUTEXTRYLOCK != 0)
01851
01866 POSEXTERN VAR_t posMutexTryLock(POSMUTEX_t mutex);
01867 #endif
01868
01881 POSEXTERN VAR_t posMutexLock(POSMUTEX_t mutex);
01882
01893 POSEXTERN VAR_t posMutexUnlock(POSMUTEX_t mutex);
01894
01895 #endif
01896
01898
01899
01900 #if (DOX!=0) || (POSCFG_FEATURE_MSGBOXES != 0)
01901
01923 #if (DOX!=0) || (POSCFG_MSG_MEMORY != 0)
01924
01937 POSEXTERN void* posMessageAlloc(void);
01938
01951 POSEXTERN void posMessageFree(void *buf);
01952 #endif
01953
01971 POSEXTERN VAR_t posMessageSend(void *buf, POSTASK_t taskhandle);
01972
01988 #if (DOX!=0) || (POSCFG_SMALLCODE == 0) || (POSCFG_FEATURE_MSGWAIT == 0)
01989 POSEXTERN void* posMessageGet(void);
01990 #else
01991
01992 #define posMessageGet() posMessageWait(INFINITE)
01993 #endif
01994
02007 POSEXTERN VAR_t posMessageAvailable(void);
02008
02009 #if (DOX!=0) || (POSCFG_FEATURE_MSGWAIT != 0)
02010
02035 POSEXTERN void* posMessageWait(UINT_t timeoutticks);
02036 #endif
02037
02038 #endif
02039
02041
02042
02043 #if (DOX!=0) || (POSCFG_FEATURE_FLAGS != 0)
02044
02064 POSEXTERN POSFLAG_t posFlagCreate(void);
02065
02066 #if (DOX!=0) || (POSCFG_FEATURE_FLAGDESTROY != 0)
02067
02077 POSEXTERN void posFlagDestroy(POSFLAG_t flg);
02078 #endif
02079
02092 POSEXTERN VAR_t posFlagSet(POSFLAG_t flg, UVAR_t flgnum);
02093
02108 POSEXTERN VAR_t posFlagGet(POSFLAG_t flg, UVAR_t mode);
02109
02110 #if (DOX!=0) || (POSCFG_FEATURE_FLAGWAIT != 0)
02111
02130 POSEXTERN VAR_t posFlagWait(POSFLAG_t flg, UINT_t timeoutticks);
02131 #endif
02132
02133 #define POSFLAG_MODE_GETSINGLE 0
02134 #define POSFLAG_MODE_GETMASK 1
02135
02136 #endif
02137
02139
02140
02162 #if DOX!=0
02163 #define HZ (timerticks per second)
02164 #endif
02165
02175 #if (DOX!=0) || (POSCFG_FEATURE_JIFFIES != 0)
02176 #if (DOX!=0) || (POSCFG_FEATURE_LARGEJIFFIES == 0)
02177 POSEXTERN volatile JIF_t jiffies;
02178 #else
02179 POSEXTERN JIF_t posGetJiffies(void);
02180 #define jiffies posGetJiffies()
02181 #endif
02182
02193 #define POS_TIMEAFTER(x, y) ((((SJIF_t)(x)) - ((SJIF_t)(y))) >= 0)
02194
02195 #endif
02196
02197 #if (DOX!=0) || (POSCFG_FEATURE_TIMER != 0)
02198
02208 POSEXTERN POSTIMER_t posTimerCreate(void);
02209
02227 POSEXTERN VAR_t posTimerSet(POSTIMER_t tmr, POSSEMA_t sema,
02228 UINT_t waitticks, UINT_t periodticks);
02240 POSEXTERN VAR_t posTimerStart(POSTIMER_t tmr);
02241
02252 POSEXTERN VAR_t posTimerStop(POSTIMER_t tmr);
02253
02254 #if (DOX!=0) || (POSCFG_FEATURE_TIMERDESTROY != 0)
02255
02265 POSEXTERN void posTimerDestroy(POSTIMER_t tmr);
02266 #endif
02267 #if (DOX!=0) || (POSCFG_FEATURE_TIMERFIRED != 0)
02268
02280 POSEXTERN VAR_t posTimerFired(POSTIMER_t tmr);
02281 #endif
02282
02283 #endif
02284
02286
02287
02288 #if (DOX!=0) || (POSCFG_FEATURE_SOFTINTS != 0)
02289
02335 POSEXTERN void posSoftInt(UVAR_t intno, UVAR_t param);
02336
02350 POSEXTERN VAR_t posSoftIntSetHandler(UVAR_t intno, POSINTFUNC_t inthandler);
02351
02352 #if (DOX!=0) || (POSCFG_FEATURE_SOFTINTDEL != 0)
02353
02366 POSEXTERN VAR_t posSoftIntDelHandler(UVAR_t intno);
02367 #endif
02368
02369 #endif
02370
02372
02373
02374 #if (DOX!=0) || (POSCFG_FEATURE_ATOMICVAR != 0)
02375
02400 POSEXTERN void posAtomicSet(POSATOMIC_t *var, INT_t value);
02401
02412 POSEXTERN INT_t posAtomicGet(POSATOMIC_t *var);
02413
02424 POSEXTERN INT_t posAtomicAdd(POSATOMIC_t *var, INT_t value);
02425
02436 POSEXTERN INT_t posAtomicSub(POSATOMIC_t *var, INT_t value);
02437
02438 #endif
02439
02442
02443
02444 #if (DOX!=0) || (POSCFG_FEATURE_LISTS != 0)
02445
02460 #define POSLIST_HEAD 0
02461 #define POSLIST_TAIL 1
02462
02478 POSEXTERN void posListAdd(POSLISTHEAD_t *listhead, UVAR_t pos, POSLIST_t *new);
02479
02511 POSEXTERN POSLIST_t* posListGet(POSLISTHEAD_t *listhead, UVAR_t pos,
02512 UINT_t timeout);
02513
02522 POSEXTERN void posListRemove(POSLIST_t *listelem);
02523
02524 #if (DOX!=0) || (POSCFG_FEATURE_LISTJOIN != 0)
02525
02544 POSEXTERN void posListJoin(POSLISTHEAD_t *baselisthead, UVAR_t pos,
02545 POSLISTHEAD_t *joinlisthead);
02546 #endif
02547
02548 #if (DOX!=0) || (POSCFG_FEATURE_LISTLEN != 0)
02549
02560 POSEXTERN UINT_t posListLen(POSLISTHEAD_t *listhead);
02561 #endif
02562
02574 POSEXTERN void posListInit(POSLISTHEAD_t *listhead);
02575
02583 POSEXTERN void posListTerm(POSLISTHEAD_t *listhead);
02584
02585 #if (DOX!=0)
02586
02598 #define POSLIST_ELEMENT(elem, type, member)
02599 #else
02600 #define POSLIST_ELEMENT(elem, type, member) \
02601 ((type*)((char*)(elem)-(char*)(&((type*)NULL)->member)))
02602 #endif
02603
02607 #define POSLIST_IS_EMPTY(plisthead) \
02608 ((plisthead)->next == (POSLIST_t*)(plisthead))
02609
02613 #define POSLIST_NEXT_ENTRY(plist) (plist)->next
02614
02618 #define POSLIST_PREV_ENTRY(plist) (plist)->prev
02619
02623 #define POSLIST_FIRST_ENTRY(plisthead) (plisthead)->next
02624
02628 #define POSLIST_LAST_ENTRY(plisthead) (plisthead)->prev
02629
02633 #define POSLIST_IS_FIRST_ENTRY(element) ((element)->prev==(element)->head)
02634
02638 #define POSLIST_IS_LAST_ENTRY(element) ((element)->next==(element)->head)
02639
02642 #define POSLIST_IS_END(plisthead, element) \
02643 ((element)==(POSLIST_t*)(plisthead))
02644
02645
02646 #if (DOX!=0)
02647
02663 #define POSLIST_FOR_EACH_ENTRY(plisthead, runvar)
02664 #else
02665 #define POSLIST_FOR_EACH_ENTRY(plisthead, runvar) \
02666 for (runvar = POSLIST_FIRST_ENTRY(plisthead); \
02667 !POSLIST_IS_END(plisthead, runvar); \
02668 runvar = POSLIST_NEXT_ENTRY(runvar))
02669 #endif
02670
02671 #if (DOX!=0)
02672
02693 #define POSLIST_FOREACH_BEGIN(plisthead, runvar, type, listmember)
02694 #else
02695 #define POSLIST_FOREACH_BEGIN(plisthead, runvar, type, listmember) \
02696 do { POSLIST_t *r, *n; \
02697 for (r = POSLIST_FIRST_ENTRY(plisthead); \
02698 !POSLIST_IS_END(plisthead, r); r = n) { \
02699 n = POSLIST_NEXT_ENTRY(r); \
02700 runvar = POSLIST_ELEMENT(r, type, listmember);
02701 #endif
02702
02703 #if (DOX!=0)
02704
02710 #define POSLIST_FOREACH_END
02711 #else
02712 #define POSLIST_FOREACH_END \
02713 } } while(0)
02714 #endif
02715
02716 #endif
02717
02720
02721
02722
02723
02768 #if (DOX!=0) || defined(HAVE_PLATFORM_ASSERT)
02769
02777 #define P_ASSERT(text,x) \
02778 if (!(x)) p_pos_assert((const char*)(text), __FILE__, __LINE__)
02779 #else
02780 #define P_ASSERT(text,x) do { } while(0)
02781 #endif
02782
02783 #if (DOX!=0) || defined(POS_DEBUGHELP)
02784
02789 enum PTASKSTATE
02790 {
02791 task_notExisting = 0,
02792 task_created = 1,
02793 task_running = 2,
02794 task_suspended = 3,
02795 task_sleeping = 4,
02796 task_waitingForSemaphore = 5,
02797 task_waitingForSemaphoreWithTimeout = 6,
02799 task_waitingForMutex = 7,
02800 task_waitingForMutexWithTimeout = 8,
02802 task_waitingForFlag = 9,
02803 task_waitingForFlagWithTimeout = 10,
02805 task_waitingForMessage = 11,
02806 task_waitingForMessageWithTimeout = 12
02808 };
02809 typedef enum PTASKSTATE PTASKSTATE;
02810
02815 enum PEVENTTYPE
02816 {
02817 event_semaphore = 0,
02818 event_mutex = 1,
02819 event_flags = 2
02820 };
02821 typedef enum PEVENTTYPE PEVENTTYPE;
02822
02832 typedef struct PICOEVENT
02833 {
02834 struct PICOEVENT *next;
02836 struct PICOEVENT *prev;
02838 #if DOX
02839 PEVENTTYPE type;
02842 #else
02843 enum PEVENTTYPE type;
02844 #endif
02845 void *handle;
02847 const char *name;
02849 INT_t counter;
02853 } PICOEVENT;
02854
02864 typedef struct PICOTASK
02865 {
02866 struct PICOTASK *next;
02868 struct PICOTASK *prev;
02870 POSTASK_t handle;
02872 POSTASKFUNC_t func;
02874 const char *name;
02876 #if DOX
02877 PTASKSTATE state;
02880 #else
02881 enum PTASKSTATE state;
02882 #endif
02883 struct PICOEVENT *event;
02885 UINT_t timeout;
02887 } PICOTASK;
02888
02889 #if DOX
02890
02912 #define POS_SETTASKNAME(taskhandle, taskname)
02913
02933 #define POS_SETEVENTNAME(eventhandle, name)
02934
02935 #else
02936 #define POS_SETTASKNAME(taskhandle, taskname) \
02937 do { if ((taskhandle) != NULL) (taskhandle)->deb.name = taskname;} while(0)
02938 #define POS_SETEVENTNAME(eventhandle, name) \
02939 posdeb_setEventName(eventhandle, name)
02940 POSEXTERN void posdeb_setEventName(void *event, const char *name);
02941 #endif
02942
02943 #ifdef _POSCORE_C
02944 struct PICOTASK *picodeb_taskhistory[3];
02945 struct PICOTASK *picodeb_tasklist = NULL;
02946 struct PICOEVENT *picodeb_eventlist = NULL;
02947 #else
02948
02962 extern struct PICOTASK *picodeb_taskhistory[3];
02963
02976 extern struct PICOTASK *picodeb_tasklist;
02977
02992 extern struct PICOEVENT *picodeb_eventlist;
02993 #endif
02994
02995 #else
02996
02997 #define POS_SETTASKNAME(taskhandle, name) do { } while(0)
02998 #define POS_SETEVENTNAME(eventhandle, name) do { } while(0)
02999
03000 #endif
03001
03004
03005
03006
03007
03008
03009
03010
03011
03012 #ifdef PICOS_PRIVINCL
03013
03014 #if MVAR_BITS == 8
03015 #ifndef _POSCORE_C
03016 POSEXTERN UVAR_t posShift1lTab_g[8];
03017 #endif
03018 #define pos_shift1l(bits) posShift1lTab_g[(UVAR_t)(bits)]
03019 #else
03020 #define pos_shift1l(bits) (((UVAR_t)1)<<(bits))
03021 #endif
03022
03023 #endif
03024
03025
03026
03027
03028
03029 #ifdef POSNANO
03030 #ifdef POSCFG_ENABLE_NANO
03031 #undef POSCFG_ENABLE_NANO
03032 #endif
03033 #define POSCFG_ENABLE_NANO 1
03034 #else
03035 #ifndef POSCFG_ENABLE_NANO
03036 #define POSCFG_ENABLE_NANO 0
03037 #endif
03038 #endif
03039 #if POSCFG_ENABLE_NANO != 0
03040 #include <pos_nano.h>
03041 #endif
03042
03043
03044
03045
03046
03047 #ifndef POSCFG_TASKEXIT_HOOK
03048 #define POSCFG_TASKEXIT_HOOK 0
03049 #endif
03050
03051
03052
03053
03054
03055 #ifndef NOS_TASKDATA
03056 #define NOS_TASKDATA
03057 #endif
03058
03059 #if POSCFG_TASKEXIT_HOOK != 0
03060 typedef enum {
03061 texh_exitcalled,
03062 texh_freestackmem
03063 } texhookevent_t;
03064 typedef void (*POSTASKEXITFUNC_t)(POSTASK_t task, texhookevent_t event);
03065 #endif
03066
03067 struct POSTASK {
03068 POS_USERTASKDATA
03069 NOS_TASKDATA
03070 #if POSCFG_TASKCB_USERSPACE > 0
03071 UVAR_t usrspace[(POSCFG_TASKCB_USERSPACE + POSCFG_ALIGNMENT +
03072 sizeof(UVAR_t)-2) / sizeof(UVAR_t)];
03073 #endif
03074 #if POSCFG_TASKEXIT_HOOK != 0
03075 POSTASKEXITFUNC_t exithook;
03076 #endif
03077 #if DOX==0
03078 #if POSCFG_ARGCHECK > 1
03079 UVAR_t magic;
03080 #endif
03081 #if SYS_TASKDOUBLELINK != 0
03082 struct POSTASK *prev;
03083 #endif
03084 struct POSTASK *next;
03085 UVAR_t bit_x;
03086 #if SYS_TASKTABSIZE_Y > 1
03087 UVAR_t bit_y;
03088 UVAR_t idx_y;
03089 #endif
03090 #ifndef POS_DEBUGHELP
03091 UINT_t ticks;
03092 #endif
03093 #if SYS_TASKSTATE != 0
03094 UVAR_t state;
03095 #endif
03096 #if POSCFG_FEATURE_ERRNO != 0
03097 VAR_t error;
03098 #endif
03099 #if POSCFG_FEATURE_MSGBOXES != 0
03100 UVAR_t msgwait;
03101 POSSEMA_t msgsem;
03102 void *firstmsg;
03103 void *lastmsg;
03104 #endif
03105 #ifdef POS_DEBUGHELP
03106 struct PICOTASK deb;
03107 #endif
03108 #endif
03109 };
03110
03111
03112 #endif
03113