字元類型驅動程式
V1.1
email: mesmerli@hotmail.com
什麼是字元類型驅動程式
Linux 的驅動程式可區分為以下三種類型:
- 字元類型驅動程式-> I/O 驅動程式 -> 磁碟與網路驅動程式之外的驅動程式
- 區塊類型驅動程式-> 磁碟驅動程式
- 網路類型驅動程式-> 網路驅動程式
LED 驅動程式實驗步驟
Host 端
-
root file system 組態設定。
-
建構新的 root file system (RAMDISK)
- dd if=/dev/zero of=ext2new bs=1k count=8192
- mke2fs -F -m0 -i 2000 ext2new
- mount -w -o loop ext2new /mnt/loop
- mount -w -o loop ext2_2418_Creator2410 /mnt/looporg
- cp -dpR /mnt/looporg/. /mnt/loop/.
- cd /mnt/loop/dev (/dev 檔案夾下,建立 裝置節點)
- mknod -m 777 led0 c 44 0
- cd /
- umount -l /mnt/loop
- gzip -9 ext2new
- 重新燒錄 root file system。
-
-
建構 LED 驅動程式
- 進入 led-demo 目錄
- make
Taget 端
-
使用 NFS 的方式,mount host 端的目錄,以存取剛剛建立的 LED 驅動程式。
- mount 192.168.0.200:/usr/src/creator/nfs /mnt
-
安裝驅動程式
- cd /dev
- mknod -m 777 led0 c 44 0
- cd /mnt/Day3/char-driver/led-demo
- insmod led-creator.o
-
執行應用程式
- ./led-demo.exe
led-creator.c
// --------------------------------------------------------------------
//
// Title : led-creator.c
// :
// Library :
// :
// Developers: MICROTIME MDS group (V1.0)
// : mesmerli@gmail.com (V1.1)
// :
// Purpose : Driver for LED of Creator
// :
// Limitation:
// :
// Note :
// :
// --------------------------------------------------------------------
// modification history :
// --------------------------------------------------------------------
// Version| mod. date: |
// V1.0 | 03/05/2004 | First release
// V1.1 | 11/15/2004 | LED by mesmerli
// --------------------------------------------------------------------
//
// Note:
//
// MICROTIME COMPUTER INC.
//
//
#include <linux/config.h>
#include <linux/kernel.h> // 必要的 Header files
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <asm/irq.h>
#include <asm/param.h>
#include <asm/uaccess.h>
#include "asm/arch/irqs.h"
#if LINUX_VERSION_CODE < 0x020100
#define GET_USER(a,b) a = get_user(b)
#else
#include <asm/uaccess.h>
#define GET_USER(a,b) get_user(a,b)
#endif
#include "asm/arch/lib/creator_s3c2410_addr.h" // 硬體暫存器定義
#include "asm/arch/lib/genfont8_8.h"
#include "led-creator.h"
/*
* Define driver major number.
*/
#define MAJOR_NUM LED_MAJOR_NUM
#define MODULE_VERSION "1.10"
#define MODULE_NAME "LED_CREATOR"
#define COPYRIGHT "Copyright (C) 2003-2004, Microtime Computer Inc."
#define MODULE_AUTHOR_STRING "Microtime Computer Inc."
#define MODULE_DESCRIPTION_STRING "Creator led module"
// 硬體控制
#define KEYPAD_SCAN_PERIOD (HZ/5) // 200ms
static UI scan_led=0x5500;
int Creator_led_cmd (int cmd, unsigned char led)
{
int rc = 0;
unsigned char bit ;
switch (cmd){
case LED_IOCTL_SET : {
/*
led value : 1 : 亮, 0 : 不亮
H/W : 0 : 亮, 1 : 不亮
*/
scan_led = ((~led) << 8);
break;
}
case LED_IOCTL_BIT_SET : {
int i ;
if (led >= 8)
return(-EINVAL);
bit = 1;
for (i=0; i < led; i++)
bit <<= 1;
scan_led &= ((~bit) << 8);
break;
}
case LED_IOCTL_BIT_CLEAR : {
int i ;
if (led >= 8)
return(-EINVAL);
bit = 1;
for (i=0; i < led; i++)
bit <<= 1;
scan_led |= (bit << 8);
break;
}
default :
return(-ENOTTY);
}
if (rc == 0)
IO_REG2 = scan_led | 0xfe;
return (rc);
}
/*****************************************************************************/
static int drv_led_open(struct inode *inode, struct file *filp)
{
MOD_INC_USE_COUNT;
return(0);
}
/*****************************************************************************/
static int drv_led_release(struct inode *inode, struct file *filp)
{
MOD_DEC_USE_COUNT;
return 0;
}
int drv_led_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
int rc = 0;
/*
分離type如果遇到錯誤的cmd, 就直接傳回ENOTTY
*/
if (_IOC_TYPE(cmd) != LED_IOCTL_MAGIC) return (-ENOTTY);
switch (cmd) {
case LED_IOCTL_SET :
case LED_IOCTL_BIT_SET :
case LED_IOCTL_BIT_CLEAR : {
unsigned short led;
if (copy_from_user(&led, (unsigned short*)arg, sizeof(unsigned short)))
return (-EINVAL);
if (Creator_led_cmd(cmd, led) < -EFAULT)
return (-EINVAL);
break;
}
default:
rc = -ENOTTY;
break;
}
return(rc);
}
/*
* Exported file operations structure for driver...
*/
struct file_operations drv_led_fops =
{
ioctl: drv_led_ioctl,
open: drv_led_open,
release: drv_led_release,
};
/*****************************************************************************/
static int __init init_module_drv_led(void)
{
int rc;
SET_MODULE_OWNER(&drv_led_fops);
/* Register lcdtxt as character device */
if ((rc = register_chrdev(MAJOR_NUM, MODULE_NAME, &drv_led_fops)) < 0) {
printk("<1>%s: can't get major %dn", MODULE_NAME, MAJOR_NUM);
return (-EBUSY);
}
printk("<1>%s: Version : %s %sn", MODULE_NAME, MODULE_VERSION, COPYRIGHT);
/* Hardware specific initialization */
return 0;
}
static void __exit cleanup_module_drv_led(void)
{
unregister_chrdev(MAJOR_NUM, MODULE_NAME);
printk("<1>%s: removedn", MODULE_NAME);
}
/* here are the compiler macro for module operation */
module_init(init_module_drv_led);
module_exit(cleanup_module_drv_led);
MODULE_AUTHOR(MODULE_AUTHOR_STRING);
MODULE_DESCRIPTION(MODULE_DESCRIPTION_STRING);
EXPORT_NO_SYMBOLS;
/*****************************************************************************/
led-creator.h
//=============================================================================
// File Name : led-creator.h
// Function : LED device drvier definition
// Program :
// Date : 11/15/2004
// Version : 1.10
// History
// 1.0.0 : Programming start (03/05/2004) -> SOP
// 1.1.0 : LED version
//=============================================================================
#ifndef LED_CREATOR_H_
#define LED_CREATOR_H_
#include <linux/config.h>
#if defined(__linux__)
#include <asm/ioctl.h> /* For _IO* macros */
#define LED_IOCTL_NR(n) _IOC_NR(n)
#elif defined(__FreeBSD__)
#include <sys/ioccom.h>
#define LED_IOCTL_NR(n) ((n) & 0xff)
#endif
#define LED_MAJOR_NUM 44
#define LED_IOCTL_MAGIC LED_MAJOR_NUM
#define LED_IO(nr) _IO(LED_IOCTL_MAGIC,nr)
#define LED_IOR(nr,size) _IOR(LED_IOCTL_MAGIC,nr,size)
#define LED_IOW(nr,size) _IOW(LED_IOCTL_MAGIC,nr,size)
#define LED_IOWR(nr,size) _IOWR(LED_IOCTL_MAGIC,nr,size)
/* LED specific ioctls */
/* 設定8個LED Lamps, Low byte 值為有效 */
#define LED_IOCTL_SET LED_IOW( 0x40, unsigned short)
/* 點亮單一個LED lamp */
#define LED_IOCTL_BIT_SET LED_IOW( 0x41, unsigned short)
/* 熄滅單一個LED lamp*/
#define LED_IOCTL_BIT_CLEAR LED_IOW( 0x42, unsigned short)
/* LED define */
#define LED_ALL_ON 0xFF /* 點亮LED Lamp */
#define LED_ALL_OFF 0x00 /* 熄滅LED Lamp */
#define LED_D9_INDEX 0 /* LED 編號D9 (1) */
#define LED_D10_INDEX 1 /* LED 編號D10(2) */
#define LED_D11_INDEX 2 /* LED 編號D11(3) */
#define LED_D12_INDEX 3 /* LED 編號D12(4) */
#define LED_D13_INDEX 4 /* LED 編號D13(5) */
#define LED_D14_INDEX 5 /* LED 編號D14(6) */
#define LED_D15_INDEX 6 /* LED 編號D15(7) */
#define LED_D16_INDEX 7 /* LED 編號D16(8) */
#endif // LED_CREATOR_H_
led-demo.c
#include <signal.h>
#include <stdio.h>
#include <strings.h>
#include <fcntl.h>
#include <time.h>
#include <sys/ioctl.h>
#include "led-creator.h"
int main()
{
int fd;
unsigned int data = 0x0;
int ret;
fd = open("/dev/led0", O_RDWR);
if (fd < 0)
{
printf("open /dev/led0 errorn");
return (-1);
}
while(1)
{
ioctl(fd, LED_IOCTL_SET, &data);
sleep(1);
data++;
if(data >= 0xff)
{
data = 0x0;
}
}
printf("Led Demo!!!n");
return 0;
}
Makefile
CROSS_COMPILE = arm-linux-
LINUXDIR = /usr/src/creator/s3c2410/linux
INCLUDE = $(LINUXDIR)/include
export LINUXDIR
#
# Include the make variables (CC, etc...)
#
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
export AS LD CC CPP AR
CFLAGS= -O2 -DMODULE -D__KERNEL__ -DEXPORT_SYMTBL -Wall -I/usr/src/creator/s3c2410/linux/include -Wstrict-prototypes -Wno-trigraphs -Os -mapcs
-fno-strict-aliasing -fno-common -gdwarf-2 -D__linux__ -fno-common -pipe -g -mapcs-32 -march=armv4 -mtune=arm9tdmi
-mshort-load-bytes -msoft-float -DKBUILD_BASENAME=creator_s3c2410_lcd
#CFLAGS= -O0 -Wall -DHAVE_CONFIG_H -D__KERNEL__ -I$(INCLUDE) -DMODULE -DFPM_DEFAULT -Dlinux -Dunix -DNDEBUG -D_REENTRANT -I.
CFLAGS_AP= -O0 -gdwarf-2 -DHAVE_CONFIG_H -DFPM_DEFAULT -Dlinux -Dunix -DNDEBUG -D_REENTRANT -I.
.c.o:
$(CC) $(CFLAGS) -c -o $@ $<
.S.o:
$(CC) $(AFLAGS) -c -o $@ $<
ALL = led-creator.o led-demo.exe
all: $(ALL)
led-creator.o: led-creator.c
$(CC) $(CFLAGS)-c -o $@ $<
led-demo.exe: led-demo.c
$(CC) $(LDFLAGS_AP) -o $@ $^ $(LDLIBS) -L/usr/local/arm/2.95.3/arm-linux/lib /usr/local/arm/2.95.3/arm-linux/lib/libpthread.a
clean:
rm -f *.o *.exe *~ core $(ALL)
0 意見:
張貼留言