基于tiny210v2的linux-3.9.6内核驱动移植4:PWM移植
来源:互联网 发布:单片机与usb连接电路图 编辑:程序博客网 时间:2024/06/03 16:20
对于做智能车的爱好者来说PWM可说是很重要的,那么如果要用arm开发板来控制pwm,首先还是要移植pwm驱动
开发板:tiny210v2,S5PV210核心。
环境: ubuntu13.04 +arm-linux-gcc
内核: linux-3.9
参考友善自带的linux-3.0.8内核代码
转载请注明:
blog.csdn.net/canyue102/article/details/9526551
一、硬件信息
对于tiny210v2开发板上有一个PWM0对应一个峰鸣器,引脚为GPD0-0
二、驱动源码
在linux-3.9.6/drivers/char文件夹下新建smdkv210_pwm.c
/* * linux/drivers/char/smdkv210_pwm.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/platform_device.h>#include <linux/fb.h>#include <linux/backlight.h>#include <linux/err.h>#include <linux/pwm.h>#include <linux/slab.h>#include <linux/miscdevice.h>#include <linux/delay.h>#include <mach/gpio.h>#include <mach/regs-gpio.h>#include <plat/gpio-cfg.h>#define DEVICE_NAME"pwm"#define PWM_IOCTL_SET_FREQ1#define PWM_IOCTL_STOP0#define NS_IN_1HZ(1000000000UL)#define BUZZER_PWM_ID0#define BUZZER_PMW_GPIOS5PV210_GPD0(0)static struct pwm_device *pwm4buzzer;static struct semaphore lock;static void pwm_set_freq(unsigned long freq) {int period_ns = NS_IN_1HZ / freq;pwm_config(pwm4buzzer, period_ns / 2, period_ns);pwm_enable(pwm4buzzer);s3c_gpio_cfgpin(BUZZER_PMW_GPIO, S3C_GPIO_SFN(2));}static void pwm_stop(void) {s3c_gpio_cfgpin(BUZZER_PMW_GPIO, S3C_GPIO_OUTPUT);pwm_config(pwm4buzzer, 0, NS_IN_1HZ / 100);pwm_disable(pwm4buzzer);}static int smdkv210_pwm_open(struct inode *inode, struct file *file) {if (!down_trylock(&lock))return 0;elsereturn -EBUSY;}static int smdkv210_pwm_close(struct inode *inode, struct file *file) {up(&lock);return 0;}static long smdkv210_pwm_ioctl(struct file *filep, unsigned int cmd,unsigned long arg){switch (cmd) {case PWM_IOCTL_SET_FREQ:if (arg == 0)return -EINVAL;pwm_set_freq(arg);break;case PWM_IOCTL_STOP:default:pwm_stop();break;}return 0;}static struct file_operations smdkv210_pwm_ops = {.owner= THIS_MODULE,.open= smdkv210_pwm_open,.release= smdkv210_pwm_close, .unlocked_ioctl= smdkv210_pwm_ioctl,};static struct miscdevice smdkv210_misc_dev = {.minor = MISC_DYNAMIC_MINOR,.name = DEVICE_NAME,.fops = &smdkv210_pwm_ops,};static int __init smdkv210_pwm_dev_init(void) {int ret;ret = gpio_request(BUZZER_PMW_GPIO, DEVICE_NAME);if (ret) {printk("request GPIO %d for pwm failed\n", BUZZER_PMW_GPIO);return ret;}gpio_set_value(BUZZER_PMW_GPIO, 0);s3c_gpio_cfgpin(BUZZER_PMW_GPIO, S3C_GPIO_OUTPUT);pwm4buzzer = pwm_request(BUZZER_PWM_ID, DEVICE_NAME);if (IS_ERR(pwm4buzzer)) {printk("request pwm %d for %s failed\n", BUZZER_PWM_ID, DEVICE_NAME);return -ENODEV;}pwm_stop();sema_init(&lock, 1);ret = misc_register(&smdkv210_misc_dev);printk(DEVICE_NAME "\tinitialized\n");return ret;}static void __exit smdkv210_pwm_dev_exit(void) {pwm_stop();misc_deregister(&smdkv210_misc_dev);gpio_free(BUZZER_PMW_GPIO);}module_init(smdkv210_pwm_dev_init);module_exit(smdkv210_pwm_dev_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("FriendlyARM Inc.");MODULE_DESCRIPTION("S5PV210 PWM Driver");
二、设置config文件
在该目录下的Kconfig文件中添加:
config SMDKV210_BUZZER
tristate "Buzzer driver for FriendlyARM TINY210 development boards"
depends on MACH_SMDKV210
default y
help
this is buzzer driver for FriendlyARM TINY210 development boards
三、修改Makefile
在该目录下的Makefile文件中添加:
obj-$(CONFIG_SMDKV210_BUZZER) += smdkv210_pwm.o
四、make测试
编译通过
五、测试程序
#include <stdio.h>#include <termios.h>#include <unistd.h>#include <stdlib.h>#define PWM_IOCTL_SET_FREQ#define PWM_IOCTL_STOP#define ESC_KEY120x1bstatic int getch(void){struct termios oldt,newt;int ch;if (!isatty(STDIN_FILENO)) {fprintf(stderr, "this problem should be run at a terminal\n");exit(1);}// save terminal settingif(tcgetattr(STDIN_FILENO, &oldt) < 0) {perror("save the terminal setting");exit(1);}// set terminal as neednewt = oldt;newt.c_lflag &= ~( ICANON | ECHO );if(tcsetattr(STDIN_FILENO,TCSANOW, &newt) < 0) {perror("set terminal");exit(1);}ch = getchar();// restore termial settingif(tcsetattr(STDIN_FILENO,TCSANOW,&oldt) < 0) {perror("restore the termial setting");exit(1);}return ch;}static int fd = -1;static void close_buzzer(void);static void open_buzzer(void){fd = open("/dev/pwm", 0);if (fd < 0) {perror("open pwm_buzzer device");exit(1);}// any function exit call will stop the buzzeratexit(close_buzzer);}static void close_buzzer(void){if (fd >= 0) {ioctl(fd, PWM_IOCTL_STOP);close(fd);fd = -1;}}static void set_buzzer_freq(int freq){// this IOCTL command is the key to set frequencyint ret = ioctl(fd, PWM_IOCTL_SET_FREQ, freq);if(ret < 0) {perror("set the frequency of the buzzer");exit(1);}}static void stop_buzzer(void){int ret = ioctl(fd, PWM_IOCTL_STOP);if(ret < 0) {perror("stop the buzzer");exit(1);}}int main(int argc, char **argv){int freq = 1000 ;open_buzzer();printf( "\nBUZZER TEST ( PWM Control )\n" );printf( "Press +/- to increase/reduce the frequency of the BUZZER\n" ) ;printf( "Press 'ESC' key to Exit this program\n\n" );while( 1 ){int key;set_buzzer_freq(freq);printf( "\tFreq = %d\n", freq );key = getch();switch(key) {case '+':if( freq < 20000 )freq += 10;break;case '-':if( freq > 11 )freq -= 10 ;break;case ESC_KEY:case EOF:stop_buzzer();exit(0);default:break;}}}
- 基于tiny210v2的linux-3.9.6内核驱动移植4:PWM移植
- 基于tiny210v2的linux-3.9.6内核驱动移植3:LCD移植
- 基于tiny210v2的linux-3.9.6内核驱动移植1:led驱动
- 基于tiny210v2的linux-3.9.6内核驱动移植2:按键驱动
- 移植linux-3.9内核到tiny210v2
- 基于S3C2440的Linux-3.6.6移植 PWM蜂鸣器驱动
- 基于tiny4412的Linux内核移植 -- PWM子系统学习
- .Linux-2.6.32.2内核在mini2440上的移植(十七)---移植PWM控制蜂鸣器驱动
- Linux-2.6.32.2内核在mini2440上的移植(十七)---移植PWM控制蜂鸣器驱动
- Linux-2.6.32.2内核在mini2440上的移植(十七)---移植PWM控制蜂鸣器驱动
- 【引用】Linux-2.6.32.2内核在mini2440上的移植(十七)---移植PWM控制蜂鸣器驱动
- Linux-2.6.32.2内核在mini2440上的移植(十七)---移植PWM控制蜂鸣器驱动 .
- 基于S3C2440的Linux-3.6.6移植——PWM蜂鸣器驱动
- S3C2410 LCD驱动的移植(基于linux-2.6.15.4内核)
- 基于Linux-2.6.35内核的wifi驱动移植
- Linux-2.6.32.2内核在mini2440上的移植(十六)---基于中断的按键驱动移植
- Linux-2.6.32.2内核在mini2440上的移植(十六)---基于中断的按键驱动移植
- Linux-2.6.32.2内核在mini2440上的移植(十六)---基于中断的按键驱动移植
- web开发中压缩js/css文件一种巧方法
- Unity 3D 多个摄像机之间的切换
- 快速排序算法
- qmake 使用笔记
- java 常用快捷键
- 基于tiny210v2的linux-3.9.6内核驱动移植4:PWM移植
- Cache与主存之间的"全相联映射","直接映射"和"组相联映射"的区别
- 正码、补码、反码
- hdu 3038
- 比较全面的gdb调试命令
- How to compile VLC on Linux Platform (From the authority)
- S3C2440 ADC
- PSD格式文件的读取
- map的类型映射