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

📄 uit_func.inl

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 INL
📖 第 1 页 / 共 5 页
字号:
#ifndef CYGONCE_COMPAT_UITRON_UIT_FUNC_INL
#define CYGONCE_COMPAT_UITRON_UIT_FUNC_INL
//===========================================================================
//
//      uit_func.inl
//
//      uITRON compatibility functions
//
//===========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//===========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):   hmt
// Contributors:        hmt
// Date:        1998-03-13
// Purpose:     uITRON compatibility functions
// Description: 
//
//####DESCRIPTIONEND####
//
//===========================================================================

#ifdef CYGPKG_UITRON

#ifdef CYGPRI_UITRON_FUNCS_HERE_AND_NOW

#include <cyg/compat/uitron/uit_objs.hxx> // uITRON setup CYGNUM_UITRON_SEMAS

// kernel facilities only needed here
#include <cyg/kernel/intr.hxx>
#include <cyg/kernel/sched.hxx>

// and the implementations of other kernel facilities
#include <cyg/kernel/thread.inl>
#include <cyg/kernel/sched.inl>
#include <cyg/kernel/clock.inl>


// ------------------------------------------------------------------------
// The variable where dis_dsp/ena_dsp state is held:
extern cyg_uint32 cyg_uitron_dis_dsp_old_priority;

// ------------------------------------------------------------------------
// Parameter checking; either check the expression and return an error code
// if not true, or assert the truth with a made-up message.

#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
// default: uitron error codes are returned
#define CYG_UIT_PARAMCHECK( _true_, _error_ ) CYG_MACRO_START           \    if ( ! (_true_) ) return (_error_);                                 \CYG_MACRO_END
#else
// ...but they are asserted if asserts are on
#define CYG_UIT_PARAMCHECK( _true_, _error_ ) CYG_MACRO_START           \    CYG_ASSERT( (_true_), "CYG_UIT_PARAMCHECK fail: " #_true_ );        \CYG_MACRO_END
#endif // else !CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS

// ------------------------------------------------------------------------
// CYG_UITRON_CHECK_AND_GETP
// 
// Macro to rangecheck and do the addressing of a static uitron system
// object; _which_ sort of object is given, and token pasting is used
// horribly to get the static array, limits and the like.
//
// Usage:
//   INT snd_msg( ID mbxid, ... ) {
//      Cyg_Mbox *p;
//      CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
//      p->...(...);

// internal: plain assignment to the object pointer, from static array
#define CYG_UIT_SPTR( _which_, _idx_, _ptr_ ) CYG_MACRO_START           \        (_ptr_) =  CYG_UITRON_OBJS( _which_ ) + ((_idx_) - 1);          \CYG_MACRO_END

// internal: plain assignment to the object pointer, from pointer array
// with error checking.
#define CYG_UIT_SPTR_PTR( _which_, _idx_, _ptr_ ) CYG_MACRO_START       \        (_ptr_) =  CYG_UITRON_PTRS( _which_ )[ ((_idx_) - 1) ];         \        if ( NULL == (_ptr_) ) return E_NOEXS;                          \CYG_MACRO_END

#define CYG_UITRON_CHECK_AND_GETP_DIRECT( _which_, _idx_, _ptr_ )       \CYG_MACRO_START                                                         \    CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID );                            \    CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID );   \    CYG_UIT_SPTR( _which_, _idx_, _ptr_ );                              \CYG_MACRO_END

#define CYG_UITRON_CHECK_AND_GETP_INDIRECT( _which_, _idx_, _ptr_ )     \CYG_MACRO_START                                                         \    CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID );                            \    CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID );   \    CYG_UIT_SPTR_PTR( _which_, _idx_, _ptr_ );                          \CYG_MACRO_END

