一、4412 xpwmTOUT1

这是4412的GPD0_1路,itop中被使用为LCD的背光电路的pwm功能。因此如果使用教程中的代码,同样操作GPD0_1是行不通的。

会出现错误,所以需要解除在内核中的占用

修改arch/arm/mach-exynos/mach-itop4412.c,找到并注释

    samsung_bl_set(&smdk4x12_bl_gpio_info, &smdk4x12_bl_data);

在内核中取消相关的模块编译,(不确定)

Device Driver>>Graphics support>>Backlight & LCD device support(取消)

然后在平台文件中增加注册设备:

    &s3c_device_timer[],

然后是测试代码:

#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 <linux/gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <linux/ioctl.h>
#include <asm-generic/uaccess.h> #define DEVICE_NAME "my_pwm3_dev"
#define DRIVER_NAME "my_pwm3_drv" #define PWM_MAGIC 'p'
#define PWM_MAX_NR 3 #define PWM_IOCTL_STOP _IO(PWM_MAGIC, 0)
#define PWM_IOCTL_SET_FREQ _IO(PWM_MAGIC, 1)
#define PWM_IOCTL_SET_DUTY _IO(PWM_MAGIC, 2) #define NS_IN_1HZ (1000000000UL) #define BUZZER_PWM_ID 0
#define PWM1_ID 1
#define PWM2_ID 2
#define PWM3_ID 3 #define BUZZER_PMW_GPIO EXYNOS4_GPD0(0)
#define PWM1_GPIO EXYNOS4_GPD0(1)
#define PWM2_GPIO EXYNOS4_GPD0(2)
#define PWM3_GPIO EXYNOS4_GPD0(3) static struct pwm_device *pwm4buzzer;
static struct semaphore lock;
static int period_ns = ;
static unsigned long freq = ;
static unsigned long duty = ; static void pwm_set_freq(void)
{
//配置周期
period_ns = NS_IN_1HZ / freq;
//配置占空比
if(duty < )
duty = ;
pwm_disable(pwm4buzzer);
pwm_config(pwm4buzzer, period_ns / duty, period_ns);
pwm_enable(pwm4buzzer);
//配置相应的GPIO,蜂鸣器IO配置成PWM输出模式
s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_SFN());
} static void pwm_stop(void)
{
s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_OUTPUT); pwm_config(pwm4buzzer, , NS_IN_1HZ / );
pwm_disable(pwm4buzzer);
} static int ops_pwm_open(struct inode *inode, struct file *file)
{
if(!down_trylock(&lock))
return ;
else
return -EBUSY;
} static int ops_pwm_close(struct inode *inode, struct file *file)
{
up(&lock);
return ;
} static long ops_pwm_ioctl(struct file *filep, unsigned int cmd,
unsigned long arg)
{
if(_IOC_TYPE(cmd)!=PWM_MAGIC) return -EINVAL;
if(_IOC_NR(cmd) > PWM_MAX_NR) return -EINVAL; switch(cmd) {
case PWM_IOCTL_SET_FREQ:
if(arg == )
return -EINVAL;
get_user(freq, (unsigned long __user *)arg);
printk(KERN_EMERG "freq is %ld\n", freq);
pwm_set_freq();
break;
case PWM_IOCTL_STOP:
pwm_stop();
break;
case PWM_IOCTL_SET_DUTY:
get_user(duty, (unsigned long __user *)arg);
printk(KERN_EMERG "duty is %ld\n", duty);
pwm_set_freq();
break;
default:
pwm_stop();
break;
}
return ;
} static struct file_operations pwm_ops = {
.owner = THIS_MODULE,
.open = ops_pwm_open,
.release = ops_pwm_close,
.unlocked_ioctl = ops_pwm_ioctl,
}; static struct miscdevice pwm_misc_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &pwm_ops,
}; static int __init iTop4412_pwm_dev_init(void)
{
int ret;
gpio_free(PWM3_GPIO); ret = gpio_request(PWM3_GPIO, DEVICE_NAME);
if(ret) {
printk(KERN_EMERG "request GPIO %d for pwm failed\n", PWM3_GPIO);
return ret;
} gpio_set_value(PWM3_GPIO, );
s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_OUTPUT); pwm4buzzer = pwm_request(PWM3_ID, DEVICE_NAME);
if (IS_ERR(pwm4buzzer)) {
printk(KERN_EMERG "request pwm %d for %s failed\n", PWM3_ID, DEVICE_NAME);
return -ENODEV;
}
pwm_stop(); sema_init(&lock, );
ret = misc_register(&pwm_misc_dev);
if(ret < ) {
gpio_free(BUZZER_PMW_GPIO);
pwm_free(pwm4buzzer);
misc_deregister(&pwm_misc_dev);
} printk(KERN_EMERG "\tinitialized\n"); return ret;
} static void __exit iTop4412_pwm_dev_exit(void)
{
gpio_free(BUZZER_PMW_GPIO);
pwm_free(pwm4buzzer);
misc_deregister(&pwm_misc_dev); printk(KERN_EMERG "\texit\n");
return;
} module_init(iTop4412_pwm_dev_init);
module_exit(iTop4412_pwm_dev_exit); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Chen Tuo");
MODULE_DESCRIPTION("Exynos4 PWM Driver");

my_pwm3.c

然后是应用程序:

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/ioctl.h> #define PWM2_NAME "/dev/my_pwm3_dev" #define PWM_MAGIC 'p'
#define PWM_MAX_NR 3 #define PWM_IOCTL_STOP _IO(PWM_MAGIC, 0)
#define PWM_IOCTL_SET_FREQ _IO(PWM_MAGIC, 1)
#define PWM_IOCTL_SET_DUTY _IO(PWM_MAGIC, 2) int fd = -; void open_pwm1(void);
void close_pwm1(void);
void set_pwm_freq(int freq);
void set_pwm_duty(int duty);
void stop_pwm(void); void open_pwm1(void)
{
fd = open(PWM2_NAME, O_RDWR);
if(fd < ) {
perror("open pwm1 device");
exit();
} // atexit(close_pwm1);
} void close_pwm1(void)
{
if(fd >= ) {
ioctl(fd, PWM_IOCTL_STOP);
close(fd);
fd = -;
}
} void set_pwm_freq(int freq)
{
int ret = ioctl(fd, PWM_IOCTL_SET_FREQ, &freq);
if(ret < ) {
perror("set the frequency of the buzzer");
exit();
}
} void set_pwm_duty(int duty)
{
int ret = ioctl(fd, PWM_IOCTL_SET_DUTY, &duty);
if(ret < ) {
perror("set the duty of the pwm");
exit();
}
} void stop_pwm(void)
{
int ret = ioctl(fd, PWM_IOCTL_STOP);
if(ret < ) {
perror("Stop the buzzer");
exit();
}
} int main(int argc, char *argv[])
{
int freq = ; open_pwm1();
stop_pwm();
if(argc < ) {
printf("usage:%s [cmd] [arg]\n", argv[]);
printf("\tstop:%s [0] [0] \n",argv[]);
printf("\tset freq:%s [1] [arg]\n", argv[]);
printf("\tset duty:%s [2] [arg]\n", argv[]);
}
switch(atoi(argv[]))
{
case :
set_pwm_duty(atoi(argv[]));
break;
case :
set_pwm_freq(atoi(argv[]));
break;
case :
default:
stop_pwm();
return -;
} return ;
}

my_pwm3_app.c

最后是Makefile:

TARGET_NAME = my_pwm3
#TARGET_NAME = example_pwm
APP1_NAME = my_pwm3_app
#APP2_NAME = open_atomic_int_two
obj-m += $(TARGET_NAME).o KDIR := /home/topeet/chen/kernel-3.0/iTop4412_Kernel_3. PWD ?= $(shell pwd) all:app1
make -C $(KDIR) M=$(PWD) modules
app1:
arm-none-linux-gnueabi-gcc $(APP1_NAME).c -o $(APP1_NAME) -static
#app2:
# arm-none-linux-gnueabi-gcc $(APP2_NAME).c -o $(APP2_NAME) -static clean:
rm -rf *.o *.ko *.mod.c *.symvers *.order \
.$(TARGET_NAME)* $(APP1_NAME) $(APP2_NAME)

Makefile

二、4412 I2C_SDA7和I2C_SCL7

注释平台文件中的代码:

//  s3c_i2c7_set_platdata(NULL);
// i2c_register_board_info(7, i2c_devs7, ARRAY_SIZE(i2c_devs7));

和这个

//  &s3c_device_i2c7,

然后make menuconfig

