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

📄 console.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
字号:
/* *  This file contains the efi68k console IO package. * *  COPYRIGHT (c) 1989-1999. *  On-Line Applications Research Corporation (OAR). * *  The license and distribution terms for this file may be *  found in the file LICENSE in this distribution or at *  http://www.rtems.com/license/LICENSE. * *  $Id: console.c,v 1.9.2.1 2003/09/04 18:44:20 joel Exp $ */#include <stdlib.h>#include <bsp.h>#include <rtems/libio.h>#define BAUD 38400#define CLK_FREQ 8000000.0/* BUFFER_LENGTH must be 2^n for n=1, 2, 3, .... */#define BUFFER_LENGTH 256#define RTS_STOP_SIZE BUFFER_LENGTH-64#define RTS_START_SIZE 16char xmt_buf[BUFFER_LENGTH];char rcv_buf[BUFFER_LENGTH];/* in: last entry into the buffer; always on a valid character *//* out: points to the next character to be pull from the buffer *//*    in+1=out => buffer empty *//*    in+2=out => buffer full */struct UART_buf {  char *offset;   char *in;   char *out;};static volatile struct UART_buf  xmt = { xmt_buf, (char *)0, (char *)1};static volatile struct UART_buf  rcv = { rcv_buf, (char *)0, (char *)1};static volatile char _debug_flag = 0;static volatile char _tx_stop = 0;/* _catchUARTint is the interrupt front-end */extern void _catchUARTint();asm("   .text\n\        .align 2\n\        .globl _catchUARTint\n\_catchUARTint:\n\        lea    %sp@(4),%sp                /* pop return address */\n\        moveml %d0-%d7/%a0-%a6,%sp@-       /* save registers */\n\        jbsr    uart_interrupt\n\        moveml  %sp@+,%d0-%d7/%a0-%a6			        \n\        rte\n\    ");/* _fake_trap_1 will continue the UART interrupt (%sr *still*   UART_ISR_LEVEL) as a trap #1 to enter the debugger */asm("   .text\n\        .align 2\n\_fake_trap_1:\n\        unlk %a6		/* clear interrupt frame */\n\        lea %sp@(4),%sp		/* remove jbsr instruction */\n\        moveml %sp@+,%d0-%d7/%a0-%a6 /* pop registers */\n\        jmp (33*6-12+_VBR)	/* jump exception 1 */\n\        ");/* dispatch UART interrupt */void xmit_interrupt(void);void rcvr_interrupt(void);void modem_status(void);void _fake_trap_1(void);void uart_interrupt(void) {  register char a;  a=*IIR & (NIP | IID_MASK); /* read interrupt id register */  switch (a) {  case 0x04: case 0x0c:    rcvr_interrupt();    break;  case 0x02:    xmit_interrupt();    break;  case 0x00:    modem_status();    break;  default:    break;  }  if (_debug_flag) {    _debug_flag = 0;		/* reset the flag */    _fake_trap_1();		/* fake a trap #1 */  }}/* transfer received character to the buffer */void rcvr_interrupt(void) {  register char *a, c;  register int length;  while ( (*LSR & DR) != 0) {    if ((c=*RBR) == 0x1a)	/* use ctl-z to reboot */      reboot();    else if (c == 0x03) {	/* use ctl-c to enter debugger */      _debug_flag = 1;      continue;    }    *(char *)((int)rcv.offset +(int)	      (a=(char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1)))) = c;    if ((char *)(((int)rcv.in+2) & ((int)BUFFER_LENGTH-1)) != rcv.out)      rcv.in=a;  }  length = (BUFFER_LENGTH -1) & (     ( ((int)rcv.out <= (int)rcv.in) ? 0 : BUFFER_LENGTH) - (int)rcv.out     + (int)rcv.in + 1);  if (length >= RTS_STOP_SIZE)    *MCR &= (char) (~RTS);}/* tranfer buffered characters to the UART */void xmit_interrupt(void) {  register short int i, oldsr;  _CPU_ISR_Disable( oldsr ); /* for when outbyte calls */  if ( (*LSR & THRE) != 0 && _tx_stop == 0 )    for (i=0;i<16;i++) {      if ((char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1))== xmt.out)	break;      *THR=*(char *)((int)xmt.offset+(int)xmt.out);      xmt.out= (char *)(((int)xmt.out+1) & ((int)BUFFER_LENGTH-1));    }  _CPU_ISR_Enable( oldsr );}void modem_status(void) {  register char a;    if ( ((a=*MDSR) & DCTS) != 0 ) {    if ( (a & CTS) == 0)      _tx_stop = 1;    else {      _tx_stop = 0;      xmit_interrupt();    }  }}/* transfer character from the buffer */char inbyte(void) {  register char a;  register int length;  while ((char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1))== rcv.out);  a=*(char *)((int)rcv.offset+(int)rcv.out);  rcv.out= (char *)(((int)rcv.out+1) & ((int)BUFFER_LENGTH-1));  length = (BUFFER_LENGTH -1) & (     ( ((int)rcv.out <= (int)rcv.in) ? 0 : BUFFER_LENGTH) - (int)rcv.out     + (int)rcv.in + 1);  if (length < RTS_START_SIZE)    *MCR |= (char) RTS;  return (a);}/* once room is avaliable in the buffer, transfer   the character into the buffer and enable    the xmtr interrupt */void outbyte(char c) {  register char *a;    while ((char *)(((int)xmt.in+2) & ((int)BUFFER_LENGTH-1)) == xmt.out);  *(char *)((int)xmt.offset+(int)	    (a=(char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1))))=c;  xmt.in=a;  if ( (*LSR & THRE) != 0 ) 	/* if THRE, uart has already interrupted */    xmit_interrupt();		/*   and was ignored. Need to restart. */}void _UART_flush(void) {  /* loop till xmt buffer empty. Works with interrupts disabled */  while ((char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1)) != xmt.out)    xmit_interrupt();  /* loop till UART buffer empty */  while ( (*LSR & TEMT) == 0 );}/*  console_initialize * *  This routine initializes the console IO driver. * *  Input parameters: NONE * *  Output parameters:  NONE * *  Return values: */ void console_init(){  /* set clock divisor */  *LCR = (char)(DLAB);  *DLL = (char)((int)(CLK_FREQ/BAUD/16.0+0.5) & 0xFF);  *DLM = (char)(((int)(CLK_FREQ/BAUD/16.0+0.5) & 0xFF00) >> 8);  /* Line control setup */  *LCR = (char)(WL_8 | NSB);  /* Interrupt setup */  *IER = (char) 0x0b;		/* enable transmit, receive, modem stat int */    /* FIFO setup */  *FCR = (char)(FIFO_E | 0xc0);  /* Modem control setup */  *MCR = (char) RTS;  /* init tx_stop with CTS */  _tx_stop = ( (*MDSR & CTS) ? 0 : 1);  set_vector(_catchUARTint, UART_ISR_LEVEL+24, 0);}rtems_device_driver console_initialize(  rtems_device_major_number  major,  rtems_device_minor_number  minor,  void                      *arg){  rtems_status_code status;  status = rtems_io_register_name(    "/dev/console",    major,    (rtems_device_minor_number) 0  );   if (status != RTEMS_SUCCESSFUL)    rtems_fatal_error_occurred(status);   return RTEMS_SUCCESSFUL;}/*  is_character_ready * *  This routine returns TRUE if a character is available. * *  Input parameters: NONE * *  Output parameters:  NONE * *  Return values: */rtems_boolean is_character_ready(  char *ch){  if ((char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1))== rcv.out)    return(FALSE);  else    return(TRUE);}/* *  Open entry point */ rtems_device_driver console_open(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg){  return RTEMS_SUCCESSFUL;} /* *  Close entry point */ rtems_device_driver console_close(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg){  return RTEMS_SUCCESSFUL;} /* * read bytes from the serial port. We only have stdin. */ rtems_device_driver console_read(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg){  rtems_libio_rw_args_t *rw_args;  char *buffer;  int maximum;  int count = 0;   rw_args = (rtems_libio_rw_args_t *) arg;   buffer = rw_args->buffer;  maximum = rw_args->count;   for (count = 0; count < maximum; count++) {    buffer[ count ] = inbyte();    if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {      buffer[ count++ ]  = '\n';      break;    }  }   rw_args->bytes_moved = count;  return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;} /* * write bytes to the serial port. Stdout and stderr are the same. */ rtems_device_driver console_write(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg){  int count;  int maximum;  rtems_libio_rw_args_t *rw_args;  char *buffer;   rw_args = (rtems_libio_rw_args_t *) arg;   buffer = rw_args->buffer;  maximum = rw_args->count;   for (count = 0; count < maximum; count++) {    if ( buffer[ count ] == '\n') {      outbyte('\r');    }    outbyte( buffer[ count ] );  }   rw_args->bytes_moved = maximum;  return 0;} /* *  IO Control entry point */ rtems_device_driver console_control(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg){  return RTEMS_SUCCESSFUL;}

⌨️ 快捷键说明

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