免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1049 | 回复: 0
打印 上一主题 下一主题

AT91RM9200下的LED驱动程序实现及其分析 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-06-29 16:44 |只看该作者 |倒序浏览
    在FFT的AT91RM9200的企业版开发板上做了一个LED的驱动程序,帖上来和大家共享一下。FFT虽说此版为企业版,但并没有提供所有硬件的驱动程序,比如LED的驱动程序就没有,而在调试软件的时候又经常会用,无奈只有自己写了。
1)说明:在头文件里面有些是我调试时用的,调试完了,懒得删除。
2)源代码:该程序的源代码,是根据刘淼(《嵌入式系统接口设计与LINUX驱动程序开发》)的双色LED驱动程序,我采用了他的程序框架,同时拷贝了AT91下的串口驱动,改8改8就成这样了。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#define MODVERSIONS      
//#include
#include
#include
#undef DEBUG
#define DEBUG
#ifdef DEBUG
#define DPRINTK(x...) printk(KERN_ALERT##"s3c2410-led:"##x)
#else
#define DPRINTK(x...)
#endif
#define LED6 15
#define LED7 16
#define LED8 17
#define LED9 26
static unsigned int led[]={AT91C_PIO_PB15,AT91C_PIO_PB16,AT91C_PIO_PB17,AT91C_PIO_PB26};
#define LEDNUM (sizeof(led)/sizeof(*led))
#define DEVICE_NAME "AT91RM9200-LED"
#define DbLedRAW_MINOR 1
static int DbLedMajor =0;
static char ledstatus = 0x00;
#define DLYNUM 100
static void Led_init1(void);
static void Led_off_all(void)
{
AT91_SYS->PIOB_SODR = AT91C_PIO_PB15|AT91C_PIO_PB16|AT91C_PIO_PB17|AT91C_PIO_PB26;
}
static void Updateled(void)
{
DPRINTK("in update ledstatus = %x\n",ledstatus);
if(ledstatus&0x01)AT91_SYS->PIOB_CODR=AT91C_PIO_PB15;
else AT91_SYS->PIOB_SODR=AT91C_PIO_PB15;
if(ledstatus&0x02)AT91_SYS->PIOB_CODR=AT91C_PIO_PB16;
  else AT91_SYS->PIOB_SODR=AT91C_PIO_PB16;
if(ledstatus&0x04)AT91_SYS->PIOB_CODR=AT91C_PIO_PB17;
  else AT91_SYS->PIOB_SODR=AT91C_PIO_PB17;
if(ledstatus&0x08)AT91_SYS->PIOB_CODR=AT91C_PIO_PB26;
  else AT91_SYS->PIOB_SODR=AT91C_PIO_PB26;
}
static void Led_init1(void)
{
AT91_SYS->PIOB_PER = AT91C_PIO_PB15|AT91C_PIO_PB16|AT91C_PIO_PB17|AT91C_PIO_PB26;
AT91_SYS->PIOB_OER = AT91C_PIO_PB15|AT91C_PIO_PB16|AT91C_PIO_PB17|AT91C_PIO_PB26;
AT91_SYS->PIOB_PPUDR = AT91C_PIO_PB15|AT91C_PIO_PB16|AT91C_PIO_PB17|AT91C_PIO_PB26;
AT91_SYS->PIOB_OWDR = AT91C_PIO_PB15|AT91C_PIO_PB16|AT91C_PIO_PB17|AT91C_PIO_PB26;
AT91_SYS->PMC_PCER = (1
static ssize_t s3c2410_DbLed_write(struct file *file,const char *buffer,size_t count,loff_t *ppos)
{
    copy_from_user(&ledstatus,buffer,sizeof(ledstatus));   
    DPRINTK("buffer = %x, ledstatus = %x\n",*buffer,ledstatus);
    Updateled();   
    return sizeof(ledstatus);
}
static int s32410_DbLed_open(struct inode *inode,struct file *filp)
{
    MOD_INC_USE_COUNT;
    DPRINTK("Open Led.\n");
    return 0;
}
static int s3c2410_DbLed_release(struct inode *inode,struct file *filp)
{
MOD_DEC_USE_COUNT;
DPRINTK("Led release.\n");
Led_off_all();
return 0;  
}
static struct file_operations s3c2410_fops={
owner: THIS_MODULE,
open: s32410_DbLed_open,
write: s3c2410_DbLed_write,
release: s3c2410_DbLed_release,
};
#ifdef CONFIG_DEVFS_FS
static devfs_handle_t devfs_DbLed_dir,devfs_DbLedraw;
#endif
static int __init s3c2410_DbLed_init(void)
{
int ret;
Led_init1();
DPRINTK("Led initialized.\n");
Updateled();

ret = register_chrdev(0,DEVICE_NAME,&s3c2410_fops);
if(ret
static void __exit s3c2410_DbLed_exit(void)
{
#ifdef CONFIG_DEVFS_FS
devfs_unregister(devfs_DbLedraw);
devfs_unregister(devfs_DbLed_dir);
#endif
unregister_chrdev(DbLedMajor,DEVICE_NAME);
Led_off_all();
}
module_init(s3c2410_DbLed_init);
module_exit(s3c2410_DbLed_exit);
EXPORT_NO_SYMBOLS;
MODULE_AUTHOR("Robin Wang");
MODULE_DESCRIPTION("AT91 4Led driver");
MODULE_LICENSE("GPL");

3)调试过程中遇到的问题:
   我在自己见的目录(比如:/usr/debug)里面把驱动编译成模块的形式,当我把编译好的模块insmod的时候,报告错误“at91_led1.o: unresolved symbol AT91_SYS”,没有办法,我只有把驱动程序直接编译到内核里面,不过时间稍微长些把了。
   不过,我希望有知道原因的朋友能一起交流一下。
   具体分析就免了吧,网上太多了,自己有板子的话直接调试一下,就知道怎么回事了。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/42100/showart_331104.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP