TextLCD 디바이스.

Slides:



Advertisements
Similar presentations
제10장 디바이스 드라이버.
Advertisements

KEY 디바이스 드라이버 Lecture #12. 2 차례 GPIO 및 Control Registers KEY 하드웨어 구성 KEY Driver 프로그램 key-driver.c 시험 응용 프로그램 key-app.c.
패러럴 포트를 이용한 Text LCD 제어 6월 17일 허정수 나선웅.
FND 디바이스 드라이버 Lecture #13.
5장. Enhanced Char Driver Operations 과제
2장. 프로그램의 기본 구성. 2장. 프로그램의 기본 구성 2-1"Hello, World!" 들여다 보기 /* Hello.c */ #include int main(void) { printf("Hello, World! \n"); return 0;
인공지능실험실 석사 2학기 이희재 TCP/IP Socket Programming… 제 11장 프로세스간 통신 인공지능실험실 석사 2학기 이희재
공유메모리 int shmget(key_t key, size_t size, int permflags);
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
FND 디바이스 드라이버 Lecture #11.
Cross Compiler를이용한 커널 컴파일 및 포팅
RnA DISPLAY 구동 Clcd 구동 Made by Bonobonobono.
08. 디바이스 드라이버의 읽기와 쓰기 김진홍
디바이스 드라이버 기초 디바이스 드라이버의 개요 파일 연산 디바이스 드라이버 등록 디바이스 드라이버 구성
디바이스 드라이버 응용 디바이스와 주소 디바이스 드라이버 구현 일반 LED 디바이스 드라이버 FND 디바이스 드라이버
디바이스 드라이버.
이식성과 데이터형 서로 다른 프로세서 상에서의 이식성을 위해 가급적 리눅스 커널이 제공하는 데이터형을 사용하는 것이 좋다.
디바이스 드라이버 개요 가상 디바이스드라이버 실습
QT 프로그래밍 발표: 김래영.
Text LCD control.
UNIT 07 Memory Map 로봇 SW 교육원 조용수.
FND (Flexible Numeric Display)
Step Motor Device Driver
양방향 파이프의 활용 양방향 통신 파이프는 기본적으로 단방향이므로 양방향 통신을 위해서는 파이프를 2개 생성한다.
Input/Output Control.
리눅스 커널과 디바이스드라이버.
07. 디바이스 드라이버의 초기화와 종료 김진홍
목 차 물리주소와 가상주소 mmap() 함수를 이용한 I/O 제어 커널 프로그래밍 리눅스 디바이스 드라이버
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
SqlParameter 클래스 선문 비트 18기 발표자 : 박성한.
컴퓨터 프로그래밍 기초 #02 : printf(), scanf()
WinCE Device Driver 실습 #4
파일 기술자 파일 기술자 현재 열려있는 파일을 구분하는 정수값 저수준 파일 입출력에서 열린 파일을 참조하는데 사용
임베디드 실습 # LED, 7’Segment 제어
메시지 큐[5] – test1.c 메시지 제어: msgctl(2) #include <sys/msg.h>
WinCE Device Driver 실습 #3
WinCE Device Driver 실습 #2
커널 모듈 프로그래밍 (Kernel Module Programming)
LCD 모듈의 특징 LCD 컨트롤러 내장으로 모든 디스플레이 기능을 명령어로 제어 8비트 혹은 4비트로 인터페이스
DK-128 실습 EEPROM 제어 아이티즌 기술연구소
HBE-SMIII-SV210 리눅스 커널과 디바이스 드라이버
파일 접근권한 제어 stat 구조체의 st_mode 항목에 파일의 종류와 접근권한 정보저장 st_mode 값의 구조.
Cross Compiler를이용한 커널 컴파일 및 포팅
사용자 함수 사용하기 함수 함수 정의 프로그램에서 특정한 기능을 수행하도록 만든 하나의 단위 작업
문자 디바이스 드라이버 임베디드 시스템.
UNIT 07 Memory Map 로봇 SW 교육원 조용수.
3장 상수 변수 기본 자료형 키워드와 식별자 상수와 변수 기본 자료형 형변환 자료형의 재정의.
Device Driver 임베디드 시스템 I.
영상처리 실습 인공지능연구실.
19. 함수 포인터와 void 포인터.
임베디드 시스템 개론 임베디드 타겟 보드 포팅 및 H/W 제어 3일차 강의 자료 Embedded System Lab.
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
리눅스 디바이스 드라이버 (Linux Device Driver)
DK-128 실습 내부 EEPROM 제어 아이티즌 기술연구소 김태성 연구원
패러럴 포트를 이용한 Text LCD 제어 6월 17일 허정수 나선웅.
Stepper Motor 디바이스 드라이버
컴퓨터 프로그래밍 기초 - 8th : 함수와 변수 / 배열 -
스마트폰을 이용한 조명제어 ㈜ 성림 M&C
컴퓨터 계측 및 실습 디지털 출력 영남대학교 기계공학부.
계산기.
Fucntion 요약.
WinCE Device Driver 실습 #4
LCD.
DK-128 개발환경 설정 아이티즌 기술연구소 김태성 연구원
DK-128 개발환경 설정 아이티즌 기술연구소
3. 모듈 (5장. 모듈).
구조체(struct)와 공용체(union)
실습과제 (변수와 자료형, ) 1. 다음 작업 (가), (나), (다)를 수행하는 프로그램 작성
06. 디바이스의 등록과 해제 김진홍
WinCE Device Driver 실습 #4
Presentation transcript:

