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

📄 6-7.c

📁 《Linux应用开发技术详解》附书光盘中的例程。
💻 C
字号:
#include "prolog.h"
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <asm/io.h>

/***   For mmap function   ***/
#include <unistd.h>
#include <sys/mman.h> 

/***   For open function   ***/
#include <sys/types.h>
#include <sys/stat.h>  
#include <fcntl.h> 

/***   For system function errors "errno", for example ***/
#include <stdlib.h>

#define BASE_ATC40_ADDR 0xd0000L /* size_t baze for mmap function and also
        Default Address Shunt Position, see "ATC40 User Manual", page 10 */
#define SIZE_ATC40_MEM  0x300L       /* size_t length for mmap function */
#define PAGE_SIZE       0x1000

/* simple for(;;) loop without hardware read (2000 countes): 600us and 100 us	*/ 
#define N_POLLS	500		/* 640us for 130MHz pentium, 950us for 33Mhz 486	*/

#include "rpcdefs.h"
#include "sedac.h"
#include "errors.h"
#include "unixcmd.h"

int nSedacLines = 4;
int SedacSimulate = 0;
u16 *ATC40Address = NULL;

u16 sedacSimulationBuffer[4];
u16 sedacSimulationCount[4] = {0,0,0,0};
SEDAC_LINE volatile *line[4];

/***************************************/
void initSedac(void)
{ 
  int i, mem_fd;
  caddr_t atc40_mem;				/* Pointer to "reflected" ATC40 memory */

  if (SedacSimulate) return;

  for (i=0; i<nSedacLines; i++)		// look for up to # SEDAC lines
  {
    if( ATC40Address == NULL ) {    /*** Open /dev/mem   ***/
      if(( mem_fd = open("/dev/mem", O_RDWR) ) < 0 ) {
        printf(" ATC40 memory-window can't open /dev/mem \n");
        exit(-1);
      }

      /***   mmap ATC40 memory   ***/
      if((atc40_mem = malloc( SIZE_ATC40_MEM + (PAGE_SIZE-1) )) == NULL) {
        printf(" ATC40 memory allocation error \n");  
        exit(-1);
      }
//      printf("malloc -> atc40_mem = %p, %x\n", atc40_mem, atc40_mem );

      if(( unsigned long)atc40_mem % PAGE_SIZE )
        atc40_mem += PAGE_SIZE - ((unsigned long)atc40_mem % PAGE_SIZE );
//      printf("corrected atc40_mem = %p, %x\n", atc40_mem, atc40_mem );

      atc40_mem = (caddr_t)mmap(   /* void *mmap */
        (void *)atc40_mem,   /* void *start */
        (size_t)SIZE_ATC40_MEM,       /* size_t length */
        PROT_READ|PROT_WRITE, /* int prot */
        MAP_SHARED|MAP_FIXED, /* int flags */
        (int)mem_fd,               /* int fd */
        (off_t)BASE_ATC40_ADDR );    /* size_t baze */
      if( (long)atc40_mem < 0 ) { 
        printf(" ATC40 memory map error: atc40_mem = %x\n", atc40_mem);  
        printf("\n\n\tERROR - mmap failed, errno: %d: %s\n", errno, strerror(errno));
        exit(-1);
      }
      /* mlock( BASE_ATC40_ADDR, SIZE_ATC40_MEM );  */
//      printf("init sedac called: mmap atc40_mem = %p, %x\n", atc40_mem, atc40_mem );
      ATC40Address = (u16 *)atc40_mem;
//    ATC40Address = (u16 *)BASE_ATC40_ADDR;
    }

    line[i] = (SEDAC_LINE *) (ATC40Address + (i/2)*0x100 + (i%2)*0x04);
    printf("Initializing SEDAC line %d at base address %x, %x, %x\n>",i+1, &line[i]->csr, &line[i]->igr, &line[i]->dat);
    
    line[i]->csr = 0;		// init sedac ip moudule
    line[i]->igr = 0;
  }
  
  RegisterUserCommand("nlines",NULL,&nSedacLines,NULL,CA_READ);
  RegisterUserCommand("sedac",cmdReadSedac,NULL,NULL,CA_READ);
  RegisterUserCommand("sedac",cmdWriteSedac,NULL,NULL,CA_WRITE);
  RegisterUserCommand("crates",cmdCrates,NULL,NULL,CA_READ);
  RegisterUserCommand("addr",cmdAddr,NULL,NULL,CA_READ);

  return;
}

