TI RF430FRL152HEVM NFC NDEF formatting



我们设计了一个基于TI RF430FRL152HEVM评估模块的具有NFC功能的板。当安卓手机靠近主板天线时,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 8096 48 00 00 e1 10 12 0001 03 a0 0c 34 03 21 d101 1d 54 02 65 6e 41 4243 44 20 20

其中41 42 43 44在UTF-8中是"ABCD"。

我们从另一个标签(使用NFC TagInfo读取)中获取这些数据(NDEF格式+标头),并将这些数据复制到我们的标签芯片的FRAM块中。我们在NDEF消息的末尾停止,FRAM的其余部分是0x000xff

显然,我们从(恩智浦)复制数据的标签和我们的标签芯片(TI)来自不同的制造商,因此前几个块中的一些数据对我们的TI芯片无效,但我们认为安卓不应该在意。

然而,当我们用NFC TagInfo读取TI标签时,它可以读取原始数据块,但它无法将该标签识别为NDEF格式的标签。

  • 是不是我们从另一个标签复制的NDEF格式对我们的标签无效,因为我们没有使用相同的标签内存大小等?

  • 如果一个人只是在正确的块中写入正确的字节,那么任何东西都可以被提取为NDEF吗?毕竟,在低级别,有什么区别?

  • 如果是这种情况,那么在哪些块中使用字节的最明智的测试用例是什么,有更好的方法来测试这个概念吗?

  • 块锁定有什么区别吗?正如我们所看到的,一些区块被锁定在一个真正的标签中。

  • 为什么当检测到NDEF时,NFC TagInfo有时会看到块,然后会看到页面?块和页是一样的吗?

  • 如果失败了,我们如何在Android中编码简单的块读取,就像NFC TagInfo执行十六进制转储一样?如果我们能做到这一点,那么NDEF就没有必要了。

附加信息2

我修改了固件,使FRAM从块0开始包含您提到的数据:

E1 40 F2 09 03 0B D1 0107 54 02 65 6E 41 42 4344 FE 00 00 00 00 00

然而,我似乎无法将TI芯片置于8字节块模式。似乎没有与此相关的控制寄存器。

从我的低级观点来看,以4或8字节写入块不是问题,也就是说,我按字节顺序将上述数据写入FRAM内存。

当我运行NFC TagInfo时,它会做两件事,但不会检测到NDEF消息:

  • 它确实正确地检测到UID,并且RF技术是类型5(ISO 15693/邻近)
  • 它也正确读取了块,在选择数据HEX显示时,我在从块0开始的块中准确地看到了上述数据

我查阅了我从中获得的NFC标签类型5规范http://open-nfc.org/documents/STS_NFC_0707-001%20NFC%20Tag%20Type%205%20Specification.pdf

因此,我尝试将更多数据从块0写入TAG,以尝试模拟SERIAL NUMBER、CONFIGURATION、Application area issuer块。然后我将NDEF消息ABCD放在以下部分之后:

01 02 03 04 05 06 07 08//序列号00 00 00 80 00 10 00//配置…

我使用了NFC TagInfo,但也无法检测到NDEF消息。然而,使用Data Hex显示器,我可以验证数据是否如上所述正确读取。

所以我的问题是:

  • 是否配置了4字节或8字节块模式,以及该模式最有可能定义在哪里?我可以在4字节块模式下工作吗
  • TAG 5序列号是否相关?根据规范,似乎不会影响NDEF检查
  • TAG 5应用领域发布者是否相关?似乎与NDEF验证无关
  • 我放置的NDEF消息是否正确
  • 对于16位值,它是高字节-低字节还是低字节-高字节排序
  • 你知道怎么了吗

附加信息3

事实证明,TI需要提供一个补丁,才能让NDEF与该芯片(FRL152H)一起工作。基本上,该芯片设计用于支持通过NFC使用内部固件应用程序对传感器功能进行高级控制。需要禁用此应用程序并更改某些设置。

以下内存配置被证明是有效的:

区块0:E1 40 79 00区块1:03 0B D1 01区块2:07 54 02 65区块3:6e 41 42 43区块4:44 FE 00 00

是不是我们从另一个标签复制的NDEF格式对我们的标签无效

这正是问题所在。查看内存转储的前12个字节,您显然从NXP NTAG203(或类似的)复制了数据块,如制造商代码(字节0:0x04)和功能容器中的内存大小(字节13:0x12)所示。恩智浦的NTAG和MIFARE超轻系列遵循NFC Forum Type 2标签操作规范。然而,您的TI芯片(RF430FRL152H)基于ISO/IEC 15693,因此遵循NFC论坛5型标签操作规范。标签操作规范定义了将NFC标签转换为NDEF标签的数据格式和命令集。由于NFC技术结合了几种不同的RF标准(ISO/IEC 14443、FeliCa、ISO/IEC 15693)并使用在NFC之前已经存在的用于这些标准的标签硬件,因此存在几种(目前为5种)不同的此类规范。

为什么当检测到NDEF时,NFC TagInfo有时会看到块,然后会看到页面?块和页是一样的吗

在这种情况下,块和页是等效的。不同的措辞只是来自芯片制造商使用的术语。请注意,RF430FRL152H芯片使用术语"页面"对几个块进行分组,因此具有不同的含义。

如果一个人只是在正确的块中写入正确的字节,那么任何东西都可以被提取为NDEF吗?毕竟,在低级别,有什么区别

不同之处在于,您的TI RF430FRL152H标签芯片需要对NDEF存储区域使用与NXP标签不同的编码。这仅仅是因为它使用了不同的底层通信技术(调制、编码、成帧、命令集),因此遵循了不同的NFC论坛标签操作规范。

