This is Unofficial EPICS BASE Doxygen Site
rtems_init.c
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2002 The University of Saskatchewan
3 * EPICS BASE Versions 3.13.7
4 * and higher are distributed subject to a Software License Agreement found
5 * in file LICENSE that is included with this distribution.
6 \*************************************************************************/
7 /*
8  * RTEMS startup task for EPICS
9  * Author: W. Eric Norum
10  * eric.norum@usask.ca
11  * (306) 966-5394
12  */
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <ctype.h>
17 #include <time.h>
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <unistd.h>
21 #include <sys/termios.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
27 #include <rtems.h>
28 #include <rtems/malloc.h>
29 #include <rtems/error.h>
30 #include <rtems/stackchk.h>
31 #include <rtems/rtems_bsdnet.h>
32 #include <rtems/imfs.h>
33 #include <librtemsNfs.h>
34 #include <bsp.h>
35 
36 #include "epicsVersion.h"
37 #include "epicsThread.h"
38 #include "epicsTime.h"
39 #include "epicsExit.h"
40 #include "envDefs.h"
41 #include "errlog.h"
42 #include "logClient.h"
43 #include "osiUnistd.h"
44 #include "iocsh.h"
45 #include "osdTime.h"
46 #include "epicsMemFs.h"
47 
48 #include "epicsRtemsInitHooks.h"
49 
50 #define RTEMS_VERSION_INT VERSION_INT(__RTEMS_MAJOR__, __RTEMS_MINOR__, 0, 0)
51 
52 /*
53  * Prototypes for some functions not in header files
54  */
55 int main(int argc, char **argv);
56 
57 static void
58 logReset (void)
59 {
60  void rtems_bsp_reset_cause(char *buf, size_t capacity) __attribute__((weak));
61  void (*fp)(char *buf, size_t capacity) = rtems_bsp_reset_cause;
62 
63  if (fp) {
64  char buf[80];
65  fp(buf, sizeof buf);
66  errlogPrintf ("Startup after %s.\n", buf);
67  }
68  else {
69  errlogPrintf ("Startup.\n");
70  }
71 }
72 
73 /*
74  ***********************************************************************
75  * FATAL ERROR REPORTING *
76  ***********************************************************************
77  */
78 /*
79  * Delay for a while, then terminate
80  */
81 static void
82 delayedPanic (const char *msg)
83 {
84  extern rtems_interval rtemsTicksPerSecond;
85 
86  rtems_task_wake_after (rtemsTicksPerSecond);
87  rtems_panic (msg);
88 }
89 
90 /*
91  * Log error and terminate
92  */
93 void
94 LogFatal (const char *msg, ...)
95 {
96  va_list ap;
97 
98  va_start (ap, msg);
99  errlogVprintf (msg, ap);
100  va_end (ap);
101  delayedPanic (msg);
102 }
103 
104 void *
105 mustMalloc(int size, const char *msg)
106 {
107  void *p;
108 
109  if ((p = malloc (size)) == NULL)
110  LogFatal ("Can't allocate space for %s.\n", msg);
111  return p;
112 }
113 
114 /*
115  ***********************************************************************
116  * REMOTE FILE ACCESS *
117  ***********************************************************************
118  */
119 #ifdef OMIT_NFS_SUPPORT
120 # include <rtems/tftp.h>
121 #endif
122 
124 const epicsMemFS *epicsRtemsFSImage = (void*)&epicsRtemsFSImage;
125 
126 /* hook to allow app specific FS setup */
127 int
128 epicsRtemsMountLocalFilesystem(char **argv) __attribute__((weak));
129 int
131 {
132  if(epicsRtemsFSImage==(void*)&epicsRtemsFSImage)
133  return -1; /* no FS image provided. */
134  else if(epicsRtemsFSImage==NULL)
135  return 0; /* no FS image provided, but none is needed. */
136  else {
137  printf("***** Using compiled in file data *****\n");
138  if (epicsMemFsLoad(epicsRtemsFSImage) != 0) {
139  printf("Can't unpack tar filesystem\n");
140  return -1;
141  } else {
142  argv[1] = "/";
143  return 0;
144  }
145  }
146 }
147 
148 static int
149 initialize_local_filesystem(char **argv)
150 {
151  extern char _DownloadLocation[] __attribute__((weak));
152  extern char _FlashBase[] __attribute__((weak));
153  extern char _FlashSize[] __attribute__((weak));
154 
155  argv[0] = rtems_bsdnet_bootp_boot_file_name;
156  if (epicsRtemsMountLocalFilesystem(argv)==0) {
157  return 1; /* FS setup successful */
158  } else if (_FlashSize && (_DownloadLocation || _FlashBase)) {
159  extern char _edata[];
160  size_t flashIndex = _edata - _DownloadLocation;
161  char *header = _FlashBase + flashIndex;
162 
163  if (memcmp(header + 257, "ustar ", 8) == 0) {
164  int fd;
165  printf ("***** Unpack in-memory file system (IMFS) *****\n");
166  if (rtems_tarfs_load("/", (unsigned char *)header, (size_t)_FlashSize - flashIndex) != 0) {
167  printf("Can't unpack tar filesystem\n");
168  return 0;
169  }
170  if ((fd = open(rtems_bsdnet_bootp_cmdline, 0)) >= 0) {
171  close(fd);
172  printf ("***** Found startup script (%s) in IMFS *****\n", rtems_bsdnet_bootp_cmdline);
173  argv[1] = rtems_bsdnet_bootp_cmdline;
174  return 1;
175  }
176  printf ("***** Startup script (%s) not in IMFS *****\n", rtems_bsdnet_bootp_cmdline);
177  }
178  }
179  return 0;
180 }
181 
182 #ifndef OMIT_NFS_SUPPORT
183 #if __RTEMS_MAJOR__>4 || \
184  (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || \
185  (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99)
186 int
187 nfsMount(char *uidhost, char *path, char *mntpoint)
188 {
189  int devl = strlen(uidhost) + strlen(path) + 2;
190  char *dev;
191  int rval = -1;
192 
193  if ((dev = malloc(devl)) == NULL) {
194  fprintf(stderr,"nfsMount: out of memory\n");
195  return -1;
196  }
197  sprintf(dev, "%s:%s", uidhost, path);
198  printf("Mount %s on %s\n", dev, mntpoint);
199  if (rtems_mkdir(mntpoint, S_IRWXU | S_IRWXG | S_IRWXO))
200  printf("Warning -- unable to make directory \"%s\"\n", mntpoint);
201  if (mount(dev, mntpoint, RTEMS_FILESYSTEM_TYPE_NFS,
202  RTEMS_FILESYSTEM_READ_WRITE, NULL)) {
203  perror("mount failed");
204  }
205  else {
206  rval = 0;
207  }
208  free(dev);
209  return rval;
210 }
211 #define NFS_INIT
212 #else
213 #define NFS_INIT rpcUdpInit(); nfsInit(0,0);
214 #endif
215 #endif
216 
217 static void
218 initialize_remote_filesystem(char **argv, int hasLocalFilesystem)
219 {
220 #ifdef OMIT_NFS_SUPPORT
221  printf ("***** Initializing TFTP *****\n");
222 #if __RTEMS_MAJOR__>4 || \
223  (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || \
224  (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99)
225  mount_and_make_target_path(NULL,
226  "/TFTP",
227  RTEMS_FILESYSTEM_TYPE_TFTPFS,
228  RTEMS_FILESYSTEM_READ_WRITE,
229  NULL);
230 #else
231  rtems_bsdnet_initialize_tftp_filesystem ();
232 #endif
233  if (!hasLocalFilesystem) {
234  char *path;
235  int pathsize = 200;
236  int l;
237 
238  path = mustMalloc(pathsize, "Command path name ");
239  strcpy (path, "/TFTP/BOOTP_HOST/epics/");
240  l = strlen (path);
241  if (gethostname (&path[l], pathsize - l - 10) || (path[l] == '\0'))
242  {
243  LogFatal ("Can't get host name");
244  }
245  strcat (path, "/st.cmd");
246  argv[1] = path;
247  }
248 #else
249  char *server_name;
250  char *server_path;
251  char *mount_point;
252  char *cp;
253  int l = 0;
254 
255  printf ("***** Initializing NFS *****\n");
256  NFS_INIT
258  server_name = env_nfsServer;
259  server_path = env_nfsPath;
260  mount_point = env_nfsMountPoint;
261  cp = mount_point;
262  while ((cp = strchr(cp+1, '/')) != NULL) {
263  *cp = '\0';
264  if ((mkdir (mount_point, 0755) != 0)
265  && (errno != EEXIST))
266  LogFatal("Can't create directory \"%s\": %s.\n",
267  mount_point, strerror(errno));
268  *cp = '/';
269  }
270  argv[1] = rtems_bsdnet_bootp_cmdline;
271  }
272  else if (hasLocalFilesystem) {
273  return;
274  }
275  else {
276  /*
277  * Use first component of nvram/bootp command line pathname
278  * to set up initial NFS mount. A "/tftpboot/" is prepended
279  * if the pathname does not begin with a '/'. This allows
280  * NFS and TFTP to have a similar view of the remote system.
281  */
282  if (rtems_bsdnet_bootp_cmdline[0] == '/')
283  cp = rtems_bsdnet_bootp_cmdline + 1;
284  else
285  cp = rtems_bsdnet_bootp_cmdline;
286  cp = strchr(cp, '/');
287  if ((cp == NULL)
288  || ((l = cp - rtems_bsdnet_bootp_cmdline) == 0))
289  LogFatal("\"%s\" is not a valid command pathname.\n", rtems_bsdnet_bootp_cmdline);
290  cp = mustMalloc(l + 20, "NFS mount paths");
291  server_path = cp;
292  server_name = rtems_bsdnet_bootp_server_name;
293  if (rtems_bsdnet_bootp_cmdline[0] == '/') {
294  mount_point = server_path;
295  strncpy(mount_point, rtems_bsdnet_bootp_cmdline, l);
296  mount_point[l] = '\0';
297  argv[1] = rtems_bsdnet_bootp_cmdline;
298  /*
299  * Its probably common to embed the mount point in the server
300  * name so, when this is occurring, dont clobber the mount point
301  * by appending the first node from the command path. This allows
302  * the mount point to be a different path then the server's mount
303  * path.
304  *
305  * This allows for example a line similar to as follows the DHCP
306  * configuration file.
307  *
308  * server-name "159.233@192.168.0.123:/vol/vol0/bootRTEMS";
309  */
310  if ( server_name ) {
311  const size_t allocSize = strlen ( server_name ) + 2;
312  char * const pServerName = mustMalloc( allocSize,
313  "NFS mount paths");
314  char * const pServerPath = mustMalloc ( allocSize,
315  "NFS mount paths");
316  const int scanfStatus = sscanf (
317  server_name,
318  "%[^:] : / %s",
319  pServerName,
320  pServerPath + 1u );
321  if ( scanfStatus == 2 ) {
322  pServerPath[0u]= '/';
323  server_name = pServerName;
324  server_path = pServerPath;
325  }
326  else {
327  free ( pServerName );
328  free ( pServerPath );
329  }
330  }
331  }
332  else {
333  char *abspath = mustMalloc(strlen(rtems_bsdnet_bootp_cmdline)+2,"Absolute command path");
334  strcpy(server_path, "/tftpboot/");
335  mount_point = server_path + strlen(server_path);
336  strncpy(mount_point, rtems_bsdnet_bootp_cmdline, l);
337  mount_point[l] = '\0';
338  mount_point--;
339  strcpy(abspath, "/");
340  strcat(abspath, rtems_bsdnet_bootp_cmdline);
341  argv[1] = abspath;
342  }
343  }
344  errlogPrintf("nfsMount(\"%s\", \"%s\", \"%s\")\n",
345  server_name, server_path, mount_point);
346  nfsMount(server_name, server_path, mount_point);
347 #endif
348 }
349 
350 static
351 const char rtems_etc_hosts[] = "127.0.0.1 localhost\n";
352 
353 /* If it doesn't already exist, create /etc/hosts with an entry for 'localhost' */
354 static
355 void fixup_hosts(void)
356 {
357  FILE *fp;
358  int ret;
359  struct stat STAT;
360 
361  ret=stat("/etc/hosts", &STAT);
362  if(ret==0)
363  {
364  return; /* already exists, assume file */
365  } else if(errno!=ENOENT) {
366  perror("error: fixup_hosts stat /etc/hosts");
367  return;
368  }
369 
370  ret = mkdir("/etc", 0775);
371  if(ret!=0 && errno!=EEXIST)
372  {
373  perror("error: fixup_hosts create /etc");
374  return;
375  }
376 
377  if((fp=fopen("/etc/hosts", "w"))==NULL)
378  {
379  perror("error: fixup_hosts create /etc/hosts");
380  }
381 
382  if(fwrite(rtems_etc_hosts, 1, sizeof(rtems_etc_hosts)-1, fp)!=sizeof(rtems_etc_hosts)-1)
383  {
384  perror("error: failed to write /etc/hosts");
385  }
386 
387  fclose(fp);
388 }
389 
390 /*
391  * Get to the startup script directory
392  * The TFTP filesystem requires a trailing '/' on chdir arguments.
393  */
394 static void
395 set_directory (const char *commandline)
396 {
397  const char *cp;
398  char *directoryPath;
399  int l;
400 
401  cp = strrchr(commandline, '/');
402  if (cp == NULL) {
403  l = 0;
404  cp = "/";
405  }
406  else {
407  l = cp - commandline;
408  cp = commandline;
409  }
410  directoryPath = mustMalloc(l + 2, "Command path directory ");
411  strncpy(directoryPath, cp, l);
412  directoryPath[l] = '/';
413  directoryPath[l+1] = '\0';
414  if (chdir (directoryPath) < 0)
415  LogFatal ("Can't set initial directory(%s): %s\n", directoryPath, strerror(errno));
416  else
417  errlogPrintf("chdir(\"%s\")\n", directoryPath);
418  free(directoryPath);
419 }
420 
421 /*
422  ***********************************************************************
423  * RTEMS/EPICS COMMANDS *
424  ***********************************************************************
425  */
426 /*
427  * RTEMS status
428  */
429 static void
430 rtems_netstat (unsigned int level)
431 {
432  rtems_bsdnet_show_if_stats ();
433  rtems_bsdnet_show_mbuf_stats ();
434  if (level >= 1) {
435  rtems_bsdnet_show_inet_routes ();
436  }
437  if (level >= 2) {
438  rtems_bsdnet_show_ip_stats ();
439  rtems_bsdnet_show_icmp_stats ();
440  rtems_bsdnet_show_udp_stats ();
441  rtems_bsdnet_show_tcp_stats ();
442  }
443 }
444 
445 static const iocshArg netStatArg0 = { "level",iocshArgInt};
446 static const iocshArg * const netStatArgs[1] = {&netStatArg0};
447 static const iocshFuncDef netStatFuncDef = {"netstat",1,netStatArgs};
448 static void netStatCallFunc(const iocshArgBuf *args)
449 {
450  rtems_netstat(args[0].ival);
451 }
452 
453 static const iocshFuncDef heapSpaceFuncDef = {"heapSpace",0,NULL};
454 static void heapSpaceCallFunc(const iocshArgBuf *args)
455 {
456  rtems_malloc_statistics_t s;
457  double x;
458 
459  malloc_get_statistics(&s);
460  x = s.space_available - (unsigned long)(s.lifetime_allocated - s.lifetime_freed);
461  if (x >= 1024*1024)
462  printf("Heap space: %.1f MB\n", x / (1024 * 1024));
463  else
464  printf("Heap space: %.1f kB\n", x / 1024);
465 }
466 
467 #ifndef OMIT_NFS_SUPPORT
468 static const iocshArg nfsMountArg0 = { "[uid.gid@]host",iocshArgString};
469 static const iocshArg nfsMountArg1 = { "server path",iocshArgString};
470 static const iocshArg nfsMountArg2 = { "mount point",iocshArgString};
471 static const iocshArg * const nfsMountArgs[3] = {&nfsMountArg0,&nfsMountArg1,
472  &nfsMountArg2};
473 static const iocshFuncDef nfsMountFuncDef = {"nfsMount",3,nfsMountArgs};
474 static void nfsMountCallFunc(const iocshArgBuf *args)
475 {
476  char *cp = args[2].sval;
477  while ((cp = strchr(cp+1, '/')) != NULL) {
478  *cp = '\0';
479  if ((mkdir (args[2].sval, 0755) != 0) && (errno != EEXIST)) {
480  printf("Can't create directory \"%s\": %s.\n",
481  args[2].sval, strerror(errno));
482  return;
483  }
484  *cp = '/';
485  }
486  nfsMount(args[0].sval, args[1].sval, args[2].sval);
487 }
488 #endif
489 
490 
491 void zoneset(const char *zone)
492 {
493  if(zone)
494  setenv("TZ", zone, 1);
495  else
496  unsetenv("TZ");
497  tzset();
498 }
499 
500 static const iocshArg zonesetArg0 = {"zone string", iocshArgString};
501 static const iocshArg * const zonesetArgs[1] = {&zonesetArg0};
502 static const iocshFuncDef zonesetFuncDef = {"zoneset",1,zonesetArgs};
503 static void zonesetCallFunc(const iocshArgBuf *args)
504 {
505  zoneset(args[0].sval);
506 }
507 
508 
509 /*
510  * Register RTEMS-specific commands
511  */
512 static void iocshRegisterRTEMS (void)
513 {
514  iocshRegister(&netStatFuncDef, netStatCallFunc);
515  iocshRegister(&heapSpaceFuncDef, heapSpaceCallFunc);
516 #ifndef OMIT_NFS_SUPPORT
517  iocshRegister(&nfsMountFuncDef, nfsMountCallFunc);
518 #endif
519  iocshRegister(&zonesetFuncDef, &zonesetCallFunc);
520 }
521 
522 /*
523  * Set up the console serial line (no handshaking)
524  */
525 static void
526 initConsole (void)
527 {
528  struct termios t;
529 
530  if (tcgetattr (fileno (stdin), &t) < 0) {
531  printf ("tcgetattr failed: %s\n", strerror (errno));
532  return;
533  }
534  t.c_iflag &= ~(IXOFF | IXON | IXANY);
535  if (tcsetattr (fileno (stdin), TCSANOW, &t) < 0) {
536  printf ("tcsetattr failed: %s\n", strerror (errno));
537  return;
538  }
539 }
540 
541 /*
542  * Ensure that the configuration object files
543  * get pulled in from the library
544  */
545 extern rtems_configuration_table Configuration;
546 extern struct rtems_bsdnet_config rtems_bsdnet_config;
547 const void *rtemsConfigArray[] = {
548  &Configuration,
549  &rtems_bsdnet_config
550 };
551 
552 /*
553  * Hook to ensure that BSP cleanup code gets run on exit
554  */
555 static void
556 exitHandler(void)
557 {
558  rtems_shutdown_executive(0);
559 }
560 
561 /*
562  * RTEMS Startup task
563  */
564 rtems_task
565 Init (rtems_task_argument ignored)
566 {
567  int result;
568  char *argv[3] = { NULL, NULL, NULL };
569  char *cp;
570  rtems_task_priority newpri;
571  rtems_status_code sc;
572  rtems_time_of_day now;
573 
574  /*
575  * Explain why we're here
576  */
577  logReset();
578 
579  /*
580  * Architecture-specific hooks
581  */
582  if (epicsRtemsInitPreSetBootConfigFromNVRAM(&rtems_bsdnet_config) != 0)
583  delayedPanic("epicsRtemsInitPreSetBootConfigFromNVRAM");
584  if (rtems_bsdnet_config.bootp == NULL) {
585  extern void setBootConfigFromNVRAM(void);
587  }
588  if (epicsRtemsInitPostSetBootConfigFromNVRAM(&rtems_bsdnet_config) != 0)
589  delayedPanic("epicsRtemsInitPostSetBootConfigFromNVRAM");
590 
591  /*
592  * Override RTEMS configuration
593  */
594  rtems_task_set_priority (
595  RTEMS_SELF,
597  &newpri);
598 
599  /*
600  * Create a reasonable environment
601  */
602  initConsole ();
603  putenv ("TERM=xterm");
604  putenv ("IOCSH_HISTSIZE=20");
605 
606  /*
607  * Display some OS information
608  */
609  printf("\n***** RTEMS Version: %s *****\n",
610  rtems_get_version_string());
611 
612  /*
613  * Start network
614  */
615  if ((cp = getenv("EPICS_TS_NTP_INET")) != NULL)
616  rtems_bsdnet_config.ntp_server[0] = cp;
617  if (rtems_bsdnet_config.network_task_priority == 0)
618  {
619  unsigned int p;
622  {
623  rtems_bsdnet_config.network_task_priority = epicsThreadGetOssPriorityValue(p);
624  }
625  }
626  printf("\n***** Initializing network *****\n");
627  rtems_bsdnet_initialize_network();
628  printf("\n***** Setting up file system *****\n");
629  initialize_remote_filesystem(argv, initialize_local_filesystem(argv));
630  fixup_hosts();
631 
632  /*
633  * More environment: iocsh prompt and hostname
634  */
635  {
636  char hostname[1024];
637  gethostname(hostname, 1023);
638  char *cp = mustMalloc(strlen(hostname)+3, "iocsh prompt");
639  sprintf(cp, "%s> ", hostname);
640  epicsEnvSet ("IOCSH_PS1", cp);
641  epicsEnvSet("IOC_NAME", hostname);
642  }
643 
644  /*
645  * Use BSP-supplied time of day if available otherwise supply default time.
646  * It is very likely that other time synchronization facilities in EPICS
647  * will soon override this value.
648  */
649  if (rtems_clock_get(RTEMS_CLOCK_GET_TOD,&now) != RTEMS_SUCCESSFUL) {
650  now.year = 2001;
651  now.month = 1;
652  now.day = 1;
653  now.hour = 0;
654  now.minute = 0;
655  now.second = 0;
656  now.ticks = 0;
657  if ((sc = rtems_clock_set (&now)) != RTEMS_SUCCESSFUL)
658  printf ("***** Can't set time: %s\n", rtems_status_text (sc));
659  }
660  if (getenv("TZ") == NULL) {
661  const char *tzp = envGetConfigParamPtr(&EPICS_TZ);
662  if (!tzp || *tzp)
663  printf("Warning: No timezone information, times will be displayed in UTC.\n");
664  else
665  epicsEnvSet("TZ", tzp);
666  }
667  tzset();
668  osdTimeRegister();
669 
670  /*
671  * Run the EPICS startup script
672  */
673  printf ("***** Preparing EPICS application *****\n");
674  iocshRegisterRTEMS ();
675  set_directory (argv[1]);
676  epicsEnvSet ("IOC_STARTUP_SCRIPT", argv[1]);
677  atexit(exitHandler);
678  errlogFlush();
679  printf ("***** Starting EPICS application *****\n");
680  result = main ((sizeof argv / sizeof argv[0]) - 1, argv);
681  printf ("***** IOC application terminating *****\n");
682  epicsThreadSleep(1.0);
683  epicsExit(result);
684 }
685 
686 #if defined(QEMU_FIXUPS)
687 /* Override some hooks (weak symbols)
688  * if BSP defaults aren't configured for running tests.
689  */
690 
691 
692 /* Ensure that stdio goes to serial (so it can be captured) */
693 #if defined(__i386__) && !USE_COM1_AS_CONSOLE
694 #include <uart.h>
695 extern int BSPPrintkPort;
696 void bsp_predriver_hook(void)
697 {
698  BSPConsolePort = BSP_CONSOLE_PORT_COM1;
699  BSPPrintkPort = BSP_CONSOLE_PORT_COM1;
700 }
701 #endif
702 
703 /* reboot immediately when done. */
704 #if defined(__i386__) && BSP_PRESS_KEY_FOR_RESET
705 void bsp_cleanup(void)
706 {
707 #if RTEMS_VERSION_INT>=VERSION_INT(4,10,0,0)
708  void bsp_reset();
709  bsp_reset();
710 #else
711  rtemsReboot();
712 #endif
713 }
714 #endif
715 
716 #endif /* QEMU_FIXUPS */
717 
718 int cexpdebug __attribute__((weak));
void errlogFlush(void)
Definition: errlog.c:529
pvac::PutEvent result
Definition: clientSync.cpp:117
LIBCOM_API const ENV_PARAM EPICS_TZ
int epicsRtemsInitPreSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config)
struct rtems_bsdnet_config rtems_bsdnet_config
LIBCOM_API const char *epicsStdCall envGetConfigParamPtr(const ENV_PARAM *pParam)
Get a configuration parameter&#39;s value or default string.
Definition: envSubr.c:81
int errlogVprintf(const char *pFormat, va_list pvar)
Definition: errlog.c:144
char * env_nfsPath
Routines to get and set EPICS environment parameters.
#define printf
Definition: epicsStdio.h:41
void epicsStdCall iocshRegister(const iocshFuncDef *piocshFuncDef, iocshCallFunc func)
Definition: iocsh.cpp:111
char * env_nfsServer
#define NULL
Definition: catime.c:38
char * sval
Definition: iocsh.h:42
void osdTimeRegister(void)
Definition: osdTime.cpp:36
LIBCOM_API void epicsStdCall epicsEnvSet(const char *name, const char *value)
Set an environment variable&#39;s value.
Definition: osdEnv.c:35
#define epicsThreadPriorityIocsh
Definition: epicsThread.h:84
const void * rtemsConfigArray[]
Definition: rtems_init.c:547
int main(int argc, char **argv)
Definition: acctstMain.c:17
int epicsThreadGetOssPriorityValue(unsigned int osiPriority)
Definition: osdThread.c:98
char * header[]
Definition: skeleton.c:51
const epicsMemFS *epicsRtemsFSImage __attribute__((weak))
#define NFS_INIT
Definition: rtems_init.c:213
LIBCOM_API void epicsExit(int status)
Calls epicsExitCallAtExits(), then the OS exit() routine.
Definition: epicsExit.c:182
Extended replacement for the Posix exit and atexit routines.
rtems_configuration_table Configuration
rtems_task Init(rtems_task_argument ignored)
Definition: rtems_init.c:565
int putenv(char *)
int epicsMemFsLoad(const epicsMemFS *fs)
Definition: epicsMemFs.c:22
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
int epicsRtemsMountLocalFilesystem(char **argv) __attribute__((weak))
Definition: rtems_init.c:130
LIBCOM_API epicsThreadBooleanStatus epicsStdCall epicsThreadHighestPriorityLevelBelow(unsigned int priority, unsigned *pPriorityJustBelow)
Definition: osdThread.c:740
#define stdin
Definition: epicsStdio.h:28
LIBCOM_API void epicsStdCall epicsThreadSleep(double seconds)
Block the calling thread for at least the specified time.
Definition: osdThread.c:790
#define epicsThreadPriorityScanLow
Definition: epicsThread.h:82
void setBootConfigFromNVRAM(void)
void LogFatal(const char *msg,...)
Definition: rtems_init.c:94
char * env_nfsMountPoint
void * mustMalloc(int size, const char *msg)
Definition: rtems_init.c:105
#define stderr
Definition: epicsStdio.h:32
EPICS time-stamps (epicsTimeStamp), epicsTime C++ class and C functions for handling wall-clock times...
C++ and C descriptions for a thread.
const epicsMemFS * epicsRtemsFSImage
Definition: rtems_init.c:124
int epicsRtemsInitPostSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config)
rtems_interval rtemsTicksPerSecond
Definition: osdTime.cpp:142
Definition: iocsh.h:56
void zoneset(const char *zone)
Definition: rtems_init.c:491