// As above but for handler numbers which return E_PAR when out of range
#define CYG_UITRON_CHECK_AND_GETHDLR( _which_, _num_, _ptr_ )           \CYG_MACRO_START                                                         \    CYG_UIT_PARAMCHECK( 0 < (_num_), E_PAR );                           \    CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_num_), E_PAR );  \    CYG_UIT_SPTR( _which_, _num_, _ptr_ );                              \CYG_MACRO_END

// And a macro to check that creation of an object is OK
#define CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( _which_, _idx_ )            \CYG_MACRO_START                                                         \    CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID );                            \    CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID );   \    Cyg_Scheduler::lock();                                              \    if ( NULL != CYG_UITRON_PTRS( _which_ )[ ((_idx_) - 1) ] ) {        \        Cyg_Scheduler::unlock();                                        \        return E_OBJ;                                                   \    }                                                                   \CYG_MACRO_END

// define a magic new operator in order to call constructors
#define CYG_UITRON_NEWFUNCTION( _class_ )                               \inline void *operator new(size_t size, _class_ *ptr)                    \{                                                                       \    CYG_CHECK_DATA_PTR( ptr, "Bad pointer" );                           \    return ptr;                                                         \}

// now configury to support selectable create/delete support ie. an
// array of pointers to the objects themselves.
#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
#define CYG_UITRON_CHECK_AND_GETP_TASKS( _idx_, _ptr_ )                 \    CYG_UITRON_CHECK_AND_GETP_INDIRECT( TASKS, _idx_, _ptr_ )
#else
#define CYG_UITRON_CHECK_AND_GETP_TASKS( _idx_, _ptr_ )                 \    CYG_UITRON_CHECK_AND_GETP_DIRECT( TASKS, _idx_, _ptr_ )
#endif

#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
#define CYG_UITRON_CHECK_AND_GETP_SEMAS( _idx_, _ptr_ )                 \    CYG_UITRON_CHECK_AND_GETP_INDIRECT( SEMAS, _idx_, _ptr_ )
#else
#define CYG_UITRON_CHECK_AND_GETP_SEMAS( _idx_, _ptr_ )                 \    CYG_UITRON_CHECK_AND_GETP_DIRECT( SEMAS, _idx_, _ptr_ )
#endif

#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
#define CYG_UITRON_CHECK_AND_GETP_MBOXES( _idx_, _ptr_ )                \    CYG_UITRON_CHECK_AND_GETP_INDIRECT( MBOXES, _idx_, _ptr_ )
#else
#define CYG_UITRON_CHECK_AND_GETP_MBOXES( _idx_, _ptr_ )                \    CYG_UITRON_CHECK_AND_GETP_DIRECT( MBOXES, _idx_, _ptr_ )
#endif

#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
#define CYG_UITRON_CHECK_AND_GETP_FLAGS( _idx_, _ptr_ )                 \    CYG_UITRON_CHECK_AND_GETP_INDIRECT( FLAGS, _idx_, _ptr_ )
#else
#define CYG_UITRON_CHECK_AND_GETP_FLAGS( _idx_, _ptr_ )                 \    CYG_UITRON_CHECK_AND_GETP_DIRECT( FLAGS, _idx_, _ptr_ )
#endif

#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( _idx_, _ptr_ )          \    CYG_UITRON_CHECK_AND_GETP_INDIRECT( MEMPOOLFIXED, _idx_, _ptr_ )
#else
#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( _idx_, _ptr_ )          \    CYG_UITRON_CHECK_AND_GETP_DIRECT( MEMPOOLFIXED, _idx_, _ptr_ )
#endif

#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( _idx_, _ptr_ )            \    CYG_UITRON_CHECK_AND_GETP_INDIRECT( MEMPOOLVAR, _idx_, _ptr_ )
#else
#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( _idx_, _ptr_ )            \    CYG_UITRON_CHECK_AND_GETP_DIRECT( MEMPOOLVAR, _idx_, _ptr_ )
#endif

// ------------------------------------------------------------------------
// Common error checking macros

