我是靠谱客的博主 甜美大白,最近开发中收集的这篇文章主要介绍125KHZ RFID 曼彻斯特码在内核域解码,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一. 曼彻斯特码理论分析:
曼彻斯特码编码的ID卡每次输出64bit 数据/8个字节,其载波编码为曼彻斯特码.
其时序图如下:
在这里插入图片描述
曼彻斯特码调制方式下,EM4100卡片每传送一位数据的时间是64个振荡周期。125KHZ载波时,卡片传送一bit数据理论频率为125KHz / 64 = 1.953125KHz。那么得到一个周期为:1 000 000us / 1.953125KHz = 512us。

也就是说:曼彻斯特码一个完整的数据跳变为一个周期(512us)。
但是特别需要注意的是:存在空跳则半个跳变为半个周期(256us)。

那么如何得到一个bit的数据呢?

如果捕获到一个电平变化,这个电平距离上次检测到电平变化时间为512us,则该位按以下读取:
	低电平-bit = 1,
	高电平-bit = 0;

如果捕获到一个电平变化,这个电平距离上次检测到电平变化时间256us,则此次不作判断,再次捕获到一个边沿时再判断如下:
	上次bit = 1 此次bit = 1,
	上次bit = 0,此次bit = 0.
此处有一个特别注意的地方,如果上次读取到256us,不管这次读取间隔是256us还是512us,都应该读取上一次的电平,并且重新检测跳包。

二.设备树配置:
配置设备树节点,用于内核驱动程序找到对应能检波的IO口。在anyka v300 平台如下:

编辑:anycloud_ak39ev330_common.dtsi
添加节点:在 gpiokeys: gpiokeys {
compatible = "anyka,ak39ev330-gpiokeys";
		status = "disable";
	};
 附近添加以下节点信息:
 rfid_control: rfid_control {
		compatible = "leo_rfid_control";
		status = "disable";
	};
	编辑:C500_SQ38_AK3918EV330_GC2063_MIPI_V1.0.0.dts:
	在"$gpio" 节点内部添加
	rfid_pins:rfid_pins{
	anyka,pins = <0>;
	anyka,function = <0>;
	anyka,pull = <0x00000001>;
    };

    然后退出$gpio节点,使能“rfid_control”节点,如下:
    
    &rfid_control{
    gpios = <&gpio 0 1>;
    pinctrl-names ="default";
    pinctrl-0 = <&rfid_pins>;
    status = "okay";
 };

好了,完成了设备树信息的编写,

第二部:接下来开始写驱动内核程序。
整个代码如下:

#include <linux/module.h>
#include <linux/poll.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <asm/current.h>
#include <linux/kthread.h>
#include <linux/delay.h>

#define diff_us(t1,t2) ((u64)t1.tv_sec - (u64)t2.tv_sec) * 1000000 + ((u64)t1.tv_usec - (u64)t2.tv_usec);

#define rfid_code_bit_value(data,index) ((data[(index)/8] >> (7 - (index)%8))&0x01)
/* 主设备号 */
static int major = 0;
/* 创建设备类的结构体 */
static struct class* rfid_class;
/* 记录设备树信息的结构体*/
static int rfid_gpio_index;

static struct task_struct *rfid_kthread;   

static char rfid_data_code[16] = {0};
static int rfid_data_count = 0;

static char rfid_code_number[4] = {0};
static char rfid_code_number_ready = 0;

static DEFINE_MUTEX(rfid_code_mutex);


static ssize_t rfid_read(struct file* file,char __user*buf,size_t size,loff_t* offset){
	
	int len  = 0;
	if(size < 4){
		return 0;
	}
	
	len = sizeof(rfid_code_number);
	//printk("read rfid value n");	
	mutex_lock(&rfid_code_mutex);
	if(rfid_code_number_ready == 0){
		mutex_unlock(&rfid_code_mutex);
		return 0;
	}
	
	copy_to_user(buf, rfid_code_number , len); 
	rfid_code_number_ready = 0;
	mutex_unlock(&rfid_code_mutex);
	return len;
}
/* 创建设备方法 */
static struct file_operations rfid_control_fops = {
	.owner = THIS_MODULE,
	.read = rfid_read,
};

