rc522命令表_linux驱动程序文件

rc522命令表_linux驱动程序文件硬件平台:1主控:SMDKExynos4412POPS5M8767A2RFID模块:君盾集团提供的RC522模块3通信接口:SPI软件平台:AndroidICS&kernelversion3.0.15一,使能主控端SPI1硬件使能:从SMDK原理图上可以看到SPI0与I2C共用,SPI1已经连接到其它设备,SPI2未用,故这里选用SPI2。2软件使能:SMDKExyno…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

硬件平台:

1主控:SMDK Exynos4412 POP S5M8767A

2 RFID模块:君盾集团提供的RC522模块

3通信接口:SPI

软件平台:Android ICS & kernel version 3.0.15

一,使能主控端SPI

1硬件使能:

从SMDK原理图上可以看到SPI0与I2C共用,SPI1已经连接到其它设备,SPI2未用,故这里选用SPI2。

9795dc8ddc95e155bda335469fde0141.png

2软件使能:

SMDK Exynos4412主控端已经配置好了SPI接口,使用时只需打开宏CONFIG_S3C64XX_DEV_SPI即可。

打开方式:make menuconfigàDevice DriversàSPI supportàSamsung S3C64XX series type SPI.

编译后生成zImage,烧录进开发板。

二,测试主控端SPI

主控端SPI已经打开,接下来可以用一个通用的SPI驱动来测试主控端SPI硬件是否能正常工作。

以模块的方式编译:drivers/spi/spidev.c,生成spidev.ko,便是通用的设备端SPI驱动程序。

编译测试程序:Documentation/spi/spidev_test.c,先修改第32行:static const char *device = “/dev/spidev1.1″的设备为“/dev/spidev2.0”,然后再以应用程序的方式来编译,生成spidev_test,即为对应SPI的测试程序。

通过串口,赋予root权限和系统可读写权限:

shell@android:/ $ su root

shell@android:/ # mount -o remount -rw /system

[391.423930] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)

shell@android:/ #

通过adb把spidev.ko和spidev_test push到开发板:

d8c0821b884fbd011e01de02bcc6ee38.png

加载驱动:

shell@android:/system # insmod spidev.ko

把MISO和MOSI短路,即自发自收,然后再执行测试程序:

e4eb67f985f793dfef03635cc48f6851.png

如上图所示,说明能通过SPI收发数据;如果全部显示为0,则说明SPI未正常工作。接下来可以放心地去调试我们的RC522模块了。

三,RC522设备端驱动调试

上面的实验已经证明了主控的SPI可以正常工作,接下来可以正式调试RC522了。――这里假设你的rfid_rc522驱动已经写好,现在只需要去调试――如果驱动没有写好,请看另一篇Blog。

1打开与开发板相关的文件:arch/arm/mach-exynos/mach-smdk4x12.c

由于使用的spi2,故要修改board_info里的modalias = “rfid_rc522”,与驱动里的spi_drviver.name相匹配,否则probe函数不成功。

点击(此处)折叠或打开

988 static struct spi_board_info spi2_board_info[] __initdata = {

989 {

990 .modalias = “rfid_rc522”,

991 .platform_data = NULL,

992 .max_speed_hz = 10*1000*1000,

993 .bus_num = 2,

994 .chip_select = 0,

995 .mode = SPI_MODE_0,

996 .controller_data = &spi2_csi[0],

997 }

998 };

2重新编译内核,并烧录到开发板。

3编译rc522驱动程序,并通过adb usb把生成的rfid_rc522.ko copy到开发板系统的/system目录下,然后insmodrfid_rc522.ko,这样驱动就以模块的形式加载进了内核系统。加载成功后,在/dev目录下就会有rfid_rc522_dev这个目录。

9a3da519839da4d750f80ed140461fab.png

四,应用程序

驱动中的write函数为:

rc522_write (struct file *filp, const char *buf, size_t count, loff_t *f_pos);

用户空间的应用程序write函数为:

write(rc522_fd, bufpw1, sizeof(bufpw1));

二者如何联系的呢?

其实应用程序中的write函数通过调用操作系统中的核心函数sys_write(unsigned int fd, const char * buf, size_t count)来实现,而sys_write()函数又对驱动中的rc522_write()进行了封装。

//摘自论坛开始

下面以字符设备驱动来具体说明:

1,insmod驱动程序。驱动程序申请次设备名和主设备号,这些可以在/proc/devieces中获得。