#if !defined( CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS ) && \    !defined( CYGDBG_USE_ASSERTS )
// if not checking and not asserted, these are removed to avoid usused
// variable warnings.
#define CYG_UITRON_CHECK_TASK_CONTEXT_SELF( _self_ )     CYG_EMPTY_STATEMENT
#define CYG_UITRON_CHECK_TASK_CONTEXT()                  CYG_EMPTY_STATEMENT
#define CYG_UITRON_CHECK_DISPATCH_ENABLED()              CYG_EMPTY_STATEMENT
#define CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( _tmout_ ) CYG_EMPTY_STATEMENT

#else
// the default:
// Check a task is actually a uITRON task
#define CYG_UITRON_CHECK_TASK_CONTEXT_SELF( _self_ ) CYG_MACRO_START    \    CYG_UIT_PARAMCHECK(                                                 \        (&cyg_uitron_TASKS[0] <= (_self_)) &&                           \        ((_self_) < &cyg_uitron_TASKS[CYGNUM_UITRON_TASKS]),            \                                  E_CTX );                              \CYG_MACRO_END

#define CYG_UITRON_CHECK_TASK_CONTEXT() CYG_MACRO_START                 \    Cyg_Thread *self = Cyg_Thread::self();                              \    CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self );                         \CYG_MACRO_END

// Check dispatching is enabled for calls which might wait
#define CYG_UITRON_CHECK_DISPATCH_ENABLED()  CYG_MACRO_START            \    CYG_UIT_PARAMCHECK( 0 == cyg_uitron_dis_dsp_old_priority, E_CTX );  \CYG_MACRO_END

#define CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO(_tmout_)  CYG_MACRO_START \    CYG_UIT_PARAMCHECK( -1 <= (_tmout_), E_PAR );                       \    if ( TMO_POL != (_tmout_) )                                         \        CYG_UITRON_CHECK_DISPATCH_ENABLED();                            \CYG_MACRO_END

#endif

#ifdef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
#define CYG_UIT_PARAMCHECK_PTR( _p_ )   CYG_MACRO_START                 \        CYG_UIT_PARAMCHECK( NADR != (_p_), E_PAR );                     \CYG_MACRO_END
#else // do check for NULL
#define CYG_UIT_PARAMCHECK_PTR( _p_ )   CYG_MACRO_START                 \        CYG_UIT_PARAMCHECK( NADR != (_p_), E_PAR );                     \        CYG_UIT_PARAMCHECK( NULL != (_p_), E_PAR );                     \CYG_MACRO_END
#endif // !CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR

// ------------------------------------------------------------------------
// CYG_UITRON_FAIL_RETURN
//
// After a call which waits, it might return with success, or due to a
// timeout or a release wait (a forced escape from the waiting condition).
// This macro examines context and finds out which, then executes a return
// with the correct uITRON condition code.

#define CYG_UITRON_FAIL_RETURN_SELF( _self_ ) CYG_MACRO_START           \    Cyg_Thread::cyg_reason reason = (_self_)->get_wake_reason();        \    if ( Cyg_Thread::TIMEOUT  == reason )                               \        return E_TMOUT;                                                 \    if ( Cyg_Thread::BREAK    == reason )                               \        return E_RLWAI;                                                 \    if ( Cyg_Thread::DESTRUCT == reason )                               \        return E_DLT;                                                   \    return E_SYS; /* if no plausible reason was found */                \CYG_MACRO_END

#define CYG_UITRON_FAIL_RETURN() CYG_MACRO_START                        \    Cyg_Thread *self = Cyg_Thread::self();                              \    CYG_UITRON_FAIL_RETURN_SELF( self );                                \CYG_MACRO_END

// ------------------------------------------------------------------------
// Interrupts disabled?
#define CYG_UITRON_CHECK_CPU_UNLOC()                                    \    CYG_UIT_PARAMCHECK( (Cyg_Interrupt::interrupts_enabled()), E_CTX )

