设备驱动(十五)
来源:互联网 发布:android网络相关面试题 编辑:程序博客网 时间:2024/05/16 12:38
开启设备的时钟
- struct clk *my_clk; //定义时钟结构体
- my_clk = clk_get(NULL, "watchdog"); //获取设备的时钟信息
- clk_enable(my_clk); //打开时钟
- clk_disable(my_clk); //关闭时钟
所有有关时钟的设备,只有打开时钟后设置设备的寄存器才有效。
看门狗驱动
原理图
PCLK = 66MHZWTCON[15:8] 0x80[5] 0x1[4:3] 0x2WTCNT0x8000
- 模块许可
- 加载函数
- 注册字符设备
- 映射
- 获取时钟
- 卸载函数
- 操作集合
- FEED_DOG
- 打开时钟
- 设置计数器WTCNT
- 使能看门狗WTCON
- release关闭时钟
PWM脉冲调制
GPD0_1
TCNTB1 0x1e
TCMPB1 0xf
TCFG0[7:0] 0xff
TCFG1[7:4] 0x4
最后设置
TCON[11:8] 0x2
TCON[11:8] 0x2
- 模块许可
- 加载函数
- 申请设备号
- 注册字符设备
- 映射寄存器
- open函数
- 设置预分频、设置再分频
- 设置tcnt、tcmp
- 设置gpd0_1为TOUT_1输出
- 使能tcon,手动更新tcnt,tcmp
- 卸载函数
- 关闭tcon
- 操作集合
- BEEP_ON
- 设置自动重装tcon、tcmp
- BEEP_OFF
- 关闭tcon
- SET_CNTB1
- 安装参数更新tcon、tcmp
- BEEP_ON
#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/cdev.h>#include <asm/io.h>//#include <plat/regs-timer.h>//#include <mach/regs-gpio.h>#include "fs210_pwm.h"MODULE_LICENSE("Dual BSD/GPL");MODULE_AUTHOR("farsight");#define GPD0CON 0xE02000A0struct pwm_timer{unsigned int tcfg0;unsigned int tcfg1;unsigned int tcon;unsigned int tcntb0;unsigned int tcmpb0;unsigned int tcnto0;unsigned int tcntb1;unsigned int tcmpb1;} *pwm_timer;static int pwm_major = 250;static int pwm_minor = 0;static struct cdev pwm_cdev;void *gpd0con;static void beep_init(void){writel((readl(gpd0con) & (~0xf<<4)) | (0x2<<4), gpd0con);writel(readl(&pwm_timer->tcfg0) | 0xff, &pwm_timer->tcfg0);writel((readl(&pwm_timer->tcfg1) & ~(0xf<<4)) | (0x4<<4), &pwm_timer->tcfg1);writel(30, &pwm_timer->tcntb1);writel(15, &pwm_timer->tcmpb1);writel((readl(&pwm_timer->tcon) & ~(0xf<<8)) | (0x2<<8), &pwm_timer->tcon);}static void beep_on(void){writel((readl(&pwm_timer->tcon) & ~(0xf<<8)) | (0x9<<8), &pwm_timer->tcon);}static void beep_off(void){writel((readl(&pwm_timer->tcon) & ~(0xf<<8)), &pwm_timer->tcon);}static void set_cnt(unsigned long count){writel(count, &pwm_timer->tcntb1);writel(count/2, &pwm_timer->tcmpb1);}static int fs210_pwm_open(struct inode *inode, struct file *file){printk("pwm: device open\n");beep_init();return 0;}static int fs210_pwm_close(struct inode *inode, struct file *file){printk("pwm: device close\n");beep_off();return 0;}static long fs210_pwm_ioctl(struct file *file, unsigned int cmd, unsigned long arg){//printk("pwm: device ioctl\n");switch(cmd){case BEEP_ON:printk("pwm: BEEP ON\n");beep_on();break;case BEEP_OFF:printk("pwm: BEEP OFF\n");beep_off();break;case SET_CNT:printk("pwm: SET CNT\n");set_cnt(arg);break;default:printk("pwm: available command\n");return -EINVAL;}return 0;}static struct file_operations fs210_pwm_ops = {.owner = THIS_MODULE,.open = fs210_pwm_open,.release = fs210_pwm_close,.unlocked_ioctl = fs210_pwm_ioctl};static int pwm_setup_cdev(struct cdev *cdev,struct file_operations *fops){int result;dev_t devno = MKDEV(pwm_major, pwm_minor);cdev_init(cdev, fops);cdev->owner = THIS_MODULE;result = cdev_add(cdev, devno, 1);if (result){printk("pwm: fail to add cdev\n");return result;}return 0;}static int __init fs210_pwm_init(void){int result;dev_t devno = MKDEV(pwm_major, pwm_minor);result = register_chrdev_region(devno, 1, "fs210_pwm");if (result){printk("pwm: unable to get major %d\n", pwm_major);return result;}result = pwm_setup_cdev(&pwm_cdev, &fs210_pwm_ops);if (result)return result;gpd0con = ioremap(GPD0CON, 4);pwm_timer = ioremap(0xE2500000, sizeof(struct pwm_timer));printk("pwm: driver installed with major %d!\n", pwm_major);return 0;}static void __exit fs210_pwm_exit(void){dev_t devno = MKDEV(pwm_major, pwm_minor);cdev_del(&pwm_cdev);unregister_chrdev_region(devno, 1);iounmap(gpd0con);iounmap(pwm_timer);printk("pwm: driver uninstalled!\n");}module_init(fs210_pwm_init);module_exit(fs210_pwm_exit);
看门狗参考代码
#include <linux/module.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/cdev.h>#include <linux/ioctl.h>#include <asm/uaccess.h>#include <asm/io.h>//#include <linux/delay.h>#include <plat/regs-watchdog.h>//#include <plat/map-base.h>#include <linux/clk.h>#define WATCHDOG_MAGIC 'k'#define FEED_DOG _IO(WATCHDOG_MAGIC,1)#define WATCHDOG_MAJOR 250#define DEVICE_NAME "s5pv210_watchdog"MODULE_LICENSE("GPL");MODULE_AUTHOR("farsight");MODULE_DESCRIPTION("s5pv210 Watchdog");#define S5PV210_PA_WTCON 0xE2700000#define S5PV210_PA_WTCNT 0xE2700008void *s5pv210_wtcon;void *s5pv210_wtcnt;struct clk *clk;static int watchdog_major = WATCHDOG_MAJOR;static struct cdev watchdog_cdev;static int watchdog_open(struct inode *inode ,struct file *file){clk_enable(clk);writel(0x8000, s5pv210_wtcnt);//设置计数寄存器,如果里面内容递减为0时,reset。writel(S3C2410_WTCON_ENABLE|S3C2410_WTCON_DIV64|S3C2410_WTCON_RSTEN |S3C2410_WTCON_PRESCALE(0x80), s5pv210_wtcon);//设置控制寄存器的属性,具体参看datasheet,主要是得到t_watchdog时钟周期。printk(KERN_NOTICE"open the watchdog now!\n");return 0;}static int watchdog_release(struct inode *inode,struct file *file){clk_disable(clk);return 0;}//喂狗static long watchdog_ioctl(struct file *file,unsigned int cmd,unsigned long arg){switch( cmd ){case FEED_DOG:writel(0x8000, s5pv210_wtcnt);break;}return 0;}//将设备注册到系统之中static void watchdog_setup_dev(struct cdev *dev,int minor,struct file_operations *fops){int err;dev_t devno = MKDEV(watchdog_major,minor);cdev_init(dev, fops);dev->owner = THIS_MODULE;err = cdev_add(dev, devno, 1);if (err)printk(KERN_INFO"Error %d adding watchdog %d\n",err,minor);}static struct file_operations watchdog_ops = {.owner = THIS_MODULE,.open = watchdog_open,.release = watchdog_release,.unlocked_ioctl = watchdog_ioctl,};//注册设备驱动程序,主要完成主设备号的注册static int __init s5pv210_watchdog_init(void){int result;dev_t dev = MKDEV(watchdog_major,0);result = register_chrdev_region(dev,1,DEVICE_NAME);if (result < 0){printk(KERN_WARNING"watchdog:unable to get major %d\n",watchdog_major);return result;}printk(KERN_NOTICE"[DEBUG] watchdog device major is %d\n",watchdog_major);watchdog_setup_dev(&watchdog_cdev, 0, &watchdog_ops);s5pv210_wtcon = ioremap(S5PV210_PA_WTCON, 4);s5pv210_wtcnt = ioremap(S5PV210_PA_WTCNT, 4);clk = clk_get(NULL, "watchdog");if (IS_ERR(clk)) {printk("failed to get watchdog clock\n");result = PTR_ERR(clk);return result;}return 0;}//驱动模块卸载static void s5pv210_watchdog_exit(void){iounmap(s5pv210_wtcon);iounmap(s5pv210_wtcnt);cdev_del(&watchdog_cdev);unregister_chrdev_region(MKDEV(watchdog_major,0),1);}module_init(s5pv210_watchdog_init);module_exit(s5pv210_watchdog_exit);
0 0
- 设备驱动(十五)
- 设备驱动
- 设备驱动
- 设备驱动
- 设备驱动
- 设备驱动
- 总线,设备,设备驱动
- Linux开发十五_lcd驱动
- 字符设备驱动--- 设备操作
- 设备模型:总线、驱动、设备
- 设备驱动和设备模型
- Pci设备驱动:设备枚举
- Linux设备驱动之《字符设备驱动》
- linux设备驱动之总线、设备、驱动
- Linux设备驱动入门----I2C设备驱动
- Linux设备驱动入门----USB设备驱动
- 设备驱动之二----字符设备驱动
- Linux 设备驱动--- 混杂设备驱动
- 开发一款高端大气上档次的android应用需要必备的知识——记于2013年末
- 设备驱动(十四)
- 实现 圆形加载view 动画效果(用CALayer,CABasicAnimation实现)
- 对android调用web Service取手机号码归属地,运行不了的解决
- URL短地址压缩算法 微博短地址原理解析 (Java实现)
- 设备驱动(十五)
- Oracle Silent Installations(静默安装)
- Android Search概述
- Core Animation之多种动画效果
- C++文件(夹)选择对话框
- 设备驱动(十六)
- Eclipse与Android源码中ProGuard工具的使用
- 浅论Android网络请求库——android-async-http
- 爬虫技术之——bloom filter(含java代码)