打印
[嵌入式linux]

开始学linux驱动,三个月熟悉,立帖为证!每日汇报进展

[复制链接]
楼主: tiger84
手机看帖
扫描二维码
随时随地手机跟帖
41
tiger84|  楼主 | 2009-12-25 19:45 | 只看该作者 回帖奖励 |倒序浏览
由于公司的诸多限制,机器都加了密,网络也全都控制着。装的linux机器上不了网,和加密的机器也都ping不通。巨郁闷

使用特权

评论回复
42
tiger84|  楼主 | 2009-12-25 19:52 | 只看该作者
上午就瞎忙活,培训,开会,申请IP权限等。想整个FTP服务器也没整成功。
下午把网络通讯试了试,服务器和客户机效果都不错。

今天晚上继续弄ftp服务器,
明天把web,tftp,nfs,smb服务器等相关的配置以及防火墙配置,用户权限管理等都弄好,并搭建好ARM开发环境。
这2周弄的2个简单的驱动程序都是照葫芦画瓢,相关的细节还没有仔细研究,打算星期天研究下,做到对简单的驱动了如指掌。
下周就要开始DSP的HPI驱动了。

使用特权

评论回复
43
tiger84|  楼主 | 2009-12-25 19:54 | 只看该作者
// 以下是利用poll做的按键驱动,逻辑上有些问题,不过可以使用
//驱动

//未加去抖动

//通过poll判断是否可读来得到中断值

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <asm/irq.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <linux/cdev.h>
#include <linux/irq.h>


#include <mach/board.h>
#include <mach/gpio.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
#include <mach/at91_pio.h>


#define DEVICE_NAME "buttons_my"
#define BUTTON_MAJOR 0                      // 定义0使用自动分配设备号
unsigned int button_major = BUTTON_MAJOR;
/*
struct button_irq_desc
{
int irq; //中断号
int pin; //中断控制的寄存器   
int pin_setting; //中断的引脚
int number; //编号
char *name; //名称
};

static struct button_irq_desc button_irqs [] =
{
{IRQ_EINT11,S3C2410_GPG3, S3C2410_GPG3_EINT11, 1,"KEY1"},
{IRQ_EINT0, S3C2410_GPF0, S3C2410_GPF0_EINT0,  2,"KEY2"},
{IRQ_EINT19,S3C2410_GPG11,S3C2410_GPG11_EINT19,3,"KEY3"},
{IRQ_EINT2, S3C2410_GPF2, S3C2410_GPF2_EINT2,  4,"KEY4"},
{IRQ_EINT6, S3C2410_GPF6, S3C2410_GPF6_EINT6,  5,"KEY5"},
{IRQ_EINT5, S3C2410_GPF5, S3C2410_GPF5_EINT5,  6,"KEY6"},
};
*/
// 按键硬件资源、键值信息结构体
static struct key_info
{
    int irq_no;                         // 中断号
    int irq_type;                       // 中断类型
    unsigned int gpio_port;             // GPIO端口
    int key_no;                         // 键值
   
   
}key_info_tab[4]=
// 按键所使用的CPU资源
{
   
    {
        AT91_PIN_PB0,AT91_AIC_SRCTYPE_FALLING,AT91_PIN_PB0,1
    },
    {
        AT91_PIN_PB1,AT91_AIC_SRCTYPE_FALLING,AT91_PIN_PB1,2
    },
    {
        AT91_PIN_PB2,AT91_AIC_SRCTYPE_FALLING,AT91_PIN_PB2,3
    },
    {
        AT91_PIN_PB3,AT91_AIC_SRCTYPE_FALLING,AT91_PIN_PB3,4
    },
};


static volatile int key_values [] = {0,0,0,0};/*key_values数组中是否有数据的标志,0表示无数据可读,1表示有数据可读*/
static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

static volatile int ev_press = 0; /*初始为0*/

// 初始化
static void at91sam9260_key_io_init(void)
{
    at91_set_gpio_input(AT91_PIN_PB0, 1);       
        at91_set_deglitch(AT91_PIN_PB0, 1);
       
        at91_set_gpio_input(AT91_PIN_PB1, 1);       
        at91_set_deglitch(AT91_PIN_PB1, 1);

        at91_set_gpio_input(AT91_PIN_PB2, 1);       
        at91_set_deglitch(AT91_PIN_PB2, 1);
       
        at91_set_gpio_input(AT91_PIN_PB3, 1);       
        at91_set_deglitch(AT91_PIN_PB3, 1);
}

// 中断处理
static irqreturn_t buttons_interrupt(int irq,void *dev_id)
{

// struct key_info *button_irqs = (struct key_info *)dev_id;
int key = (int)dev_id;

//没去抖动   
// key_values[button_irqs->key_no - 1] = button_irqs->key_no;  //zhh
key_values[key] = key + 1;
ev_press = 1; // 表示数组已经可读了
wake_up_interruptible(&button_waitq);   //zhh

return IRQ_RETVAL(IRQ_HANDLED);
}

static int request_irqs(void)
{
   
    struct key_info *k;
    int i;
    int ret;
   
    for(i = 0; i < sizeof(key_info_tab)/sizeof(key_info_tab[1]); i++)

    {
        k = key_info_tab + i;
        //设置4个IO口为中断下降沿触发方式
         set_irq_type(key_info_tab[i].irq_no, key_info_tab[i].irq_type);      // 设置中断类型
            
        //申请中断(类型为快速中断,中断服务时屏蔽所有外部中断?)将按键序列号作为参数传入中断服务程序        
      //  if(request_irq(k->irq_no,at91sam9260_enit_key,0,DEVICE_NAME,(void *)i))
        ret = request_irq(k->irq_no,buttons_interrupt,0,DEVICE_NAME,(void *)i);        
        if(ret)
        {
            printk(KERN_NOTICE "buttons:err is %d\r\n",ret);
            break;
        }
    }

    if(ret)
    {
        i--;
        for(;i >=0; i--)
        {
            disable_irq(key_info_tab[i].irq_no);
            free_irq(key_info_tab[i].irq_no,(void *)&key_info_tab[i]);
        }
        return -EBUSY;
    }

    return 0;
   
}

//open 注册中断
static int buttons_open(struct inode *inode,struct file *file)
{
    int i;

    i = 0;
   
    return 0;
}
//close 释放中断
static int buttons_close(struct inode *inode,struct file *file)
{
    int i;
    for(i = 0;i < sizeof(key_info_tab)/sizeof(key_info_tab[0]);i++)
    {
        disable_irq(key_info_tab[i].irq_no);
        free_irq(key_info_tab[i].irq_no,(void *)&key_info_tab[i]);
    }
   
    return 0;
}
//read
static int buttons_read(struct file *filp,char __user *buff,size_t count,loff_t *offp)
{
    unsigned long err;  

    if(!ev_press) /*标志位为0,即无数据时*/
    {
        if(filp->f_flags & O_NONBLOCK) //不能以非阻塞读取
        {
              return -EAGAIN;
        }      
        else
        {
             wait_event_interruptible(button_waitq,ev_press);
        }      
      
    }

    err = copy_to_user(buff,(const void *)key_values,min(sizeof(key_values),count));
    memset((void *)key_values,0,sizeof(key_values));
    ev_press = 0;
    if(err)
    {
          return -EFAULT;
    }  
    else
    {
         return min(sizeof(key_values),count);
    }   
}
//buttons_poll
static unsigned int buttons_poll(struct file *file,struct poll_table_struct *wait)
{
    unsigned int mask = 0;

    poll_wait(file,&button_waitq,wait);
   
    if(ev_press)
    {
        mask |= POLLIN | POLLRDNORM;
    }
   
    return mask;
}

static struct file_operations buttons_fops =
{
.owner = THIS_MODULE,
.open = buttons_open, /*open()*/
.release = buttons_close, /*release()*/
.read = buttons_read, /*read()*/
.poll = buttons_poll /*poll()*/
};
struct cdev button_cdev;                       // cdev结构体
/* 初始化并注册cdev */
static void buttons_setup_cdev(void)
{
    int err,devno = MKDEV(button_major,0);
    cdev_init(&button_cdev,&buttons_fops);
    button_cdev.owner = THIS_MODULE;
    button_cdev.ops = &buttons_fops;
    err = cdev_add(&button_cdev, devno, 1);
    if (err)
        printk(KERN_NOTICE "Error %d adding utukey", err);
}
//init
static int __init buttons_init(void)
{
int result;
dev_t devno = MKDEV(button_major,0);    // 用主次设备号生成设备号

at91sam9260_key_io_init();
    /* 申请设备号 */
    if (button_major)
        result = register_chrdev_region(devno, 1, DEVICE_NAME);
    else    /* 动态申请设备号 */
    {
        result = alloc_chrdev_region(&devno, 0, 1, DEVICE_NAME);
        button_major = MAJOR(devno);
        printk(KERN_INFO "Todo: mknod /dev/%s c %d 0\n", DEVICE_NAME, button_major);
    }
if (result < 0)
        return result;

buttons_setup_cdev();

// 注册中断函数
if(-1 == request_irqs())
{
    printk(KERN_NOTICE "request_irqs failed!\r\n");
}
else
{
    printk(KERN_NOTICE "request_irqs success!\r\n");
}


printk(DEVICE_NAME " initialized\n");
return 0;
}
//buttons_exit()
static void __exit buttons_exit(void)
{
cdev_del(&button_cdev);                             // 注销cdev
unregister_chrdev_region(MKDEV(button_major, 0), 1);    // 释放设备号
}

module_init(buttons_init);
module_exit(buttons_exit);

MODULE_AUTHOR("http://www.xxx.net");
MODULE_DESCRIPTION("S3C2410/S3C2440 BUTTON Driver");
MODULE_LICENSE("GPL");

使用特权

评论回复
44
tiger84|  楼主 | 2009-12-25 19:54 | 只看该作者
// 与poll配套的select应用程序
//测试代码

/*按键测试程序*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>

int main(void)
{
    int i;
    int buttons_fd;
    int key_value[4];
    fd_set rds;
    int ret;

    buttons_fd = open("/dev/buttons_my",0);
    if(buttons_fd < 0)
    {
        perror("open device buttons");
        exit(1);
    }

    while(1)
    {
        FD_ZERO(&rds);
        FD_SET(buttons_fd,&rds);

        ret = select(buttons_fd + 1,&rds,NULL,NULL,NULL);
        if(ret < 0)
        {
            perror("select");
            exit(1);
        }     
        if(ret == 0)
        {
            printf("Timeout.\n");
        }
        else if(FD_ISSET(buttons_fd,&rds))
        {
            int ret = read(buttons_fd,key_value,sizeof(key_value));
            if(ret != sizeof(key_value))
            {
                if(errno != EAGAIN)   
                perror("read buttons");
                continue;
            }
            else
            {
                for(i = 0; i < 4 ; i++)
                {
                    if(key_value[i] != 0)
                    printf("You pressed buttons %d\n", key_value[i]);
                }   
            }
        }
    }
    /*关闭设备*/
    close(buttons_fd);
    return 0;
}

使用特权

评论回复
45
tiger84|  楼主 | 2009-12-26 17:44 | 只看该作者
今天上午把相关的如telnet,ftp服务器都搭建好了,试了下功能,都可以做些简单的应用。
主要困难在于机器无法直接连到网络,以前安装时利用命令yum install xxxx就搞定了,现在就相对麻烦一点。
刚开始下的是源码,安装时虽然指定了路径,但是使用时总是出现一些小问题,很头大。于是下了RPM包才搞定。
所以像俺这样的菜鸟,还是推荐使用RPM包安装。

下午就开始搭建ARM开发平台,编译u-boot时出现了问题,现在仍然没有解决。

使用特权

评论回复
46
icecut| | 2009-12-26 18:05 | 只看该作者
呵呵.我下载的是3.几个G的安装包

使用特权

评论回复
47
tiger84|  楼主 | 2009-12-26 19:58 | 只看该作者
编译u-boot不成功的主要原因是现在用的fedora 11,里面的包之类的都是i586的,弄了很久都没有成功。
在考虑是不是要返回fedoa 10

使用特权

评论回复
48
tiger84|  楼主 | 2009-12-27 16:06 | 只看该作者
今天跑到华强北辛辛苦苦找了半天,去买了2张比较新的redhat,兴冲冲的安装,靠,不能用!气愤的扔了!然后开始骂那个奸商!

使用特权

评论回复
49
icecut| | 2009-12-27 21:52 | 只看该作者
网上能下。

不过这个与系统真没关系。

交叉编译怎么能用host有关系呢?

使用特权

评论回复
50
icecut| | 2009-12-27 21:56 | 只看该作者
我用的10.你要不换灰10.试试。换环境也是不错的方法

使用特权

评论回复
51
tiger84|  楼主 | 2009-12-29 08:21 | 只看该作者
昨天没来报道,惭愧,因为基本在忙其他的事,先来签个到。
今日主要打算安装系统,做好权限管理,防火墙之类的工作。
这个xsheel工具里面的xftp好像登上去了,什么权限都有,郁闷。

使用特权

评论回复
52
tiger84|  楼主 | 2009-12-29 12:34 | 只看该作者
系统已经安装好了,相关环境也搭建完毕。
打算下午搞个DS1302驱动。
LDD3据说很不错,下了个电子版,打算今天到元旦抽空走马观花看完。

使用特权

评论回复
53
tiger84|  楼主 | 2009-12-29 21:24 | 只看该作者
继续。
没想到DS1302的驱动也比较难弄,估计明天也未必能搞定。
主要原因就是我现在只是熟悉了字符设备驱动,其他的还没看,得抓紧时间看了。

使用特权

评论回复
54
tiger84|  楼主 | 2009-12-29 21:27 | 只看该作者
现在的计划是元旦之前搞定简单混杂设备及平台设备驱动。

使用特权

评论回复
55
itelectron| | 2009-12-30 16:21 | 只看该作者
:handshake   顶

使用特权

评论回复
56
牛牛特工| | 2009-12-30 20:53 | 只看该作者
俺们折腾了半天 Uboot还没启动起来呢 编译好了 能够下载了 但还运行不了
一上来程序就跑飞了 连一个指令都没执行 郁闷的我没话说~~
我现在先看看鸟哥的linux私房菜 看看一些基本命令 好歹熟悉一下吧 ~~

使用特权

评论回复
57
tiger84|  楼主 | 2009-12-31 18:42 | 只看该作者
很惭愧。ds1302驱动还未搞定。
主要原因:
对linux驱动未整体把握。

由于女朋友回来了,元旦只能拿出1到2天,不过一定得搞定。

使用特权

评论回复
58
123654789| | 2009-12-31 18:48 | 只看该作者
一般情况之下 能跑LINUX的CPU都带有时钟寄存器
不知道楼上为什么还要用DS1302 ???

使用特权

评论回复
59
tiger84|  楼主 | 2009-12-31 18:54 | 只看该作者
ds1302驱动要加进去,打算使用的步骤:
1,在arch/arm/mach-at91/board-sam9260ek.c里添加该设备相关信息设备地址;
2,参考rtc-ds1302.c文件,改成合适为手上的开发板;
3,修改./driver/rtc/Kconfig,把ds1302的配置显示出来(源文件中依赖于一个sh之类的CPU吧,直接去掉了)
内核显示:
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
选中RTC
[*]   Set system time from RTC on startup and resume

(rtc0)  RTC used to set the system time
<*>   DALLas DS1302
4,改busybox文件系统的hwclock

使用特权

评论回复
60
tiger84|  楼主 | 2009-12-31 18:55 | 只看该作者
这大半个月的linux驱动学习:只是基本掌握了字符驱动,对Linux驱动有了一点认识。
学习中的主要困难就是对驱动一无所知,非常茫然,不知道从何下手,碰到问题了只能google。有时1个简单的问题要好几天。
收集了一个arm-linux启动资料,一并贴出来。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则