开发环境:VMware 下的fedora9
开发板:mini2440(64M FLASH)
内核:linux-2.6.32.2(FriendlyARM光盘中所带,将其解压到/opt/FriendlyARM/mini2440/目录下)
(一)编写编译及加载LED模块驱动程序
(1) 编写LED模块驱动程序mini2440led.c,如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static unsigned long led_table[]=
{
S3C2410_GPB(5),
S3C2410_GPB(6),
S3C2410_GPB(7),
S3C2410_GPB(8),
};
dev_t devno;//1.0 分配设备号变量
struct cdev dev; //2.0 分配dev结构体
static int mini2440_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
{
if(arg<4) //因为开发板上只有四个LED(0.1.2.3)所以限制一下操作LED的数量
{
switch(cmd)
{
case 0:
s3c2410_gpio_setpin(led_table[arg],!cmd);
return 0;
case 1:
s3c2410_gpio_setpin(led_table[arg],!cmd);
return 0;
default:
return -EINVAL;
}
}
else
{
printk("<0>""the led number is faile!\n");
return -EINVAL;
}
}
struct file_operations fops={ //2.0 分配file_operations结构体
.owner = THIS_MODULE,
.ioctl = mini2440_ioctl,
};
static int __init led_init(void)
{
int i;
printk("<0>""the led function startup!\n");
for(i=0;i<4;i++) //配置相应的LED脚为输出
{
s3c2410_gpio_cfgpin(led_table[i],S3C2410_GPIO_OUTPUT);
}
for(i=0;i<4;i++) //配置相应的LED输出高电平全部熄灭
{
s3c2410_gpio_setpin(led_table[i],1);
}
alloc_chrdev_region(&devno,0,1,"luciensong-led");//1.1 动态申请设备号
cdev_init(&dev,&fops); //2.1 初始化dev,并建立dev与fops间的连接
dev.owner=THIS_MODULE; //2.1 指定dev模块所属
cdev_add(&dev,devno,1); //2.2 添加dev
return (0);
}
static void __exit led_exit(void)
{
int i;
printk("<0>""the led function end!\n");
for(i=0;i<4;i++) //
{
s3c2410_gpio_setpin(led_table[i],1);
}
cdev_del(&dev);//3.0注销设备dev
unregister_chrdev_region(devno,1);//3.1注销设备号
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lucien Song");
MODULE_VERSION("V0.1");
(2)将其放入/opt/FriendlyARM/mini2440/linux-2.6.32.2/drivers/char/目录下,修改此目录下的Makefile.(添加obj-m += mini2440led.o)
(3) 因为这个内核源代码是经FriendlyARM公司修改过的,所以有些东西我们不需要再去修改,比如ARCH=arm, CORSS_COMPILE=arm-linux-都已为ARM平台修改好,这里我们复制config_mini2440_n35并重新命令为.config.
cp config_mini2440_n35 .config
(4) 编译模块.
make modules
编译结束后,在/opt/FriendlyARM/mini2440/linux-2.6.32.2/drivers/char/目录下会生成相应的mini2440led.ko文件.
(5) 通过串口将其下载到开发板的/lib/modules/2.6.32.2-FriendlyARM/目录下.
(6) 加载LED驱动模块
cd /lib/modules/2.6.32.2-FriendlyARM/
insomd ./mini2440led.ko
(7) 获取设备号,因为这里的LED驱动模块简单的编写成了动态申请设备号,获取设备号是为了下一步在/dev目录下创建一个设备.
cat /proc/devices
luciensong-led这个设备就是我编写的LED模块设备名称.
(8) 创建设备. mknod /dev/设备名 类型(字符设备c,块设备b) 主设备号 次设备号
mknod /dev/luciensong-led c 253 0
然后ls /dev就可以查看到创建的这个设备.
(二)编写LED应用程序并编译下载.
(1) 编写LED应用程序mini2440led_aps.c
#include
#include
#include
#include
#include
#include
int main(int argc,char *argv[])
{
int num;
int statue;
int fd;
sscanf(argv[1],"%d",&num);
sscanf(argv[2],"%d",&statue);
fd = open("/dev/luciensong-led",O_RDWR);
if(fd<0)
{
perror("open dev/luciensong-led faile!\n");
return (-1);
}
printf("open /dev/luciensong-led success!\n");
ioctl(fd,statue,num);
printf("statue=%d,num=%d\n",statue,num);
close(fd);
return (0);
}
(2) 编译
# arm-linux-gcc mini2440led_aps.c -o mini2440led_aps
之后会生成相应的mini2440led_aps可执行文件
(3) 通过串口下载到开发板上的/lib/modules/2.6.32.2-FriendlyARM/目录下(也可以下载到别的目录,这里和驱动模块下载到了同目录下,方便查看)
(4) 修改权限
# chmod +X mini2440led_aps
(5) 运行(运行LED模块之前应把内核本身加载的LED卸载,具体可参考开发板的使用手册)
./mini2440led_aps 2 1
这时开发板上的第三个灯会被点亮