static int rfid_code_leave_wait(int* level,int min,int middle,int max,struct timeval* pre_tv){
	
	u64 us = 0;
  	struct timeval tv;
  	
  	int cur_level = gpio_get_value(rfid_gpio_index) ;
	while(gpio_get_value(rfid_gpio_index) == cur_level){
	
		do_gettimeofday(&tv);
		us = diff_us(tv,(*pre_tv));
		
		if(us > max){
			return -1;
		}
	}
	do_gettimeofday(&tv);
	us = diff_us(tv,(*pre_tv));
	*level = cur_level?0:1;
	if(us < min){
		return -1;
	}
	else if((us > min)&&(us < middle)){
		return 0;
	}
	return 1;
}

static char rfid_code_jump_flg = 0;

static int rfid_code_read_proc(void){

	int i = 0;
	int reslut = 0;
	int level = 0;
	struct timeval tv;
	unsigned char value = 0;

	memset(rfid_data_code,0,sizeof(rfid_data_code));
	rfid_data_count = 0;
	rfid_code_jump_flg = 0;
	do_gettimeofday(&tv);
	while(1){
	
		reslut = rfid_code_leave_wait(&level,125,375,625,&tv);
		do_gettimeofday(&tv);
		if((reslut == 0)&&(rfid_code_jump_flg == 0)){

			rfid_code_jump_flg = 1;
		}
		else if((reslut == 1)||((reslut == 0)&&(rfid_code_jump_flg == 1))){
		
			if(rfid_code_jump_flg == 1){
			
				value = ((rfid_data_code[(rfid_data_count - 1) / 8] >> (7 - (rfid_data_count - 1) % 8)) & 0x01) ? 1 : 0;
			}
			else{
				value = level?0:1;
			}
			
			rfid_code_jump_flg = 0;
			rfid_data_code[rfid_data_count / 8] |= (value << (7 - rfid_data_count % 8));
			rfid_data_count++;
			if(rfid_data_count >= 128){
			
				return 1;
			}
		}
		else if(reslut < 0){
			
			return -1;
		}
	}
	return 0;
}

static int rfid_code_data_check(void){

	int index = 0,i = 0,j = 0,n = 0;
	int value = 0;
	for(index = 0; index < 64 ; index++){
		
		value = 0;
		for(i = 0 ; i < 9 ; i++){
		
			value <<= 1;
			value |= rfid_code_bit_value(rfid_data_code,index + i);
			//printk("%d",rfid_code_bit_value(rfid_data_code,index + i));
		}
		
		if(value == 0x1FF){
			index += 9;
			break;
		}
	}
	
	if(index == 64){
	
		printk("check rfid data failed (%s,%d)n",__func__,__LINE__);
		return -1;
	}
	
	for(i = index; i < (index + 45) ; i+=5){
		
		value = 0;
		for( j = 0 ;j < 4 ; j++){
		
			value += rfid_code_bit_value(rfid_data_code,i + j);
		}
		if((value %2) != rfid_code_bit_value(rfid_data_code,i + j)){
		
			printk("check rfid data failed (%s,%d)n",__func__,__LINE__);
			return -1;
		}
	}
	
	for( i = index; i < (index + 4) ; i++){
	
		value = 0;
		for( j = 0 ; j < 50 ; j+= 5){
		
			value += rfid_code_bit_value(rfid_data_code,i + j);
		}
		
		if((value %2) != rfid_code_bit_value(rfid_data_code,i + j)){
			
			printk("check rfid data failed (%s,%d)n",__func__,__LINE__);
			return -1;
		}
	}
	
	if(rfid_code_bit_value(rfid_data_code,index + 54) != 0){
	
		printk("stop failed n");
		return -1;
	}
	n = 0;
	mutex_lock(&rfid_code_mutex);
	rfid_code_number_ready = 0;
	mutex_unlock(&rfid_code_mutex);
	memset(rfid_code_number,0,sizeof(rfid_code_number));
	for(i = index + 10 ; i < (index + 50) ; i+=10){
		
		value = 0;
		for( j = 0 ; j < 9; j++){
		
			if(j == 4){
			
				continue;
			}
			value <<= 1;
			value |= rfid_code_bit_value(rfid_data_code,i+j);
			
		}
		rfid_code_number[n++] = value;
		//printk("%02x ",value);
	}
	//printk("n");
	
	mutex_lock(&rfid_code_mutex);
	rfid_code_number_ready = 1;
	mutex_unlock(&rfid_code_mutex);
	return 1;
}

static int k_rfid_task(void*data){

	int pre_level = gpio_get_value(rfid_gpio_index);
	int cur_level = pre_level;
	char det_start_flag = 0;
	
	printk("leo:kernel rfid card task success! n");
	while(1){
	
		if(kthread_should_stop()){
			break;
		}
		
		if(det_start_flag == 0){
			cur_level = gpio_get_value(rfid_gpio_index);
			if(cur_level == 0){
				det_start_flag = 1;
				pre_level = cur_level;
			}
			else
			{
				msleep(100);
			}
		}
		else{
		
			if(rfid_code_read_proc() == 1){
				
				//printk("check data n");
				rfid_code_data_check();	
			}
			gpio_set_value(rfid_gpio_index,1);
			pre_level = gpio_get_value(rfid_gpio_index);
			det_start_flag = 0;
			msleep(10);
		}
	}
	return 0;
}

static int rfid_probe(struct platform_device*pdev){

	int irq;
	struct device_node *np = pdev->dev.of_node;
	printk("leo:rfid probe success n");
	rfid_gpio_index = of_get_named_gpio(np, "gpios", 0);
	if(rfid_gpio_index < 0){
	
		printk("rfid gpio setting failedn");
	}
	else{
		printk("rfid setting gpio%dn",rfid_gpio_index);
	}
	device_create(rfid_class,NULL,MKDEV(major,0),NULL,"rfid_control");
	
	gpio_direction_output(rfid_gpio_index,1);
	msleep(100);
	gpio_direction_input(rfid_gpio_index);
	
	mutex_init(&rfid_code_mutex);
	
	rfid_kthread = kthread_create(k_rfid_task,NULL,"rfid_kthread");
	if(IS_ERR(rfid_kthread)){
		printk("create rfid_kthread faieldn");
		return 0;
	}
	wake_up_process(rfid_kthread);
	return 0;	
}

static int rfid_remove(struct platform_device*pdev)
{
	int irq;
	printk("leo:rfid driver removen");
	kthread_stop(rfid_kthread);
	
	device_destroy(rfid_class,MKDEV(major,0));
	return 0;
}

static const struct of_device_id rfid_board_control[]={
	{.compatible = "leo_rfid_control"},
	{}
};

static struct platform_driver rfid_platform_drv = {
	
	.probe = rfid_probe,
	.remove = rfid_remove,
	.driver = {
		.name = "rfid_control",
		.of_match_table = rfid_board_control,
	},
};

static int __init rfid_drv_init(void){

	printk("leo:rfid drv init startn");
	
	//注册主字符设备号
	major = register_chrdev(0,"rfid_control",&rfid_control_fops);
	
	//创建设备类
	rfid_class = class_create(THIS_MODULE,"rfid_class");
	if(IS_ERR(rfid_class)){
		printk("rfid class create failedn");
		unregister_chrdev(major,"rfid_control");
		return PTR_ERR(rfid_class);
	}
	
	return platform_driver_register(&rfid_platform_drv);
}



static void __exit rfid_drv_exit(void){

	platform_driver_unregister(&rfid_platform_drv);
	class_destroy(rfid_class);
	unregister_chrdev(major,"rfid_control");
}

/*
* ko创建
*/
module_init(rfid_drv_init);
module_exit(rfid_drv_exit);

MODULE_LICENSE("GPL");

生成rfid.ko之后,上次insom rfid.ko,完成内核模块的安装。
第三步:应用层的编写:
整体代码如下:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

#define RFID_DEVICE_PATH "/dev/rfid_control"

int main(int argc,char** argv){

	if(access(RFID_DEVICE_PATH,F_OK) != 0){
		
		printf("%s not exitn",RFID_DEVICE_PATH);
		return 0;
		
		
	}
	
	int fd = open(RFID_DEVICE_PATH,O_RDONLY);
	if(fd < 0 ){
	
		printf("open %s failed n",RFID_DEVICE_PATH);
		return 0;
	}
	
	unsigned char data[4] = {0};
	while(1){
	
		if(read(fd,data,sizeof(data)) == 4){
		
			printf("%02x%02x%02x%02xn",data[0],data[1],data[2],data[3]);
		}
		usleep(1000*10);
	}

	return 0;
}

最后

以上就是甜美大白为你收集整理的125KHZ RFID 曼彻斯特码在内核域解码的全部内容,希望文章能够帮你解决125KHZ RFID 曼彻斯特码在内核域解码所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部