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

📄 file.c

📁 代码在ti的c67系列单片机上实现了完整的TCPIP协议栈
💻 C
字号:
//--------------------------------------------------------------------------
// Streaming/Socket IO Layer
//--------------------------------------------------------------------------
// file.c
//
// File Management Functions
//
// Author: Michael A. Denio
// Copyright 1999 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <stkmain.h>
#include "fdt.h"

//--------------------------------------------------------------------
// FDWaitEvent()
//
// Wait for a file event on the supplied FD handle with a timeout
//
// If timeout is NULL, function waits forever
//
// Returns 1 if the event was detected, or 0 on timeout
//--------------------------------------------------------------------
int FDWaitEvent( HANDLE hFd, uint EventFlags, UINT32 timeout )
{
    FILEDESC *pfd  = (FILEDESC *)hFd;

#ifdef _STRONG_CHECKING
    if( pfd->Type != HTYPE_FD )
    {
        DbgPrintf(DBG_ERROR,"FDWaitEvent: HTYPE %04x",pfd->Type);
        return(0);
    }
#endif

    // Sync the task to track FD activity
    fdint_clearevent( pfd->pfdt );

    // Add the current request to the state
    pfd->EventFlags |= EventFlags;

    // If there's no timeout, this will wait forever
    // Else wait for the time limit
    fdint_waitevent( pfd->pfdt, timeout );

    // If EventFlags still set, then we timed out
    if( (pfd->EventFlags & EventFlags) == EventFlags )
    {
        pfd->EventFlags &= ~EventFlags;
        return(0);
    }

    return(1);
}

//--------------------------------------------------------------------
// FDSignalEvent()
//
// Signal a file event on the supplied FD handle
//
// Note: hFd can be NULL
//--------------------------------------------------------------------
void FDSignalEvent( HANDLE hFd, uint EventFlags )
{
    FILEDESC *pfd  = (FILEDESC *)hFd;

    // The calling parameter can be NULL. Also, if the FD is in
    // an orphaned state, there's no owner task to notify.
    if( !pfd || !pfd->pfdt )
        return;

#ifdef _STRONG_CHECKING
    if( pfd->Type != HTYPE_FD )
    {
        DbgPrintf(DBG_ERROR,"FDSignalEvent: HTYPE %04x",pfd->Type);
        return;
    }
#endif

    // Wake if conditions are right
    if( pfd->EventFlags & EventFlags )
    {
        // Since we're waking, clear all the wake bits
        pfd->EventFlags &= ~(FD_EVENT_READ | FD_EVENT_WRITE | FD_EVENT_EXCEPT);

        // Wake the owining task
        fdint_signalevent( pfd->pfdt );
    }
}

//--------------------------------------------------------------------
// fdint_new()
//
// Create a new file descriptor
//--------------------------------------------------------------------
int fdint_new( FDTABLE *pfdt, FILEDESC **ppfd, uint fdType )
{
    int      i;
    FILEDESC *pfd;

    // Look for an open slot
    for( i=0; i<FD_MAX; i++ )
        if( !pfdt->pfd[i] )
            break;
    if( i==FD_MAX )
        return( EMFILE );

    // Allocate the file descriptor
    if( !(pfd = (FILEDESC*)mmAlloc(sizeof(FILEDESC))) )
        return( ENOMEM );

    // Save the FD
    pfdt->pfd[i] = pfd;

    // Initialize the FD
    pfd->Type       = HTYPE_FD;
    pfd->fdType     = fdType;
    pfd->EventFlags = 0;
    pfd->hSock      = 0;
    pfd->pfdt       = pfdt;
    pfd->fd         = i+1;

    *ppfd           = pfd;
    return( 0 );
}

//--------------------------------------------------------------------
// fdint_free()
//
// Free an unused file descriptor
//--------------------------------------------------------------------
void fdint_free( FILEDESC *pfd )
{
    // Simple abort
    pfd->pfdt->pfd[pfd->fd-1] = 0;
    mmFree( pfd );
}

