void logInit(void) { int i; if(isInit) return; logs = &_log_start; logsLen = &_log_stop - &_log_start; logsCrc = crcSlow(logs, logsLen); // Big lock that protects the log datastructures logLock = xSemaphoreCreateMutex(); for (i=0; i<logsLen; i++) { if(!(logs[i].type & LOG_GROUP)) logsCount++; } //Manually free all log blocks for(i=0; i<LOG_MAX_BLOCKS; i++) logBlocks[i].id = BLOCK_ID_FREE; //Init data structures and set the log subsystem in a known state logReset(); //Start the log task xTaskCreate(logTask, (const signed char * const)"log", configMINIMAL_STACK_SIZE, NULL, /*priority*/1, NULL); isInit = true; }
void logInit(void) { int i; rt_thread_t log_thread; if(isInit) return; logs = &_log_start; logsLen = &_log_stop - &_log_start; logsCrc = crcSlow(logs, logsLen); // Big lock that protects the log datastructures logLock = rt_mutex_create("log_lock",RT_IPC_FLAG_FIFO); for (i=0; i<logsLen; i++) { if(!(logs[i].type & LOG_GROUP)) logsCount++; } //Manually free all log blocks for(i=0; i<LOG_MAX_BLOCKS; i++) logBlocks[i].id = BLOCK_ID_FREE; //Init data structures and set the log subsystem in a known state logReset(); //Start the log task //xTaskCreate(logTask, (const signed char * const)"log", // configMINIMAL_STACK_SIZE, NULL, /*priority*/1, NULL); log_thread = rt_thread_create("log", logTask, RT_NULL, 512, 10, 5); isInit = RT_TRUE; }
void logControlProcess() { int ret = ENOEXEC; switch (p.data[0]) { case CONTROL_CREATE_BLOCK: ret = logCreateBlock(p.data[1], (struct ops_setting*) &p.data[2], (p.size - 2) / sizeof(struct ops_setting)); break; case CONTROL_APPEND_BLOCK: ret = logAppendBlock(p.data[1], (struct ops_setting*) &p.data[2], (p.size - 2) / sizeof(struct ops_setting)); break; case CONTROL_DELETE_BLOCK: ret = logDeleteBlock(p.data[1]); break; case CONTROL_START_BLOCK: ret = logStartBlock(p.data[1], p.data[2] * 10); break; case CONTROL_STOP_BLOCK: ret = logStopBlock(p.data[1]); break; case CONTROL_RESET: logReset(); ret = 0; break; } //Commands answer p.data[2] = ret; p.size = 3; crtpSendPacket(&p); }
/* This function is usually called by the worker subsystem */ void logRunBlock(void * arg) { struct log_block *blk = arg; struct log_ops *ops = blk->ops; static CRTPPacket pk; unsigned int timestamp; xSemaphoreTake(logLock, portMAX_DELAY); timestamp = ((long long)xTaskGetTickCount())/portTICK_RATE_MS; pk.crtp_header = CRTP_HEADER(CRTP_PORT_LOG, LOG_CH); pk.size = 4; pk.crtp_data[0] = blk->id; pk.crtp_data[1] = timestamp&0x0ff; pk.crtp_data[2] = (timestamp>>8)&0x0ff; pk.crtp_data[3] = (timestamp>>16)&0x0ff; while (ops) { int valuei = 0; float valuef = 0; switch(ops->storageType) { case LOG_UINT8: valuei = *(uint8_t *)ops->variable; break; case LOG_INT8: valuei = *(int8_t *)ops->variable; break; case LOG_UINT16: valuei = *(uint16_t *)ops->variable; break; case LOG_INT16: valuei = *(int16_t *)ops->variable; break; case LOG_UINT32: valuei = *(uint32_t *)ops->variable; break; case LOG_INT32: valuei = *(int32_t *)ops->variable; break; case LOG_FLOAT: valuei = *(float *)ops->variable; break; } if (ops->logType == LOG_FLOAT || ops->logType == LOG_FP16) { if (ops->storageType == LOG_FLOAT) valuef = *(float *)ops->variable; else valuef = valuei; if (ops->logType == LOG_FLOAT) { memcpy(&pk.crtp_data[pk.size], &valuef, 4); pk.size += 4; } else { valuei = single2half(valuef); memcpy(&pk.crtp_data[pk.size], &valuei, 2); pk.size += 2; } } else //logType is an integer { memcpy(&pk.crtp_data[pk.size], &valuei, typeLength[ops->logType]); pk.size += typeLength[ops->logType]; } ops = ops->next; } xSemaphoreGive(logLock); // Check if the connection is still up, oherwise disable // all the logging and flush all the CRTP queues. if (!crtpIsConnected()) { logReset(); crtpReset(); } else { crtpSendPacket(&pk); } }
/* * RTEMS Startup task */ rtems_task Init (rtems_task_argument ignored) { int i; char *argv[3] = { NULL, NULL, NULL }; char *cp; rtems_task_priority newpri; rtems_status_code sc; rtems_time_of_day now; /* * Explain why we're here */ logReset(); /* * Architecture-specific hooks */ if (epicsRtemsInitPreSetBootConfigFromNVRAM(&rtems_bsdnet_config) != 0) delayedPanic("epicsRtemsInitPreSetBootConfigFromNVRAM"); if (rtems_bsdnet_config.bootp == NULL) { extern void setBootConfigFromNVRAM(void); setBootConfigFromNVRAM(); } if (epicsRtemsInitPostSetBootConfigFromNVRAM(&rtems_bsdnet_config) != 0) delayedPanic("epicsRtemsInitPostSetBootConfigFromNVRAM"); /* * Override RTEMS configuration */ rtems_task_set_priority ( RTEMS_SELF, epicsThreadGetOssPriorityValue(epicsThreadPriorityIocsh), &newpri); /* * Create a reasonable environment */ initConsole (); putenv ("TERM=xterm"); putenv ("IOCSH_HISTSIZE=20"); /* * Display some OS information */ printf("\n***** RTEMS Version: %s *****\n", rtems_get_version_string()); /* * Start network */ if ((cp = getenv("EPICS_TS_NTP_INET")) != NULL) rtems_bsdnet_config.ntp_server[0] = cp; if (rtems_bsdnet_config.network_task_priority == 0) { unsigned int p; if (epicsThreadHighestPriorityLevelBelow(epicsThreadPriorityScanLow, &p) == epicsThreadBooleanStatusSuccess) { rtems_bsdnet_config.network_task_priority = epicsThreadGetOssPriorityValue(p); } } printf("\n***** Initializing network *****\n"); rtems_bsdnet_initialize_network(); initialize_remote_filesystem(argv, initialize_local_filesystem(argv)); /* * More environment: iocsh prompt and hostname */ { char hostname[1024]; gethostname(hostname, 1023); char *cp = mustMalloc(strlen(hostname)+3, "iocsh prompt"); sprintf(cp, "%s> ", hostname); epicsEnvSet ("IOCSH_PS1", cp); epicsEnvSet("IOC_NAME", hostname); } /* * Use BSP-supplied time of day if available otherwise supply default time. * It is very likely that other time synchronization facilities in EPICS * will soon override this value. */ if (rtems_clock_get(RTEMS_CLOCK_GET_TOD,&now) != RTEMS_SUCCESSFUL) { now.year = 2001; now.month = 1; now.day = 1; now.hour = 0; now.minute = 0; now.second = 0; now.ticks = 0; if ((sc = rtems_clock_set (&now)) != RTEMS_SUCCESSFUL) printf ("***** Can't set time: %s\n", rtems_status_text (sc)); } if (getenv("TZ") == NULL) { const char *tzp = envGetConfigParamPtr(&EPICS_TIMEZONE); if (tzp == NULL) { printf("Warning -- no timezone information available -- times will be displayed as GMT.\n"); } else { char tz[10]; int minWest, toDst = 0, fromDst = 0; if(sscanf(tzp, "%9[^:]::%d:%d:%d", tz, &minWest, &toDst, &fromDst) < 2) { printf("Warning: EPICS_TIMEZONE (%s) unrecognizable -- times will be displayed as GMT.\n", tzp); } else { char posixTzBuf[40]; char *p = posixTzBuf; p += sprintf(p, "%cST%d:%.2d", tz[0], minWest/60, minWest%60); if (toDst != fromDst) p += sprintf(p, "%cDT", tz[0]); epicsEnvSet("TZ", posixTzBuf); } } } tzset(); osdTimeRegister(); /* * Run the EPICS startup script */ printf ("***** Starting EPICS application *****\n"); iocshRegisterRTEMS (); set_directory (argv[1]); epicsEnvSet ("IOC_STARTUP_SCRIPT", argv[1]); atexit(exitHandler); i = main ((sizeof argv / sizeof argv[0]) - 1, argv); printf ("***** IOC application terminating *****\n"); epicsThreadSleep(1.0); epicsExit(0); }
/* This function is usually called by the worker subsystem */ void logRunBlock(void * arg) { struct log_block *blk = arg; struct log_ops *ops = blk->ops; static CRTPPacket pk; unsigned int timestamp; xSemaphoreTake(logLock, portMAX_DELAY); timestamp = ((long long)xTaskGetTickCount())/portTICK_RATE_MS; pk.header = CRTP_HEADER(CRTP_PORT_LOG, LOG_CH); pk.size = 4; pk.data[0] = blk->id; pk.data[1] = timestamp&0x0ff; pk.data[2] = (timestamp>>8)&0x0ff; pk.data[3] = (timestamp>>16)&0x0ff; while (ops) { float variable; int valuei = 0; float valuef = 0; // FPU instructions must run on aligned data. Make sure it is. variable = *(float *)ops->variable; switch(ops->storageType) { case LOG_UINT8: valuei = *(uint8_t *)&variable; break; case LOG_INT8: valuei = *(int8_t *)&variable; break; case LOG_UINT16: valuei = *(uint16_t *)&variable; break; case LOG_INT16: valuei = *(int16_t *)&variable; break; case LOG_UINT32: valuei = *(uint32_t *)&variable; break; case LOG_INT32: valuei = *(int32_t *)&variable; break; case LOG_FLOAT: valuei = *(float *)&variable; break; } if (ops->logType == LOG_FLOAT || ops->logType == LOG_FP16) { if (ops->storageType == LOG_FLOAT) valuef = *(float *)&variable; else valuef = valuei; // Try to append the next item to the packet. If we run out of space, // drop this and subsequent items. if (ops->logType == LOG_FLOAT) { if (!appendToPacket(&pk, &valuef, 4)) break; } else { valuei = single2half(valuef); if (!appendToPacket(&pk, &valuei, 2)) break; } } else //logType is an integer { if (!appendToPacket(&pk, &valuei, typeLength[ops->logType])) break; } ops = ops->next; } xSemaphoreGive(logLock); // Check if the connection is still up, oherwise disable // all the logging and flush all the CRTP queues. if (!crtpIsConnected()) { logReset(); crtpReset(); } else { crtpSendPacket(&pk); } }