zmain_ext_addr()函数研究(转).doc_第1页
zmain_ext_addr()函数研究(转).doc_第2页
zmain_ext_addr()函数研究(转).doc_第3页
zmain_ext_addr()函数研究(转).doc_第4页
zmain_ext_addr()函数研究(转).doc_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

4.4大致说了:CC2530芯片在TI出厂时已经预先烧写了 Primary IEEE address,这个64位地址是全球唯一的。这个地址在CC2530的FLASH信息页中,是只读的。但是用户貌似可以重新写这个预先烧写的Primary IEEE address。具体再来看看 Section 7.2 7.2中说Z-STACK通过4个步骤来确定设备的IEEE地址: 1.从Z-stack的NV中读取 2.从Second IEEE 的位置中寻找 3.在Primary IEEE 的位置寻找 4.由随机数产生器产生一个临时IEEE地址。 也就是说,ZigBee设备在上电后,首先会从NV中读取IEEE地址,如果读取失败,则从FLASH的Second IEEE 的存放位置读取IEEE地址,如果读取失败,则再从Primary IEEE 的存放位置读取IEEE,如果还是失败,则由随机数发生器产生一个临时IEEE地址。步骤2或者步骤3一旦有效并且使能了“NV_RESTORE”,就会把这个IEEE地址写入到NV中去。这样下次上电的时候,就可以通过步骤1从NV中直接读取 IEEE地址。 接下来我们再来看看每一个步骤具体是怎么实现的:Step1 从Z-stack的NV中读取 IEEE地址: 源代码见 Z-stack 2.5.1.a - ZMain.c - main( ) -zmain_ext_addr()我将源代码拿上来,自己添加了注释。1. static void zmain_ext_addr(void)2. 3. uint8 nullAddrZ_EXTADDR_LEN = 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF;4. uint8 writeNV = TRUE;5.6. / First check whether a non-erased extended address exists in the OSAL NV.7. if (SUCCESS != osal_nv_item_init(ZCD_NV_EXTADDR, Z_EXTADDR_LEN, NULL)| /如果NV初始化失败8. (SUCCESS != osal_nv_read(ZCD_NV_EXTADDR, 0, Z_EXTADDR_LEN, aExtendedAddress) |/或者NV读取失败9. (osal_memcmp(aExtendedAddress, nullAddr, Z_EXTADDR_LEN) /或者NV没有被写过10. 11. / Attempt to read the extended address from the location on the lock bits page12. / where the programming tools know to reserve it.13. / 若NV读取IEEE地址失败,则从Secondary IEEE中读取,在FLASH最后的偏移24个地址的地方,即0x3FFE80x3FFEF14. HalFlashRead(HAL_FLASH_IEEE_PAGE, HAL_FLASH_IEEE_OSET, aExtendedAddress, Z_EXTADDR_LEN);15.16. if (osal_memcmp(aExtendedAddress, nullAddr, Z_EXTADDR_LEN) /如果Secondary IEEE 也是无效的则读取Primary IEEE17. 18. / Attempt to read the extended address from the designated location in the Info Page.19. / Primary IEEE 在信息页偏移0x0c-0x13的地方,即(0x7800+0x0c)=0x780c,这个地址是映射到Xdata上的,不是CODE地址20. if (!osal_memcmp(uint8 *)(P_INFOPAGE+HAL_INFOP_IEEE_OSET), nullAddr, Z_EXTADDR_LEN)21. 22. osal_memcpy(aExtendedAddress, (uint8 *)(P_INFOPAGE+HAL_INFOP_IEEE_OSET), Z_EXTADDR_LEN);23. 24. else/ No valid extended address was found.如果Primary IEEE 还是无效,则产生随机地址,随机地址以0xF8开头25. 26. uint8 idx;27.28. #if !defined ( NV_RESTORE )29. writeNV = FALSE;/ Make this a temporary IEEE address30. #endif31.32. /* Attempt to create a sufficiently random extended address for expediency.33. * Note: this is only valid/legal in a test environment and34. * must never be used for a commercial product.35. */36. for (idx = 0; idx (Z_EXTADDR_LEN - 2);)37. 38. uint16 randy = osal_rand();39. aExtendedAddressidx+ = LO_UINT16(randy);40. aExtendedAddressidx+ = HI_UINT16(randy);41. 42. / Next-to-MSB identifies ZigBee devicetype.43. #if ZG_BUILD_COORDINATOR_TYPE & !ZG_BUILD_JOINING_TYPE44. aExtendedAddressidx+ = 0x10;45. #elif ZG_BUILD_RTRONLY_TYPE46. aExtendedAddressidx+ = 0x20;47. #else48. aExtendedAddressidx+ = 0x30;49. #endif50. / MSB has historical signficance.51. aExtendedAddressidx = 0xF8;52. 53. 54.55. if (writeNV)56. 57. (void)osal_nv_write(ZCD_NV_EXTADDR, 0, Z_EXTADDR_LEN, aExtendedAddress);58. 59. 60.61. / Set the MAC PIB extended address according to results from above.62. (void)ZMacSetReq(MAC_EXTENDED_ADDRESS, aExtendedAddress);63. 复制代码从代码中可以看到,第一个 if 从NV的 ZCD_NV_EXTADDR 中读取了 IEEE地址。 如果 NV 读取IEEE成功,则直接跳到最后,执行(void)ZMacSetReq(MAC_EXTENDED_ADDRESS, aExtendedAddress); /将读取成功的 IEEE地址 写到MAC层的PIB属性中 如果 NV 读取失败,或者读取出来的值全为0xFF,则说明 NV中 ZCD_NV_EXTADDR 这个元素并没有被配置过,视为无效,那就从Step2 中读取 IEEE 地址Step2 从Second IEEE 的位置中找到 IEEE 地址 这个Second IEEE到底在哪里呢,Z-Stack Users Guide - CC2530DB.pdf 的 7.2 中已经提到,这个位置是在 FLASH 地址最后置偏移 0x0018个地址的地方。拿CC2530F256来说,256K的FLASH,那偏移0x18地址的位置应该是:0x3FFE8,IEEE 地址长度是8个字节,所以 Second IEEE 地址的存放地址应该是 0x3FFE8 3FFEF。 有人可能会疑惑,为什么是偏移0x18个地址呢,这里我个人的理解是:0x18=24=16+8. 这里的8就是IEEE地址的长度,这个16应该是FLASH最后的加密位。 再从代码来看,第一个 if 满足之后便是下面这句:HalFlashRead(HAL_FLASH_IEEE_PAGE, HAL_FLASH_IEEE_OSET, aExtendedAddress, Z_EXTADDR_LEN); 这是直接读FLASH 的函数,从 HAL_FLASH_IEEE_PAGE 这一页的 HAL_FLASH_IEEE_OSET 位置来读取 Second IEEE 在来看看 HAL_FLASH_IEEE_PAGE 和 HAL_FLASH_IEEE_OSET 分别是什么1. / Re-defining Z_EXTADDR_LEN here so as not to include a Z-Stack .h file.2. #define HAL_FLASH_IEEE_SIZE 83. #define HAL_FLASH_IEEE_PAGE (HAL_NV_PAGE_END+1)/1274. #define HAL_FLASH_IEEE_OSET (HAL_FLASH_PAGE_SIZE - HAL_FLASH_LOCK_BITS - HAL_FLASH_IEEE_SIZE)/(2048-16-8)=2024复制代码从宏定义来看,HAL_FLASH_IEEE_PAGE 是NV最后一页再加1,也就是127页,是FLASH的最后一页(1也是2048 byte),地址是 HAL_FLASH_PAGE_SIZE - HAL_FLASH_LOCK_BITS - HAL_FLASH_IEEE_SIZE,也就是地址最后减去16 字节的加密位和8字节的IEEE地址,即2048-24 = 2024, 这也验证了我之前step1 中的猜想。 第二个 if 是判断这个 Second IEEE 地址是否有效,如果有效,则到代码的最后将有效的 IEEE 地址写入 PIB 中,若无效则进入Step3Step3 从Primary IEEE 的位置中找到 IEEE 地址 这个 Primary IEEE 地址到底又在什么地方呢,Z-Stack Users Guide - CC2530DB.pdf 的 7.2 中已经提到,Primary IEEE 位于 FLASH 信息页偏移 0x0c 0x13 个地址的地方。那么这个 FLASH 信息页到底又在哪里呢,参照 CC2530 users guide 的 2.2.2 CPU memery space ,可以知道, 这个 FLASH information page 是映射到 XDADA的 0x7800 0x7FFF 上的,那么偏移0x0c个地址,应该就是XData 的 0x780c 0x7813 地址上。 再来看看源代码1. if(!osal_memcmp(uint8 *)(P_INFOPAGE+HAL_INFOP_IEEE_OSET), nullAddr, Z_EXTADDR_LEN)2. 3. osal_memcpy(aExtendedAddress, (uint8 *)(P_INFOPAGE+HAL_INFOP_IEEE_OSET), Z_EXTADDR_LEN);4. 复制代码/code源代码中第三个if直接用osal_memcmp 将 Xdata 中 (P_INFORFAGE + HAL_INFOP_IEEE_OSET) 与 8个 0xFF作比较。这个(P_INFORFAGE + HAL_INFOP_IEEE_OSET) 到底又是什么呢,请看它的宏定义:1. #define P_INFOPAGEPXREG( 0x7800 )/* Pointer to Start of Flash Information Page */2.3. #define HAL_INFOP_IEEE_OSET 0xC复制代码很明显,这个地址便是 0x7800 + 0xc = 0x780c,正确。如果这个地址有效,就作为 IEEE地址 使用,若无效则需要进入Step4Step4 随机得到这个 IEEE 地址文档中说到,如果前面的step1 step3 都失效,则只能随机产生这个 IEEE地址,随机产生的这个 IEEE 地址 是以 0XF8 开头的。并且这个 IEEE地址不会被保存到 NV 中,因此如果说这个 IEEE 地址时随机产生的,那么这个值 每次上电后都是随机产生的,即使你使能了“NV_RESTORN”也不会存到 NV 中。这样的话如果用于实际应用其实是很危险的,所以尽量不要这种情况发生。 接下来看看是怎么产生这个随机 IEEE 地址的:1. else/ No valid extended address was found.如果Primary IEEE 还是无效,则产生随机地址,随机地址以0xF8开头2. 3. uint8 idx;4.5. #if !defined ( NV_RESTORE )6. writeNV = FALSE;/ Make this a temporary IEEE address7. #endif8.9. /* Attempt to create a sufficiently random extended address for expediency.10. * Note: this is only valid/legal in a test environment and11. * must never be used for a commercial product.12. */13. for (idx = 0; idx (Z_EXTADDR_LEN - 2);)14. 15. uint16 randy = osal_rand();16. aExtendedAddres

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论