为了使您的标签芯片成为NDEF标签,您需要对从块0开始的NDEF内存区域使用以下编码:请注意,功能容器中填充了假定块大小为8字节的值。您可以使用固件控制寄存器中的标志ISOBlockSize更改ISO块大小选项(请参阅RF430FRL15xH固件用户指南中的第7.54节"固件系统控制寄存器")。

E1 40 F2 09 03 0B D1 0107 54 02 65 6E 41 42 4344 FE 00 00 00 00 00

这将导致NDEF消息包含一条带有消息"ABCD"的文本记录。

前4个字节(E1 40 F2 09)是能力容器:

  • 0xE1是标识标签的能力容器的幻数,其中完整的内存区域可以用一字节块地址寻址
  • 0x40对类型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:记录头字节:
    • 位7和6:这是NDEF消息的唯一记录
    • 比特4:这是一个短记录(即有效载荷长度用单个字节编码)
    • 位2..0:记录类型编码NFC论坛的知名类型
  • 0x01:类型名称字段的长度为1字节
  • 0x07:有效载荷字段的长度为7个字节
  • 0x54:表示NFC论坛众所周知的文本记录类型(文本RTD)的类型名称(ASCII:"T")
  • 0x02。。0x44:Text记录的有效载荷字段:
    • 0x02:文本以UTF-8编码,语言字段由2个字节组成
    • 0x65 0x6E:语言字段(ASCII:"en"),表示语言为英语
    • 0x41 0x42 0x43 0x44:文本负载(UTF-8格式:"ABCD")

下一个字节(FE)是终止器TLV,指示所用数据区域的结束。该块的剩余字节应填充零(0x00),以避免某些Android设备出现问题。

块锁定有什么区别吗

不,阻止锁定不会改变检测标签的方式。它只更改读取(Android)设备访问它的方式:读/写访问或只读访问。

这个标签在所有安卓设备上都能检测到吗

不幸的是,没有。NFC论坛5型标签操作规范在2015年7月才最终确定。虽然一些安卓设备在该日期之前在ISO/IEC 15693(NFC-V)标签上实现了NDEF,但不要指望所有安卓设备都会出现这种情况。不过,它应该适用于从安卓5.0开始的大多数设备。一些安卓设备应该能够在某些NFC-V标签上支持NDEF,甚至从安卓4.3开始。

理论与实践

经过进一步的测试,我发现即使是在类型5(NFC-V)标签上支持NDEF的设备,在其NFC堆栈的实现中似乎也有显著的局限性(错误??)。我测试了一台三星Galaxy S6(Android 5.1.1),它有两种来自TI tag it HF-I系列的标签类型:

  1. 标记为HF-I Plus(2048位用户内存,64 x 4字节块)
  2. 标记为HF-I标准(256位用户内存,8 x 4字节块)

不幸的是,他们都没有使用我上面描述的功能容器与Galaxy S6合作。问题是NDEF存储区域(MLEN,存储在CC的第三个字节中)的大小。显然,上面使用的大小对于这两个标签来说太长了。因此,我减少了它,以匹配每个标签的标签内存大小:

  1. 标记为HF-I Plus:
    • 64 x 4字节=256字节
    • 256字节/8=32(MLEN始终计算为8字节的倍数)
    • 减去1块,因为CC不算作数据区的一部分(根据类型5标记操作规范)
    • MLEN=31=0x1F
    • 抄送:E1 40 1F 09
  2. 标记为HF-I标准:
    • 8 x 4字节=32字节
    • 32字节/8=4(MLEN始终计算为8字节的倍数)
    • 减去1块,因为CC不算作数据区的一部分(根据类型5标记操作规范)
    • MLEN=3=0x03
    • 抄送:E1 40 03 09

尽管如此,这还是不起作用。未将标签检测为NDEF标签(仅检测为NdefFormatable)。最后,我发现Galaxy S6只有在MLEN字节准确地反映整个内存区域的大小(包括CC字节)的情况下才检测到这些标签。因此,只有以下值有效:

  1. 标记为HF-I Plus:
    • 抄送:E1 40 20 09
  2. 标记为HF-I标准:
    • 抄送:E1 40 04 09

更糟糕的是,虽然CCE1 40 04 09在Tag-it HF-I Standard标签上工作,但它在Tag-it-HF-I Plus标签上没有工作。因此,Galaxy S6的NFC堆栈似乎期望不同标签产品上的CC具有非常特定的值。

基于此,以下CC值应适用于RF430FRL152H:

  1. 当块大小设置为8字节时:E1 40 F3 09
  2. 当块大小设置为4字节时: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) {
}
}
}

使用一些通用的标记编写器应用程序也可以完成同样的操作(除了NXP标记编写器,它似乎无法写入标记)。

如果失败了,我们如何在Android中实现简单的块读取,就像NFC TagInfo执行十六进制转储一样

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规范"混淆。尽管两个规范都谈到了标签">类型5",但它们指的是一个完全不同的标签平台。open-nfc.org的规格与RF430FRL15xH芯片不兼容。

  • 与最终NFC论坛5型标签操作规范非常接近的公开文件是恩智浦应用说明AN11032恩智浦ICODE型标签操作。然而,NFC论坛类型5标签操作规范和该应用说明之间存在一些显著差异(特别是在能力容器的格式方面)
  • NFC数据交换格式(NDEF)规范:也可从NFC论坛网站或此处获取
  • NFC记录类型定义(RTD)规范:也可从NFC论坛网站或此处获取
  • 文本记录类型定义规范:也可从NFC论坛网站或此处获取
  • 数字协议规范中的NFC-V:也来自NFC论坛网站
  • ISO/IEC 15693:本标准定义了标准的低级命令
  • RF430FRL15xH用户指南:您可以在第4.2ff节中找到访问RAM内存区域的自定义命令

最新更新