//--------------------------------------------------------------------
// fdint_close()
//
// Close an FD
//--------------------------------------------------------------------
int fdint_close( FILEDESC *pfd )
{
    int   error = 0;
    int   tmp;

    // We need to free the file descriptor.

    // *** In this OS, all file descriptors are sockets or pipes ***
    if( pfd->hSock )
    {
        if( pfd->fdType == FDTYPE_SOCKET )
        {
            // If fd is an orphan or we're closing someone else's fd,
            // then we can't block during close
            if( !pfd->pfdt || pfd->pfdt->hOwner != TaskSelf() )
            {
                tmp = 0;
                SockSet(pfd->hSock, SOL_SOCKET, SO_BLOCKING, &tmp, sizeof(int));
            }

            // Close it
            error = SockClose( pfd->hSock );
        }
        else
            error = PipeClose( pfd->hSock );
    }

    // If not orphan, free the file descriptor from the table
    if( pfd->pfdt )
        pfd->pfdt->pfd[pfd->fd-1] = 0;

    // Free fd
    mmFree( pfd );

    return( error );
}

//--------------------------------------------------------------------
// fdint_verify()
//
// Verifies an FD and returns a pointer to it.
// If return is NULL, this function has already set a reasonable error
//--------------------------------------------------------------------
FILEDESC *fdint_verify( int fd, uint fdType )
{
    FDTABLE *pfdt;

    // Get a pointer to the FD Table
    pfdt = fdint_getfdt( 0 );

    // If pointer is bad, we can't do a thing
    if( !pfdt )
        return( 0 );

    // Verify File Descriptor
    fd--;
    if( fd < 0 || fd >= FD_MAX || !pfdt->pfd[fd] )
    {
        pfdt->error = EBADF;
        return( 0 );
    }

    // If the caller specified a file type, it must match
    if( fdType != FDTYPE_ANY && pfdt->pfd[fd]->fdType != fdType )
        return( 0 );

    // Return a pointer to the FD
    return( pfdt->pfd[fd] );
}

//--------------------------------------------------------------------
// fdint_getfdt()
//
// Returns a handle to File Descriptor Table.
//
// When called with NULL handle, the FDT for the current task is
// returned.
//--------------------------------------------------------------------
FDTABLE *fdint_getfdt( HANDLE hTask )
{
    if( !hTask )
        return( TaskGetEnv( TaskSelf(), 0 ) );
    else
        return( TaskGetEnv( hTask, 0 ) );
}

//--------------------------------------------------------------------
// fdint_clearevent()
//
// Clears any pending file events for the current task
//--------------------------------------------------------------------
void fdint_clearevent( FDTABLE *pfdt )
{
    pfdt->Evented = 0;
    SemReset( pfdt->hSem, 0 );
}

//--------------------------------------------------------------------
// fdint_signalevent()
//
// Signals a file event for the indicated table
//--------------------------------------------------------------------
void fdint_signalevent( FDTABLE *pfdt )
{
    pfdt->Evented = 1;
    SemPost( pfdt->hSem );
}

//--------------------------------------------------------------------
// fdint_signaltimeout()
//
// Signals a file timeout for the indicated table
//--------------------------------------------------------------------
void fdint_signaltimeout( FDTABLE *pfdt )
{
    pfdt->Evented = 0;
    SemPost( pfdt->hSem );
}

//--------------------------------------------------------------------
// fdint_waitevent()
//
// Wait for a file event with a timeout. If no timeout is specified,
// the function waits forever.
//--------------------------------------------------------------------
void fdint_waitevent( FDTABLE *pfdt, UINT32 timeout )
{
    // If already evented, return
    if( pfdt->Evented )
        return;

    // Convert a timeout of 0 to forever
    if( !timeout )
        timeout = SEM_FOREVER;

    // Since this SemPend may block, we must exit and then
    // reenter the kernel mode
    llExit();
    SemPend( pfdt->hSem, timeout );
    llEnter();
}

⌨️ 快捷键说明

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