最近爸妈和小姨来玩,学习进度稍微有点放缓。这两天抓紧补了下进度,呵呵。下面分享下蜂鸣器的驱动吧。
0. 环境
硬件:44b0开发板
软件:ucLinux 2.4内核
1. 驱动程序
1.1 驱动源码
在uClinux-dist/linux-2.4.x/drivers/char下建立驱动源文件FengMingQi.c,内容如下
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#include <asm/arch/s3c44b0x.h>
int FMQ_major=188;
#define Non_Cache_Start (0x2000000)
#define Non_Cache_End (0xc000000)
#define BEEP_CMD_SIGNAL 0
/***************PORTS********************/
static int ledman_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
void Port_Init(void)
{
(*(volatile unsigned*)S3C44B0X_PCONA)=0x1ff;
(*(volatile unsigned*)S3C44B0X_PDATB)=0x3ff;
(*(volatile unsigned*)S3C44B0X_PCONB)=0x3ff;
(*(volatile unsigned*)S3C44B0X_PDATC)=0xffff; //All I/O is high
(*(volatile unsigned*)S3C44B0X_PCONC)=0x0f05ff55;
(*(volatile unsigned*)S3C44B0X_PUPC)=0x30f0; //PULL UP Registor should be enabled to I/O
(*(volatile unsigned*)S3C44B0X_PDATD)=0xff;
(*(volatile unsigned*)S3C44B0X_PCOND)=0x0;
(*(volatile unsigned*)S3C44B0X_PUPD)=0x0;
(*(volatile unsigned*)S3C44B0X_PDATE)=0x1ff;
(*(volatile unsigned*)S3C44B0X_PCONE)=0x25568;
(*(volatile unsigned*)S3C44B0X_PUPE)=0x0df;
(*(volatile unsigned*)S3C44B0X_PDATF)=0x1ff;
(*(volatile unsigned*)S3C44B0X_PCONF)=0x20800a;
(*(volatile unsigned*)S3C44B0X_PUPF)=0x163;
(*(volatile unsigned*)S3C44B0X_PDATG)=0xff;
(*(volatile unsigned*)S3C44B0X_PCONG)=0x00ff;
(*(volatile unsigned*)S3C44B0X_PUPG)=0x0;
(*(volatile unsigned*)S3C44B0X_SPUCR)=0x7;
(*(volatile unsigned*)S3C44B0X_EXTINT)=0x0;
(*(volatile unsigned*)S3C44B0X_NCACHBE0)=0;
}
void Beep(int BeepStatus)
{
//PE5 Low available
if(BeepStatus==0)
{
(*(volatile unsigned*)S3C44B0X_PDATE)=(*(volatile unsigned*)S3C44B0X_PDATE)&0x1df; }
else
{
(*(volatile unsigned*)S3C44B0X_PDATE)=(*(volatile unsigned*)S3C44B0X_PDATE)|0x020;
}
}
static int ledman_ioctl(struct inode*inode, struct file*file, unsigned int cmd, unsigned long arg)
{
int i;
if(cmd == BEEP_CMD_SIGNAL)
{
printk("beep0/n");
Beep(0);
return(0);
}
else
{
printk("beep1/n");
Beep(1);
}
return 0;
}
struct file_operations FMQ_fops=
{
ioctl: ledman_ioctl,
};
int FMQ_test_init(void)
{
int result;
result=register_chrdev(188, "FengMingQiTest", &FMQ_fops);
if(result < 0)
{
printk("FengMingQiTest: cannot get major number!/n");
return result;
}
Port_Init();
return 0;
}
void cleanup_FMQmodule(void)
{
unregister_chrdev(FMQ_major, "FengMingQiTest");
}
1.2 修改uClinux-dist/linux-2.4.x/drivers/char/Makefile
添加一行:obj - $(CONFIG_FMQ_TEST) + = FengMingQi.o
1.3 修改uClinux-dist/linux-2.4.x/drivers/ char/Config.in
添加一行: bool ’test FengMingQi device’ CONFIG_FMQ_TEST
1.4 修改uClinux-dist/linux-2.4.x/drivers/ char/mem. c
添加:
# ifdef CONFIG_FMQ_TEST
extern void FMQ_test_init(void) ;
# endif
同时在chr_dev_init () 函数中添加:
# ifdef CONFIG_FMQ_TEST
FMQ_test_init() ;
# endif
1.5 修改uClinux-dist/vendors/Samsung/44B0/Makefile建立设备节点
DEVICE 部分添加如下内容:
FengMingQiTest,c,188,0
2. 驱动测试程序
2.1 新建路径
在uClinux-dist/user/建立测试驱动程序的文件夹FMQAppTest
2.2 驱动测试程序源码
在uClinux-dist/user/FMQAppTest下创建文件FMQAppTest.c,并编写代码如下
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
main()
{
int fd, i, j;
char buf[10];
fd = open("/dev/FengMingQiTest", O_RDWR);
if(fd < 0)
{
printf("cannot open file /n");
exit(0);
}
for(i = 0; i < 20; ++i)
{
ioctl(fd, 1, 0);
sleep(100);
ioctl(fd, 0, 0);
sleep(100);
}
close(fd);
}
2.3 Makefile
在uClinux-dist/user/FMQAppTest下创建文件Makefile,并编辑内容如下:
EXEC = FMQAppTest
OBJS = FMQAppTest.o
all:$(EXEC)
$(EXEC):$(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS)
romfs:
$(ROMFSINST) /bin/$(EXEC)
clean:
-rm -f $(EXEC) *.elf *.gdb *.o
2.4 在uClinux-dist/user/Makefile中加入FMQAppTest的路径
dir_$(CONFIG_USER_FMQ_APP) += FMQAppTest
2.5 在uClinux-dist/config/Configure.help中加入
CONFIG_USER_FMQ_APP
This program tests Feng Ming Qi driver.
2.6 uClinux-dist/config/config.in里加入
bool ’FengMingQiTest’ CONFIG_USER_FMQ_APP
3. 配置内核并编译
3.1 定制内核
make menuconfig
注意选择驱动test FengMingQi device和应用程序FengMingQiTest
3.2 编译内核
make dep
make clean
make lib_only
make user_only
make romfs
make image
make
3.3 结果
/uClinux-dist/images下会有新生成的三个文件:
romfs.img uclinux_ram.bin.gz uclinux_rom.bin
4. 在开发板运行
1) 通过loadb 0xc008000将uclinux_rom.bin拷到开发板的ram中
2) erase命令将flash用户区域0x50000之后的部分擦除
3) cp命令将uclinux_rom.bin从0xc008000拷到0x50000。
4) 重启开发板
5) 运行bin下的FMQAppTest
看看效果吧。是不是蜂鸣器响了?
另外还写了个LED控制的驱动,由于差不多仅仅是寄存器不同而已,这里就不再贴出来了。字符设备的驱动再了解几个,比如看门狗,按键等等,就准备进入块设备的驱动的学习了。当然,这些都是在2.4内核上写的,以后还要升级内核到2.6,同时将这些驱动移植到2.6框架下。不能着急啊,44b0就够我学一段时间了,2440还不能着急啊。