初级会员
- 积分
- 68
- 金钱
- 68
- 注册时间
- 2020-5-19
- 在线时间
- 14 小时
|
发表于 2021-5-17 16:42:45
|
显示全部楼层
我也发现这个问题,我刚刚解决了。
正点原子和野火对于这个pwm,都没有说清楚。
韦东山老师没有pwm的讲解。
我结合他们三位老师的讲解,我摸索着解决了问题:
我这是实现了两路pwm的驱动和app测试
设备树:
- fs_pwm {
- compatible = "fsml,fs_pwm";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_fspwm>;
- pwm_power {
- pwm-names = "pwm_power";
- pwms = <&pwm1 0 50000>;
- };
- pwm_motor {
- pwm-names = "pwm_motor";
- pwms = <&pwm2 0 50000>;
- };
- };
- pinctrl_fspwm:fspwmgrp {
- fsl,pins = <
- MX6UL_PAD_LCD_DATA00__PWM1_OUT 0x1b0b0 /*/pwm1&motor pwm*/
- MX6UL_PAD_LCD_DATA01__PWM2_OUT 0x1b0b0 /*/pwm1&motor pwm*/
- >;
复制代码
驱动:
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/platform_device.h>
- #include <linux/of_platform.h>
- #include <linux/err.h>
- #include <linux/pwm.h>
- #include <linux/slab.h>
- #include <linux/types.h>
- #include <linux/seq_file.h>
- #include <linux/stat.h>
- #include <linux/tty.h>
- #include <linux/kmod.h>
- #include <linux/gfp.h>
- struct pwm_device *pwm_power_dev = NULL; //定义pwm设备结构体
- struct pwm_device *pwm_motor_dev = NULL;
- /*精简版 prob函数*/
- /* 1. 确定主设备号 */
- static int major = 0;
- static struct class *fspwm_class;
- //static struct gpio_desc *led_gpio;
- /* 3. 实现对应的open/read/write等函数,填入file_operations结构体 */
- static ssize_t fspwm_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
- {
- printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
- return 0;
- }
- /* write(fd, &val, 1); */
- static ssize_t fspwm_write (struct file *file, const char __user *buf, size_t size, loff_t *offset)
- {
- int err;
- int k_buf = 0;
- short duty_ns,period;
- //struct inode *inode = file_inode(file);
- //int minor = iminor(inode);
-
- printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
- err = copy_from_user(&k_buf, (void*)buf, sizeof(int));
- period = k_buf & 0xffff;
- duty_ns = (k_buf >> 16) & 0xffff;
- err = pwm_config(pwm_power_dev, duty_ns, period);
- err = pwm_config(pwm_motor_dev, duty_ns, period);
- printk("%s %d %d %d\r\n", __FUNCTION__, k_buf, duty_ns, period);
-
- return 1;
- }
- static int fspwm_open (struct inode *node, struct file *file)
- {
- //int minor = iminor(node);
-
- printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
-
- return 0;
- }
- static int fspwm_close (struct inode *node, struct file *file)
- {
- printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
- return 0;
- }
- /* 定义自己的file_operations结构体 */
- static struct file_operations fspwm_dev = {
- .owner = THIS_MODULE,
- .open = fspwm_open,
- .read = fspwm_read,
- .write = fspwm_write,
- .release = fspwm_close,
- };
- static int pwm_power_probe_new(struct platform_device *pdev)
- {
- int ret = 0;
- struct device_node * child;
- struct device_node * child2;
- struct device *dev = &pdev->dev;
- printk("match success \n");
- //注册operations
- major = register_chrdev(0, "fspwm", &fspwm_dev);
- fspwm_class = class_create(THIS_MODULE, "fspwm_class");
- if (IS_ERR(fspwm_class)) {
- printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
- unregister_chrdev(major, "fspwm");
- return PTR_ERR(fspwm_class);
- }
- device_create(fspwm_class, NULL, MKDEV(major, 0), NULL, "fspwm_%s","motor");
- child = of_get_next_child(dev->of_node, NULL);
- printk(""%s"'s child: "%s"\n", dev->of_node->full_name, child->full_name);
- printk("%s %s line %d\r\n"__FILE__, __FUNCTION__, __LINE__);
- if(NULL == child)
- {
- printk("of_get_next_child error\r\n");
- }
- if (child)
- {
- pwm_power_dev = devm_of_pwm_get(dev, child, NULL);
- if (IS_ERR(pwm_power_dev))
- {
- printk(KERN_ERR" pwm_power_dev,get pwm error!!\n");
- return -1;
- }
-
- //pwm_motor_dev = devm_of_pwm_get(dev, chile, )
- }
- else
- {
- printk(KERN_ERR" pwm_power_dev of_get_next_child error!!\n");
- return -1;
- }
- child2 = of_get_next_child(dev->of_node, child);
-
- printk(""%s"'s child2: "%s"\n", dev->of_node->full_name, child2->full_name);
- printk(""%s"'s child2: "%s"\n", dev->of_node->full_name, child2->full_name);
- printk(""%s"'s child2: "%s"\n", dev->of_node->full_name, child2->full_name);
- printk("%s %s line %d\r\n"__FILE__, __FUNCTION__, __LINE__);
- if(NULL == child2)
- {
- printk("of_get_next_child2 error\r\n");
- }
- if (child2)
- {
- if (IS_ERR(child2))
- {
- printk(KERN_ERR" of_get_next_child,child2 error!!\n");
- return -1;
- }
- printk(""%s"'s devm_of_pwm_get: "%s"\n", dev->of_node->full_name, child2->full_name);
- pwm_motor_dev = devm_of_pwm_get(dev, child2, NULL);
- //pwm_motor_dev = devm_pwm_get(dev, child2->full_name);
- if (IS_ERR(pwm_motor_dev))
- {
- printk(KERN_ERR" pwm_power_dev,get pwm error!!\n");
- return -1;
- }
- }
- else
- {
- printk(KERN_ERR" pwm_power_dev of_get_next_child error!!\n");
- return -1;
- }
- printk("set pwm_power...\r\n");
- /*配置频率100KHz 占空比80%*/
- ret = pwm_config(pwm_power_dev, 1000, 5000);
- printk("ret:%d\r\n", ret);
- /*反相 频率100KHz 占空比20%*/
- ret = pwm_set_polarity(pwm_power_dev, PWM_POLARITY_INVERSED);
- printk("ret:%d\r\n", ret);
- ret = pwm_enable(pwm_power_dev);
- printk("ret:%d\r\n", ret);
- printk("set pwm_motor...\r\n");
- /*配置频率100KHz 占空比80%*/
- ret = pwm_config(pwm_motor_dev, 1000, 5000);
- printk("ret:%d\r\n", ret);
- /*反相 频率100KHz 占空比20%*/
- ret = pwm_set_polarity(pwm_motor_dev, PWM_POLARITY_NORMAL);
- printk("ret:%d\r\n", ret);
- ret = pwm_enable(pwm_motor_dev);
- printk("ret:%d\r\n", ret);
- return ret;
- }
- static int pwm_power_remove(struct platform_device *pdev)
- {
- device_destroy(fspwm_class, MKDEV(major, 0));
- class_destroy(fspwm_class);
- unregister_chrdev(major, "fspwm");
- printk("%s %s line %d\r\n"__FILE__, __FUNCTION__, __LINE__);
- return 0;
- }
- static const struct of_device_id of_pwm_leds_match[] = {
- {.compatible = "fs_pwm"},
- {},
- };
- static struct platform_driver led_pwm_driver = {
- .probe = pwm_power_probe_new,
- .remove = pwm_power_remove,
- .driver = {
- .name = "fs_pwm",
- .of_match_table = of_pwm_leds_match,
- },
- };
- /*
- *驱动初始化函数
- */
- static int __init pwm_driver_init(void)
- {
- printk("%s %s line %d\r\n"__FILE__, __FUNCTION__, __LINE__);
- return platform_driver_register(&led_pwm_driver);
- }
- /*
- *驱动注销函数
- */
- static void __exit pwm_driver_exit(void)
- {
- printk(KERN_ERR "%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
- /*注销平台设备*/
- platform_driver_unregister(&led_pwm_driver);
- }
- module_init(pwm_driver_init);
- module_exit(pwm_driver_exit);
- MODULE_LICENSE("GPL");
-
复制代码
APP:
- #include "stdio.h"
- #include "unistd.h"
- #include "sys/types.h"
- #include "sys/stat.h"
- #include "fcntl.h"
- #include "stdlib.h"
- #include "string.h"
- //#include "linux/ioctl.h"
- #include "sys/ioctl.h"
- int main(int argc, char *argv[])
- {
- int fd = 0;
- int ret = 0;
- int data = 0;
- char *filename = NULL;
- unsigned int value = 0;
- unsigned short duty,period;
- int cmd=0;
- printf("\r\n\r\n\r\nargc num:%d\r\n",argc);
- filename = argv[1];
- duty = atoi(argv[2]);
- period = atoi(argv[3]);
- cmd = (duty << 16)+period;
- fd = open(filename, O_RDWR);
- if(0 > fd)
- {
- printf("can't open file %s\r\n", filename);
- return -1;
- }
- printf("open fsio_dev ok cmd:%d\r\n",cmd);
- write(fd, &cmd, sizeof(int));
- close(fd);
- printf("open fsio_dev ok cmd:%d,%d,%d\r\n",cmd,duty,period);
- return ret;
- }
复制代码 |
|