linux c led 驱动程序,uclinux简单LED驱动程序

uclinux简单LED驱动程序

by panasonic.lin@163.com

这回还是拿44b0x板上的LED开唰,这是linux2.4的方法,linux2.6有很大区别,相比之下还是2.4的内核比较简单,2.6比较灵活点。

首先声明,此方法是把驱动编译进内核,如果驱动程序比较多的话可能导致内核很冗肿,这时候建议用可加载模块的方式。顶层的简单应用程序放在文件系统中。

1.0

uClinux-dist20050311/linux-2.4.x/drivers/char/{led.h,led.c}

驱动头文件

/************************************************************************************************************/

/*************led.h*************************************************/

/***********************************************************************************************************/

#ifndef __CONFIG_H

#define __CONFIG_H

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define LED_MAJOR_NR 231

#define DEVICE_NAME "led"

#define PCONC (*(volatile unsigned *)0x01D20010)

#define PDATC (*(volatile unsigned *)0x01D20014)

#define SET_LED_OFF 0

#define SET_LED_ON  1

#define LED0_CON (0x01<<2)

#define LED1_CON (0x01<<4)

#define LED2_CON (0x01<<6)

#define LED0_DAT (0X1<<1)

#define LED1_DAT (0X1<<2)

#define LED2_DAT (0X1<<3)

#endif

驱动程序主体:

/************************************************************************************************************/

/*************led.c*************************************************/

/***********************************************************************************************************/

#include"led.h"

static int led_open(struct inode *inode,struct file *filp);

static int led_release(struct inode *inode,struct file *filp);

static int led_ioctl(struct inode *inode,struct file *filp,unsigned int cmd);

int led_init(void);

void led_cleanup(void);

static struct file_operations LED_fops=

{

owner:THIS_MODULE,

#if 0

llseek:gpio_llseek,

read:gpio_read,

write:gpio_write,

#endif

ioctl:led_ioctl,

open:led_open,

release:led_release,

};

static int led_open(struct inode *inode,struct file *filp)

{

PCONC =(PCONC&(~(0XC)))|LED0_CON;//change led0,not change led1 and led2!

MOD_INC_USE_COUNT;

return 0;

}

static int led_release(struct inode *inode,struct file *filp)

{

MOD_DEC_USE_COUNT;

return 0;

}

static int led_ioctl(struct inode *inode,struct file *filp,unsigned int cmd)

{

switch(cmd)

{

case 0:

PDATC |= LED0_DAT;//LED0=1

break;

case 1:

PDATC &=~(LED0_DAT);//LED0=0

break;

default:

return -1;

break;

}

return 0;

}

int led_init(void){

int result;

result=register_chrdev(231,"led",&LED_fops);

if(result<0)

{

printk(KERN_ERR ":unable to register!\n");

return (result);

}

printk(KERN_DEBUG ":init OK\n");

return 0;

}

void led_cleanup(void)

{

unregister_chrdev(231,"led");

}

2.0

/uClinux-dist20050311/user/ledtest/{ledtest.c,Makefile}

用户空间程序

/************************************************************************************************************/

/*************ledtest.c*********************************************/

/***********************************************************************************************************/

#include

#include

#include

#include

#include

#include

void delay(int delay){

int i;

for(;delay>0;delay--){

for(i=0;i<5000;i++);

}

}

int main(){

int fd1;

int j;

fd1=open("/dev/led",O_RDWR);

if(fd1== -1){

printf("file can not be open");

return -1;

}

for(j=0;j<10;j++)

{

ioctl(fd1,1);

delay(1000);

ioctl(fd1,0);

delay(1000);

}

close(fd1);

return 0;

}

/************************************************************************************************************/

/*************Makefile*********************************************/

/***********************************************************************************************************/

EXEC = ledtest

OBJS = ledtest.o

all: $(EXEC)

$(EXEC): $(OBJS)

$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS)

romfs:

$(ROMFSINST)   /bin/$(EXEC)

clean:

rm -f $(EXEC) *.elf *.gdb *.o

3.0

修改添加驱动配置文件和Makefile

uClinux-dist20050311/linux-2.4.x/drivers/char/{Makefile,config.in,mem.c}

Makefile

obj-$(CONFIG_C5471_WDT) += wdt_c5471.o

#add by panasonic 2009-12-12

obj-$(CONFIG_LED_TEST) += led.o

config.in

if [ "$CONFIG_CPU_S3C44B0X" = "y" ]; then

bool 'Samsung S3C44B0X serial ports support' CONFIG_SERIAL_S3C44B0X

bool 'test led drivers' CONFIG_LED_TEST

