read : 커널 모듈로부터 장문
의 데이터 받기
write : 커널 모듈로에 장문
의 데이터 보내기
app.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
printf("OPEN FILE!!\n");
int fd = open("/dev/nobrand", O_RDWR); // 읽기 쓰기 둘가 가능 모드로 설정
if (fd == -1) {
printf("FILE OPEN ERROR!!!\n");
return 0;
}
//write
write(fd, "Let's go\n", 7);
//read
char buf[100];
read(fd, buf, 100);
printf("%s\n", buf);
printf("%s\n", buf);
printf("CLOSE FILE!!\n");
close(fd);
return 0;
}
nobrand.c
#include <linux/module.h>
#include <linux/fs.h>
#define NOD_NAME "nobrand"
#define NOD_MAJOR 100
MODULE_LICENSE("GPL");
static int nobrand_open(struct inode *inode, struct file *filp) {
printk( KERN_INFO "OPEN!!!\n");
return 0;
}
static int nobrand_release(struct inode *inode, struct file *filp) {
printk( KERN_INFO "CLOSE!!!\n");
return 0;
}
static ssize_t nobrand_read(struct file *filp, char *buf, size_t count, loff_t *ppos) {
buf[0] = 'H';
buf[1] = 'I';
buf[2] = '\0';
return count;
}
static ssize_t nobrand_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
{
printk( KERN_INFO "HIHI\n\n");
printk( KERN_INFO "app message : %s\n", buf);
return count;
}
static struct file_operations fops = {
.open = nobrand_open,
.release = nobrand_release,
.read = nobrand_read,
.write = nobrand_write
};
static int nobrand_init(void) {
printk( KERN_INFO "OK HELLO NOBRAND!!\n");
if (register_chrdev(NOD_MAJOR, NOD_NAME, &fops) < 0) {
printk( KERN_INFO "ERROR!!! register error\n");
}
return 0;
}
static void nobrand_exit(void) {
unregister_chrdev(NOD_MAJOR, NOD_NAME);
printk( KERN_INFO "BYE BYE\n\n");
}
module_init(nobrand_init);
module_exit(nobrand_exit);
ioctl : 만능, read/write 둘다 가능, 대신 가독성 떨어짐
또한 ioctl은 값 하나
의 데이터를 보내고 받을 수 있다.
장문의 데이터를 송수신하려면 copy_from_user()
와 같은 커널함수를 추가 작성해줘야 한다.
app.c
에 추가
#include <sys/ioctl.h>
ioctl(fd, 3, 0); // 3 전송
ioctl(fd, 4, 0); // 4 전송
nobrand.c
에 추가
static long nobrand_ioctl(struct file *flip, unsigned int cmd, unsigned long arg)
{
printk( KERN_ALERT "%d\n", cmd); // 3과 4 커널 로그에 찍음
return 0;
}
static struct file_operations fops = {
.open = nobrand_open,
.release = nobrand_release,
.read = nobrand_read,
.write = nobrand_write,
.unlocked_ioctl = nobrand_ioctl
};
Native 환경 개발
: 개발할 장치 OS에서 코딩하는 것으로, Device Driver와 App을 개발할 때는 유용하다.Cross Compile
: 개발 PC 개발 후 Target 보드로 옮겨 테스트하며 개발하는 것으로, Kernel 혹은 규모가 큰 Device Driver와 App을 개발할 때 유용하다.참고 : intel CPU 컴파일러를 통해 나온 실행파일은 ARM Core에서 작동되지 않는다. 따라서, ARM 컴파일러를 통해 실행파일을 만들면 된다.