// ============  poll sedac active bit ===================================
int sedacReady(u16 ln, u16 *data)
{ int i;
  u16 ret;
  for (i=0; i<N_POLLS ; i++ ) {
	ret = line[ln]->csr;
	if ( (ret & _RBE) == 0 ) break;
  }
  if ( data && i < N_POLLS ) *data = line[ln]->dat;
  return (i < N_POLLS ? (ret & ERRALL) : -2) ;
}

// ============  write routine  ===================================
int wsedac(u16 ln, u16 crate, u16 subadd, u16 data)
{ int i, ret;

  if (ln<1 || ln>nSedacLines) return -1;
  ln--;

  if (SedacSimulate) 
  {
    sedacSimulationBuffer[ln] = data;
    return 0;
  }

  line[ln]->dat = data;
  line[ln]->cmd = 0x4000 | (crate << 8) | subadd;
  return sedacReady(ln, 0);
}

// ================  read routine  ===================================
int rsedac(u16 ln, u16 crate, u16 subadd, u16 *data)
{ int i, ret;

  if (ln<1 || ln>nSedacLines) return -1;
  ln--;

  if (SedacSimulate) {
    *data = sedacSimulationBuffer[ln] + sedacSimulationCount[ln]++;
    return 0;
  }

  line[ln]->cmd = 0x8000 | (crate << 8) | subadd;
  return sedacReady(ln, data);
}

// ================  read Async routine  ===================================
int rsedacAsync(u16 ln, u16 crate, u16 subadd)
{
  if (ln<1 || ln>nSedacLines) return -1;
  ln--;

  if ( SedacSimulate == 0 ) line[ln]->cmd = 0x8000 | (crate << 8) | subadd;
  return 0;
}

// ================  read Async Poll routine  ===================================
int rsedacPoll(u16 ln, u16 *data)
{ int i, ret;

  if (ln<1 || ln>nSedacLines) return -1;
  ln--;

  if (SedacSimulate) {
    *data = sedacSimulationBuffer[ln] + sedacSimulationCount[ln]++;
    return 0;
  }
  return sedacReady(ln, data);
}
// ============  Block routines ==========================================
void sedac4(SedacInfo *sedacList, int RWF, int num, int (*fcn)(int))
{ int i, l;

  switch( RWF )
  {
    case READ:
	  for (i=0; i<num; i++) {
        for (l=0; !SedacSimulate && l<nSedacLines; l++) line[l]->cmd = 0x8000 | sedacList[l].csa[i];
	    if (fcn) fcn(i);				// service function
	    for (l=0; l<nSedacLines; l++)   // SEDAC line in
          if (SedacSimulate) {
            sedacList[l].data[i] = sedacSimulationBuffer[l] + sedacSimulationCount[l]++;
            sedacList[l].error[i] = 0;
		  } else {
			sedacList[l].error[i] = sedacReady(l, &sedacList[l].data[i]);
		  }
 	  }
      if (fcn) fcn(i);
      return;
    case WRITE:
	  for (i=0; i<num; i++) {
		for (l=0; !SedacSimulate && l<nSedacLines; l++) {
		  line[l]->dat = sedacList[l].data[i];
		  line[l]->cmd = 0x4000 | sedacList[l].csa[i];
        }
	    if (fcn) fcn(i);
for (l=0; l<nSedacLines; l++) {   // SEDAC lines in
		  if (SedacSimulate) {
            sedacSimulationBuffer[l] = sedacList[l].data[i];
	        sedacList[l].error[i] = 0;
		  } else {						  /* poll RBE bit */
			sedacList[l].error[i] = sedacReady(l, 0);
		  }
        }
	  }
      if (fcn) fcn(i);                                    // i = num
  }
  return;
}

