学了好几年的C,还比较精通。LINUX也玩过好一段时间,算是有点入门吧,不过硬件方面的知识不是很扎实。
毕业设计选了,LINUX下的驱动开发,我目前在看的是《LINUX设备驱动程序》AlessandroRubini写的,看的我是一个头两个大!
不知道大家有什么好的意见没有?有什么比较合适的书吗?
我这有一个驱动的例子:这是我这次毕业设计 做ARM 应用设计参考的例子
虽然是嵌入试系统上面的,但我想都是基于linux的驱动开发,大体有点相同
在这网站下栽这例子
/*用户程序*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define LED "/dev/led"
int main(int argc,char** argv)
{
int led,tt;
led = open(LED, O_RDWR); //秨币 〃/dev/led〃 硂じ砞称郎
if (led < 0)
printf("led error device\n");
else
printf("led success\n");
scanf("%d",&tt); //既氨祘Α
close(led); //闽超〃/dev/led〃硂じ砞称郎
return 0;
}
/* 驱动程序 */
#include <linux/malloc.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <asm/segment.h>
#include <unistd.h>
//﹚竡Αノ魁既竟﹍ず籔い耞璸计
typedef struct {
unsigned int orig_mod; //IOPMOD Register
unsigned int orig_con; //IOPCON Register
unsigned int orig_dbw; //EXTDBWTH Register
unsigned int count;
} led_demo_driver_t;
//﹚竡既竟┮
#define EXTDBWTH *(unsigned int *)0x3FF3010
#define IOPMOD *(unsigned int *)0x3FF5000
#define IOPCON *(unsigned int *)0x3FF5004
//﹚竡砞称腹絏 111
#define LED_CHDRV_MAJOR 111
//﹚竡砞称嘿 LED_Int_DemoDrv
char LED_INT_CHDRV_NAME[] = "LED_Int_DemoDrv";
//┑捌祘Α
void led_delay()
{
unsigned int i;
for(i = 0; i < 500000; ++i) ;
}
//い耞矪瞶盽Α
void led_interrupt( int irq, void *dev_id, struct pt_regs *regs )
{
led_demo_driver_t *dev = (led_demo_driver_t *)dev_id;
dev->count++; //い耞祇ネ璸计
//块い耞祇ネ璸计
printk("irq %d dev->PC = %08x \n",irq , dev->count++);//for debug interrupt
}
//秨币ㄧ计
int led_chdev_open( struct inode *inode, struct file *file )
{
led_demo_driver_t *dev;
int flags;
//だ皌癘拘砰丁倒dev
dev = (led_demo_driver_t *)kmalloc(sizeof(led_demo_driver_t), GFP_KERNEL);
if(dev == NULL)
{
return -ENOMEM;
}
//︽魁I/O既竟
dev->orig_mod = IOPMOD;
dev->orig_con = IOPCON;
dev->orig_dbw = EXTDBWTH;
//砞﹚场I/O蹲瑈逼糴32bits
EXTDBWTH |= 0x0FF00000;
led_delay();
//GPIO port 8块家Αport 8 = 0other hold
IOPMOD &= 0x7FEFF;
led_delay();
//︽砞﹚既竟IOPCON[4:0] = 11100场い耞0砞﹚
//だEnableActive HighFiltering onLevel detection
IOPCON &= 0xFFFFFFE0;
led_delay();
IOPCON |= 0x1C; //reference s3c4510 spec. page 12-4 about external irq setting
led_delay();
file->private_data = dev;//dev爹Θ杆竚private data
led_delay();
dev->count = 0x00; //﹍てい耞璸计0
led_delay();
save_flags_cli(flags); //纗篨夹
//爹い耞矪瞶盽Α
if( request_irq( 0, led_interrupt, SA_INTERRUPT, "led", dev ))
{
printk("kernel: request_irq error!\n"); //讽爹い耞ア毖
}
restore_flags(flags); //篨夹
return 0;
}
//睦ㄧ计
void led_chdev_release( struct inode *inode, struct file *file )
{
led_demo_driver_t *dev = (led_demo_driver_t *)file->private_data;
int flags;
save_flags_cli(flags); //纗篨夹
free_irq(0, dev); //氨ゎdev眖场い耞0莉眔戈方
if(dev) {
//I/O既竟
IOPMOD = dev->orig_mod;
IOPCON = dev->orig_con;
EXTDBWTH = dev->orig_dbw;
//睦dev癘拘砰丁
kfree(dev);
}
restore_flags(flags); //篨夹
}
//杆竚ㄧ计爹Αセ祘Αㄏノopen籔releaseㄧ计
static struct file_operations led_chdrv_fops = {
NULL, /* lseek */
NULL, /* read */
NULL, /* write */
NULL, /* readdir */
NULL, /* select */
NULL, /* ioctl */
NULL, /* mmap */
led_chdev_open, /* open */
led_chdev_release /* release */
};
//﹍てㄧ计
int led_init()
{
//Linuxみ爹じ杆竚
if( register_chrdev(LED_CHDRV_MAJOR, LED_INT_CHDRV_NAME, &led_chdrv_fops) )
{
printk("kernel: %s: Unable to register character device\n", LED_INT_CHDRV_NAME); //狦爹じ杆竚ア毖
return -EIO;
}
return 0;
}
你只需要一本书,就是《Linux设备驱动程序》
我做过Unix下的驱动,看的就是这本书和Unix的官方文档
看这本书主要是明白原理
官方文档主要是查API
一般来说
先做一个空的驱动
然后写一个虚拟设备
最后和硬件联调中断
基本原理很重要,要不碰到问题,不理解原理根本就不知道怎么回事