LVS
/*
 * Building: cc -o com com.c
 * Usage   : ./com /dev/device [speed]
 * Example : ./com /dev/ttyS0 [115200]
 * Keys    : Ctrl-A - exit, Ctrl-X - display control lines status
 * Darcs   : darcs get http://tinyserial.sf.net/
 * Homepage: http://tinyserial.sourceforge.net //원작자 사이트
 * Version : 2009-03-05
 *
 * Ivan Tikhonov, http://www.brokestream.com, kefeer@brokestream.com
 * Patches by Jim Kou, Henry Nestler, Jon Miner, Alan Horstmann
 *
 */


/* Copyright (C) 2007 Ivan Tikhonov

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.

  Ivan Tikhonov, kefeer@brokestream.com

*/

#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>

int transfer_byte(int from, int to, int is_control);

typedef struct {char *name; int flag; } speed_spec;


void print_status(int fd) {
int status;
unsigned int arg;
status = ioctl(fd, TIOCMGET, &arg);
fprintf(stderr, "[STATUS]: ");
if(arg & TIOCM_RTS) fprintf(stderr, "RTS ");
if(arg & TIOCM_CTS) fprintf(stderr, "CTS ");
if(arg & TIOCM_DSR) fprintf(stderr, "DSR ");
if(arg & TIOCM_CAR) fprintf(stderr, "DCD ");
if(arg & TIOCM_DTR) fprintf(stderr, "DTR ");
if(arg & TIOCM_RNG) fprintf(stderr, "RI ");
fprintf(stderr, "\r\n");
}