>>Device Drivers>>Input device support>>Touchscreens【】取消选择

三、尝试编写控制PWM波形的驱动和应用程序

my_pwm3.c(驱动)

#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 <linux/gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <linux/ioctl.h>
#include <asm-generic/uaccess.h> #define DEVICE_NAME "my_pwm3_dev"
#define DRIVER_NAME "my_pwm3_drv" #define PWM_MAGIC 'p'
#define PWM_MAX_NR 3 #define PWM_IOCTL_STOP _IO(PWM_MAGIC, 0)
#define PWM_IOCTL_SET_FREQ _IO(PWM_MAGIC, 1)
#define PWM_IOCTL_SET_DUTY _IO(PWM_MAGIC, 2) #define NS_IN_1HZ (1000000000UL) #define BUZZER_PWM_ID 0
#define PWM1_ID 1
#define PWM2_ID 2
#define PWM3_ID 3 #define BUZZER_PMW_GPIO EXYNOS4_GPD0(0)
#define PWM1_GPIO EXYNOS4_GPD0(1)
#define PWM2_GPIO EXYNOS4_GPD0(2)
#define PWM3_GPIO EXYNOS4_GPD0(3) static struct pwm_device *pwm4buzzer;
static struct semaphore lock;
static int period_ns = ;
static unsigned long freq = ;
static unsigned long duty = ; static void pwm_set_freq(void)
{
//配置周期
period_ns = NS_IN_1HZ / freq;
//配置占空比
if(duty < )
duty = ;
pwm_disable(pwm4buzzer);
pwm_config(pwm4buzzer, period_ns / duty, period_ns);
pwm_enable(pwm4buzzer);
//配置相应的GPIO,蜂鸣器IO配置成PWM输出模式
s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_SFN());
} static void pwm_stop(void)
{
s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_OUTPUT); pwm_config(pwm4buzzer, , NS_IN_1HZ / );
pwm_disable(pwm4buzzer);
} static int ops_pwm_open(struct inode *inode, struct file *file)
{
if(!down_trylock(&lock))
return ;
else
return -EBUSY;
} static int ops_pwm_close(struct inode *inode, struct file *file)
{
up(&lock);
return ;
} static long ops_pwm_ioctl(struct file *filep, unsigned int cmd,
unsigned long arg)
{
if(_IOC_TYPE(cmd)!=PWM_MAGIC) return -EINVAL;
if(_IOC_NR(cmd) > PWM_MAX_NR) return -EINVAL; switch(cmd) {
case PWM_IOCTL_SET_FREQ:
if(arg == )
return -EINVAL;
get_user(freq, (unsigned long __user *)arg);
printk(KERN_EMERG "freq is %ld\n", freq);
pwm_set_freq();
break;
case PWM_IOCTL_STOP:
pwm_stop();
break;
case PWM_IOCTL_SET_DUTY:
get_user(duty, (unsigned long __user *)arg);
printk(KERN_EMERG "duty is %ld\n", duty);
pwm_set_freq();
break;
default:
pwm_stop();
break;
}
return ;
} static struct file_operations pwm_ops = {
.owner = THIS_MODULE,
.open = ops_pwm_open,
.release = ops_pwm_close,
.unlocked_ioctl = ops_pwm_ioctl,
}; static struct miscdevice pwm_misc_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &pwm_ops,
}; static int __init iTop4412_pwm_dev_init(void)
{
int ret;
gpio_free(PWM3_GPIO); ret = gpio_request(PWM3_GPIO, DEVICE_NAME);
if(ret) {
printk(KERN_EMERG "request GPIO %d for pwm failed\n", PWM3_GPIO);
return ret;
} gpio_set_value(PWM3_GPIO, );
s3c_gpio_cfgpin(PWM3_GPIO, S3C_GPIO_OUTPUT); pwm4buzzer = pwm_request(PWM3_ID, DEVICE_NAME);
if (IS_ERR(pwm4buzzer)) {
printk(KERN_EMERG "request pwm %d for %s failed\n", PWM3_ID, DEVICE_NAME);
return -ENODEV;
}
pwm_stop(); sema_init(&lock, );
ret = misc_register(&pwm_misc_dev);
if(ret < ) {
gpio_free(BUZZER_PMW_GPIO);
pwm_free(pwm4buzzer);
misc_deregister(&pwm_misc_dev);
} printk(KERN_EMERG "\tinitialized\n"); return ret;
} static void __exit iTop4412_pwm_dev_exit(void)
{
gpio_free(BUZZER_PMW_GPIO);
pwm_free(pwm4buzzer);
misc_deregister(&pwm_misc_dev); printk(KERN_EMERG "\texit\n");
return;
} module_init(iTop4412_pwm_dev_init);
module_exit(iTop4412_pwm_dev_exit); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Chen Tuo");
MODULE_DESCRIPTION("Exynos4 PWM Driver");

