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

📄 linuxucos.c

📁 关于ucos 在avr128 中应用用icc编译
💻 C
📖 第 1 页 / 共 3 页
字号:
/* linuxucos.c    v0.2.0  01-Jan-02    David Poole davep@mbuf.com * * Portions copyright as follows: * *                            (c) Copyright 2001, Jean J. Labrosse, Weston, FL *                                           All Rights Reserved * * Simple wrapper around SysV and POSIX threads functions to mimic uCOS-II * features.  Has only been tested on RedHat Linux 7 and 7.2.   * * Currently supported features are: * * Semaphores: *  none * * Mutual Exclusion Semaphores: *  OSMutexAccept() *  OSMutexCreate() *  OSMutexDel() *  OSMutexPend() *  OSMutexPost() * * Event Flags: *  OSFlagAccept() *  OSFlagCreate() *  OSFlagPend() *  OSFlagPost() * * Message Mailboxes: *  none * * Message Queues: *  OSQAccept() *  OSQCreate() *  OSQDel() *  OSQPend() *  OSQPost() * * Memory Management: *  none * * Task Management: *  OSTaskCreate() *  OSTaskCreateExt() * * Time Management: *  OSTimeDly() *  OSTimeGet() * * Miscellaneous: *  OSInit(); *  OSStart(); * * * uCOS-II specific information:  I'm using a 1ms "tick" on Linux so * OS_TICKS_PER_SEC must be 1000.   * */#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#include <sys/sem.h>#include <sys/time.h>#include <errno.h>#include <unistd.h>#include <pthread.h>#include <time.h>#include <assert.h>#define LINUX_UCOS#include "includes.h"// using a 1 ms tick on Linux#define NANOSECONDS_PER_TICK 1000000l#define SECONDS              1000// Table of EVENT control blocks #define OS_EVENT_COUNT 99OS_EVENT lnxOSEventTbl[OS_EVENT_COUNT];  // mutex to protect the lnxOSEventTbl listpthread_mutex_t oseventtbl_mutex = PTHREAD_MUTEX_INITIALIZER;// Table of available OS_FLAG_GRP #define OS_MAX_FLAGS 99OS_FLAG_GRP lnxOSFlagTbl[OS_MAX_FLAGS];// mutex to protect the lnxOSFlagTbl listpthread_mutex_t osflagtbl_mutex = PTHREAD_MUTEX_INITIALIZER;// uCOS-II flags are implemented using pthread's condition variables;struct pthread_flag {    pthread_mutex_t mutex;    pthread_cond_t  cond;};// "blank" mutex and condition for initializing struct pthread_flag memberspthread_mutex_t blank_mutex = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t blank_cond = PTHREAD_COND_INITIALIZER;// for debugging #define PRINTF  printf#define PERROR  perror#define ASSERT  assert// returned when an interface function encounters// an error; this should never happen#define OS_ERR_INTERNAL  -1// there are a few places where a lack of a timeout// on SysV IPC mechanisms means a poll #define POLL_DELAY   10 // ticks// sigh#ifndef min#define min(x,y)  ((x)<(y)?(x):(y))#endifstruct sembuf sem_release = { 0,  1, IPC_NOWAIT };struct sembuf sem_claim   = { 0, -1, IPC_NOWAIT };// convert a uCOS-II 'prio' (used as a task ID as of 2.51)// into the pthread_t id// 64 is the maximum number of tasks in the current version// of ucOS-II; could change in a future version so beware#define MAX_TASKS  64pthread_t pthread_to_prio[MAX_TASKS];// time is measure from when the system "booted", ie// when the program was started (see epoch_init())struct timeval epoch;void epoch_init( void ){    gettimeofday( &epoch, NULL );}INT32U get_ms_time( void ){    INT32U ms;    struct timeval now;    gettimeofday( &now, NULL );        ms = now.tv_sec * 1000 + now.tv_sec / NANOSECONDS_PER_TICK;    return ms;}OS_EVENT *get_free_event( INT8U evttype ){    int i, perr;    // lock the table     perr = pthread_mutex_lock( &oseventtbl_mutex );    ASSERT( perr == 0 );        // get a free OS_EVENT    for( i=0 ; i<OS_EVENT_COUNT ; i++ ) {        if( lnxOSEventTbl[i].OSEventType == OS_EVENT_TYPE_UNUSED ) {            lnxOSEventTbl[i].OSEventType = evttype;            // unlock the table            perr = pthread_mutex_unlock( &oseventtbl_mutex );            ASSERT( perr == 0 );            return &lnxOSEventTbl[i];        }    }    // unlock the table    perr = pthread_mutex_unlock( &oseventtbl_mutex );    ASSERT( perr == 0 );        return NULL;}// *****************//// Time Functions//// *****************void OSTimeDly( INT16U ticks ){    int ret;    struct timespec req, rem;    ldiv_t nanotime;    // using a 1ms "tick" on Linux     nanotime = ldiv( ticks, SECONDS );    req.tv_sec = nanotime.quot;    req.tv_nsec = (nanotime.rem) * NANOSECONDS_PER_TICK;    while( 1 ) {        ret = nanosleep( &req, &rem );        if( ret == 0 ) {            // successfully finished the sleep             break;        }        assert( errno == EINTR );        // at this point, we were interrupted by a signal         // recalculate how much we needed to sleep and do it again         memcpy( &req, &rem, sizeof(struct timespec) );    }}INT32U OSTimeGet( void ){    // get_ms_time() returns ms since program start    return get_ms_time();}// *****************//// Flag Functions//  // *****************OS_FLAGS OS_FlagTest( OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT16U timeout, INT8U *err ){    OS_FLAGS      flags_cur;    OS_FLAGS      flags_rdy;    BOOLEAN       consume;    int perr;    struct pthread_flag *pflag;    struct timeval now;    struct timespec sleeptime;    ldiv_t nanotime;    if( pgrp == NULL ) {        *err = OS_FLAG_INVALID_PGRP;        return 0;    }    if( pgrp->OSFlagType != OS_EVENT_TYPE_FLAG ) {        *err = OS_ERR_EVENT_TYPE;        return 0;    }    // wait_type can be    //      OS_FLAG_WAIT_CLR_ALL -- all bits in 'flags' will be clear    //      OS_FLAG_WAIT_CLR_ANY -- any bits in 'flags' will be clear    //      OS_FLAG_WAIT_SET_ALL -- all bits in 'flags' will be set    //      OS_FLAG_WAIT_SET_ANY -- any bits in 'flags' will be clear        // test the flags    pflag = (struct pthread_flag *)pgrp->OSFlagWaitList;    // lock the pthread condition    perr = pthread_mutex_lock( &(pflag->mutex) );    ASSERT( perr == 0 );       // test     if (wait_type & OS_FLAG_CONSUME) {                     /* See if we need to consume the flags      */        wait_type &= ~OS_FLAG_CONSUME;        consume    = TRUE;    } else {        consume    = FALSE;    }    *err = OS_NO_ERR;    /* timeout of 1 => no wait */    /* timeout of 0 => wait forever */    if( timeout > 1 ) {        // our timeout is in 1ms "ticks" so convert to system nanoseconds        nanotime = ldiv( timeout, SECONDS );        gettimeofday( &now, NULL );        sleeptime.tv_sec = now.tv_sec + nanotime.quot;        sleeptime.tv_nsec = now.tv_usec + nanotime.rem * NANOSECONDS_PER_TICK;    }    *err = OS_NO_ERR;    flags_cur = 0;    switch( wait_type ) {        case OS_FLAG_WAIT_SET_ALL :            flags_rdy = pgrp->OSFlagFlags & flags;        /* Extract only the bits we want            */            perr = 0;            while (flags_rdy != flags && perr != ETIMEDOUT ) {                                     if( timeout == 0 ) {                    /* wait forever */                    perr = pthread_cond_wait( &(pflag->cond), &(pflag->mutex) );                }                else if( timeout > 1 ) {                    perr = pthread_cond_timedwait( &(pflag->cond), &(pflag->mutex), &sleeptime );                }                else {                    *err  = OS_FLAG_ERR_NOT_RDY;                    goto fail;                }                flags_rdy = pgrp->OSFlagFlags & flags;                    }            if( perr == ETIMEDOUT ) {                *err = OS_TIMEOUT;                goto fail;            }            if (consume == TRUE) {                    /* See if we need to consume the flags      */                pgrp->OSFlagFlags &= ~flags_rdy;      /* Clear ONLY the flags that we wanted      */            }            flags_cur = pgrp->OSFlagFlags;                /* Will return the state of the group       */            break;                    case OS_FLAG_WAIT_SET_ANY :            flags_rdy = pgrp->OSFlagFlags & flags;        /* Extract only the bits we want            */            perr = 0;            while(flags_rdy == (OS_FLAGS)0 && perr != ETIMEDOUT ) {                if( timeout == 0 ) {                    /* wait forever */                    perr = pthread_cond_wait( &(pflag->cond), &(pflag->mutex) );                }                else if( timeout > 1 ) {                    perr = pthread_cond_timedwait( &(pflag->cond), &(pflag->mutex), &sleeptime );                }                else {                    *err  = OS_FLAG_ERR_NOT_RDY;                    goto fail;                }                flags_rdy = pgrp->OSFlagFlags & flags;                    }            if( perr == ETIMEDOUT ) {                *err = OS_TIMEOUT;                goto fail;            }            if (consume == TRUE) {                    /* See if we need to consume the flags      */                pgrp->OSFlagFlags &= ~flags_rdy;      /* Clear ONLY the flags that we got         */            }            flags_cur = pgrp->OSFlagFlags;                /* Will return the state of the group       */            break;        case OS_FLAG_WAIT_CLR_ALL :             flags_rdy = ~pgrp->OSFlagFlags & flags;       /* Extract only the bits we want            */            perr = 0;            while( flags_rdy != flags && perr != ETIMEDOUT ) {                                     if( timeout == 0 ) {                    /* wait forever */                    perr = pthread_cond_wait( &(pflag->cond), &(pflag->mutex) );                }                else if( timeout > 1 ) {                    perr = pthread_cond_timedwait( &(pflag->cond), &(pflag->mutex), &sleeptime );                }                else {                    *err  = OS_FLAG_ERR_NOT_RDY;                    goto fail;                }                flags_rdy = ~pgrp->OSFlagFlags & flags;                   }            if( perr == ETIMEDOUT ) {                *err = OS_TIMEOUT;                goto fail;            }            if (consume == TRUE) {                    /* See if we need to consume the flags      */                pgrp->OSFlagFlags |= flags_rdy;       /* Set ONLY the flags that we wanted        */            }            flags_cur = pgrp->OSFlagFlags;                /* Will return the state of the group       */            break;        case OS_FLAG_WAIT_CLR_ANY :            flags_rdy = ~pgrp->OSFlagFlags & flags;       /* Extract only the bits we want            */            perr = 0;            while(flags_rdy == (OS_FLAGS)0 && perr != ETIMEDOUT ) {                               if( timeout == 0 ) {                    /* wait forever */                    perr = pthread_cond_wait( &(pflag->cond), &(pflag->mutex) );                }                else if( timeout > 1 ) {                    perr = pthread_cond_timedwait( &(pflag->cond), &(pflag->mutex), &sleeptime );                }                else {                    *err  = OS_FLAG_ERR_NOT_RDY;                    goto fail;                }                flags_rdy = ~pgrp->OSFlagFlags & flags;                   }            if( perr == ETIMEDOUT ) {                *err = OS_TIMEOUT;                goto fail;            }            if (consume == TRUE) {                    /* See if we need to consume the flags      */                pgrp->OSFlagFlags |= flags_rdy;       /* Set ONLY the flags that we got           */            }            flags_cur = pgrp->OSFlagFlags;                /* Will return the state of the group       */            break;        default :            ASSERT(0);            flags_cur = (OS_FLAGS)0;            *err      = OS_FLAG_ERR_WAIT_TYPE;    }fail:    // unlock the pthread condition     perr = pthread_mutex_unlock( &(pflag->mutex) );    ASSERT( perr == 0 );    return flags_cur;}OS_FLAGS OSFlagAccept( OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT8U *err ){    OS_FLAGS flags_cur;    /* timeout == 0 => wait forever so use 1 to indicate no wait.     * If a caller passes in 1 deliberately to OSFlagPend(), the system     * will (supposedly) only delay for 1 tick which is pretty much nothing     * anyway.     */    flags_cur = OS_FlagTest( pgrp, flags, wait_type, 1/* no wait */, err );    return flags_cur;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -