海思Hi3559AV100平台韦根发送程序

      项目中需要基于海思Hi3559AV100开发韦根功能。韦根分为韦根输出和韦根输入,这篇文章讲韦根输出程序,前一篇文章讲韦根输入程序。

      首先,必须要感谢https://blog.csdn.net/qq_37803273/article/details/84993627 《RK3288韦根发送驱动》的作者的无私分享,文章中提供了源码(以下简称例程),很详细,我的代码也是以这篇文章中的代码为基础进行修正改进而得到的。

      其次,需要说明的是,韦根发送程序的坑不像韦根接收程序那么多,主要的点在延时上。例程中使用了msleep和usleep_range函数,但实测是无法保证精确低脉冲的。纠结于是否使用udelay,担心其占据CPU特性以及相对较长的延时会影响实时视频传输导致卡顿。但最终实测下来,效果还是可以接受的,因此在代码中广泛使用了udelay。

      最后,整个工程源码以附件形式放到网上,初始设定为0积分加载。

 

韦根输出代码如下:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


//msleep:实现毫秒级的延时,该延时保证至少延时所设置的延时时间,不会提前超时返回,会让出CPU
#define delay_1ms(x)	msleep(x)

#define GPIO12_4	(12 * 8 + 4)
#define GPIO12_2	(12 * 8 + 2)
#define WG_DATA0	GPIO12_4
#define WG_DATA1	GPIO12_2


struct wiegand26
{
	bool flag;
	char data[24];
} wiegand26;

struct wiegand34
{
	bool flag;
	char data[32];
} wiegand34;

static struct workqueue_struct *queue = NULL;
static struct work_struct work;
static int major;
static struct class *class = NULL;
static struct device *dev = NULL;
static int even = 0;
static int odd = 0;


//设置相应GPIO引脚为输出,并输出为高
void gpio_set_output(void)
{
	gpio_direction_output(WG_DATA0, 1); //DATA0初始为高
	gpio_direction_output(WG_DATA1, 1); //DATA1初始为高
}

//初始化相应GPIO
void gpio_init(void)
{
	gpio_request(WG_DATA0, "wiegand_d0");
	gpio_request(WG_DATA1, "wiegand_d1");
	gpio_set_output();
}

int wiegand26_int_to_char(int data)
{
	int i = 0;

	odd = 0;
	even = 0;

	for(i=0; i<24; i++)
	{
		if((1<dev.kobj, &wiegand_out_attribute_group);

	wiegand26.flag = false;
	wiegand34.flag = false;

	printk("wiegand_out_probe, end ret=%d\n",ret);

	return ret;
}

static int wiegand_out_remove(struct platform_device *pdev)
{
	printk("wiegand_out_remove\n");

	//删除接口函数
	sysfs_remove_group(&pdev->dev.kobj, &wiegand_out_attribute_group);

	device_remove_file(dev, &dev_attr_wiegand26);
	device_remove_file(dev, &dev_attr_wiegand34);
	//删除设备节点
	device_unregister(dev);
	//注销创建的设备类
	class_destroy(class);
	//取消注册设备驱动
	unregister_chrdev(major, "wiegand_out");

	//释放注册的GPIO编号
	gpio_free(WG_DATA0);
	gpio_free(WG_DATA1);

	return 0;
}

static struct platform_driver wiegand_out_drv =
{
	//完成具体设备的初始化操作
	.probe = wiegand_out_probe, //匹配到dev之后调用probe
	//完成具体设备的退出操作
	.remove = wiegand_out_remove,
	.driver =
	{
		.name = "wiegand_out",
		.owner = THIS_MODULE,
		//.of_match_table = of_match_ptr(wiegand_out_of_match),
	},
};

static void wiegand_out_device_release(struct device *dev)
{
	return;
}

static struct platform_device wiegand_out_device =
{
	.name = "wiegand_out",
	.id = -1,
	//必须有release函数,否则卸载模块时会报"Device 'wiegand_out' does not have a release() function, it is broken and must be fixed."
	.dev =
	{
		.release = wiegand_out_device_release,
	}
};

//设备驱动模块加载函数
static int __init wiegand_out_init(void)
{
	int ret = 0;

	printk("wiegand_out_init\n");

	//创建一个单线程的工作队列
	queue = create_singlethread_workqueue("weigand_send");
	if(!queue)
	{
		printk(KERN_ERR "create_singlethread_workqueue failed\n");
		return -1;
	}

	//平台驱动注册
	ret = platform_driver_register(&wiegand_out_drv);
	if(ret)
	{
		printk(KERN_ERR "platform_driver_register failed\n");
		destroy_workqueue(queue);
		return -1;
	}

	//平台设备注册
	ret = platform_device_register(&wiegand_out_device);
	if(ret)
	{
		printk(KERN_ERR"platform_device_register failed\n");
		platform_driver_unregister(&wiegand_out_drv);
		destroy_workqueue(queue);
		return -1;
	}

	return 0;
}

//设备驱动模块卸载函数
static void __exit wiegand_out_exit(void)
{
	printk(KERN_ALERT "wiegand_out_exit\n");

	//平台设备注销
	platform_device_unregister(&wiegand_out_device);
	//平台驱动注销
	platform_driver_unregister(&wiegand_out_drv);
	//释放工作队列所占的资源 
	destroy_workqueue(queue);
}

module_init(wiegand_out_init);
module_exit(wiegand_out_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("[email protected]");

 

项目资源下载地址:

 https://download.csdn.net/download/phmatthaus/12209392

 

你可能感兴趣的:(Hi35XX,c\c++,Linux)