日期:2014-05-16  浏览次数:20569 次

zedboard 驱动理解

1 驱动程序的编写

  驱动是LINUX开发的必经之路,应用层对底层的调用经过了库与内核,内核下面才是驱动层,当你在应用程序执行对底层的控制时,驱动程序为你的控制提供了接口,或者说是策略。



#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/io.h>


#define DEVICE_NAME "PWM_MOUDLE"
#define PWM_MOUDLE_PHY_ADDR 0x6CA00000    //This Address is based XPS 这个地址ISE EDK中分配的地址就是硬件的东东啦
/* 描述驱动程序的一些信息,不是必须的 */
MODULE_AUTHOR("Xilinx XUP");             // 驱动程序的作者
MODULE_DESCRIPTION("PWM moudle dirver"); // 一些描述信息
MODULE_VERSION("v1.0");
MODULE_LICENSE("GPL");                   // 遵循的协议


static int pwm_driver_major;
static struct class* pwm_driver_class = NULL;
static struct device* pwm_driver_device = NULL;

unsigned long pwm_fre_addr = 0;		//pwm moulde's frequency visual address
unsigned long pwm_duty_addr = 0;	//pwm moulde's duty visual address
static long frequency=0;

/*这个结构是字符设备驱动的核心*/
static struct file_operations pwm_driver_fops = {
    .owner = THIS_MODULE,               /* 这是一个宏,推向编译模块时自动创建的__this_module变量 在Export.h (c:\users\administrator\desktop\linux-3.3-digilent\include\linux):#define THIS_MODULE (&__this_module)*/
};
static ssize_t sys_pwm_frequency_set (struct device* dev, struct device_attribute* attr, const char* buf, size_t count)
{
    long value = 0;
    int i;
    frequency=0;
    outl(value,  pwm_fre_addr); //close pwm moudle before we modfiy the frequency

    for (i = 0; i < count-1; i++){
        frequency  *= 10;
        frequency += buf[i] - '0';
    }
    if(value>100000000) value=100000000;
    value=100000000/frequency;  // 100Mhz/frequency 100Mhz is set by XPS
	
    outl(value,  pwm_fre_addr);
    return count;
} 

static ssize_t sys_pwm_duty_set (struct device* dev, struct device_attribute* attr, const char* buf, size_t count) //duty cycle 
{
    long value = 0;
    int i;
//
	outl(value,  pwm_duty_addr); //close pwm moudle before we modfiy the duty cycle

    for (i = 0; i < count-1; i++){
        value  *= 10;
        value += buf[i] - '0';
    }
	if (value>100) value=100;
	value=100000000/frequency*value/100;
   
    if (value!= 0)
        value = va