TextLCD 디바이스

TextLCD 디바이스 TextLCD HBE-SM III-SV210의 TextLCD 영문자와 숫자 일본어, 특수문자를 표현하여 정보를 전달하는데 사용되는 디바이스이다. HBE-SM III-SV210의 TextLCD 16문자*2라인을 Display TextLCD를 제어하기 위하여 FPGA 내부에 Controller가 설계되어 있다

TextLCD 디바이스 TextLCD Control Register의 데이터 비트 구조를 나타낸 표 Physical Address 0x8800_0010 CLCD_Ctrl_Reg BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 Reserved CLCD_RS CLCD_RW CLCD_E CLCD_D7 CLCD_D6 CLCD_D5 CLCD_D4 CLCD_D3 CLCD_D2 CLCD_D1 CLCD_D0 Reset X Bits Name Description CLCD Data Bit 0 CLCD Data Bit 1 CLCD Data Bit 2 CLCD Data Bit 3 CLCD Data Bit 4 CLCD Data Bit 5 CLCD Data Bit 6 CLCD Data Bit 7 CLCD Enable Bit (Active High) CLCD Read/Write Control Bit (‘1’read, ‘0’Write) CLCD Data Instruction Register Set

TextLCD 디바이스 TextLCD 모듈의 제어 명령표 기 능 제어 신호 제어 명령 (D0 ~ D7) 실행 시간 RS R/W 6 5 4 3 2 1 Clear Display 1.64ms Return Home 40us Entry Mode Set I/D S Display on/off control D C Cursor or Display Shift S/C R/L Function Set D/L N F Set CG RAM Address CG RAM Address Set DD RAM Address DD RAM Address Read Busy Flag and Address BF Address Counter Data Write to CG RAM or DD RAM Write Address Data Read to CG RAM or DD RAM Read Address

디바이스 드라이버 textlcd.ko

Devide Driver textlcd textlcd.c modules.order Makefile lcdtest.c – LCD 테스트 어플리케이션

Makefile # # Makefile for TextLCD Device Driver # Hanback Electronics Co.,ltd CC = arm-linux-gcc obj-m := textlcd.o KDIR := /Android/linux-2.6.35-hanback PWD := $(shell pwd) TEST_TARGET = lcdtest TEST_SRCS = lcdtest.c default:$(TEST_TARGET) $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules $(CC) -o $(TEST_TARGET) $(TEST_SRCS) rm -f default clean: rm -f *.ko rm -f *.o rm -f *.mod.* rm -f .*. rm -f $(TEST_TARGET)

