#include
#include
#incldue <fcntl.h>
#define DEVNAME "/dev/buzzer"
#define PWM_IOCTL_SET_FREQ 1
#define PWM_IOCTL_STOP 0
int main(void)
{
int fd=-1;
fd=open(DEVNAME,O_RDWR);
if(fd<0){
perror("open");return -1;
}
ioctl(fd,PWM_IOCTL_SET_FREQ,10000);
sleep(3);
ioctl(fd,PWM_IOCTL_STOP);
sleep(3);
ioctl(fd,PWM_IOCTL_SET_FREQ,3000);
sleep(3);
ioctl(fd,PWM_IOCTL_STOP);
sleep(3);
close(fd);return 0;
}
1、何为misc
2、misc 类驱动框架架构
1、misc 源码框架基础
2、misc 类设备的注册
1、open 函数分析
2、misc 在 proc 下的展现
3、内核互斥锁
1、dev_init
2、ioctl
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DEVICE_NAME "buzzer"
#define PWM_IOCTL_SET_FREQ 1
#define PWM_IOCTL_STOP 0
typedef unsigned long u_long;
static struct semaphore lock;
//被ioctl调用// TCFG0 在 Uboot 中设置,这里不再重复设置
static void PWM_Set_Freq(unsigned long freq)
{
u_long tcon,tcnt,tcfg1,pclk;
struct clk* clk_p;
s3c_gpio_cfgpin(S5PV210_GPD0(2),S3C_GPIO_SFN(2));//设置 GPD0_2 为 PWM 输出
tcon=__raw_readl(S3C2410_TCON);
tcfg=__raw_readl(S3C2410_TCFG1);
tcfg1&=~(0xf<<8);//mux=1/16
tcfg1|=(0x4<<8);
__raw_write(tcfg1,S3C2410_TCFG1);
clk_p=clk_get(NULL,"pclk");
pclk=clk_get_rate(clk_p);
tcnt=(pclk/16/16)/freq;
__raw_write(tcnt,S3C2410_TCNTB(2));
__raw_write(tcnt/2,S3C2410_TCMPB(2));//占空比0.5
tcon &= ~(0xf<<12);
tcon |= (0xb<<12);
__raw_writel(tcon, S3C2410_TCON);
tcon &= ~(2<<12);
__raw_writel(tcon, S3C2410_TCON);
}
// 被ioctl调用
void PWM_Stop(void)
{
s3c_gpio_cfgpin(S5PV210_GP0(2),S3C_GPIO_SFN(0));//将GPD0_2设置为input
}
static int x210_pwm_open(struct inode* inode,struct file* file)
{
if(!down_trylock(&lock))//上锁
return 0;
else
return -EBUSY;
}
static int x210_pwm_close(struct inode* inode,struct file* file,unsigned int cmd,unsigned long arg)
{
ip(&lock);//解锁
return 0;
}
//PWM:GPF14->PWM0
static int x210_pwm_ioctl(struct inode* inode,struct file* file,unsigned int cmd,unsigned long arg)
{
switch(cmd)
{
case PWM_IOCTL_SET_FREQ:
printk("PWM_IOCTL_SET_FREQ:\r\n");
if (arg == 0) return -EINVAL;
PWM_Set_Freq(arg);break;
case PWM_IOCTL_STOP:
default:
printk("PWM_IOCTL_STOP:\r\n");
PWM_Stop(); break;
}
return 0;
}
// 文件操作结构体
static struct file_operations dev_fops={
.owner=THIS_MODULE,
.open=x210_pwm_open,
.release=x210_pwm_close,
.ioctl=x210_pwm_ioctl,
}
//设备结构体
static int __init dev_init(void)
{
.minor=MISC_DYNAMIC_MINOR,
.name=DEVICE_NAME,
.fops=&dev_fops,
}
//设备安装函数
static int __init dev_init(void)
{
int ret=-1;
init_MUTEX(&lock);
ret=misc_register(&misc);//设备
/*GPD0_2(PWMTOUT2)*/
ret=gpio_request(S5PV210_GPD0(2),"GPD0");//申请资源
if(ret) printk("buzzer-x210: request gpio GPD0(2) fail");
s3c_gpio_setpull(S5PV210_GPD0(2),S3C_GPIO_PULL_UP);//gpio初始化
s3c_gpio_cfgpin(S5PV210_GPD0(2),S3C_GPIO_SFN(1));
gpio_set_value(S5PV210_GPD0(2),0);
printk ("x210 "DEVICE_NAME" initialized\n"); return ret;
}
//设备卸载函数
static void __exit dev_exit(void)
{
misc_deregister(&misc);//注销设备
gpio_free(S5PV210_GPD0(2));//释放资源
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("www.9tripod.com");
MODULE_DESCRIPTION("x210 PWM Driver");