my_pwm3.c

my_pwm3_app.c

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/ioctl.h> #define PWM2_NAME "/dev/my_pwm3_dev" #define PWM_MAGIC 'p'
#define PWM_MAX_NR 3 #define PWM_IOCTL_STOP _IO(PWM_MAGIC, 0)
#define PWM_IOCTL_SET_FREQ _IO(PWM_MAGIC, 1)
#define PWM_IOCTL_SET_DUTY _IO(PWM_MAGIC, 2) int fd = -; void open_pwm1(void);
void close_pwm1(void);
void set_pwm_freq(int freq);
void set_pwm_duty(int duty);
void stop_pwm(void); void open_pwm1(void)
{
fd = open(PWM2_NAME, O_RDWR);
if(fd < ) {
perror("open pwm1 device");
exit();
} // atexit(close_pwm1);
} void close_pwm1(void)
{
if(fd >= ) {
ioctl(fd, PWM_IOCTL_STOP);
close(fd);
fd = -;
}
} void set_pwm_freq(int freq)
{
int ret = ioctl(fd, PWM_IOCTL_SET_FREQ, &freq);
if(ret < ) {
perror("set the frequency of the buzzer");
exit();
}
} void set_pwm_duty(int duty)
{
int ret = ioctl(fd, PWM_IOCTL_SET_DUTY, &duty);
if(ret < ) {
perror("set the duty of the pwm");
exit();
}
} void stop_pwm(void)
{
int ret = ioctl(fd, PWM_IOCTL_STOP);
if(ret < ) {
perror("Stop the buzzer");
exit();
}
} int main(int argc, char *argv[])
{
int freq = ; open_pwm1();
stop_pwm();
if(argc < ) {
printf("usage:%s [cmd] [arg]\n", argv[]);
printf("\tstop:%s [0] [0] \n",argv[]);
printf("\tset freq:%s [1] [arg]\n", argv[]);
printf("\tset duty:%s [2] [arg]\n", argv[]);
}
switch(atoi(argv[]))
{
case :
set_pwm_duty(atoi(argv[]));
break;
case :
set_pwm_freq(atoi(argv[]));
break;
case :
default:
stop_pwm();
return -;
} return ;
}

my_pwm3_app.c

Makefile

TARGET_NAME = my_pwm3
#TARGET_NAME = example_pwm
APP1_NAME = my_pwm3_app
#APP2_NAME = open_atomic_int_two
obj-m += $(TARGET_NAME).o KDIR := /home/topeet/chen/kernel-3.0/iTop4412_Kernel_3. PWD ?= $(shell pwd) all:app1
make -C $(KDIR) M=$(PWD) modules
app1:
arm-none-linux-gnueabi-gcc $(APP1_NAME).c -o $(APP1_NAME) -static
#app2:
# arm-none-linux-gnueabi-gcc $(APP2_NAME).c -o $(APP2_NAME) -static clean:
rm -rf *.o *.ko *.mod.c *.symvers *.order \
.$(TARGET_NAME)* $(APP1_NAME) $(APP2_NAME)

Makfile

总结:内核接收ioctl的信息时需要使用特定的函数进行保护,防止被乱七八糟的传入数据。