2,从/proc/devices中获得主设备号,并使用mknod命令建立设备节点文件。这是通过主设备号将设备节点文件和设备驱动程序联系在一起。设备节点文件中的file属性中指明了驱动程序中fops方法实现的函数指针。

3,用户程序使用open打开设备节点文件,这时操作系统内核知道该驱动程序工作了,就调用fops方法中的open函数进行相应的工作。open方法一般返回的是文件标示符,实际上并不是直接对它进行操作的,而是有操作系统的系统调用在背后工作。

4,当用户使用write函数操作设备文件时,操作系统调用sys_write函数,该函数首先通过文件标示符得到设备节点文件对应的inode指针和flip指针。inode指针中有设备号信息,能够告诉操作系统应该使用哪一个设备驱动程序,flip指针中有fops信息,可以告诉操作系统相应的fops方法函数在那里可以找到。

5,然后这时sys_write才会调用驱动程序中的write方法来对设备进行写的操作。

其中1-3都是在用户空间进行的,4-5是在内核空间进行的。用户的write函数和操作系统的write函数通过系统调用sys_write联系在了一起。

注意:

对于块设备来说,还存在写的模式的问题,这应该是由GNU C库来解决的,这里不予讨论,因为我没有看过GNU C库的源代码。

//摘自论坛结束

应用程序源码如下:

点击(此处)折叠或打开

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

static enum IO_CMD {

READ_CARD = 0,

CHANGE_PASSWD = 1,

CHANGE_BLOCK = 3,

SET_RW_TIME = 4,

WRITE_CARD = 5,

};

int main(int argc, char** argv)

{

int rc522_fd;

int i, read_num;

char r[256];

printf(“test: rc522 %s %s\n”, __DATE__, __TIME__);

printf(“test: before open rc522_fd\n”);

rc522_fd = open(“/dev/rfid_rc522_dev”, O_RDWR);

printf(“test: rc522_fd=%d\n”, rc522_fd);

if(rc522_fd == -1)

{

printf(“test: Error Opening rc522\n”);

return(-1);

}

printf(“test: wait 01\n”);

sleep(1); //wait

printf(“test: wait 02\n”);

/******* Never to open ********/

#if 0

// change password as:020202020202

ioctl(rc522_fd, CHANGE_BLOCK, 0);//参数3:选第0块

ioctl(rc522_fd, CHANGE_PASSWD, 0);

char bufpw1[6] = {0xff,0xff,0xff,0xff,0xff,0xff};

write(rc522_fd, bufpw1, sizeof(bufpw1));

#endif

ioctl(rc522_fd, CHANGE_BLOCK, 0);//参数3:选第0块

ioctl(rc522_fd, READ_CARD, 0);//参数3没用

for(i = 0; i < 3; i++) //读三次卡号

{

read_num = read(rc522_fd, r, 0);

printf(“test: i=%d read_num=%d “, i, read_num);

if(read_num > 0){

printf(“r=[0x%.2X]”, r[0]);

}

printf(“\n”);

sleep(1);

}

// write something to the card

ioctl(rc522_fd, CHANGE_BLOCK, 1);//参数3:选第2块

ioctl(rc522_fd, WRITE_CARD, 1);

printf(“before write card!\n”);

char buf[11] = “186653803xx”;

if(write(rc522_fd, buf,sizeof(buf)))

{

printf(“write error\n”);

}

// read block[1], just writed with

ioctl(rc522_fd, CHANGE_BLOCK, 1);//参数3:选第1块

ioctl(rc522_fd, READ_CARD, 0);//参数3没用

read_num = read(rc522_fd, r, 0);

printf(“read block[1]\n\n\n The number you just writed is: %s\n\n\n”, r);

printf(“test: close rc522_fd\n”);

close(rc522_fd);

printf(“test: exit rc522_fd\n”);

return 0;

}

应用程序编译的Makefile如下:

点击(此处)折叠或打开

# Comment/uncomment the following line to disable/enable debugging

#DEBUG = y

DEST_BIN_DIR= drivers/

EXTRA_CFLAGS += -D_V3

#TESTFLAGS = -D_V3

# Add your debugging flag (or not) to CFLAGS

ifeq ($(DEBUG),y)

DEBFLAGS = -O -g -DSCULL_DEBUG # “-O” is needed to expand inlines

else

DEBFLAGS = -O2

endif

EXTRA_CFLAGS += $(DEBFLAGS)

EXTRA_CFLAGS += -I$(LDDINC)

EXTRA_CFLAGS += -DREV_VERSION=$(REV_VERSION)

LDFLAGS += –static

all: test

clean:

rm -rf test_rc522

cp:

cp -f test_rc522 $(DEST_BIN_DIR)

mv:

mv -f test_rc522 $(DEST_BIN_DIR)

test:

arm-linux-gcc $(CFLAGS) $(LDFLAGS) -O2 test_rc522.c -o test_rc522

depend .depend dep:

$(CC) $(CFLAGS) -M *.c > .depend

ifeq (.depend,$(wildcard .depend))

include .depend

endif

测试时,把卡靠近RC522的天线区域,即可正常读到卡ID。

628572871b5b8253ad52bd744cd88441.png

五,总结

本次调试比较顺利,遇到几个比较大的问题如下:

1 SMDK开发板SPI0通信有问题,开始一直以为驱动的问题,也不知道应该如何测试开发板SPI接口是否OK,在网上找了一些资料后发现SPI驱动可以通过内核自带的驱动模块和应用程序进行测试。

2应用程序(测试程序)无法在开发板系统上运行,原因是链接库未设置成静态。

3 RC522中的VCC供电需要3.3V,MOSI,CLK等TTL高电平也是3.3V。但4412主控的GPIO输出的高电平全部是1.8V,故模块无法正常工作。由于是调试,故不可能加一个TTL电平转换的IC了。后来试着把VCC调低到2.6V,结果模块可以正常工作了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/193357.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • linux系统 系统推荐 deepin国产系统 最好用的国产linux系统 Windows系统的优秀替代品 deepin系统安装 系统安装 deepin[通俗易懂]

    linux系统 系统推荐 deepin国产系统 最好用的国产linux系统 Windows系统的优秀替代品 deepin系统安装 系统安装 deepin[通俗易懂]前言:我用过多款linux系统,电脑上装的是Ubuntu和deepin,服务器端用的是centos,还用过优麒麟等。黑苹果也用了一段时间。现在linux系统已经发展的比较完善,内核及其图形界面也很稳定,当要说真的可以当做个人操作系统来使用的,我认为是deepin系统。deepin是一款国产系统,基于debian开发的linux操作系统,它拥有linux系统的所有优势,而且完美结合deepin-…

  • Linux Vi 文本编辑器常用命令

    Linux Vi 文本编辑器常用命令*LinuxVi文本编辑器常用命令**引言:在Linux中我们常用的文本编辑器有Vi,Vim(Vi的增强版)。而且vi编辑器不仅仅是适用于Linux,它是所有Unix以及Linux系统下的标准编辑器,几乎适用于Unix、Linux系统的所有版本。vi或vim虽然没有Windows操作系统中的图形界面编辑器那样点鼠标的简单操作,但vi编辑器在系统管理、服务器管理字符界面中,永远不是图形界面的编辑器能比的。它能轻易地创建和修改文本文件,维护Linux系统中的配置文件。其实刚开始的时候我也觉得很不习…

  • Oracle报错:不是单组分组函数解决「建议收藏」

    Oracle报错:不是单组分组函数解决「建议收藏」Oracle报错:不是单组分组函数解决报错:不是单组分组函数实例:selectdeptno,count(empno)fromemp;报错:不是单组分组函数原因:1,如果程序中使用了分组函数,则有两种情况可以使用:程序中存在groupby,并指定了分组条件,这样可以将分组条件一起查询出来改为:selectdeptno,count(empno)fromempgrou…

  • Android开发之activity跳转页面失败的问题

    Android开发之activity跳转页面失败的问题今天做地址管理,跳转新建地址页面发现一个问题,这么也跳转不到下一个页面代码如下:/***跳转创建地址页面*/privatevoidcreateAddress(){startActivityForResult(newIntent(this,CreateAddressActivity.class),CREATE_ADDR…

  • ES6数组的高阶方法,箭头函数,对象[通俗易懂]

    ES6数组的高阶方法,箭头函数,对象[通俗易懂]一.数组的高阶方法forEach(遍历)vararr=[‘我’,’和’,’我的’,’祖国’];arr.forEach(function(item,index,self){ console.log(item,index,self);})map(映射)vararr=[12,34,56];vararr2=arr.map(function(item,index,self){ console.log(item,index,self); returnitem*2;})

  • Linux安装nmap命令

    Linux安装nmap命令在线安装yuminstallnmap本地安装rpm软件包的安装可以使用程序rpm来完成。执行下面的命令:rpm-ivhyour-package.rpm

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号