2장 : 커널 내부 탐험 - 김석구
2011. 1. 5. 13:12발표일시 : 2011.01.03(월)
발표자 : 김석구
발표내용:
¨ 시동
¨ 커널모드와 유저모드
¨ 프로세스 문맥과 언터럽트 문맥
¨ 커널 타이머
¨ 커널 동시성
¨ 프로세스 파일 시스템
¨ 메모리 할당하기
'BooK > 코드로 읽는 디바이스 드라이버' 카테고리의 다른 글
3장 커널 기능 -강남용- (1) | 2011.01.05 |
---|
3장 커널 기능 -강남용-
2011. 1. 5. 13:01
발표일시 : 2011.01.03(월)
발표자 : 강남용
발표내용:
커널 스레드
- 스레드란?
- 스레드 종류
도우미 인터페이스
- 연결 리스트
- 해시 리스트
- 작업 큐
- 통지 연쇄
- 완료 인터페이스
- kthread 도우미
- 오류 처리 지원
'BooK > 코드로 읽는 디바이스 드라이버' 카테고리의 다른 글
2장 : 커널 내부 탐험 - 김석구 (1) | 2011.01.05 |
---|
HPM 100-A(전력측정기)에서 시리얼 통신으로 데이타 값 받아오기.
2011. 1. 4. 23:09
/*
* 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]*/144145 #ifdef __USE_BSD146 long int tm_gmtoff; /* Seconds east of UTC. */147 __const char *tm_zone; /* Timezone abbreviation. */148 #else149 long int __tm_gmtoff; /* Seconds east of UTC. */150 __const char *__tm_zone; /* Timezone abbreviation. */151 #endif152 };*/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);
'LVS' 카테고리의 다른 글
IPVS Configuration : DR (Direct Routing) (0) | 2010.12.29 |
---|---|
LVS 구축에 관한 이론 (NAT 부터 WLC 까지) (2) | 2010.12.23 |
RR 알고리즘 개선 -> N번째 N번 부하 분산 (0) | 2010.12.20 |
커널 소켓 프로그래밍 (0) | 2010.11.20 |
모듈 프로그래밍 (1) | 2010.11.10 |