📄 exstbtop.c
字号:
} } taskTotal += timeDoctor_tasks[task].time_total; } } return taskTotal;}/* * @brief Function to extract information about the system idle time */static uint32_t idleInfo(void){ int32_t task; uint32_t taskTotal = 0; for(task=0; task<timeDoctor_taskCount; task++) { if (timeDoctor_tasks[task].task_number == 0) { taskTotal += timeDoctor_tasks[task].time_total; } } return taskTotal;}/* * @brief Function to initialise time doctor */static int32_t timeDoctor_init(int32_t *pTimeDoctor, uint32_t **pTimeDoctorData){ /* Open the timedoctor device */ *pTimeDoctor = open(TIMEDOCTOR_FILE, O_RDWR); if (*pTimeDoctor<0) { (void)printf("Error: Cannot open timedoctor interface '%s'.\n", TIMEDOCTOR_FILE); (void)printf("Enable 'timedoctor' in kernel configuration!\n"); return -1; } /* Find out the number of event entries */ timeDoctor_numEntries = ioctl( *pTimeDoctor, TIMEDOCTOR_IOCTL_GET_MAX_ENTRIES ); /* Map the timedoctor output memory */ *pTimeDoctorData = mmap( 0, timeDoctor_numEntries * sizeof(uint32_t), PROT_READ, MAP_SHARED, *pTimeDoctor, 0 ); if (*pTimeDoctorData == MAP_FAILED) { (void)printf("Error: Cannot map timedoctor memory.\n"); *pTimeDoctorData = NULL; (void)close( *pTimeDoctor ); return -1; } return 0;}/* * @brief Function to add a time doctor event (interrupt or task) */static __inline__ void timeDoctor_addEvent(const uint32_t *record){ /* Check for task events */ if ((record[1] & 0x00ff0000) == TDI_TASK) { if ((record[1] & (TDI_START << 24)) == (TDI_START << 24)) { char_t task_name[MAX_NAME]; task_name[0] = (char_t)((record[2]>>24)&0xff); task_name[1] = (char_t)((record[2]>>16)&0xff); task_name[2] = (char_t)((record[2]>>8)&0xff); task_name[3] = (char_t)((record[2])&0xff); task_name[4] = (char_t)((record[3]>>24)&0xff); task_name[5] = (char_t)((record[3]>>16)&0xff); task_name[6] = (char_t)((record[3]>>8)&0xff); task_name[7] = (char_t)((record[3])&0xff); task_name[8] = '\0'; pushEvent((record[1] & 0xFFFF), task_name, false, record[0]); } else { popEvent(record[0]); } } /* Check for interrupt events */ if ((record[1] & (TDI_ISR << 16)) == (TDI_ISR << 16)) { if ((record[1] & (TDI_START << 24)) == (TDI_START << 24)) { pushEvent((record[1] & 0xFFFF), "int", true, record[0]); } else { popEvent(record[0]); } }}/* * @brief Function to output summary information */static void timedoctor_output(int32_t file, char *string){ if (timeDoctor_outputFileEnabled) { (void)write(file, string, strlen(string)); } if ((serverMode == false) && (timeDoctor_outputFileEnabled == false)) { (void)printf("%s", string); }}/* * @brief Function to monitor system information via time doctor */static void timeDoctor_monitor(int32_t timeDoctor, const uint32_t *pTimeDoctorData, int32_t duration){ timeDoctor_taskCount = MAX_TASKS; while(timeDoctor_keepAppAlive==true) { int32_t i; int32_t wait; /* Initialise interrupt and task information */ for(i=0;i<MAX_IRQS;i++) { timeDoctor_intTime[i] = 0; } for(i=0;i<timeDoctor_taskCount;i++) { timeDoctor_tasks[i].time_total = 0; } timeDoctor_taskCount = 0; timeDoctor_stackPosition = 0; timeDoctor_totalTime = 0; timeDoctor_started = false; /* Reset time doctor */ (void)ioctl( timeDoctor, TIMEDOCTOR_IOCTL_RESET ); /* Start data gathering */ (void)ioctl( timeDoctor, TIMEDOCTOR_IOCTL_START ); for(wait=(duration*10); timeDoctor_keepAppAlive && wait; wait--) { /* Wait for a while */ (void)usleep(100000); } /* Stop data gathering */ (void)ioctl( timeDoctor, TIMEDOCTOR_IOCTL_STOP ); if (timeDoctor_keepAppAlive==true) { uint32_t irqTime; uint32_t taskTime; uint32_t idleTime; int32_t numEntries; /* Find out the number of event entries */ numEntries = ioctl( timeDoctor, TIMEDOCTOR_IOCTL_GET_ENTRIES ); /* Process the information */ for(i=0; i<numEntries; i+=4) { timeDoctor_addEvent(&pTimeDoctorData[i]); } /* Output process information */ if ((serverMode == false) && (timeDoctor_outputFileEnabled == false)) { (void)printf("\n\n\n"); } irqTime = irqInfo(); sortTasks(); taskTime = taskInfo(); idleTime = idleInfo(); if ((serverMode == false) && (timeDoctor_outputFileEnabled == false)) { printf("\n"); } if (timeDoctor_totalTime != 0) { int32_t file = 0; char string[128]; if (timeDoctor_outputFileEnabled) { file = open(timeDoctor_outputFile, O_RDWR | O_CREAT); if (file < 0) { printf("Error: Unable to open file '%s'\n", timeDoctor_outputFile); timeDoctor_outputFileEnabled = false; } } lastValues[0] = irqTime/(timeDoctor_totalTime/100); lastValues[1] = taskTime/(timeDoctor_totalTime/100); lastValues[2] = idleTime/(timeDoctor_totalTime/100); (void)sprintf(string, "Summary:\n"); timedoctor_output(file, string); (void)sprintf(string, "IRQ : %d%%\n", lastValues[0]); timedoctor_output(file, string); (void)sprintf(string, "Task : %d%%\n", lastValues[1]); timedoctor_output(file, string); (void)sprintf(string, "Idle : %d%%\n", lastValues[2]); timedoctor_output(file, string); if (timeDoctor_outputFileEnabled) { close(file); } } } }}/* * @brief Function to terminate time doctor */static void timeDoctor_term(int32_t timeDoctor, uint32_t *pTimeDoctorData){ (void)munmap( (void*)pTimeDoctorData, timeDoctor_numEntries * sizeof(uint32_t) ); (void)close(timeDoctor);}/* * @brief Function to display application usage */static void printUsage(char_t* commandLine){ (void)printf("Usage: %s [-d <seconds>] [-f <filename>] [-h]\n", commandLine); (void)printf("-d specifies the duration of each sample period (default 1)\n"); (void)printf("-f output a summary to a file\n"); (void)printf("-h displays this help!\n");#ifdef TMFL_STBIPC (void)printf("-s creates a server at address %s\n", PH_STBIPC_DSP_EXSTBTOP_SERVER_ADDRESS);#endif exit(0);}#ifdef TMFL_STBIPCstatic void *serverThreadFunction(void *pArg){ tmErrorCode_t err; pphStbIpc_Server_t server; (void)pArg; err = phStbIpc_ServerCreate( PH_STBIPC_DSP_EXSTBTOP_SERVER_ADDRESS, &server); if (err != TM_OK) { (void)fprintf(stderr, "exStbDemo: phStbIpc_ServerCreate(\"" PH_STBIPC_DSP_EXSTBTOP_SERVER_ADDRESS "\") error 0x%x", err); return NULL; } while (1) { pphStbIpc_Connection_t connection; err = phStbIpc_ServerAccept(server, &connection); if (err != TM_OK) { (void)fprintf(stderr, "exStbDemo: phStbIpc_ServerAccept error 0x%x", err); (void)phStbIpc_ServerDestroy(server); return NULL; } while (err == TM_OK) { uint8_t buf[1]; size_t len; err = phStbIpc_ReadExactly( connection, buf, 1U, &len); if (err == TM_OK) { err = phStbIpc_WriteExactly( connection, (uint8_t*)lastValues, sizeof(lastValues), &len); } } (void)phStbIpc_Close(connection); } (void)phStbIpc_ServerDestroy(server); return NULL;}static int setupServer(void){ int status; /* Create a separate thread */ status = pthread_create (&serverThread, NULL, serverThreadFunction, (void*)NULL); if (status != 0) { (void)fprintf(stderr, "exStbDemo: error in pthread_create %d", status); return 1; } return 0;}static void terminateServer(void){ (void)pthread_cancel(serverThread); (void)pthread_join (serverThread, NULL);}#endif/* * @brief Example application demonstrating time doctor to display task and interrupt information. */int32_t main(int32_t argc, char* argv[]){ int32_t timeDoctor; uint32_t *pTimeDoctorData; int32_t duration = 1; if (argc > 3) { printUsage(argv[0]); } if (argc > 1) { int32_t i; int32_t arg_add; for(i=1; i<argc; i+=arg_add) { arg_add = 1; if (!strcmp(argv[i], "-d")) { if (argc > (i+1)) { duration = atoi(argv[i+1]); arg_add++; } else { printUsage(argv[0]); } continue; } if (!strcmp(argv[i], "-f")) { if (argc > (i+1)) { strncpy(timeDoctor_outputFile, argv[i+1], OUTPUT_FILE_LENGTH); timeDoctor_outputFileEnabled = true; arg_add++; } else { printUsage(argv[0]); } continue; } if (!strcmp(argv[i], "-h")) { printUsage(argv[0]); continue; } if (!strcmp(argv[i], "-s")) {#ifdef TMFL_STBIPC serverMode = true;#else (void)printf("Servermode is not available!\n"); printUsage(argv[0]);#endif continue; } printUsage(argv[0]); } } /* Handle Ctrl C so that the application can be exited */ (void)signal(SIGINT, signal_handler); (void)signal(SIGTERM, signal_handler); (void)signal(SIGSEGV, signal_handler);#ifdef TMFL_STBIPC if (serverMode != false) { if (setupServer() != 0) { return 1; } }#endif if (timeDoctor_init(&timeDoctor, &pTimeDoctorData) == 0) { timeDoctor_monitor(timeDoctor, pTimeDoctorData, duration); timeDoctor_term(timeDoctor, pTimeDoctorData); }#ifdef TMFL_STBIPC if (serverMode) { terminateServer(); }#endif return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -