嵌入式驅動編寫-按鍵驅動程序




今天,寫出開發板上的最簡單的按鍵驅動程序,首先需要閱讀開發板的原理圖和芯片手冊.

GPG3  GPG11  GPF0  GPF2四個引腳控制按鍵.











由原理圖可知,需要將GPG3  GPG11  GPF0  GPF2設爲輸入引腳.


1 編寫驅動程序

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>

//定義兩個類,自動創建設備節點
static struct class *seconddrv_class;
static struct class_device	*seconddrv_class_dev;

volatile unsigned long *gpfcon;//gpf寄存器
volatile unsigned long *gpfdat;

volatile unsigned long *gpgcon;//gpg寄存器
volatile unsigned long *gpgdat;

static int second_drv_open(struct inode *inode, struct file *file)
{
	/* 配置GPF0,2爲輸入引腳 */
	*gpfcon &= ~((0x3<<(0*2)) | (0x3<<(2*2)));

	/* 配置GPG3,11爲輸入引腳 */
	*gpgcon &= ~((0x3<<(3*2)) | (0x3<<(11*2)));

	return 0;
}

ssize_t second_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
	/* 返回4個引腳的電平 */
	unsigned char key_vals[4];
	int regval;

	if (size != sizeof(key_vals))
		return -EINVAL;

	/* 讀GPF0,2 */
	regval = *gpfdat;
	key_vals[0] = (regval & (1<<0)) ? 1 : 0;
	key_vals[1] = (regval & (1<<2)) ? 1 : 0;
	

	/* 讀GPG3,11 */
	regval = *gpgdat;
	key_vals[2] = (regval & (1<<3)) ? 1 : 0;
	key_vals[3] = (regval & (1<<11)) ? 1 : 0;

	copy_to_user(buf, key_vals, sizeof(key_vals));
	
	return sizeof(key_vals);
}


static struct file_operations sencod_drv_fops = {
    .owner  =   THIS_MODULE,    /* 這是一個宏,推向編譯模塊時自動創建的__this_module變量 */
    .open   =   second_drv_open,     
	.read	=	second_drv_read,	   
};


int major;
//驅動入口
static int second_drv_init(void)
{
	major = register_chrdev(0, "second_drv", &sencod_drv_fops);

	seconddrv_class = class_create(THIS_MODULE, "second_drv");

	seconddrv_class_dev = class_device_create(seconddrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */

	gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);
	gpfdat = gpfcon + 1;

	gpgcon = (volatile unsigned long *)ioremap(0x56000060, 16);
	gpgdat = gpgcon + 1;

	return 0;
}
//出口函數
static void second_drv_exit(void)
{
	unregister_chrdev(major, "second_drv");
	class_device_unregister(seconddrv_class_dev);
	class_destroy(seconddrv_class);
	iounmap(gpfcon);
	iounmap(gpgcon);
	return 0;
}


module_init(second_drv_init);

module_exit(second_drv_exit);

MODULE_LICENSE("GPL");

2 編寫makefile文佳

KERN_DIR = /work/system/linux-2.6.22.6

all:
	make -C $(KERN_DIR) M=`pwd` modules 

clean:
	make -C $(KERN_DIR) M=`pwd` modules clean
	rm -rf modules.order

obj-m	+= second_drv.o

將代碼上傳導服務器,編譯,放到網絡文件系統上,啓動開發板,掛接驅動程序

# insmod  second_drv.ko 
# cat /proc/devices 
Character devices:
  1 mem
  2 pty
  3 ttyp
  4 /dev/vc/0
  4 tty
  4 ttyS
  5 /dev/tty
  5 /dev/console
  5 /dev/ptmx
  6 lp
  7 vcs
 10 misc
 13 input
 14 sound
 29 fb
 90 mtd
 99 ppdev
116 alsa
128 ptm
136 pts
180 usb
189 usb_device
204 s3c2410_serial
252 second_drv
253 usb_endpoint
254 rtc

Block devices:
  1 ramdisk
  7 loop
  8 sd
 31 mtdblock
 65 sd
 66 sd
 67 sd
 68 sd
 69 sd
 70 sd
 71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
179 mmc
看到設備號爲252,查看設備目錄

# ls -l /dev/buttons 
crw-r--r--    1 0        0        252,   0 Jan  1 00:01 /dev/buttons

如果沒有創建成功,手動創建

# mknod  /dev/buttons c 252 0
3 編寫測試程序

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

/* seconddrvtest 
  */
int main(int argc, char **argv)
{
	int fd;
	unsigned char key_vals[4];
	int cnt = 0;
	
	fd = open("/dev/buttons", O_RDWR);
	if (fd < 0)
	{
		printf("can't open!\n");
	}

	while (1)
	{
		read(fd, key_vals, sizeof(key_vals));
		if (!key_vals[0] || !key_vals[1] || !key_vals[2] || !key_vals[3])
		{
			printf("%04d key pressed: %d %d %d %d\n", cnt++, key_vals[0], key_vals[1], key_vals[2], key_vals[3]);
		}
	}
	
	return 0;
}


上傳導服務器,編譯 放到網絡文件系統上,在開發板上運行

# ./seconddrvtest 
0000 key pressed: 1 1 0 1
0001 key pressed: 1 1 0 1
0002 key pressed: 1 1 0 1
0003 key pressed: 1 1 0 1
0004 key pressed: 1 1 0 1
0005 key pressed: 1 1 0 1
0006 key pressed: 1 1 0 1
0007 key pressed: 1 1 0 1
0008 key pressed: 1 1 0 1
0009 key pressed: 1 1 0 1
0010 key pressed: 1 1 0 1
0011 key pressed: 1 1 0 1
0012 key pressed: 1 1 0 1
0013 key pressed: 1 1 0 1
0014 key pressed: 1 1 0 1
0015 key pressed: 1 1 0 1
0016 key pressed: 1 1 0 1
0017 key pressed: 1 1 0 1
0018 key pressed: 1 1 0 1
0019 key pressed: 1 1 0 1
0020 key pressed: 1 1 0 1
0021 key pressed: 1 1 0 1
0022 key pressed: 1 1 0 1
0023 key pressed: 1 1 0 1
0024 key pressed: 1 1 0 1
0025 key pressed: 1 1 0 1
0026 key pressed: 1 1 0 1
0027 key pressed: 1 1 0 1
0028 key pressed: 1 1 0 1
0029 key pressed: 1 1 0 1
0030 key pressed: 1 1 0 1
0031 key pressed: 1 1 0 1
0032 key pressed: 1 1 0 1
0033 key pressed: 1 1 0 1
0034 key pressed: 1 1 0 1
0035 key pressed: 1 1 0 1
0036 key pressed: 1 1 0 1
0037 key pressed: 1 1 0 1
0038 key pressed: 1 1 0 1
0039 key pressed: 1 1 0 1
0040 key pressed: 1 1 0 1
0041 key pressed: 1 1 0 1
0042 key pressed: 1 1 0 1
0043 key pressed: 1 1 0 1
0044 key pressed: 1 1 0 1
0045 key pressed: 1 1 0 1
0046 key pressed: 1 1 0 1
0047 key pressed: 1 1 0 1
0048 key pressed: 1 1 0 1
0049 key pressed: 1 1 0 1
0050 key pressed: 1 1 0 1
0051 key pressed: 1 1 0 1
0052 key pressed: 1 1 0 1
0053 key pressed: 1 1 0 1
0054 key pressed: 1 1 0 1
0055 key pressed: 1 1 0 1
0056 key pressed: 1 1 0 1
0057 key pressed: 1 1 0 1
0058 key pressed: 1 1 0 1
0059 key pressed: 1 1 0 1
0060 key pressed: 1 1 0 1
0061 key pressed: 1 1 0 1
0062 key pressed: 1 1 0 1
0063 key pressed: 1 1 0 1
0064 key pressed: 1 1 0 1
0065 key pressed: 1 1 0 1
0066 key pressed: 1 1 0 1
0067 key pressed: 1 1 0 1
0068 key pressed: 1 1 0 1
0069 key pressed: 1 1 0 1
0070 key pressed: 1 1 0 1
0071 key pressed: 1 1 0 1
0072 key pressed: 1 1 0 1
0073 key pressed: 1 1 0 1
0074 key pressed: 1 1 0 1
0075 key pressed: 1 1 0 1
0076 key pressed: 1 1 0 1
0077 key pressed: 1 1 0 1
0078 key pressed: 1 1 0 1
0079 key pressed: 1 1 0 1
0080 key pressed: 1 1 0 1
0081 key pressed: 1 1 0 1
0082 key pressed: 1 1 0 1
0083 key pressed: 1 1 0 1
0084 key pressed: 1 1 0 1
0085 key pressed: 1 1 0 1
0086 key pressed: 1 1 0 1
0087 key pressed: 1 1 0 1
0088 key pressed: 1 1 0 1
0089 key pressed: 1 1 0 1
0090 key pressed: 1 1 0 1
0091 key pressed: 1 1 0 1
0092 key pressed: 1 1 0 1
0093 key pressed: 1 1 0 1
0094 key pressed: 1 1 0 1
0095 key pressed: 1 1 0 1
0096 key pressed: 1 1 0 1
0097 key pressed: 1 1 0 1
0098 key pressed: 1 1 0 1
0099 key pressed: 1 1 0 1
0100 key pressed: 1 1 0 1
0101 key pressed: 1 1 0 1
0102 key pressed: 1 1 0 1
0103 key pressed: 1 1 0 1
0104 key pressed: 1 1 0 1
0105 key pressed: 1 1 0 1
0106 key pressed: 1 1 0 1
0107 key pressed: 1 1 0 1
0108 key pressed: 1 1 0 1
0109 key pressed: 1 1 0 1
0110 key pressed: 1 1 0 1
0111 key pressed: 1 1 0 1
0112 key pressed: 1 1 0 1
0113 key pressed: 1 1 0 1
0114 key pressed: 1 1 0 1
0115 key pressed: 1 1 0 1
0116 key pressed: 1 1 0 1
0117 key pressed: 1 1 0 1
0118 key pressed: 1 1 0 1
0119 key pressed: 1 1 0 1
0120 key pressed: 1 1 0 1
0121 key pressed: 1 1 0 1
0122 key pressed: 1 1 0 1
0123 key pressed: 1 1 0 1
0124 key pressed: 1 1 0 1
0125 key pressed: 1 1 0 1
0126 key pressed: 1 1 0 1
0127 key pressed: 1 1 0 1
0128 key pressed: 1 1 0 1
0129 key pressed: 1 1 0 1
0130 key pressed: 1 1 0 1
0131 key pressed: 1 1 0 1
0132 key pressed: 1 1 0 1
0133 key pressed: 1 1 0 1
0134 key pressed: 1 1 0 1
0135 key pressed: 1 1 0 1
0136 key pressed: 1 1 0 1
0137 key pressed: 1 1 0 1
0138 key pressed: 1 1 0 1
0139 key pressed: 1 1 0 1
0140 key pressed: 1 1 0 1
0141 key pressed: 1 1 0 1
0142 key pressed: 1 1 0 1
0143 key pressed: 1 1 0 1
0144 key pressed: 1 1 0 1
0145 key pressed: 1 1 0 1
0146 key pressed: 1 1 0 1
0147 key pressed: 1 1 0 1
0148 key pressed: 1 1 0 1
0149 key pressed: 1 1 0 1
0150 key pressed: 1 1 0 1
0151 key pressed: 1 1 0 1
0152 key pressed: 1 1 0 1
0153 key pressed: 1 1 0 1
0154 key pressed: 1 1 0 1
0155 key pressed: 1 0 1 1
0156 key pressed: 1 0 1 1
0157 key pressed: 1 0 1 1
0158 key pressed: 1 0 1 1
0159 key pressed: 1 0 1 1
0160 key pressed: 1 0 1 1
0161 key pressed: 1 0 1 1
0162 key pressed: 1 0 1 1
0163 key pressed: 1 0 1 1
0164 key pressed: 1 0 1 1
0165 key pressed: 1 0 1 1
0166 key pressed: 1 0 1 1
0167 key pressed: 1 0 1 1
0168 key pressed: 1 0 1 1
0169 key pressed: 1 0 1 1
0170 key pressed: 1 0 1 1
0171 key pressed: 1 0 1 1
0172 key pressed: 1 0 1 1
0173 key pressed: 1 0 1 1
0174 key pressed: 1 0 1 1
0175 key pressed: 1 0 1 1
0176 key pressed: 1 0 1 1
0177 key pressed: 1 0 1 1
0178 key pressed: 1 0 1 1
0179 key pressed: 1 0 1 1
0180 key pressed: 1 0 1 1
0181 key pressed: 1 0 1 1
0182 key pressed: 1 0 1 1
0183 key pressed: 1 0 1 1
0184 key pressed: 1 0 1 1
0185 key pressed: 1 0 1 1
0186 key pressed: 1 0 1 1
0187 key pressed: 1 0 1 1
0188 key pressed: 1 0 1 1
0189 key pressed: 1 0 1 1
0190 key pressed: 1 0 1 1
0191 key pressed: 1 0 1 1
0192 key pressed: 1 0 1 1
0193 key pressed: 1 0 1 1
0194 key pressed: 1 0 1 1
0195 key pressed: 1 0 1 1
0196 key pressed: 1 0 1 1
0197 key pressed: 1 0 1 1
0198 key pressed: 1 0 1 1
0199 key pressed: 1 0 1 1
0200 key pressed: 1 0 1 1
0201 key pressed: 1 0 1 1
0202 key pressed: 1 0 1 1
0203 key pressed: 1 0 1 1
0204 key pressed: 1 0 1 1
0205 key pressed: 1 0 1 1
0206 key pressed: 1 0 1 1
0207 key pressed: 1 0 1 1
0208 key pressed: 1 0 1 1
0209 key pressed: 1 0 1 1
0210 key pressed: 1 0 1 1
0211 key pressed: 1 0 1 1
0212 key pressed: 1 0 1 1
0213 key pressed: 1 0 1 1
0214 key pressed: 1 0 1 1
0215 key pressed: 1 0 1 1
0216 key pressed: 1 0 1 1
0217 key pressed: 1 0 1 1
0218 key pressed: 1 0 1 1
0219 key pressed: 1 0 1 1
0220 key pressed: 1 0 1 1
0221 key pressed: 1 0 1 1
0222 key pressed: 1 0 1 1
0223 key pressed: 1 0 1 1
0224 key pressed: 1 0 1 1
0225 key pressed: 1 0 1 1
0226 key pressed: 1 0 1 1
0227 key pressed: 1 0 1 1
0228 key pressed: 1 0 1 1
0229 key pressed: 1 0 1 1
0230 key pressed: 1 0 1 1
0231 key pressed: 1 0 1 1
0232 key pressed: 1 0 1 1
0233 key pressed: 1 0 1 1
0234 key pressed: 1 0 1 1
0235 key pressed: 1 0 1 1
0236 key pressed: 1 0 1 1
0237 key pressed: 1 0 1 1
0238 key pressed: 1 0 1 1
0239 key pressed: 1 0 1 1
0240 key pressed: 1 0 1 1
0241 key pressed: 1 0 1 1
0242 key pressed: 1 0 1 1
0243 key pressed: 1 0 1 1
0244 key pressed: 1 0 1 1
0245 key pressed: 1 0 1 1
0246 key pressed: 1 0 1 1
0247 key pressed: 1 0 1 1
0248 key pressed: 1 0 1 1
0249 key pressed: 1 0 1 1
0250 key pressed: 1 0 1 1
0251 key pressed: 1 0 1 1
0252 key pressed: 1 0 1 1
0253 key pressed: 1 0 1 1
0254 key pressed: 1 0 1 1
0255 key pressed: 1 0 1 1
0256 key pressed: 1 0 1 1
0257 key pressed: 1 0 1 1
0258 key pressed: 1 0 1 1
0259 key pressed: 1 0 1 1
0260 key pressed: 1 0 1 1
0261 key pressed: 1 0 1 1
0262 key pressed: 1 0 1 1
0263 key pressed: 1 0 1 1
0264 key pressed: 1 0 1 1
0265 key pressed: 1 0 1 1
0266 key pressed: 1 0 1 1
0267 key pressed: 1 0 1 1
0268 key pressed: 1 0 1 1
0269 key pressed: 1 0 1 1
0270 key pressed: 1 0 1 1
0271 key pressed: 1 0 1 1
0272 key pressed: 1 0 1 1
0273 key pressed: 1 0 1 1
0274 key pressed: 1 0 1 1
0275 key pressed: 1 0 1 1
0276 key pressed: 1 0 1 1
0277 key pressed: 1 0 1 1
0278 key pressed: 1 0 1 1
0279 key pressed: 1 0 1 1
0280 key pressed: 1 0 1 1
0281 key pressed: 1 0 1 1
0282 key pressed: 1 0 1 1
0283 key pressed: 1 0 1 1
0284 key pressed: 1 0 1 1
0285 key pressed: 1 0 1 1
0286 key pressed: 1 0 1 1
0287 key pressed: 1 0 1 1
0288 key pressed: 1 0 1 1
0289 key pressed: 1 0 1 1
0290 key pressed: 1 0 1 1
0291 key pressed: 1 0 1 1
0292 key pressed: 1 0 1 1
0293 key pressed: 1 0 1 1
0294 key pressed: 1 0 1 1
0295 key pressed: 1 0 1 1
0296 key pressed: 1 0 1 1
0297 key pressed: 1 0 1 1
0298 key pressed: 1 0 1 1
0299 key pressed: 1 0 1 1
0300 key pressed: 1 0 1 1
0301 key pressed: 1 0 1 1
0302 key pressed: 1 0 1 1
0303 key pressed: 1 0 1 1
0304 key pressed: 1 0 1 1
0305 key pressed: 1 0 1 1
0306 key pressed: 1 0 1 1
0307 key pressed: 1 0 1 1
0308 key pressed: 1 0 1 1
0309 key pressed: 1 0 1 1
0310 key pressed: 0 1 1 1
0311 key pressed: 0 1 1 1
0312 key pressed: 0 1 1 1
0313 key pressed: 0 1 1 1
0314 key pressed: 0 1 1 1
0315 key pressed: 0 1 1 1
0316 key pressed: 0 1 1 1
0317 key pressed: 0 1 1 1
0318 key pressed: 0 1 1 1
0319 key pressed: 0 1 1 1
0320 key pressed: 0 1 1 1
0321 key pressed: 0 1 1 1
0322 key pressed: 0 1 1 1
0323 key pressed: 0 1 1 1
0324 key pressed: 0 1 1 1
0325 key pressed: 0 1 1 1
0326 key pressed: 0 1 1 1
0327 key pressed: 0 1 1 1
0328 key pressed: 0 1 1 1
0329 key pressed: 0 1 1 1
0330 key pressed: 0 1 1 1
0331 key pressed: 0 1 1 1
0332 key pressed: 0 1 1 1
0333 key pressed: 0 1 1 1
0334 key pressed: 0 1 1 1
0335 key pressed: 0 1 1 1
0336 key pressed: 0 1 1 1
0337 key pressed: 0 1 1 1
0338 key pressed: 0 1 1 1
0339 key pressed: 0 1 1 1
0340 key pressed: 0 1 1 1
0341 key pressed: 0 1 1 1
0342 key pressed: 0 1 1 1
0343 key pressed: 0 1 1 1
0344 key pressed: 0 1 1 1
0345 key pressed: 0 1 1 1
0346 key pressed: 0 1 1 1
0347 key pressed: 0 1 1 1
0348 key pressed: 0 1 1 1
0349 key pressed: 0 1 1 1
0350 key pressed: 0 1 1 1
0351 key pressed: 0 1 1 1
0352 key pressed: 0 1 1 1
0353 key pressed: 0 1 1 1
0354 key pressed: 0 1 1 1
0355 key pressed: 0 1 1 1
0356 key pressed: 0 1 1 1
0357 key pressed: 0 1 1 1
0358 key pressed: 0 1 1 1
0359 key pressed: 0 1 1 1
0360 key pressed: 0 1 1 1
0361 key pressed: 0 1 1 1
0362 key pressed: 0 1 1 1
0363 key pressed: 0 1 1 1
0364 key pressed: 0 1 1 1
0365 key pressed: 0 1 1 1
0366 key pressed: 0 1 1 1
0367 key pressed: 0 1 1 1
0368 key pressed: 0 1 1 1
0369 key pressed: 0 1 1 1
0370 key pressed: 0 1 1 1
0371 key pressed: 0 1 1 1
0372 key pressed: 0 1 1 1
0373 key pressed: 0 1 1 1
0374 key pressed: 0 1 1 1
0375 key pressed: 0 1 1 1
0376 key pressed: 0 1 1 1
0377 key pressed: 0 1 1 1
0378 key pressed: 0 1 1 1
0379 key pressed: 0 1 1 1
0380 key pressed: 0 1 1 1
0381 key pressed: 0 1 1 1
0382 key pressed: 0 1 1 1
0383 key pressed: 0 1 1 1
0384 key pressed: 0 1 1 1
0385 key pressed: 0 1 1 1
0386 key pressed: 0 1 1 1
0387 key pressed: 0 1 1 1
0388 key pressed: 0 1 1 1
0389 key pressed: 0 1 1 1
0390 key pressed: 0 1 1 1
0391 key pressed: 0 1 1 1
0392 key pressed: 0 1 1 1
0393 key pressed: 0 1 1 1
0394 key pressed: 0 1 1 1
0395 key pressed: 0 1 1 1
0396 key pressed: 0 1 1 1
0397 key pressed: 0 1 1 1
0398 key pressed: 0 1 1 1
0399 key pressed: 0 1 1 1
0400 key pressed: 0 1 1 1
0401 key pressed: 0 1 1 1
0402 key pressed: 0 1 1 1
0403 key pressed: 0 1 1 1
0404 key pressed: 0 1 1 1
0405 key pressed: 0 1 1 1
0406 key pressed: 0 1 1 1
0407 key pressed: 0 1 1 1
0408 key pressed: 0 1 1 1
0409 key pressed: 0 1 1 1
0410 key pressed: 0 1 1 1
0411 key pressed: 0 1 1 1
0412 key pressed: 0 1 1 1
0413 key pressed: 0 1 1 1
0414 key pressed: 0 1 1 1
0415 key pressed: 0 1 1 1
0416 key pressed: 0 1 1 1
0417 key pressed: 0 1 1 1
0418 key pressed: 0 1 1 1
0419 key pressed: 0 1 1 1
0420 key pressed: 0 1 1 1
0421 key pressed: 0 1 1 1
0422 key pressed: 0 1 1 1
0423 key pressed: 0 1 1 1
0424 key pressed: 0 1 1 1
0425 key pressed: 0 1 1 1
0426 key pressed: 0 1 1 1
0427 key pressed: 0 1 1 1
0428 key pressed: 0 1 1 1
0429 key pressed: 0 1 1 1
0430 key pressed: 0 1 1 1
0431 key pressed: 0 1 1 1
0432 key pressed: 0 1 1 1
0433 key pressed: 0 1 1 1
0434 key pressed: 0 1 1 1
0435 key pressed: 0 1 1 1
0436 key pressed: 0 1 1 1
0437 key pressed: 0 1 1 1
0438 key pressed: 0 1 1 1
0439 key pressed: 0 1 1 1
0440 key pressed: 0 1 1 1
0441 key pressed: 0 1 1 1
0442 key pressed: 0 1 1 1
0443 key pressed: 0 1 1 1
0444 key pressed: 0 1 1 1
0445 key pressed: 0 1 1 1
0446 key pressed: 0 1 1 1
0447 key pressed: 0 1 1 1
0448 key pressed: 0 1 1 1
0449 key pressed: 0 1 1 1
0450 key pressed: 0 1 1 1
0451 key pressed: 0 1 1 1
0452 key pressed: 0 1 1 1
0453 key pressed: 0 1 1 1
0454 key pressed: 0 1 1 1
0455 key pressed: 0 1 1 1
0456 key pressed: 0 1 1 1
0457 key pressed: 0 1 1 1
0458 key pressed: 0 1 1 1
0459 key pressed: 0 1 1 1
0460 key pressed: 0 1 1 1
0461 key pressed: 0 1 1 1
0462 key pressed: 0 1 1 1
0463 key pressed: 0 1 1 1
0464 key pressed: 0 1 1 1

這種死循環查詢的方式非常耗費CPU資源,如何優化?

通過中斷的方式,在按下的時候觸發中斷

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>


static struct class *thirddrv_class;
static struct class_device	*thirddrv_class_dev;

volatile unsigned long *gpfcon;
volatile unsigned long *gpfdat;

volatile unsigned long *gpgcon;
volatile unsigned long *gpgdat;


static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

/* 中斷事件標誌, 中斷服務程序將它置1,third_drv_read將它清0 */
static volatile int ev_press = 0;


struct pin_desc{
	unsigned int pin;
	unsigned int key_val;
};


/* 鍵值: 按下時, 0x01, 0x02, 0x03, 0x04 */
/* 鍵值: 鬆開時, 0x81, 0x82, 0x83, 0x84 */
static unsigned char key_val;

struct pin_desc pins_desc[4] = {
	{S3C2410_GPF0, 0x01},
	{S3C2410_GPF2, 0x02},
	{S3C2410_GPG3, 0x03},
	{S3C2410_GPG11, 0x04},
};


/*
  * 確定按鍵值
  */
static irqreturn_t buttons_irq(int irq, void *dev_id)
{
	struct pin_desc * pindesc = (struct pin_desc *)dev_id;
	unsigned int pinval;
	
	pinval = s3c2410_gpio_getpin(pindesc->pin);

	if (pinval)
	{
		/* 鬆開 */
		key_val = 0x80 | pindesc->key_val;
	}
	else
	{
		/* 按下 */
		key_val = pindesc->key_val;
	}

    ev_press = 1;                  /* 表示中斷髮生了 */
    wake_up_interruptible(&button_waitq);   /* 喚醒休眠的進程 */

	
	return IRQ_RETVAL(IRQ_HANDLED);
}

static int third_drv_open(struct inode *inode, struct file *file)
{
	/* 配置GPF0,2爲輸入引腳 */
	/* 配置GPG3,11爲輸入引腳 */
	request_irq(IRQ_EINT0,  buttons_irq, IRQT_BOTHEDGE, "S2", &pins_desc[0]);
	request_irq(IRQ_EINT2,  buttons_irq, IRQT_BOTHEDGE, "S3", &pins_desc[1]);
	request_irq(IRQ_EINT11, buttons_irq, IRQT_BOTHEDGE, "S4", &pins_desc[2]);
	request_irq(IRQ_EINT19, buttons_irq, IRQT_BOTHEDGE, "S5", &pins_desc[3]);	

	return 0;
}

ssize_t third_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
	if (size != 1)
		return -EINVAL;

	/* 如果沒有按鍵動作, 休眠 */
	wait_event_interruptible(button_waitq, ev_press);

	/* 如果有按鍵動作, 返回鍵值 */
	copy_to_user(buf, &key_val, 1);
	ev_press = 0;
	
	return 1;
}


int third_drv_close(struct inode *inode, struct file *file)
{
	free_irq(IRQ_EINT0, &pins_desc[0]);
	free_irq(IRQ_EINT2, &pins_desc[1]);
	free_irq(IRQ_EINT11, &pins_desc[2]);
	free_irq(IRQ_EINT19, &pins_desc[3]);
	return 0;
}


static struct file_operations sencod_drv_fops = {
    .owner   =  THIS_MODULE,    /* 這是一個宏,推向編譯模塊時自動創建的__this_module變量 */
    .open    =  third_drv_open,     
	.read	 =	third_drv_read,	   
	.release =  third_drv_close,	   
};


int major;
static int third_drv_init(void)
{
	major = register_chrdev(0, "third_drv", &sencod_drv_fops);

	thirddrv_class = class_create(THIS_MODULE, "third_drv");

	thirddrv_class_dev = class_device_create(thirddrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */

	gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);
	gpfdat = gpfcon + 1;

	gpgcon = (volatile unsigned long *)ioremap(0x56000060, 16);
	gpgdat = gpgcon + 1;

	return 0;
}

static void third_drv_exit(void)
{
	unregister_chrdev(major, "third_drv");
	class_device_unregister(thirddrv_class_dev);
	class_destroy(thirddrv_class);
	iounmap(gpfcon);
	iounmap(gpgcon);
	return 0;
}


module_init(third_drv_init);

module_exit(third_drv_exit);

MODULE_LICENSE("GPL");


編寫測試程序

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

/* thirddrvtest 
  */
int main(int argc, char **argv)
{
	int fd;
	unsigned char key_val;
	
	fd = open("/dev/buttons", O_RDWR);
	if (fd < 0)
	{
		printf("can't open!\n");
	}

	while (1)
	{
		read(fd, &key_val, 1);
		printf("key_val = 0x%x\n", key_val);
		sleep(5);
	}
	
	return 0;
}