// ================  read/write nwords telegram  ===================================
int sedac(int ln, u16 csa, int RWF, u16 *data, int nwords)
{ int i, err;
  u16 addr;

  if (ln<1 || ln>nSedacLines) return -1;
  ln--;

  switch( RWF )
  {
    case READ:
	  addr = 0x8000 | csa;
	  for (err=0, i=0; i<nwords; i++, data++) {
		if (SedacSimulate) {
          *data = sedacSimulationBuffer[ln] + sedacSimulationCount[ln]++;
        } else {
		  line[ln]->cmd = addr;
		  if ( sedacReady(ln, data) ) err++;
        }
      }
      return err;
    case WRITE:
      addr = 0x4000 | csa;
      for (err=0,i=0; i<nwords; i++, data++ ) {
        if (SedacSimulate) {
          sedacSimulationBuffer[ln] = *data;
        } else {
		  line[ln]->dat = *data;
		  line[ln]->cmd = addr;
		  if ( sedacReady(ln, 0) ) err++;
        } 
      }
      return err;
    default:
      return -1;
  }
}

// ================  find crates  ===================================
int F_crates(int *ncrates, int rwflag, u16 ln)
{ u16 data;
  int i,n;

  if (ln < 1 || ln > nSedacLines) return no_such_line;

  switch (rwflag)
  {
    case  READ:
 printf("line %d has crates :\n>",ln);
      for (i=0,n=0; i<32; i++) if (!rsedac(ln, i, 252, &data))
      {
        printf("  %2d",i);
		if ((++n%10) == 0) printf("\n>");
      }
      printf("\n>");
      *ncrates = n;
      return 0;
    default:
	  return illegal_read_write;
  }
}

// ================  find sub addres (16*n) ===================================
int F_addr(int *naddr, int rwflag, u16 ln, u16 crate)
{ u16 data;
  int i,n;

  if (ln < 1 || ln > nSedacLines) return no_such_line;

  switch (rwflag)
  {
    case READ:
      printf("line %d crate %d has subaddresses :\n>",ln,crate);
      for (i=0,n=0; i<252; i+=16) if (!rsedac(ln,crate,i,&data))
      {
        printf("  %2d",i);
		if ((++n%10) == 0) printf("\n>");
      }
      printf("\n>");
      *naddr = n;
      return 0;
    default:
	  return illegal_read_write;
  }
}

int cmdReadSedac(int ln,int cr,int sa,int val)
{
  UINT16 data;
  int cc;
  char str[128];

  if (nSedacLines)
  {
    if ((cc=rsedac(ln,cr,sa,&data)) != 0) sprintf(str,"SEDAC error");
    else sprintf(str,"lin %d cra %d bsa %d : %d (0x%x)\n>",ln,cr,sa,data,data);
    ttyoutput(str);
    return cc;
  }
  return -1;
}
int cmdWriteSedac(int ln,int cr,int sa,int val)
{
  UINT16 data = val;
  int cc=0;
  char str[128];

  if (nSedacLines)
  {
    if ((cc=wsedac(ln,cr,sa,data)) != 0) sprintf(str,"SEDAC error");
   else sprintf(str,"lin %d cra %d bsa %d wrote : %d (0x%x)\n>",ln,cr,sa,data,data);
    ttyoutput(str);
    return cc;
  }
  return -1;
}
int cmdCrates(int ln,int cr,int sa,int access)
{
  UINT16 data;
  int cc,n=0;
  char str[128];

  if (nSedacLines)
  {
    if ((cc=F_crates(&n,1,ln)) != 0) sprintf(str,"line %d : %s",ln,erlst[cc]);
    else sprintf(str,"line %d : %d crates\n>",ln,n);
    ttyoutput(str);
    return n;
  }
}
int cmdAddr(int ln,int cr,int sa,int access)
{
  UINT16 data;
  int cc,n=0;
  char str[128];

  if (nSedacLines)
  {
    if ((cc=F_addr(&n,1,ln,cr)) != 0) sprintf(str,"lin %d cra %d : %s",ln,cr,erlst[cc]);
    else sprintf(str,"lin %d cra %d : %d sub-addresses\n>",ln,cr,n);
    ttyoutput(str);
    return n;
  }
}

⌨️ 快捷键说明

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