// ------------------------------------------------------------------------
// Timing: is it in eCos clock ticks or milliSeconds (or something else?)

#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK

#ifdef CYGSEM_UITRON_TIME_IS_MILLISECONDS
extern Cyg_Clock::converter uit_clock_to_system;
extern Cyg_Clock::converter uit_clock_from_system;

#define CYG_UITRON_TIME_UIT_TO_SYS32( t ) \Cyg_Clock::convert( (cyg_uint64)(t), &uit_clock_to_system )

#define CYG_UITRON_TIME_SYS_TO_UIT32( t ) \Cyg_Clock::convert( (cyg_uint64)(t), &uit_clock_from_system )

// long (cyg_uint64) versions:
#define CYG_UITRON_TIME_UIT_TO_SYS64( t ) \Cyg_Clock::convert( (t), &uit_clock_to_system )

#define CYG_UITRON_TIME_SYS_TO_UIT64( t ) \Cyg_Clock::convert( (t), &uit_clock_from_system )

#else // Time is whatever the system clock is doing:

// Straight through - int (cyg_int32) argument versions:
#define CYG_UITRON_TIME_UIT_TO_SYS32( t )  ( t )
#define CYG_UITRON_TIME_SYS_TO_UIT32( t )  ( t )
// long (cyg_uint64) versions:
#define CYG_UITRON_TIME_UIT_TO_SYS64( t )  ( t )
#define CYG_UITRON_TIME_SYS_TO_UIT64( t )  ( t )
#endif

#endif // CYGVAR_KERNEL_COUNTERS_CLOCK - otherwise these should not be used.

// ------------------------------------------------------------------------
// the function definitions themselves:

// ******************************************************
// ***    6.5 C Language Interfaces                   ***
// ******************************************************

// - Task Management Functions

#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
CYG_UITRON_NEWFUNCTION( Cyg_Thread )

CYG_UIT_FUNC_INLINE
ER
cre_tsk ( ID tskid, T_CTSK *pk_ctsk )
{
    ER ret = E_OK;
    CYG_UIT_PARAMCHECK_PTR( pk_ctsk );
    CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( TASKS, tskid );

    Cyg_Thread *p = &(CYG_UITRON_OBJS( TASKS )[ tskid - 1 ]);
    cyg_uint32 state = p->get_state();
    if ( 0 == (state & Cyg_Thread::EXITED) )
        ret = E_OBJ; // how did it get to be running?
    else if ( ((INT)p->get_stack_size()) < pk_ctsk->stksz )
        ret = E_NOMEM; // more stack requested than available
    else {
        CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] =
            new( p ) Cyg_Thread(
                (CYG_ADDRWORD)      pk_ctsk->itskpri,
                (cyg_thread_entry *)pk_ctsk->task,
                (CYG_ADDRWORD)      0,
                // preserve the original name and stack:
#ifdef CYGVAR_KERNEL_THREADS_NAME
                p->get_name(),
#else
                NULL,
#endif
                p->get_stack_base(),
                p->get_stack_size() );
        // but ensure the task state is dormant:
        // (it is not constructed dormant, but suspended)
        p->kill();
#ifdef CYGIMP_THREAD_PRIORITY
        // and record the initial priority outside the task too.
        CYG_UITRON_TASK_INITIAL_PRIORITY( tskid ) = pk_ctsk->itskpri;
#endif
    }
    Cyg_Scheduler::unlock();
    return ret;
}

CYG_UIT_FUNC_INLINE
ER
del_tsk ( ID tskid )
{
    Cyg_Thread *p;
    ER ret = E_OK;
    CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
    
    Cyg_Scheduler::lock();
    // deal with the race condition here
    if ( p != CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] ) {
        Cyg_Scheduler::unlock();
        return E_NOEXS;
    }
    cyg_uint32 state = p->get_state();
    if ( state & Cyg_Thread::EXITED )
        // just disconnect the pointer from its object
        CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] = NULL;

⌨️ 快捷键说明

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