int main(int argc, char *argv[])
{
int comfd;
struct termios oldtio, newtio;       //place for old and new port settings for serial port
struct termios oldkey, newkey;       //place tor old and new port settings for keyboard teletype
char *devicename = argv[1];
int need_exit = 0;
speed_spec speeds[] =
{
{"1200", B1200},
{"2400", B2400},
{"4800", B4800},
{"9600", B9600},
{"19200", B19200},
{"38400", B38400},
{"57600", B57600},
{"115200", B115200},
{NULL, 0}
};
int speed = B9600;

if(argc < 2) {
fprintf(stderr, "example: %s /dev/ttyS0 [115200]\n", argv[0]);
exit(1);
}

comfd = open(devicename, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (comfd < 0)
{
perror(devicename);
exit(-1);
}

if(argc > 2) {
speed_spec *s;
for(s = speeds; s->name; s++) {
if(strcmp(s->name, argv[2]) == 0) {
speed = s->flag;
fprintf(stderr, "setting speed %s\n", s->name);
break;
}
}
}

fprintf(stderr, "C-a exit, C-x modem lines status\n");

tcgetattr(STDIN_FILENO,&oldkey);
newkey.c_cflag = B9600 | CRTSCTS | CS8 | CLOCAL | CREAD;
newkey.c_iflag = IGNPAR;
newkey.c_oflag = 0;
newkey.c_lflag = 0;
newkey.c_cc[VMIN]=1;
newkey.c_cc[VTIME]=0;
tcflush(STDIN_FILENO, TCIFLUSH);
tcsetattr(STDIN_FILENO,TCSANOW,&newkey);


tcgetattr(comfd,&oldtio); // save current port settings 
newtio.c_cflag = speed | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
newtio.c_lflag = 0;
newtio.c_cc[VMIN]=1;
newtio.c_cc[VTIME]=0;
tcflush(comfd, TCIFLUSH);
tcsetattr(comfd,TCSANOW,&newtio);

print_status(comfd);
    
while(!need_exit) {
fd_set fds;
int ret;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
FD_SET(comfd, &fds);


ret = select(comfd+1, &fds, NULL, NULL, NULL);
if(ret == -1) {
perror("select");
} else if (ret > 0) {
if(FD_ISSET(STDIN_FILENO, &fds)) {
need_exit = transfer_byte(STDIN_FILENO, comfd, 1);
}
if(FD_ISSET(comfd, &fds)) {
need_exit = transfer_byte(comfd, STDIN_FILENO, 0);
}
}

    }

tcsetattr(comfd,TCSANOW,&oldtio);
tcsetattr(STDIN_FILENO,TCSANOW,&oldkey);
close(comfd);

return 0;
}


int transfer_byte(int from, int to, int is_control) {
    char c;
int ret;
do {
ret = read(from, &c, 1); 
} while (ret < 0 && errno == EINTR);
if(ret == 1) {
if(is_control) {
if(c == '\x01') { // C-a
return -1;
} else if(c == '\x18') { // C-x
print_status(to);
return 0;
}
}
while(write(to, &c, 1) == -1) {
if(errno!=EAGAIN && errno!=EINTR) { perror("write failed"); break; }
}
} else {
fprintf(stderr, "\nnothing to read. probably port disconnected.\n");
return -2;
}
   struct tm *time_struct;
    time_t local;

    (void)time(&local);
    time_struct=localtime(&local);
    FILE *fp;
    fp =fopen("watt.txt", "a+");
  if(c == '\r'){fprintf(fp, "[%02d-%02d-%02d %02d:%02d:%02d] ",time_struct->tm_year+1900,time_struct->tm_mon+1, time_struct->tm_mday, time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);}
       else{fprintf(fp, "%c", c);}
    fclose(fp);
  
    return 0;
}



Download: com.c   // <------- 원본 소스
Building: cc -o com com.c
Usage   : ./com /dev/device [speed]  // <-------- 사용방법
Example : ./com /dev/ttyS0 [115200]   //<-------- 예를들어서 이렇게( HPM-100A  경우 .com /dev/ttyUSB0 [9600]
Keys    : Ctrl-A - exit, Ctrl-X - display control lines status
Darcs   : darcs get http://tinyserial.sf.net/
Scr.shot: screenshot.png (8862 bytes)
형광펜 부분이 추가해준 소스 입니다.
추가해준 내용은 TIME 정보를 추가해주었습니다.
S //  start 
22003Vo //전압
10003Am //전류
22002Wa //와트
10001Pf //역률
60001Hz //주파수
E //  end
[2010-01-01 01:01:01] //시간

실제 실행 결과 
S:  21693Vo:  42412Am:  46461Wa:     21Wh:   5051Pf:  59981Hz:     01Kg:     01Eu  E[2011-01-05 07:57:32] 
S:  21693Vo:  42422Am:  46481Wa:     31Wh:   5051Pf:  59981Hz:     01Kg:     01Eu  E[2011-01-05 07:57:33] 
S:  21693Vo:  42422Am:  46481Wa:     31Wh:   5051Pf:  59971Hz:     01Kg:     01Eu  E[2011-01-05 07:57:33] 
S:  21693Vo:  42432Am:  46461Wa:     41Wh:   5041Pf:  59971Hz:     01Kg:     01Eu  E[2011-01-05 07:57:34] 




추가한 소스 분석
(형광펜 부분)
#include <time.h>  // 시간 함수를 사용하기 위한  header 파일
struct tm *time_struct;
/*
struct tm  //  time.h에 정의되어있는 tm  구조체 내부
134 {
135   int tm_sec;           /* Seconds. [0-60] (1 leap second) */
136   int tm_min;           /* Minutes. [0-59] */
137   int tm_hour;          /* Hours.   [0-23] */
138   int tm_mday;          /* Day.     [1-31] */
139   int tm_mon;           /* Month.   [0-11] */
140   int tm_year;          /* Year - 1900.  */ // 1990년 이후 경과 년수를 의미한다,
141   int tm_wday;          /* Day of week. [0-6] */ // 0은 일요일 ~ 6은 토요일을 의미
142   int tm_yday;          /* Days in year.[0-365] */
143   int tm_isdst;         /* DST.     [-1/0/1]*/
144 
145 #ifdef  __USE_BSD
146   long int tm_gmtoff;       /* Seconds east of UTC.  */
147   __const char *tm_zone;    /* Timezone abbreviation.  */
148 #else
149   long int __tm_gmtoff;     /* Seconds east of UTC.  */
150   __const char *__tm_zone;  /* Timezone abbreviation.  */
151 #endif
152 };
*/
time_t local;  //  time_t 시분초일월을 모두 숫자로 압축한 시간 전용 자료형이다.

(void)time(&local); //1970년 1월 1일 0시 후 경과된 초를 조사합니다.
 time_struct=localtime(&local); // time_t 형의 값을  tm  구조체형태로 변환 시켜준다.
 FILE *fp;
 fp =fopen("watt.txt", "a+"); //파일을 열되 마지막 위치한 부분부터 추가
 if(c == '\r'){ //엔터의 아스키 코드값이 '\r'이 들어오면 실행하라는 의미
//현재 시간을 연산해서 보여준다.
fprintf(fp, "[%02d-%02d-%02d %02d:%02d:%02d] ",time_struct->tm_year+1900,time_struct->tm_mon+1, time_struct->tm_mday, time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);}
else{     
fprintf(fp, "%c", c);  //시리얼 통신으로 들어오는 문자를 파일에 저장해준다.
}
    fclose(fp);
 

New Post