/* based on minimal daemon code from the daemon-HOWTO */ int main(void) { /* Our process ID and Session ID */ pid_t pid, sid; /* Fork off the parent process */ pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } /* If we got a good PID, then we can exit the parent process. */ if (pid > 0) { exit(EXIT_SUCCESS); } /* Change the file mode mask */ umask(0); /* Create a new SID for the child process */ sid = setsid(); if (sid < 0) { //syslog(LOG_ERR,"setsid() error. EXIT."); exit(EXIT_FAILURE); } /* Change the current working directory */ if ((chdir("/")) < 0) { /* Log the failure */ //syslog(LOG_ERR,"chdir() error. EXIT."); exit(EXIT_FAILURE); } /* Close out the standard file descriptors */ close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); /* Daemon-specific initialization goes here */ /* use syslog */ setlogmask (LOG_UPTO (LOG_NOTICE)); openlog ("spec_ptp2ntpd", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); syslog (LOG_NOTICE, "Program started by User %d", getuid()); // Attach to SPEC shared memory int bar = BASE_BAR0; int bus = -1, dev_fn = -1; void *card; void *map_base; card = spec_open(bus, dev_fn); if(!card) { syslog(LOG_ERR, "Can't detect a SPEC card under the given " "adress. Make sure a SPEC card is present in your PC, " "the driver is loaded and you run the program as root. EXIT.\n"); exit(1); } syslog(LOG_NOTICE,"Found SPEC at %x \n",(uint)card); map_base = spec_get_base(card, bar); if(!map_base || map_base == (void *) -1) { syslog(LOG_ERR,"mmap(/dev/mem): %s. EXIT.\n", strerror(errno)); syslog(LOG_ERR, "map_base = %x \n",(uint)map_base); exit(1); } syslog(LOG_NOTICE,"map_base = %u \n",(uint)map_base); syslog (LOG_NOTICE, "Attached to SPEC SHM at %x", (uint)map_base); // attach to NTP shared memory T = getShmTime(0); if (T==0) { /* error */ syslog(LOG_ERR,"getShmTime() error"); syslog(LOG_ERR,"EXITING."); exit(EXIT_FAILURE); } else { syslog (LOG_NOTICE, "Attached to NTP SHM at %x", (uint)T); } // initialize T->mode=1; // does it matter? set here or by NTP? T->leap=0; // ? T->precision=-10; //? T->nsamples=10; // ? shmdt(T); //detach struct timeval tv; uint32_t nsec_cycles, s_lsb, usecs; double cycle = 1/125e6; uint32_t nsecs; /* The Big Loop */ while (1) { T = getShmTime(0); // attach to shared memory gettimeofday(&tv,NULL); // system time-stamp // WR time nsec_cycles = read_mem(map_base, 4 ); // read nanoseconds, in number of 62.5MHz ref cycles nsecs = (uint32_t) (cycle*nsec_cycles*1e9); usecs = (uint32_t) (cycle*nsec_cycles*1e6); s_lsb = read_mem(map_base, 8 ); // read utc lsb //s_msb = read_mem(map_base, 12 ); // read utc msb // clock time T->clockTimeStampSec = s_lsb; T->clockTimeStampUSec = usecs; // offset 4 msec, just for fun T->clockTimeStampNSec = nsecs; // time stamp T->receiveTimeStampSec = tv.tv_sec; T->receiveTimeStampUSec = tv.tv_usec; T->receiveTimeStampNSec = tv.tv_usec*1000; T->valid = 1; T->count += 1; shmdt(T); // detach, required here? syslog (LOG_NOTICE, "WR time is %d.%09d ", (int)s_lsb,(int)nsecs); syslog (LOG_NOTICE, "system time is %d.%06d ", (int)tv.tv_sec,(int)tv.tv_usec); sleep(8); // minpoll is 4, so NTP reads every 16s } spec_close(card); closelog(); exit(EXIT_SUCCESS); }
int main(int argc, char **argv) { int i, fd; FILE *f; uint32_t base; struct stat stbuf; void *map_base; unsigned char *buf; unsigned int *ibuf; volatile uint32_t *p; if (argc != 2) { fprintf(stderr, "Use: \"%s <program>\"\n", argv[0]); exit(1); } if((fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0) { fprintf(stderr, "%s: open(/dev/mem): %s\n", argv[0], strerror(errno)); exit(1); } base = spec_get_base(); if (base == (typeof(base))-1) { fprintf(stderr, "%s: spec_get_base(): %s\n", argv[0], strerror(errno)); exit(1); } map_base = mmap(0, 1024 * 1024, /* gennum's bar 0 is 1M */ PROT_READ | PROT_WRITE, MAP_SHARED, fd, base); if(map_base == (void *) -1) { fprintf(stderr, "%s: mmap(/dev/mem): %s\n", argv[0], strerror(errno)); exit(1); } close(fd); f = fopen(argv[1], "r"); if (!f) { fprintf(stderr, "%s: %s: %s\n", argv[0], argv[1], strerror(errno)); exit(1); } if (fstat(fileno(f), &stbuf)) { fprintf(stderr, "%s: stat(%s): %s\n", argv[0], argv[1], strerror(errno)); exit(1); } if (!S_ISREG(stbuf.st_mode)) { fprintf(stderr, "%s: %s: Not a regular file\n", argv[0], argv[1]); exit(1); } buf = malloc(stbuf.st_size); if (!buf) { fprintf(stderr, "%s: Can't allocate buffer (%li bytes): %s\n", argv[0], (long)stbuf.st_size, strerror(errno)); exit(1); } i = fread(buf, 1, stbuf.st_size, f); if (i < 0) { fprintf(stderr, "%s: read(%s): %s\n", argv[0], argv[1], strerror(errno)); exit(1); } if (i != stbuf.st_size) { fprintf(stderr, "%s: short read from %s\n", argv[0], argv[1]); exit(1); } ibuf = (void *)buf; /* Phew... we are there, finally */ *(volatile uint32_t *)(map_base + 0xA0400) = 0x1deadbee; while ( !((*(volatile uint32_t *)(map_base + 0xA0400)) & (1<<28)) ) ; p = map_base + 0x80000; for (i = 0; i < (stbuf.st_size + 3) / 4; i++) { p[i] = htonl(ibuf[i]); /* big endian */ sync(); } for (i = 0; i < (stbuf.st_size + 3) / 4; i++) { if (p[i] != htonl(ibuf[i])) fprintf(stderr, "programming error at %x " "(expected %08x, found %08x)\n", i*4, htonl(ibuf[i]), p[i]); } *(volatile uint32_t *)(map_base + 0xA0400) = 0x0deadbee; if (getenv("VERBOSE")) printf("%s: Wrote %li bytes at offset 0x8000\n", argv[0], (long)stbuf.st_size); exit (0); }
int main(int argc, char **argv) { int i, fd; uint32_t base, *ptr; uint32_t uarg[3]; void *map_base; char *end; if (argc < 2 || argc > 3) { fprintf(stderr, "Use: \"%s <offset> [<value>]\" (I/O is 32 bits)\n", argv[0]); exit(1); } if((fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0) { fprintf(stderr, "%s: open(/dev/mem): %s\n", argv[0], strerror(errno)); exit(1); } base = spec_get_base(); if (base == (typeof(base))-1) { fprintf(stderr, "%s: spec_get_base(): %s\n", argv[0], strerror(errno)); exit(1); } map_base = mmap(0, 1024 * 1024, /* gennum's bar 0 is 1M */ PROT_READ | PROT_WRITE, MAP_SHARED, fd, base); if(map_base == (void *) -1) { fprintf(stderr, "%s: mmap(/dev/mem): %s\n", argv[0], strerror(errno)); exit(1); } for (i = 1; i < argc; i++) { uarg[i] = strtol(argv[i], &end, 16); if (end && *end) { fprintf(stderr, "%s: \"%s\" is not an hex number\n", argv[0], argv[i]); exit(1); } } if (uarg[1] & 3) { fprintf(stderr, "%s: address \"%s\" not multiple of 4\n", argv[0], argv[1]); exit(1); } ptr = map_base + uarg[1]; /* by default, operate quietly (only report read value) */ if (argc == 2) { uarg[2] = *ptr; if (!getenv("VERBOSE")) printf("%08x\n", uarg[2]); } else { *ptr = uarg[2]; } /* be verbose, if so requested */ if (getenv("VERBOSE")) { if (argc == 2) printf("%08x == %08x\n", uarg[1], uarg[2]); else printf("%08x := %08x\n", uarg[1], uarg[2]); } exit (0); }