linux 2.6.30内核,9g45开发板,gpio驱动

gaoqiaoming 2012-04-19 01:58:56
求一个atmel sam9g45开发板的gpio驱动程序,应用程序通过写入1/0控制led灯的亮暗,管脚用AT91_PIN_PB20,用insmod加载,小弟对驱动一无所知,也不知道问题讲清楚没,刚开始了解一天,求大牛帮忙
...全文
259 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
gaoqiaoming 2012-04-27
  • 打赏
  • 举报
回复
驱动已经好了,成功加载实现控制led的亮跟灭了,结贴给分了
nadleeh 2012-04-26
  • 打赏
  • 举报
回复
内核里面写的话 要用到ioremap,具体百度下
nadleeh 2012-04-26
  • 打赏
  • 举报
回复
说下步骤吧,首先你得有电路图,知道LED和芯片怎么连的,连到那跟脚上去了(一般是GPXX),然后去查芯片文档关于GPXX的描述,然后建立指针,赋值。。。。
pengchy 2012-04-19
  • 打赏
  • 举报
回复
给你提供一个代码,你在自己的内核交叉编译环境上编译,有可能头文件引用的不怎么正确,编译的时候修改一下就OK了.
头文件: geo_ds_gpio.h

#ifndef __GEO_DS_GPIO_H__
#define __GEO_DS_GPIO_H__

#include <linux/sched.h>
#include <linux/init.h>

/* PIN definitions */

#define GEO_DS_GPIO_MAGIC 's'

#define SWITCH_LED_ON _IOW( GEO_DS_GPIO_MAGIC, 0, int ))

#define GEO_DS_GPIO_MAXNR 1

/* PIN definitions */
#define PIN_LED_STAT AT91_PIN_PB30

#endif // __GEO_DS_GPIO_H__


代码: geo_ds_gpio.c

#include <linux/init.h>
#include <linux/module.h> /* get MOD_DEC_USE_COUNT, not the version string */
#include <linux/moduleparam.h>
#include <linux/version.h> /* need it for conditionals in geoad.h */
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/string.h>
#include <asm/arch/gpio.h>
#include <linux/cdev.h>
#include <linux/delay.h>

#include <asm/system.h> /* rmb(), wmb() */
#include <asm/io.h> /* inb(), outb() */
#include <asm/uaccess.h>

#include <mach/board.h>
#include <mach/gpio.h>
#include <mach/at91sam9_smc.h>
#include <mach/at91_ssc.h>

#include "geo_ds_gpio.h" /* local definitions */

#define GPIO_NR_DEVS 1 /* device number */

int gpio_major = 105; /* major device number */
int gpio_nr_devs = GPIO_NR_DEVS; /* number of gpio control devices */
char gpio_name[16]; /* device name */

MODULE_AUTHOR( "Pengchy" );
MODULE_LICENSE( "GPL" );

int gpio_ioctl( struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg )
{
if( _IOC_TYPE(cmd) != GEO_DS_GPIO_MAGIC )
return -EINVAL;
if( _IOC_NR(cmd) >= GEO_DS_GPIO_MAXNR )
return -EINVAL;

switch( cmd )
{
case SWITCH_LED_ON:
at91_set_gpio_value( PIN_LED_STAT, arg ); break;
default:
return -ENOTTY;
}

return 0;
}

/*
* Open and close.
*/
int gpio_open( struct inode *inode, struct file *filp )
{
return 0;
}

int gpio_release( struct inode *inode, struct file *filp )
{
return 0;
}

/* for device gpio control */
static struct file_operations gpio_fops =
{
.owner = THIS_MODULE,
.open = gpio_open,
.release = gpio_release,
.ioctl = gpio_ioctl,
};

struct GPIO_DEVS
{
struct cdev cdev; /* Char device structure */
};

static struct GPIO_DEVS gpio_device;

static struct gpio_dev_info
{
char *name;
struct GPIO_DEVS *dev;
struct file_operations *fops;
} gpio_devs[] = {
{ "gpio_ctl", &gpio_device, &gpio_fops }
};

/*
* Set up the char_dev structure for this device.
*/
void gpio_setup_cdev( struct gpio_dev_info *devinfo, int index )
{
int err, devno = MKDEV( gpio_major, index );
struct GPIO_DEVS *dev = devinfo->dev;

/* Do the cdev stuff. */
cdev_init( &dev->cdev, devinfo->fops );
kobject_set_name( &dev->cdev.kobj, devinfo->name );
dev->cdev.owner = THIS_MODULE;
dev->cdev.ops = devinfo->fops;
err = cdev_add( &dev->cdev, devno, 1 );

/* Fail gracefully if need be */
if( err )
{
printk( KERN_NOTICE "Error %d adding %s\n", err, devinfo->name );
kobject_put( &dev->cdev.kobj );
}
else
printk( KERN_NOTICE "%s registered at %x\n", devinfo->name, devno );
}

static void init_hardware_pin()
{
at91_set_gpio_output( PIN_LED_STAT, 1 );
}

static int __init gpio_init( void )
{
int err = -1, i = 0;
dev_t devno = MKDEV( gpio_major, 0 );

memset( gpio_name, '\0', sizeof(gpio_name) );
sprintf( gpio_name, "%s", "gpio_ctl" );

/*
* Get a range of minor numbers to work with, asking for a dynamic
* major unless directed otherwise at load time.
*/
if( gpio_major )
err = register_chrdev_region( devno, gpio_nr_devs, gpio_name );
else
{
err = alloc_chrdev_region( &devno, 0, gpio_nr_devs, gpio_name );
gpio_major = MAJOR( devno );
}

if( err < 0 )
{
printk( KERN_WARNING "gpio: can't get major %d\n", gpio_major );
goto err001;
}

// Setup the geo devices.
for( i = 0; i < gpio_nr_devs; i++ )
gpio_setup_cdev( &gpio_devs[i], i );

init_hardware_pin();

printk( KERN_INFO "***************** gpio control driver started **************\n" );

return 0;

err001:
return err;
}

static void __exit gpio_exit( void )
{
int i = 0;
dev_t devno = MKDEV( gpio_major, 0 );

init_hardware_pin();

/* Clean up the static devs */
for( i = 0; i < gpio_nr_devs; i++ )
{
struct GPIO_DEVS *dev = gpio_devs[i].dev;
cdev_del( &dev->cdev );
}

unregister_chrdev_region( devno, gpio_nr_devs );
}

module_init( gpio_init );
module_exit( gpio_exit );
awsqsh 2012-04-19
  • 打赏
  • 举报
回复
去找本书 抄抄得了 要别人帮你写个驱动,估计大家都不愿意。

21,597

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