int main(int argc, char *argv[]) { pthread_t thread_wdt; pthread_t thread_log; pthread_t thread_fifoSrv; pthread_t thread_snmpSrv; pthread_t thread_sendfifo; pthread_t thread_ch1, thread_ch2; pthread_t thread_rtSend, thread_rtRecv; struct wdt_thread_arg wdt_targ; struct log_thread_arg log_targ; struct fifo_thread_arg fifoSrv_targ; struct snmp_thread_arg snmpSrv_targ; struct sfifo_thread_arg sendfifo_targ; struct chan_thread_arg ch1_targ, ch2_targ; struct rt_thread_arg rtSend_targ, rtRecv_targ; int result; char cfile[64]; char lfile[64]; char lfile_old[64]; char lifeFile[64]; int rs_parity, rs_databits, rs_stopbit; int rs_speed; unsigned int utxdel; int tscan; int tout, nretries; int wdt_en; unsigned long wdt_tm; int ch1_enable, ch2_enable; char ip[16]; unsigned int fifo_port; char rt_ipSend[16]; char rt_ipRecv[16]; unsigned int rt_portSend, rt_portRecv; char logSend_ip[16]; unsigned int logSend_port, logMaxLines; int snmp_n, snmp_uso; char *tempip; char ls_gen[32]; char req_ag[32]; char req_ns[32]; char req_gl[32]; char req_ms[32]; int cdDest; int cdaId; int cdnsId; int cdquLogId; int cdmsId; int i; char key[7] = {0}; TOHT *cfg; if( argc == 2) sprintf(cfile, argv[1]); else { sprintf(cfile, "mslave_default.cfg"); gen_moxa_default_cfg(cfile); /** Генерация slave конфиг файла * по умолчанию */ } cfg = cfg_load(cfile); /** Загрузили общий конфиг */ /** Установка лог файла */ sprintf(lfile, cfg_getstring(cfg, "moxa:log", NULL)); sprintf(lfile_old, cfg_getstring(cfg, "moxa:log_old", NULL)); bo_setLogParam(lfile, lfile_old, 0, 1000); /** Генерация таблицы для расчета контрольной суммы * кадра сети RS485 по алгоритму CRC16-MODBUS */ gen_tbl_crc16modbus(); /** Установка таймеров */ tscan = cfg_getint(cfg, "moxa:Tscan", -1); tout = cfg_getint(cfg, "moxa:Tout", -1); nretries = cfg_getint(cfg, "moxa:nRetries", -1); /** Установка параметров WatchDog */ wdt_targ.tsec = cfg_getint(cfg, "WDT:Tsec", -1); wdt_targ.tusec = cfg_getint(cfg, "WDT:Tusec", -1); wdt_tm = (unsigned long)cfg_getint(cfg, "WDT:Tms", -1); wdt_en = cfg_getint(cfg, "WDT:enable", -1); /** Инициализация файла для контроля жизни программы через CRON */ sprintf(lifeFile, cfg_getstring(cfg, "WDT:lifeFile", NULL)); /* gen_moxa_cron_life(lifeFile); */ /** IP адрес узла */ sprintf(ip, cfg_getstring(cfg, "eth0:ip", NULL)); /** FIFO сервер */ fifo_port = (unsigned int)cfg_getint(cfg, "FIFO:port", -1); fifoSrv_targ.qu_len = cfg_getint(cfg, "FIFO:queue_len", -1); fifoSrv_targ.len = cfg_getint(cfg, "FIFO:len", -1); /** RT SEND server IP, port */ sprintf(rt_ipSend, cfg_getstring(cfg, "RT:sendIp", NULL)); rt_portSend = (unsigned int)cfg_getint(cfg, "RT:sendPort", -1); /** RT RECV server IP, port */ sprintf(rt_ipRecv, cfg_getstring(cfg, "RT:recvIp", NULL)); rt_portRecv = (unsigned int)cfg_getint(cfg, "RT:recvPort", -1); /** LOGGER server IP, port, максимальное количество строк */ sprintf(logSend_ip, cfg_getstring(cfg, "LOGGER:sendIp", NULL)); logSend_port = (unsigned int)cfg_getint(cfg, "LOGGER:sendPort", -1); logMaxLines = (unsigned int)cfg_getint(cfg, "LOGGER:maxLines", -1); /** SNMP */ snmp_n = cfg_getint(cfg, "SNMP:n", -1); /** Адрес УСО */ snmp_uso = cfg_getint(cfg, "SNMP:uso", -1); if (snmp_n > 0 && snmp_n <= SNMP_IP_MAX) for (i=0; i<snmp_n; i++) { sprintf(key, "SNMP:%01d", i+1); snmpSrv_targ.ip[i] = malloc(sizeof(char) * 16); tempip = cfg_getstring(cfg, key, NULL); memcpy(*(snmpSrv_targ.ip+i), tempip, strlen(tempip)+1); } /** Загрузка параметров серийного порта */ /** 0: none, 1: odd, 2: even, 3: space, 4: mark */ rs_parity = cfg_getint(cfg, "RS:prmParity", -1); /** 5 .. 8 */ rs_databits = cfg_getint(cfg, "RS:prmDatabits", -1); /** 1, 2 */ rs_stopbit = cfg_getint(cfg, "RS:prmStopbit", -1); /** Скорость канала RS485 */ rs_speed = cfg_getint(cfg, "RS:speed", -1); /** Длительность одного бита (в микросекундах) вычисляется по формуле: T= 1000000 / V, где V - скорость передачи в бодах. Например, для скорости 19200 бод длительность одного бита составляет 1000000/19200= 52 мкс. */ /** коэффициент для задержки на время передачи по серийному каналу */ utxdel = 1000000 / rs_speed * 10; /** Главная подсистема ЛС 'General' */ sprintf(ls_gen, cfg_getstring(cfg, "LS:gen", NULL)); cdDest = mfnv1a(ls_gen); /** Разрешение на выдачу данных 'AccessGranted' */ sprintf(req_ag, cfg_getstring(cfg, "REQ:ag", NULL)); cdaId = mfnv1a(req_ag); /** Состояние сети RS485 */ sprintf(req_ns, cfg_getstring(cfg, "REQ:ns", NULL)); cdnsId = mfnv1a(req_ns); /** Запрос лога */ sprintf(req_gl, cfg_getstring(cfg, "REQ:gl", NULL)); cdquLogId = mfnv1a(req_gl); /** Состояние магистрали */ sprintf(req_ms, cfg_getstring(cfg, "REQ:ms", NULL)); cdmsId = mfnv1a(req_ms); /** Установка параметров и открытие порта 1 RS485 */ ch1_targ.port = cfg_getint(cfg, "RS485_1:port", -1) - 1; ch1_targ.src = cfg_getint(cfg, "RS485_1:adr", -1); ch1_targ.dst_beg = cfg_getint(cfg, "RS485_1:dstBeg", -1); ch1_targ.dst_end = cfg_getint(cfg, "RS485_1:dstEnd", -1); ch1_enable = cfg_getint(cfg, "RS485_1:enable", -1); if (ch1_enable) { SerialSetParam(ch1_targ.port, rs_parity, rs_databits, rs_stopbit); SerialOpen(ch1_targ.port); SerialSetSpeed(ch1_targ.port, rs_speed); printf("Open port%d, speed= %d\n", ch1_targ.port+1, rs_speed); } else printf("Port1 disabled\n"); /** Установка параметров и открытие порта 2 RS485 */ ch2_targ.port = cfg_getint(cfg, "RS485_2:port", -1) - 1; ch2_targ.src = cfg_getint(cfg, "RS485_2:adr", -1); ch2_targ.dst_beg = cfg_getint(cfg, "RS485_2:dstBeg", -1); ch2_targ.dst_end = cfg_getint(cfg, "RS485_2:dstEnd", -1); ch2_enable = cfg_getint(cfg, "RS485_2:enable", -1); if (ch2_enable) { SerialSetParam(ch2_targ.port, rs_parity, rs_databits, rs_stopbit); SerialOpen(ch2_targ.port); SerialSetSpeed(ch2_targ.port, rs_speed); printf("Open port%d, speed2= %d\n", ch2_targ.port+1, rs_speed); } else printf("Port2 disabled\n"); cfg_free(cfg); /** Выделение памяти под буфер для глобальной таблицы * маршрутов загружаемой с контроллера master */ rtBuf = (unsigned char *)malloc(BO_MAX_TAB_BUF); if(rtBuf == NULL) { bo_log("main() ERROR %s", "can't alloc mem for rtBuf"); return 1; } bo_log("Init ok"); printf("Init ok\n"); if (bo_init_fifo_out(10) == -1) { bo_log("bo_init_fifo_out() ERROR"); return 1; } /** Установка атрибутов функционирования нитей PTHREAD: * - инициализирует структуру, указываемую pattr, значениями "по умолчанию"; * - область действия конкуренции (scope) определяет связность * потока с LWP; * - отсоединенность (detachstate); * - область действия блокировки PTHREAD_PROCESS_PRIVATE. */ pthread_attr_init(&pattr); pthread_attr_setscope(&pattr, PTHREAD_SCOPE_SYSTEM); pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_JOINABLE); pthread_mutex_init(&mx_psv, NULL); pthread_mutex_init(&mx_actFIFO, NULL); pthread_mutex_init(&mx_rtl, NULL); pthread_mutex_init(&mx_rtg, NULL); pthread_mutex_init(&mx_sendSocket, NULL); init_thrState(&psvdata_ready); init_thrState(&psvAnsdata_ready); init_thrState(&actFIFOdata_ready); init_thrRxBuf(&rxBuf); init_thrTxBuf(&txBuf); init_thrDstBuf(&dstBuf); init_thrRxBuf(&rx2Buf); init_thrTxBuf(&tx2Buf); init_thrDstBuf(&dst2Buf); /** Инициализация условных переменных с выделением памяти */ pthread_cond_init(&psvdata, NULL); pthread_cond_init(&psvAnsdata, NULL); pthread_cond_init(&actFIFOdata, NULL); /** Таблицы маршрутов */ rtl = ht_new(0); /** собственный узел */ rtg = ht_new(0); /** внешние узлы */ rtSend_sock = 0; rtRecv_sock = 0; logSend_sock = 0; fifo_idx = 0; log_targ.logSend_ip = logSend_ip; log_targ.logSend_port = logSend_port; result = pthread_create(&thread_log, &pattr, &logSendSock_connect, &log_targ); if (result) { printf("th_log: result = %d: %s\n", result, strerror(errno)); return 1; } rtRecv_targ.ip = rt_ipRecv; rtRecv_targ.port = rt_portRecv; rtRecv_targ.host_ip = ip; result = pthread_create(&thread_rtRecv, &pattr, &rtbl_recv, &rtRecv_targ); if (result) { printf("th_rtRecv: result = %d: %s\n", result, strerror(errno)); return 1; } rtSend_targ.ip = rt_ipSend; rtSend_targ.port = rt_portSend; rtSend_targ.host_ip = ip; result = pthread_create(&thread_rtSend, &pattr, &rtbl_send, &rtSend_targ); if (result) { printf("th_rtSend: result = %d: %s\n", result, strerror(errno)); return 1; } if (snmp_n > 0 && snmp_n <= SNMP_IP_MAX) { snmpSrv_targ.n = snmp_n; printf("ip=%s, n=%d\n", (snmpSrv_targ.ip[0]), snmpSrv_targ.n); result = pthread_create(&thread_snmpSrv, &pattr, &snmp_serv, &snmpSrv_targ); if (result) { printf("th_snmpSrv: result = %d: %s\n", result, strerror(errno)); return 1; } printf("snmp start ok\n"); } fifoSrv_targ.port = fifo_port; result = pthread_create(&thread_fifoSrv, &pattr, &fifo_serv, &fifoSrv_targ); if (result) { printf("th_fifoSrv: result = %d: %s\n", result, strerror(errno)); return 1; } write(1, "fifo start ok\n", 14); sendfifo_targ.port = fifo_port; result = pthread_create(&thread_sendfifo, &pattr, &send_fifo, &sendfifo_targ); if (result) { printf("th_sendfifo: result = %d: %s\n", result, strerror(errno)); return 1; } write(1, "send_fifo start ok\n", 14); ch1_targ.ch1_enable = ch1_enable; ch1_targ.ch2_enable = ch2_enable; ch1_targ.tscan = tscan; ch1_targ.tout = tout; ch1_targ.utxdel = utxdel; ch1_targ.wdt_en = wdt_en; ch1_targ.nretries = nretries; ch1_targ.ip = ip; ch1_targ.fifo_port = fifo_port; ch1_targ.snmp_n = snmp_n; ch1_targ.snmp_uso = snmp_uso; ch1_targ.logMaxLines = logMaxLines; ch1_targ.cdDest = cdDest; ch1_targ.cdaId = cdaId; ch1_targ.cdnsId = cdnsId; ch1_targ.cdquLogId = cdquLogId; ch1_targ.cdmsId = cdmsId; result = pthread_create(&thread_ch1, &pattr, &chan1, &ch1_targ); if (result) { printf("th_ch1: result = %d: %s\n", result, strerror(errno)); return 1; } write(1, "ch1 start ok\n", 13); ch2_targ.ch1_enable = ch1_enable; ch2_targ.ch2_enable = ch2_enable; ch2_targ.tscan = tscan; ch2_targ.tout = tout; ch2_targ.utxdel = utxdel; ch2_targ.wdt_en = wdt_en; ch2_targ.nretries = nretries; ch2_targ.ip = ip; ch2_targ.fifo_port = fifo_port; ch2_targ.snmp_n = snmp_n; ch2_targ.snmp_uso = snmp_uso; ch2_targ.logMaxLines = logMaxLines; ch2_targ.cdDest = cdDest; ch2_targ.cdaId = cdaId; ch2_targ.cdnsId = cdnsId; ch2_targ.cdquLogId = cdquLogId; ch2_targ.cdmsId = cdmsId; result = pthread_create(&thread_ch2, &pattr, &chan2, &ch2_targ); if (result) { printf("th_ch2: result = %d: %s\n", result, strerror(errno)); return 1; } write(1, "ch2 start ok\n", 13); #if defined (__MOXA_TARGET__) && defined (__WDT__) if (wdt_en) { /* set watch dog timer, must be refreshed in 5ms..60s */ wdt_fd = mxwdg_open(wdt_tm); if (wdt_fd < 0) { printf("fail to open the watch dog !: %d [%s]\n", wdt_fd, strerror(errno)); return 1; } init_thrWdtlife(&wdt_life); printf("WatchDog enabled ok\n"); } #endif wdt_targ.wdt_en = wdt_en; wdt_targ.lifeFile = lifeFile; result = pthread_create(&thread_wdt, &pattr, &wdt, &wdt_targ); if (result) { printf("th_wdt: result = %d: %s\n", result, strerror(errno)); return 1; } /** Ожидаем завершения потоков */ if (!pthread_equal(pthread_self(), thread_log)) pthread_join(thread_log, NULL); if (!pthread_equal(pthread_self(), thread_rtRecv)) pthread_join(thread_rtRecv, NULL); if (!pthread_equal(pthread_self(), thread_rtSend)) pthread_join(thread_rtSend, NULL); if (snmp_n > 0 && snmp_n <= SNMP_IP_MAX) if (!pthread_equal(pthread_self(), thread_snmpSrv)) pthread_join(thread_snmpSrv, NULL); if (!pthread_equal(pthread_self(), thread_fifoSrv)) pthread_join(thread_fifoSrv, NULL); if (!pthread_equal(pthread_self(), thread_sendfifo)) pthread_join(thread_sendfifo, NULL); if (!pthread_equal(pthread_self(), thread_ch1)) pthread_join(thread_ch1, NULL); if (!pthread_equal(pthread_self(), thread_ch2)) pthread_join(thread_ch2, NULL); if (!pthread_equal(pthread_self(), thread_wdt)) pthread_join(thread_wdt, NULL); /** Разрушаем блокировки и условные переменные, освобождаем память. */ pthread_mutex_destroy(&mx_psv); pthread_mutex_destroy(&mx_actFIFO); pthread_mutex_destroy(&mx_rtl); pthread_mutex_destroy(&mx_rtg); pthread_mutex_destroy(&mx_sendSocket); destroy_thrRxBuf(&rxBuf); destroy_thrTxBuf(&txBuf); destroy_thrDstBuf(&dstBuf); destroy_thrRxBuf(&rx2Buf); destroy_thrTxBuf(&tx2Buf); destroy_thrDstBuf(&dst2Buf); pthread_cond_destroy(&psvdata); pthread_cond_destroy(&psvAnsdata); pthread_cond_destroy(&actFIFOdata); destroy_thrState(&psvdata_ready); destroy_thrState(&psvAnsdata_ready); destroy_thrState(&actFIFOdata_ready); #if defined (__MOXA_TARGET__) && defined (__WDT__) if (wdt_en) { destroy_thrWdtlife(&wdt_life); mxwdg_close(wdt_fd); } #endif if(rtBuf != NULL) free(rtBuf); rt_free(rtl); rt_free(rtg); return 0; }
int main() { unsigned char buf[255]; int i, len,ret, fd=PORT3, direction; float speed, temperature, avgspeed; printf("Opening serial port..."); ret = SerialOpen(fd); if(ret < 0) { printf("Error: SerialOpen returned: %d\n", ret); SerialClose(fd); return -1; } printf("Done\n"); printf("Setting port speed..."); ret = SerialSetSpeed(fd, 2400); if(ret < 0) { printf("Error: SerialSetSpeed returned: %d\n", ret); SerialClose(fd); return -1; } printf("Done\n"); printf("Setting port parameters..."); ret = SerialSetParam(fd, 0, 8, 1); if(ret < 0) { printf("Error: SerialSetParam returned: %d\n", ret); SerialClose(fd); return -1; } printf("Done\n"); printf("Setting port flow control..."); ret = SerialFlowControl(fd, NO_FLOW_CONTROL); if(ret < 0) { printf("Error: SerialFlowControl returned: %d\n", ret); SerialClose(fd); return -1; } printf("Done\n"); printf("Setting data logger mode..."); ret = SerialWrite(fd, ">I\r", 3); // data logger mode if(ret < 0) { printf("Error: SerialWrite returned: %d\n", ret); SerialClose(fd); return -1; } printf("Done\n"); printf("Waiting for header..."); get_data_header(fd); get_data_header(fd); printf("Found\n"); printf("Waiting for data..."); ret = SerialBlockRead(fd, buf, 50); // read data if(ret < 0) { printf("Error: SerialBlockRead returned: %d\n", ret); SerialClose(fd); return -1; } printf("Found\n"); for(i=0;i<48;i++) { printf("%c\n", buf[i]); } if((buf[48] != 13) && (buf[49] != 10)) { printf("Error: End of data incorrect!\n"); SerialClose(fd); return -1; } //printf("end= %d %d\n", buf[48], buf[49]); ret = SerialWrite(fd, ">\r", 2); SerialClose(fd); speed = (float)get_value(buf, SPEED_OFFSET); speed = speed / 10; speed = speed / 3.6; //(speed * 1.60934) / 3.6; direction = get_value(buf, DIRECTION_OFFSET) & 0x00FFFFFF; // highest byte may be FF sometimes direction = (int)((360.0/255.0) * direction); temperature = (float)get_value(buf, TEMPERATURE_OFFSET); temperature = temperature / 10; temperature = (temperature - 32) * 5 / 9; avgspeed = (float)get_value(buf, AVGSPEED_OFFSET); avgspeed = avgspeed / 10; avgspeed = avgspeed / 3.6; printf("speed=%.1f, direction=%d, temperature=%.1f, avg.speed=%.1f\n", speed, direction, temperature, avgspeed); sprintf(buf, "wget --spider \"%s?speed=%.1f&dir=%d&temp=%.1f&avgspeed=%.1f\"\n", POST_URL, speed, direction, temperature, avgspeed); system(buf); return 0; }