fmql之Linux下AXI GPIO、MISC

AXI GPIO

正点原子第41章

 

 

要使用AXI GPIO,就要在vivado工程中,添加相关的IP。 然后dts会自动生成相关的AXi GPIO的设备树内容。

MISC

正点原子第42章

 

/***************************************************************
 Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved.
 文件名    : miscbeep.c
 作者      : Skylar
 版本      : V1.0
 描述      : MISC设备驱动框架
 其他      : beeper
 论坛      : www.openedv.com
 日志      : 初版V1.0 2024/10/9 创建
 ***************************************************************/

#include <linux/module.h>
#include <linux/of_gpio.h>
// #include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/platform_device.h>
// #include <linux/leds.h>
#include <linux/miscdevice.h>

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/of_address.h>
#include <linux/of.h>
#include <linux/kern_levels.h>


struct mybeep_dev {
	struct miscdevice mdev;
	int gpio;
};

struct mybeep_dev beep_dev;

/* beep相关初始化操作
 * @ pdev: struct platform_device指针
 * 		   platform设备指针
 * @ 成功返回0,失败返回负数
 */
static int mybeep_init(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	int ret;

	beep_dev.gpio = of_get_named_gpio(dev->of_node, "beeper-gpio", 0);
	if(!gpio_is_valid(beep_dev.gpio)){
		dev_err(dev, "Failed t oget gpio");
		return -EINVAL;
	}

	ret = devm_gpio_request(dev, beep_dev.gpio, "Beep Gpio");
	if(ret){
		dev_err(dev, "Failde to request gpio");
		return ret;
	}

	gpio_direction_output(beep_dev.gpio, 0);

	return 0;
}

static int mybeep_open(struct inode *inode, struct file *filp)
{
	return 0;
}

/*
 * @description : 向设备写数据
 * @param – filp : 设备文件,表示打开的文件描述符
 * @param – buf : 要写给设备写入的数据
 * @param – cnt : 要写入的数据长度
 * @param – offt : 相对于文件首地址的偏移
 * @return : 写入的字节数,如果为负值,表示写入失败
 */
static ssize_t mybeep_write(struct file *filp, const char __user *buf,
				size_t cnt, loff_t *offt)
{
	int ret;
	char kern_buf[5];

	ret = copy_from_user(kern_buf, buf, cnt);
	if(ret < 0){
		printk(KERN_ERR "mybeep: Failed to copy data from user buffer\r\n");
		return -EFAULT;
	}

	if(kern_buf[0] == 0)
		gpio_set_value(beep_dev.gpio, 0);
	else if(kern_buf[0] == 1)
		gpio_set_value(beep_dev.gpio, 1);

	return 0;
}

static struct file_operations mybeep_fops = {
	.owner	= THIS_MODULE,
	.open	= mybeep_open,
	.write	= mybeep_write,
};

/* platform驱动的probe函数
 * @ 当驱动与设备匹配成功后此函数会执行
 * @ pdev: platforme设备指针
 * @ 成功返回0, 失败返回负值
 */
static int mybeep_probe(struct platform_device *pdev)
{
	struct miscdevice *mdev;
	int ret;

	dev_info(&pdev->dev, "Driver and beep device have been matched\n");

	/* 初始化beep */
	ret = mybeep_init(pdev);
	if(ret){
		return ret;
	}
	
	/* 初始化beep_data变量 */
	mdev			= &beep_dev.mdev;
	mdev->name		= "mybeep";	// 设备名
	mdev->minor		= MISC_DYNAMIC_MINOR;	// 动态分配次设备号
	mdev->fops		= &mybeep_fops;
	
	/* 向linux系统misc驱动框架核心层注册beep设备 */
	return misc_register(mdev);
}

/* platform驱动模块卸载时
 * 此函数i执行
 * @ dev: platform设备指针
 * @ 成功返回0, 失败返回负值
 */
static int mybeep_remove(struct platform_device *pdev)
{
	gpio_set_value(beep_dev.gpio, 0);

	/* 注销MISC设备驱动 */
	misc_deregister(&beep_dev.mdev);

	dev_info(&pdev->dev, "Beep device was removed\n");

	return 0;
}

/* 匹配列表 */
static const struct of_device_id beep_of_match[] = {
	{.compatible = "fmql,beep"},
	{/* Sentinel */}
};

static struct platform_driver mybeep_driver = {
	.driver = {
		.name			= "mybeep",		/* platform_driver name*/
		.of_match_table	= beep_of_match,
	},
	.probe = mybeep_probe,
	.remove = mybeep_remove,
};


module_platform_driver(mybeep_driver);

MODULE_AUTHOR("Skylar <Skylar@33.com>");
MODULE_DESCRIPTION("MISC BEEP Device");
MODULE_LICENSE("GPL");

/***************************************************************
 Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved.
 文件名                 : miscbeepAPP.c
 作者                   : Skylar
 版本                   : V1.0
 描述                   : beep MISC
 其他                   : 
 使用方法                : ./miscbeepAPP /dev/mybeep 0
                          ./miscbeepAPP /dev/mybeep 1
 论坛                   : www.openedv.com
 日志                   : 初版V1.0 2024/10/9 创建
 ***************************************************************/

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
// #include <sys/ioctl.h>
// #include <poll.h>
// #include <signal.h>	

int main(int argc, char *argv[]
{
    int fd, ret;
    unsigned char buf[1];

    if(argc != 3){
        printf("Usage:\n"
            "\t./miscbeepApp /dev/mybeep 0 @ close Beep\n"
            "\t./miscbeepApp /dev/mybeep 1 @ open Beep\n"
        );
    return -1;
    }

    fd = open(argv[1], O_RDWR);
    if(fd < 0){
        printf("Erroe: file %s open failed\r\n", argv[1]);
        return -1;
    }

    buf[0] = atoi(argv[2]);     // char -> int

    ret = write(fd, buf, sizeof(buf));
    if(ret < 0){
        close(fd);
        return -1;
    }

    close(fd);
    return 0;
})

 Makefile:

KERN_DIR :=/。。。/FMQL-Linux-SDK-Prj-20230801/linux-4.14.55-fmsh

CURRENT_DIR := $(shell pwd)

obj-m :=miscbeep.o

all:
	make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -C $(KERN_DIR) M=`pwd` modules

clean:
	make -C $(KERN_DIR) M=`pwd` clean

因为开发板上没有beep,所以就不进行测试了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值