textlcd.c(#1) /* * TextLCD Device Driver * Hanback Electronics Co.,ltd * File : textlcd.c * Date : April,2009 */ // 모듈의 헤더파일 선언 #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/ioport.h> #include <asm/io.h> #include <asm/ioctl.h> #include <asm/uaccess.h> #include <linux/delay.h>

textlcd.c(#2) #include "textlcd.h" #define SET_1 1 #define SET_2 1 #define SET_3 1 #define WRI_1 1 #define WRI_2 1 #define WRI_3 1 // 디바이스 드라이버 내부에서 사용하는 함수 // 이 함수에 명령값 command를 인자로 실행하면 TextLCD에 명령이 실행된다. void setcommand(unsigned short command) { command &= 0x00FF; *textlcd_ioremap = command | 0x0000; mdelay(1); *textlcd_ioremap = command | 0x0100; }

textlcd.c(#3) // TextLCD에 문자를 출력하는 함수 // ch에 표시하고자 하는 문자값을 입력해서 이 함수를 실행하면 TextLCD에 나타난다. void writebyte(char ch) { unsigned short data; data = ch & 0x00FF; *textlcd_ioremap = data & 0x400; mdelay(1); *textlcd_ioremap = data | 0x500; *textlcd_ioremap = data | 0x400; } // TextLCD를 초기화 하는 함수 void initialize_textlcd() function_set(2,0); //Function Set:8bit,display 2l ines,5x7 mod display_control(1,0,0); // Display on, Cursor off clear_display(); // Display clear entry_mode_set(1,0); // Entry Mode Set : shift right cursor return_home(); // go home

// TextLCD를 두 줄로 표시할지와 폰트 크기를 정하는 함수 int function_set(int rows, int nfonts) { unsigned short command = 0x30; if(rows == 2) command |= 0x08; else if(rows == 1) command &= 0xf7; else return -1; command = nfonts ? (command | 0x04) : command; setcommand(command); return 1; } // TextLCD의 표시방법과 커서를 보이게 할 것인지에 대한 설정함수 int display_control(int display_enable, int cursor_enable, int nblink) unsigned short command = 0x08; command = display_enable ? (command | 0x04) : command; command = cursor_enable ? (command | 0x02) : command; command = nblink ? (command | 0x01) : command;

// 표시된 문자들을 쉬프트하는 함수 int cursor_shift(int set_screen, int set_rightshit) { unsigned short command = 0x10; command = set_screen ? (command | 0x08) : command; command = set_rightshit ? (command | 0x04) : command; setcommand(command); return 1; } // TextLCD의 모드를 지정하는 함수 int entry_mode_set(int increase, int nshift) unsigned short command = 0x04; command = increase ? (command | 0x2) : command; command = nshift ? ( command | 0x1) : command;

// TextLCD의 커서를 홈으로 옮기는 함수 int return_home() { unsigned short command = 0x02; setcommand(command); return 1; } // TextLCD의 화면을 지우는 함수 int clear_display() unsigned short command = 0x01; // TextLCD의 ddram의 주소를 설정하는 함수 int set_ddram_address(int pos) unsigned short command = 0x80; command += pos;

// open() 함수를 이용하여 디바이스 드라이버가 열린 경우 호출되는 함수 static int textlcd_open(struct inode *minode, struct file *mfile) { // 디바이스가 열려 있는지 확인. if(textlcd_usage != 0) return -EBUSY; // 가상주소 매핑 textlcd_ioremap= (unsigned short *)ioremap(TEXTLCD_ADDRESS,TEXTLCD_ADDRESS_RANGE); // 등록할 수 있는 I/O 영역인지 확인 if(!check_mem_region((unsigned long)textlcd_ioremap,TEXTLCD_ADDRESS_RANGE)) // I/O 메모리 영역을 등록 request_mem_region((unsigned long)textlcd_ioremap,TEXTLCD_ADDRESS_RANGE,TEXTLCD_NAME); } else printk(KERN_WARNING"Can't get IO Region 0x%x\n",TEXTLCD_ADDRESS); textlcd_usage = 1; initialize_textlcd(); return 0;

// 응용 프로그램에서 디바이스를 더이상 사용하지 않아서 닫기를 구현하는 함수 static int textlcd_release(struct inode *minode, struct file *mfile) { // 매핑된 가상주소를 해제 iounmap(textlcd_ioremap); // 등록된 I/O 메모리 영역을 해제 release_mem_region((unsigned long)textlcd_ioremap,TEXTLCD_ADDRESS_RANGE); textlcd_usage = 0; return 0; }

// 디바이스 드라이버의 쓰기를 구현하는 함수 static ssize_t textlcd_write(struct file // 디바이스 드라이버의 쓰기를 구현하는 함수 static ssize_t textlcd_write(struct file *inode, const char*gdata, size_t length, loff_t *off_what) { int i,ret; char buf[100]; // 사용자 메모리 gdata를 커널 메모리 buf에 length만큼 복사 ret=copy_from_user(buf,gdata,length); if(ret < 0) return -1; for(i=0;i<length;i++) { writebyte(buf[i]); } return length;

//read()와 write()로 구현하기 곤란한 디바이스 드라이버의 입출력 처리를 구현하는 함수 static int textlcd_ioctl(struct inode *inode, struct file *file,unsigned int cmd,unsigned long gdata) { struct strcommand_varible strcommand; int ret; // 사용자 메모리 gdata를 커널 메모리 strcommand로 32바이트 복사 ret=copy_from_user(&strcommand,(char *)gdata,32); if(ret<0) return -1; switch(cmd){ case TEXTLCD_COMMAND_SET: setcommand(strcommand.command); break; case TEXTLCD_FUNCTION_SET: function_set((int)(strcommand.rows+1),(int)(strcommand.nfonts)); case TEXTLCD_DISPLAY_CONTROL: display_control((int)strcommand.display_enable, (int)strcommand.cursor_enable,(int)strcommand.nblink);

case TEXTLCD_CURSOR_SHIFT: cursor_shift((int)strcommand case TEXTLCD_CURSOR_SHIFT: cursor_shift((int)strcommand.set_screen,(int)strcommand.set_rightshit); break; case TEXTLCD_ENTRY_MODE_SET: entry_mode_set((int)strcommand.increase,(int)strcommand.nshift); case TEXTLCD_RETURN_HOME: return_home(); case TEXTLCD_CLEAR: clear_display(); case TEXTLCD_DD_ADDRESS: set_ddram_address((int)strcommand.pos); case TEXTLCD_WRITE_BYTE: writebyte(strcommand.buf[0]); default: printk("driver : no such command!\n"); return -ENOTTY; } return 0;

// 파일 오퍼레이션 구조체 // 파일을 열때 open()을 사용한다. open()는 시스템 콜을 호출하여 커널 내부로 들어간다. // 해당 시스템 콜과 관련된 파일 연산자 구조체 내부의 open에 해당하는 필드가 드라이버 내에서 // textlcd_open()으로 정의되어 있으므로 textlcd_open()가 호출된다. // 만약 등록되지 않은 동작에 대해서는 커널에서 정의해 놓은 default 동작을 하도록 되어 있다. static struct file_operations textlcd_fops = { .owner = THIS_MODULE, .open = textlcd_open, .write = textlcd_write, .ioctl = textlcd_ioctl, .release = textlcd_release, };

// 모듈을 커널 내부로 삽입 // 모듈 프로그램의 핵심적인 목적은 커널 내부로 들어가서 서비스를 제공받는 것이므로 // 커널 내부로 들어가는 init()을 먼저 시작한다. // 응용 프로그램은 소스 내부에서 정의되지 않은 많은 함수를 사용한다. 그것은 외부 // 라이브러리가 컴파일 과정에서 링크되어 사용되기 때문이다. 모듈 프로그램은 커널 // 내부하고만 링크되기 때문에 커널에서 정의하고 허용하는 함수만을 사용할 수 있다. int textlcd_init(void) { int result; // 문자 디바이스 드라이버를 등록한다. result = register_chrdev(TEXTLCD_MAJOR,TEXTLCD_NAME,&textlcd_fops); if(result < 0) { printk(KERN_WARNING"Can't get any major\n"); return result; } // major 번호를 출력한다. printk(KERN_INFO"Init Module, TextLCD Major Number : %d\n",TEXTLCD_MAJOR); return 0;

// 모듈을 커널에서 제거 void textlcd_exit(void) { // 문자 디바이스 드라이버를 제거한다 // 모듈을 커널에서 제거 void textlcd_exit(void) { // 문자 디바이스 드라이버를 제거한다. unregister_chrdev(TEXTLCD_MAJOR,TEXTLCD_NAME); printk("driver: %s DRIVER EXIT\n", TEXTLCD_NAME); } module_init(textlcd_init); // 모듈 적재 시 호출되는 함수 module_exit(textlcd_exit); // 모듈 제거 시 호출되는 함수 MODULE_AUTHOR(DRIVER_AUTHOR); // 모듈의 저작자 MODULE_DESCRIPTION(DRIVER_DESC);// 모듈에 대한 설명 MODULE_LICENSE("Dual BSD/GPL"); // 모듈의 라이선스 등록

module.order kernel//Android/device_drivers/243.textlcd_driver/textlcd.ko

Application(lcdtest .c) #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #define TEXTLCD_BASE 0xbc #define TEXTLCD_COMMAND_SET _IOW(TEXTLCD_BASE,0,32) #define TEXTLCD_FUNCTION_SET _IOW(TEXTLCD_BASE,1,32) #define TEXTLCD_DISPLAY_CONTROL _IOW(TEXTLCD_BASE,2,32) #define TEXTLCD_CURSOR_SHIFT _IOW(TEXTLCD_BASE,3,32) #define TEXTLCD_ENTRY_MODE_SET _IOW(TEXTLCD_BASE,4,32) #define TEXTLCD_RETURN_HOME _IOW(TEXTLCD_BASE,5,32) #define TEXTLCD_CLEAR _IOW(TEXTLCD_BASE,6,32) #define TEXTLCD_DD_ADDRESS _IOW(TEXTLCD_BASE,7,32) #define TEXTLCD_WRITE_BYTE _IOW(TEXTLCD_BASE,8,32)

struct strcommand_varible { char rows; char nfonts; char display_enable; char cursor_enable; char nblink; char set_screen; char set_rightshit; char increase; char nshift; char pos; char command; char strlength; char buf[20]; };

int main(int argc, char **argv) { int dev; struct strcommand_varible strcommand; strcommand.pos = 0x40; dev = open("/dev/textlcd", O_WRONLY|O_NDELAY ); if (dev != -1) write(dev,"Welcome !",15); ioctl(dev,TEXTLCD_DD_ADDRESS,&strcommand,32); write(dev,"Hello Embedded! ",15); close(dev); } else { printf( "application : Device Open ERROR!\n"); exit(-1); return(0);

컴파일(Compile) make 우분투 터미널 창에서 경로 : /Android/device_drivers/243.textlcd_driver# 안에서 make

임베디드 보드로 옮기기 [STEP] #cd /Android/driver/243.textlcd_driver [STEP1] #cp textlcd.ko /tftpboot/ [STEP2] #cp lcdtest /tftpboot/ [STEP3] 보드 전원과 시리얼 케이블 연결확인 !! (minicom 실행 후 시리얼 모니터 확인 !!)

Tftp 이용 드라이버 받기 [먼저] Ubuntu 의 Host IP 확인 하기.. $tftp –r lcdtext.ko –g 192.168.123.100

Tftp 이용 어플리케이션 받기 [먼저] Ubuntu 의 Host IP 확인 하기.. $tftp –r lcdtest –g 192.168.123.100

파일 확인 실행 권한 변경 $ls $chmod 777 lcdtest

드라이버 모듈 올리고 확인하기 $insmod textlcd.ko <- 드라이버 모듈 올리기 $lsmod <- 드라이버 모듈 확인

Insmod ? Sys_create_module() 을 사용 드라이버 메모리 할당 Sys_get_kernel_syms()이용 드라이버 심볼을 커널에 등록 sys_init_module() 을 이용 메모리에 적재 Init_module() 실행 , register_chrdev() 가 수행 드라이버 이름과 메이저 번호와 file_operations 구조체를 커널 변수인 chrdevs 에 등록한다.

장치 노드 만들기(mknod) [형식] mknod /dev/device c [주번호] [부번호] 응용프로그램에서 장치노드를 오픈하여 사용한다. $mknod /dev/textlcd c 243 0 <- 노드생성 $cat /proc/devices <- 드라이버 포트 확인

드라이버 테스트하기 $./lcdtest

어플리케이션 프로그램 과제 [과제1] lcdtest.c 소스를 수정해서 1번줄에 성 2번째 줄에 이름을 쓰세요. [과제2] buzzer 제어 어플리케이션을 만드세요. 명령 ) buzzertest 0 <- buzzer off buzzertest 1 <- buzzer on Tip : /Android/driver/248.buzzer_driver 에 있는.. > Makefile 을 수정한다. (기존에 Makefile 을 복사..) > buzzertest.c 를 새롭게 작성한다. ( ledtest.c 의 내용을 복사한 후 장치 open 하는 부문을 /dev/buzzer 로 바꾼다. )

Buzzer 디바이스 드라이버 Make File CC = arm-linux-gcc obj-m := buzzer.o KDIR := /Android/linux-2.6.35-hanback PWD := $(shell pwd) TEST_TARGET = buzzertest TEST_SRCS = buzzertest.c default: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules #$(CC) $(TEST_SRCS) -I$(KDIR)/include -o $@ $(CC) -o $(TEST_TARGET) $(TEST_SRCS) rm -f default clean: rm -f *.ko rm -f *.o rm -f *.mod.* rm -f .*.cmd rm -f $(TEST_TARGET)수정하기..

Buzzertest.c (1/2) #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(int argc, char **argv) { int dev; char buff; // 아규먼트가 1개 이상이어야 한다. if(argc <= 1) { printf("please input the parameter ! ex)./buzzer 0 or 1 \n"); exit(1); } // 디바이스 드라이버 열기 dev = open("/dev/buzzer", O_WRONLY);

Buzzertest.c (2/2) if(dev != -1) { if(argv[1][0] == '0' && (argv[1][1] == 'x' || argv[1][1] == 'X')) { buff = (unsigned char)strtol(&argv[1][2],NULL,16); } // ledtest 0x 가 없이 ledtest 12 로 입력하면 12를 정수로 변환하여 출력 else { buff = atoi(argv[1]); write(dev,&buff,8) ; close(dev); } else { printf("Device Driver Open Error ! \n"); exit(1); return 0; // 정수형 main 함수 이므로 정수값을 리턴해 주어야 한다.