if [ "$CONFIG_SERIAL_S3C44B0X" = "y" ]; then

mem.c

int __init chr_dev_init(void)

{

if (devfs_register_chrdev(MEM_MAJOR,"mem",&memory_fops))

printk("unable to get major %d for memory devs\n", MEM_MAJOR);

memory_devfs_register();

rand_initialize();

/*add by panasonic 2009-1-1*/

#ifdef CONFIG_LED_TEST

led_init();

#endif

#ifdef CONFIG_I2C

i2c_init_all();

#endif

uClinux-dist20050311/vendors/Samsung/44B0/Makefile

DEVICES = \

tty,c,5,0    console,c,5,1    cua0,c,5,64    cua1,c,5,65 \

\

mem,c,1,1    kmem,c,1,2    null,c,1,3 \

zero,c,1,5    random,c,1,8    urandom,c,1,9  \

\

ram0,b,1,0    ram1,b,1,1 \

\

ptyp0,c,2,0    ptyp1,c,2,1    ptyp2,c,2,2    ptyp3,c,2,3 \

ptyp4,c,2,4    ptyp5,c,2,5    ptyp6,c,2,6    ptyp7,c,2,7 \

ptyp8,c,2,8    ptyp9,c,2,9    ptypa,c,2,10    ptypb,c,2,11 \

ptypc,c,2,12    ptypd,c,2,13    ptype,c,2,14    ptypf,c,2,15 \

\

rom0,b,31,0    rom1,b,31,1    rom2,b,31,2    rom3,b,31,3 \

rom4,b,31,4    rom5,b,31,5    rom6,b,31,6    rom7,b,31,7 \

rom8,b,31,8    rom9,b,31,9 \

\

tty0,c,4,0    tty1,c,4,1    tty2,c,4,2    tty3,c,4,3 \

ttyS0,c,4,64    ttyS1,c,4,65 \

\

ttyp0,c,3,0    ttyp1,c,3,1    ttyp2,c,3,2    ttyp3,c,3,3 \

ttyp4,c,3,4    ttyp5,c,3,5    ttyp6,c,3,6    ttyp7,c,3,7 \

ttyp8,c,3,8    ttyp9,c,3,9    ttypa,c,3,10    ttypb,c,3,11 \

ttypc,c,3,12    ttypd,c,3,13    ttype,c,3,14    ttypf,c,3,15 \

\

led,c,231,0

4.0

修改添加应用程序的配置和Makefile

uClinux-dist20050311/user/Makefile

dir_$(CONFIG_USER_HELLO)                    += app

dir_$(CONFIG_USER_LEDTEST)                  += ledtest

uClinux-dist20050311/config/config.in

#############################################################################

mainmenu_option next_comment

comment 'led driver test'

bool 'LEDtest'    CONFIG_USER_LEDTEST

comment "LED_TEST"

endmenu

#############################################################################

5.0

编译连接调试

$make menuconfig

选中customize kernel settings/customize vendor/user settings

然后在kernel setting那里选中test led drivers

最后在vendor/user setting那里选中led drivers test下面的LEDtest应用程序

6bbc806a-948e-4035-8865-dccb26706899.jpg

7ca729b8-0008-42b3-9167-196f34b50dae.jpg

dfd945ee-e44c-4f66-aaac-3e3006f56286.jpg

7f364db9-6af0-4654-8ed2-245279272871.jpg

$make clean

$make dep

$make lib_only

$make user_only

$make romfs

$make image

$make

生成uclinux_rom.bin,uclinux_ram.bin.gz,romfs.img

uclinux_rom.bin拷贝到tftp输出目录。

将根文件系统映像挂载到回环设备,然后拷贝到nfs输出目录:

$mount -o loop romfs.img /mnt

$cp -a /mnt/* /home/panasonic/nfs-root/

在根文件系统的/etc目录新建init.d目录,在init.d目录下新建rcS脚本

#!/bin/sh

mount -t proc proc /proc

hostname 44b0

cat /etc/motd

/bin/msh

$chmod +x rcS添加可执行属性。

重启nfs服务

打开minicom

打开板子

$ping 192.168.0.1

$tftpboot 0xc500000

$bootm 0xc500000

进入shell后首先看看/dev下面有没有led的设备文件

20d9909a-0c57-4ae7-acca-a95f9e03e692.jpg

也可以cat /proc/devices查看

78165579-74f2-4de5-a19b-264ce1033f63.jpg

好,看看bin目录有没有用户空间应用程序ledtest

5f835400-aec4-4761-a50a-cb8de264709b.jpg

运行./ledtest即可看到led一闪一闪的。

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值