TI RF430FRL152HEVM NFC NDEF格式
我们设计了一款基于具有NFC功能的TI RF430FRL152HEVM评估模块的电路板。 当Android手机靠近电路板的天线时,NFC允许处理器启动并开始读取数据。 它将它读取的数据存入内存。
然后,手机必须使用NFC(或ISO 15693)从设备中获取数据。
我们现在知道如何做到这一点的唯一方法是将其写入标准的NFC存储器模块中。
我们下载了名为NFC TagInfo的Android应用程序,这让我们可以扫描我们的传感器并收集传感器内存中的所有数据,即所有块。
我们将它写入芯片制造商所说的FRAM中的NDEF消息区域。 我为另一个项目编写了读写器NFC应用程序,运行良好,但它拒绝读取数据,尽管NFC TagInfo读取数据。
我们假定TI芯片已经过NDEF格式化,但是我们发现的关于如何做到这一点的所有文档都很不清楚。 所以我们猜测它没有。
有人可以解释如何正确准备存储器内容,以便手机可以读取NDEF消息吗?
附加信息
我们从数据块0开始向FRAM写入数据,并试图模仿在包含非常简单的NDEF消息的典型标签中看到的数据。 例如,我们存储了消息“ABCD”,并使用NFC TagInfo在前几个块中看到:
04 5c d8 08 4a 62 3e 80 96 48 00 00 e1 10 12 00 01 03 a0 0c 34 03 21 d1 01 1d 54 02 65 6e 41 42 43 44 20 20 ...
其中41 42 43 44
是UTF-8中的“ABCD”。
我们从另一个标签(使用NFC TagInfo读取)获取这些数据(NDEF格式+标头),并将这些数据复制到我们标签芯片的FRAM块中。 我们在NDEF消息的末尾停下来,其余的FRAM是0x00
或0xff
。
很明显,我们从恩智浦和我们的标签芯片(TI)复制数据的标签来自不同的制造商,因此前几个模块中的一些数据对我们的TI芯片无效,但假定Android不应该在意。
但是,当我们使用NFC TagInfo阅读我们的TI标签时,它可以读取原始数据块,但它不会将该标签识别为NDEF格式标签。
是否我们从另一个标签复制的NDEF格式对我们的标签无效,因为我们没有使用相同的标签内存大小等等?
如果只是在正确的块中写入正确的字节,那么什么都可以作为NDEF来提取,毕竟在低层次上有什么不同?
如果是这种情况,在哪些块中使用最明智的字节测试用例,是否有更好的方法来测试这个概念?
块锁定有什么区别? 我们可以看到一些块被锁定在一个真实的标签中。
为什么NFC TagInfo有时会看到块,然后在检测到NDEF时出现页面? 块和页面是否相同?
如果没有其他的一切,我们如何才能在Android简单块阅读中编码,就像NFC TagInfo执行其十六进制转储一样? 如果我们能做到这一点,那么NDEF并不是真的有必要。
附加信息2
我修改了固件,使FRAM从块0开始包含您提到的数据:
E1 40 F2 09 03 0B D1 01 07 54 02 65 6E 41 42 43 44 FE 00 00 00 00 00 00
但我似乎无法将TI芯片置于8字节块模式。 似乎没有与此相关的控制寄存器。
从我的低级角度来看,写入4或8字节的数据块不是问题,也就是说,我将字节数据按顺序写入FRAM存储器中。
当我运行NFC TagInfo时,它执行两件事但不检测NDEF消息:
我已经咨询了我从http://open-nfc.org/documents/STS_NFC_0707-001%20NFC%20Tag%20Type%205%20Specification.pdf得到的NFC标签类型5规范
所以我试图从block 0写入更多的数据到TAG中,尝试和模拟SERIAL NUMBER,CONFIGURATION和Application area issuer blocks。 然后我将NDEF消息ABCD放在段落后面:
01 02 03 04 05 06 07 08 //serial number 00 00 00 80 00 10 00 00 //configuration ...
我使用了NFC TagInfo,但我无法检测到NDEF消息。 但是,使用数据十六进制显示我可以验证数据正确地读出如上。
所以我的问题是:
补充信息3
事实证明,TI需要提供补丁才能使NDEF与该芯片(FRL152H)一起工作。 基本上,该芯片旨在支持通过NFC对传感器功能进行高级控制,并使用内部固件应用程序。 这个应用程序需要被禁用并且一些设置被改变。
下面的内存配置证明是可行的:
Block 0: E1 40 79 00 Block 1: 03 0B D1 01 Block 2: 07 54 02 65 Block 3: 6e 41 42 43 Block 4: 44 FE 00 00
是否我们从另一个标签复制的NDEF格式对我们的标签无效?
这正是问题所在。 查看内存转储的前12个字节,您显然已从制造商代码(字节0: 0x04
)所示的NXP NTAG203(或类似的)和容量容器中的内存大小(字节13: 0x12
)中复制了数据块)。 恩智浦的NTAG和MIFARE Ultralight系列遵循NFC论坛2型标签操作规范。 但是,您的TI芯片(RF430FRL152H)基于ISO / IEC 15693标准,因此遵循NFC论坛5类标签操作规范。 标签操作规范定义了将NFC标签变为NDEF标签的数据格式和命令集。 由于NFC技术结合了几种不同的RF标准(ISO / IEC 14443,FeliCa,ISO / IEC 15693),并且在NFC之前使用了这些标准已经存在的标签硬件,所以有几种(目前有5种)不同的规格。
为什么NFC TagInfo有时会看到块,然后在检测到NDEF时出现页面? 块和页面是否相同?
在这种情况下,块和页面是等效的。 不同的措词只是来自芯片制造商使用的术语。 请注意,RF430FRL152H芯片使用术语“页”来分组几个块,因此具有不同的含义。
如果只是在正确的块中写入正确的字节,那么什么都可以作为NDEF来提取,毕竟在低层次上有什么不同?
不同之处在于,您的TI RF430FRL152H标签芯片需要对NDEF存储区使用与恩智浦标签不同的编码。 这仅仅是因为它使用了不同的低级别通信技术(调制,编码,成帧,命令集),因此遵循不同的NFC论坛标签操作规范。
为了使您的标记芯片成为NDEF标记,您需要在块0开始为NDEF存储区使用以下编码:请注意,容器容器中填充了假定块大小为8字节的值。 您可以使用固件控制寄存器中的标志ISOBlockSize更改ISO块大小选项(请参阅RF430FRL15xH固件用户指南中的第7.54节“固件系统控制寄存器”)。
E1 40 F2 09 03 0B D1 01 07 54 02 65 6E 41 42 43 44 FE 00 00 00 00 00 00
这将导致一个NDEF消息包含一条带有消息“ABCD”的文本记录。
前4个字节( E1 40 F2 09
)是性能容器:
0xE1
是标识能力容器的神奇数字,标签中可以用一个字节块地址对完整的存储区进行寻址。 0x40
为Type 5标记内存映射的版本1.0编码并指示对内存的可用读/写访问。 0xF2
定义了整个NDEF存储器区域(CC字节除外)长度为242( 0xF2
)乘以8个字节(= 1936字节)。 请参阅下面的“理论与实践”部分! 0x09
表示您的标签支持READ_MULTIPLE_BLOCKS命令(位0设置)和LOCK_BLOCK命令(位3设置)。 接下来的2个字节( 03 0B
)是NDEF消息TLV(标签长度 - 值编码数据结构)的头部:
0x03
:表示NDEF消息TLV的标头字节。 0x0B
:NDEF消息TLV的长度= 11个字节。 接下来的11个字节( D1 01 07 54 02 656E 41424344
)是NDEF消息:
0xD1
:记录标题字节: 0x01
:类型名称字段的长度为1个字节。 0x07
:有效载荷字段的长度为7个字节。 0x54
:类型名称(ASCII码:“T”),表示NFC论坛着名的文本记录类型(Text RTD)。 0x02
.. 0x44
:文本记录的有效载荷字段: 0x02
:文本以UTF-8编码,语言字段由2个字节组成。 0x65 0x6E
:表示语言英语的语言字段(ASCII:“en”)。 0x41 0x42 0x43 0x44
:文本有效载荷(UTF-8:“ABCD”)。 下一个字节( FE
)是表示所用数据区域结束的终止器TLV。 该块的其余字节应填充零( 0x00
)以避免某些Android设备出现问题。
块锁定有什么区别?
不,块锁定不会改变您的标签被检测到的方式。 它只会改变读取(Android)设备访问它的方式:读/写访问或只读访问。
这个标签是否可以在所有Android设备上检测到?
很不幸的是,不行。 NFC论坛第5类标签操作规范仅在2015年7月完成。尽管有些Android设备在该日期之前在ISO / IEC 15693(NFC-V)标签上实施了NDEF,但不要期望所有Android设备都适用这种情况。 它应该适用于大多数从Android 5.0开始的设备。 一些Android设备应该能够在某些NFC-V标签上支持NDEF,即使是Android 4.3也是如此。
理论与实践
经过一些进一步的测试后,我发现甚至在类型5(NFC-V)标签上支持NDEF的设备似乎在其NFC栈的实现方面具有明显的限制( 错误??? )。 我使用TI Tag-it HF-I系列中的两种标签类型测试了三星Galaxy S6(Android 5.1.1):
不幸的是,他们都没有使用我上面描述的功能容器与Galaxy S6一起工作。 问题在于NDEF存储区的大小(MLEN,存储在CC的第三个字节中)。 显然,上面使用的尺寸对于这两个标签来说太长了。 因此我将它缩小到与每个标签的标签内存大小相匹配:
E1 40 1F 09
E1 40 03 09
尽管如此,这并没有奏效。 标签未被检测为NDEF标签(仅作为NdefFormatable
)。 最后,我发现如果MLEN字节完全反映整个内存区域的大小(包括CC字节),Galaxy S6 只会检测这些标记。 因此,只有以下值有效:
E1 40 20 09
E1 40 04 09
更糟的是,虽然CC E1 40 04 09
使用Tag-it HF-I标签,但它不适用于Tag-it HF-I Plus标签。 因此,Galaxy S6的NFC堆栈似乎期望CC在不同标签产品上具有非常具体的价值。
基于此,以下CC值应适用于RF430FRL152H:
E1 40 F3 09
E1 40 79 09
“应该”,因为现在还不清楚标签是如何识别并映射到预期的CC值的。 此外,目前还不清楚Galaxy S6是否知道该特定芯片的任何预期CC值。
找到CC字节的“正确”(=预期)值的另一种方法是使用NdefFormatable
技术将NDEF消息写入标签,然后使用NFC TagInfo等标签阅读器应用程序读取CC字节:
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
NdefFormatable ndefFormatable = NdefFormatable.get(tag);
if (ndefFormatable != null) {
try {
ndefFormatable.connect();
ndefFormatable.format(new NdefMessage(NdefRecord.createTextRecord("en", "ABCD")));
} catch (Exception e) {
} finally {
try {
ndefFormatable.close();
} catch (Exception e) {
}
}
}
使用一些通用标签写入器应用程序(除了恩智浦TagWriter似乎无法写入标签)也可以做到这一点。
否则,我们如何在Android中实现简单的块读取,就像NFC TagInfo执行十六进制转储一样?
Android应用程序会检测到RF430FRL152H为NFC-V(NFC术语中的ISO / IEC 15693)标签。 所以一旦你收到NFC意图,你可以获得标签句柄并获得NfcV
类的一个实例:
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
NfcV nfcV = NfcV.get(tag);
您可以连接到标签并使用收发方法交换低级命令(例如READ_SINGLE_BLOCK):
nfcV.connect();
byte[] tagUid = tag.getId(); // store tag UID for use in addressed commands
int blockAddress = 0;
byte[] cmd = new byte[] {
(byte)0x60, // FLAGS
(byte)0x20, // READ_SINGLE_BLOCK
0, 0, 0, 0, 0, 0, 0, 0,
(byte)(blockAddress & 0x0ff)
};
System.arraycopy(tagUid, 0, cmd, 2, 8);
byte[] response = nfcV.transceive(cmd);
nfcV.close();
我可以在哪里获得关于标签格式化,NDEF和低级命令的更多信息?
NFC论坛第5类标签操作规范:来自NFC论坛网站(遗憾的是,NFC论坛规范已不再免费提供)。
重要提示:小心不要将它与open-nfc.org提供的“NFC标签类型5规范”混合使用。 尽管两个规范都谈到了“Type 5”标签,但它们指的是完全不同的标签平台。 open-nfc.org的规范与RF430FRL15xH芯片不兼容。