4412 4路pwm输出的更多相关文章

  1. 16路PWM输出的pca9685模块

    今天要介绍的就是该模块,该模块是16路pwm模块,使用I2C总线可以控制16路舵机(led). 接线OE空着就可以,其他VCC是芯片供电+5,SCL时钟线,SDA信号线,GND地线. 芯片介绍可以看: ...

  2. J20航模遥控器开源项目系列教程(五)| 制作STM32F0接收机,8路PWM输出,SBUS输出,PPM输出 | 加密狗无线化,畅玩飞行模拟器

    我们的开源宗旨:自由 协调 开放 合作 共享 拥抱开源,丰富国内开源生态,开展多人运动,欢迎加入我们哈~ 和一群志同道合的人,做自己所热爱的事! 项目开源地址:https://github.com/J ...

  3. STM32 PWM输出(映射)

    STM32 的定时器除了 TIM6 和 7.其他的定时器都可以用来产生 PWM 输出.其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出.而通用定时器也能同时产生多达 4 ...

  4. 定时器同步+触发三ADC采样+输出6路PWM波

    为了熟悉定时器定时器和ADC 用STM32F407DIS做了一个简单的工程: 通过高级定时器TIM1溢出更新时间作为触发输出信号(TRGO),触发TIM8开始计数: 同时TIM1的通道1.2.3以及分 ...

  5. (五)转载:通用定时器PWM输出

    1.     TIMER输出PWM基本概念 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有 ...

  6. STM32 HAL库学习系列第4篇 定时器TIM----- 开始定时器与PWM输出配置

    基本流程: 1.配置定时器 2.开启定时器 3.动态改变pwm输出,改变值  HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); 函数总结: __HAL_TIM ...

  7. STM32(7)——通用定时器PWM输出

    1.TIMER输出PWM基本概念         脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种 ...

  8. stm32 PWM输出学习

    STM32 的定时器除了 TIM6 和 7,其他的定时器都可以用来产生 PWM 输出.其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出.通用定时器也能同时产生多达 4路 ...

  9. STM32F103ZET6 PWM输出

    1.通用定时器的PWM功能 STM32F103ZET6有4个通用定时器,分别是TIM2.TIM3.TIM4.TIM5. 通用定时器由一个可编程预分频器驱动的16位自动装载计数器构成. 通用定时器的很多 ...

随机推荐

  1. Drone - 安装,搭配 GitLab 下的配置和使用

    参考资料: Drone 官网地址:https://drone.io Drone 的 GitHub 地址:https://github.com/drone/drone 简介:https://imnerd ...

  2. 04 | 基础篇:经常说的 CPU 上下文切换是什么意思?(下)

    上一节,我给你讲了 CPU 上下文切换的工作原理.简单回顾一下,CPU 上下文切换是保证 Linux 系统正常工作的一个核心功能,按照不同场景,可以分为进程上下文切换.线程上下文切换和中断上下文切换. ...

  3. Java IO(1)

    IO这一部分内容还是比较多的,对于基础的枯燥但是又重要的内容还是将它记下来比较好. 关于File类 Ø File类直接继承与Object类,File类描述了文件本身的一些属性,File类用来获取或者处 ...

  4. JSP基础--javaBean

    JavaBean 1 JavaBean概述 1.1 什么是JavaBean JavaBean是一种规范,也就是对类的要求.它要求Java类的成员变量提供getter/setter方法,这样的成员变量被 ...

  5. Shell脚本语言学习总结

    Shell 是一种脚本程序,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了. 编写第一个Shell 程序 在linux命令行执行 [root@iz2zeexr9tk4ckr7dp ...

  6. jsoncpp解析非json串

    转自:https://www.cnblogs.com/huojing/articles/5927488.html 由于Jsoncpp解析非法json时,会自动容错成字符类型.对字符类型取下标时,会触发 ...

  7. 最短路 dijkstra算法

    题目 给定n个点的带权有向图,求从1到n的路径中边权之和最小的路径. dijkstra实现方法 用dist[i]表示i这个点到原点的最短距离,一开始初始化为无穷大,然后将原点设为0. 用ok[i]表示 ...

  8. python的小介绍

    Python简介 龟叔 优美.清晰.简单 主要应用领域: 云计算 WEB开发 科学技术.人工智能 系统运维 爬虫 金融量化分析 图形GUI 游戏 Python发展史 1989年,Guido开始写Pyt ...

  9. [fw]拦截系统调用

    今天在ubuntu中玩了下“拦截系统调用”,记录下自己对整个实现的理解. 原理 在linux kernel中,系统调用都放在一个叫做“sys_call_table”的分配表里面,在进入一个系统调用的最 ...

  10. Java-技术专区-设计模式-reactor模式

    模型:         反应器模式做法是:汽车是乘客访问的主体(Reactor),乘客上车后,到售票员(acceptor)处登记,之后乘客便可以休息睡觉去了,当到达乘客所要到达的目的地后,售票员将其唤 ...