在開發板上運行

# insmod third_drv.ko 
# ./thirddrvtest 

# rm -r /dev/buttons 
# ./thirddrvtest 
can't open!
mkn     ^H^H^H
# mknod  /dev/buttons c 252 0
# ./thirddrvtest 

# cat /proc/devices 
Character devices:
  1 mem
  2 pty
  3 ttyp
  4 /dev/vc/0
  4 tty
  4 ttyS
  5 /dev/tty
  5 /dev/console
  5 /dev/ptmx
  6 lp
  7 vcs
 10 misc
 13 input
 14 sound
 29 fb
 90 mtd
 99 ppdev
116 alsa
128 ptm
136 pts
180 usb
189 usb_device
204 s3c2410_serial
251 third_drv
252 second_drv
253 usb_endpoint
254 rtc

Block devices:
  1 ramdisk
  7 loop
  8 sd
 31 mtdblock
 65 sd
 66 sd
 67 sd
 68 sd
 69 sd
 70 sd
 71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
179 mmc
# mknod  /dev/buttons c 251 0
mknod: /dev/buttons: File exists
# rm -r /dev/buttons 
# mknod  /dev/buttons c 251 0
# ./thirddrvtest 

# ./thirddrvtest 
key_val = 0x81
key_val = 0x81
key_val = 0x83
key_val = 0x82
key_val = 0x81
key_val = 0x2
key_val = 0x82
key_val = 0x83
key_val = 0x81








































發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章