📄 pg_io.c
字号:
///////////////////////////////////////////////////////////////
//
//
// PGOS : A Portable,Configable Embedded System Kernel
//
// Intel X86 Specific Code
//
// This is an open source project under GPL lincence
//
// Version 0.9.0 ---- Development Snopshot
//
// File name : PG_BASICIO.C : Basic IO Operations
//
// Note : This is the IO emulation implenmentions!
//
// History :
//
// 2005-08-12 First build by X.K. @ PGOS Team
//
/////////////////////////////////////////////////////////////////
#include "PGOS.H"
#include "stdio.h"
#include "stdlib.h"
/////////////////////////////////////////////////////////////////
// Ring buffer
//
/////////////////////////////////////////////////////////////////
BYTE* pg_ring_buffer ;
BYTE* ring_w_ptr;
BYTE* ring_r_ptr ;
WORD ringlen ;
BYTE io_flag ; // IO operation status flag
BYTE io_wait[255] ; // IO operation waiting list
WORD cur_read ;
WORD cur_write ;
REGSZ io_drv_stk[ 512 ] ;
/////////////////////////////////////////////////////////////////
// PGOS Basic IO Operations
//
// High level
// All high level IO operations will cause a block
//
/////////////////////////////////////////////////////////////////
// Read a byte from the PG_INDEV devices
PGOS_STATUS pgos_io_readbyte( BYTE* ch )
{
while( pgos_lowio_rb( ch, PG_DEFDEV ) != PGOS_SUCCESS )
{
pgos_lowio_wait( PG_READ ) ;
}
return PGOS_SUCCESS ;
}
// Write a string to the PG_INDEV devices
PGOS_STATUS pgos_io_wrtstring( const BYTE* buffer, WORD len )
{
while( pgos_lowio_wbstr( buffer, len ) != PGOS_SUCCESS )
{
pgos_lowio_wait( PG_WRITE ) ;
}
return PGOS_SUCCESS ;
}
// Flush internal ring buffer
PGOS_STATUS pgos_io_flush( VOID )
{
// Empty functions yet
return PGOS_SUCCESS ;
}
// Write a byte to the PG_OUTDEV devices
PGOS_STATUS pgos_io_wrtbyte( BYTE ch )
{
while( pgos_lowio_wb( ch, PG_INDEV ) != PGOS_SUCCESS )
{
pgos_lowio_wait( PG_WRITE ) ;
}
return PGOS_SUCCESS ;
}
/////////////////////////////////////////////////////////////////
// PGOS IO Operations
//
// Low level
/////////////////////////////////////////////////////////////////
// Write a byte to the given device ring buffer
PGOS_STATUS pgos_lowio_wb( BYTE ch, BYTE device )
{
///////////////////////////////////////////////
// We assumes all devices menas Monitor
//
///////////////////////////////////////////////
device = device ;
pgos_int_disable() ;
if( ( io_flag & PG_WRT_BIT ) == PG_IO_ALLOWED )
{
*ring_w_ptr = ch ;
ring_w_ptr ++ ;
}
else
{
pgos_int_enable() ;
return PGOS_FAIL_NM ;
}
pgos_int_enable() ;
return PGOS_SUCCESS ;
}
// Write string to the given device ring buffer
PGOS_STATUS pgos_lowio_wbstr( const BYTE* buffer, WORD len )
{
// Not implementation yet
return PGOS_FAIL_NM ;
}
// Read a byte from the given device ring buffer
PGOS_STATUS pgos_lowio_rb( BYTE* ch, BYTE device )
{
///////////////////////////////////////////////
// We assumes all devices menas Monitor
//
///////////////////////////////////////////////
device = device ;
pgos_int_disable() ;
if( ( io_flag & PG_RED_BIT ) == PG_IO_ALLOWED )
{
*ch = *ring_r_ptr ;
ring_r_ptr ++ ;
}
else
{
pgos_int_enable() ;
return PGOS_FAIL_NM ;
}
pgos_int_enable() ;
return PGOS_SUCCESS ;
}
// Set the IO operation device
VOID pgos_lowio_setdefdev( BYTE device )
{
// Not implementation yet
return ;
}
// Initialize the IO operations
PGOS_STATUS pgos_lowio_init( WORD rl )
{
WORD i = 0 ;
BYTE drvid ;
pg_ring_buffer = ( BYTE * )malloc( sizeof( BYTE ) * rl ) ;
if( !pg_ring_buffer )
return PGOS_FAIL_NM ;
ring_r_ptr = ( BYTE * )( pg_ring_buffer + rl * sizeof( BYTE ) ) ;
ring_w_ptr = pg_ring_buffer ;
ringlen = rl ;
for( i = 0 ; i < 255 ; i ++ )
io_wait[ i ] = 0 ;
io_flag = 0x01 ;
cur_read = 0 ;
cur_write = 1 ;
return pgos_tk_cre( pgos_io_driver, PRIO_LOWEST + 5, &io_drv_stk[ 511 ], &drvid ) ;
}
// Return the empty space in ring buffer
WORD pgos_lowio_emptysize( VOID )
{
// not ready yet
return 0 ;
}
// Wait for IO operations allowed
VOID pgos_lowio_wait( BYTE flag )
{
BYTE taskid ;
taskid = pgos_tk_getcurid() ;
switch( flag )
{
case PG_READ :
io_wait[ cur_read ] = taskid ;
cur_read += 2 ;
pgos_tk_suspend( taskid ) ;
break ;
case PG_WRITE :
io_wait[ cur_write ] = taskid ;
cur_write += 2 ;
pgos_tk_suspend( taskid ) ;
break ;
default :
break ;
}
}
VOID pgos_io_driver( VOID )
{
WORD offset ;
BYTE temp ;
BYTE drvid ;
DRIVER_ENTRY io_drv_entry ;
temp = MSG_SEND ;
io_drv_entry.CallBackDriver = pgos_io_drv_callback ;
pgos_drv_install( io_drv_entry, CALLBACK_DRV, &drvid, &temp ) ;
for( ; ; )
{
pgos_int_disable() ;
offset = ring_w_ptr - ring_r_ptr ;
switch( ( int )offset )
{
case 1 :
io_flag = 0x01 ; // Forbid Read
break ;
case 0 :
io_flag = 0x02 ; // Forbid write
break ;
default :
if( ( ( int )offset ) > 0 )
{
io_flag = 0x03 ; // All operations OK
}
else
{
if( ring_w_ptr != pg_ring_buffer )
io_flag = 0x03 ; // All operations OK
else
io_flag = 0x01 ; // Forbid Read
}
break ;
}
switch( io_flag )
{
case 0x01 :
temp = cur_write ;
if( cur_write + 2 >= 254 )
cur_write = 1 ;
else
cur_write += 2 ;
pgos_tk_sendmsg( io_wait[ temp ], MSG_IO_OPERATION, 0 ) ;
break ;
case 0x02 :
temp = cur_read ;
if( cur_read + 2 >= 254 )
cur_read = 0 ;
else
cur_read += 2 ;
pgos_tk_sendmsg( io_wait[ temp ], MSG_IO_OPERATION, 0 ) ;
break ;
case 0x03 :
temp = cur_write ;
if( cur_write + 2 >= 254 )
cur_write = 1 ;
else
cur_write += 2 ;
pgos_tk_sendmsg( io_wait[ temp ], MSG_IO_OPERATION, 0 ) ;
temp = cur_read ;
if( cur_read + 2 >= 254 )
cur_read = 0 ;
else
cur_read += 2 ;
pgos_tk_sendmsg( io_wait[ temp ], MSG_IO_OPERATION, 0 ) ;
break ;
default :
break ;
}
pgos_int_enable() ;
pgos_tk_sleep( pgos_tk_getcurid(), 15 ) ;
}
}
VOID pgos_io_drv_callback( VOID* info )
{
pgMSG* Message = NULL ;
Message = ( pgMSG * )info ;
if( Message -> m_msg == MSG_IO_OPERATION )
{
pgos_tk_resume( ( Message -> To & 0x00FF ) ) ;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -