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

📄 pg_io.c

📁 一个移植到凌阳单片机spce061a上面的实时操作系统
💻 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 + -