emFile with NOR Flash Crash

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • emFile with NOR Flash Crash

    I'm using emFILE v3.28 library for evaluating for EA1788 evaluation board with Keil IDE.
    I tried to run the physical layer FS_NOR_PHY_CFI_1x16 and could not.
    The flash is connected as follows:



    So I had to implement my own:

    C Source Code

    1. #include <stdio.h>
    2. #include "norflash_sst39vf3201.h"
    3. #include "FS.h"
    4. #include "RTOS.h"
    5. static int WriteOff(U8 Unit, U32 Off, const void * pSrc, U32 Len);
    6. static int ReadOff(U8 Unit, void * pDest, U32 Off, U32 Len);
    7. static int EraseSector(U8 Unit, unsigned int SectorIndex);
    8. static void GetSectorInfo(U8 Unit, unsigned int SectorIndex, U32 * pOff, U32 * pLen);
    9. static int GetNumSectors(U8 Unit);
    10. static void Configure(U8 Unit, U32 BaseAddr, U32 StartAddr, U32 NumBytes);
    11. static void OnSelectPhy(U8 Unit);
    12. static void DeInit(U8 Unit);
    13. const FS_NOR_PHY_TYPE FS_NOR_PHY_CFI_39FV3201 __attribute__ ((section("EXT_FLASH"))) = {
    14. WriteOff,
    15. ReadOff,
    16. EraseSector,
    17. GetSectorInfo,
    18. GetNumSectors,
    19. Configure,
    20. OnSelectPhy,
    21. DeInit
    22. };
    23. typedef struct
    24. {
    25. U32 BaseAddr;
    26. U32 StartAddr;
    27. U32 NumBytes;
    28. } DRIVER_INSTANCE;
    29. DRIVER_INSTANCE iDriver[10];
    30. static int WriteOff(U8 Unit, U32 Off, const void * pSrc, U32 Len)
    31. {
    32. U32 flash_addr;
    33. U16 *pSource16;
    34. U8 *pSource8;
    35. // printf("WriteOff - Off: %lX, pSrc: %lX, Len: %lu\n", Off, (U32)pSrc, Len);
    36. // fflush(stdout);
    37. pSource16 = (U16 *)pSrc;
    38. flash_addr = iDriver[Unit].StartAddr + ((Off >> 1) << 1);
    39. // Se offset ímpar
    40. if (Off % 2)
    41. {
    42. pSource8 = (U8 *)pSrc;
    43. OS_EnterRegion();
    44. if (NORFLASHWriteWord(flash_addr, ((*pSource8++) << 8) | *((U8 *)flash_addr)) != 0)
    45. {
    46. OS_LeaveRegion();
    47. return 1;
    48. }
    49. OS_LeaveRegion();
    50. pSource16 = (U16 *)pSource8;
    51. Len--;
    52. flash_addr += 2;
    53. }
    54. while (Len >= 2)
    55. {
    56. OS_EnterRegion();
    57. if (NORFLASHWriteWord(flash_addr, *pSource16++) != 0)
    58. {
    59. OS_LeaveRegion();
    60. return 1;
    61. }
    62. OS_LeaveRegion();
    63. Len -= 2;
    64. flash_addr += 2;
    65. }
    66. if (Len == 1)
    67. {
    68. pSource8 = (U8 *)pSource16;
    69. OS_EnterRegion();
    70. if (NORFLASHWriteWord(flash_addr, ((*((U8 *)(flash_addr + 1))) << 8) | *pSource8) != 0)
    71. {
    72. OS_LeaveRegion();
    73. return 1;
    74. }
    75. OS_LeaveRegion();
    76. }
    77. return 0;
    78. }
    79. static int ReadOff(U8 Unit, void * pDest, U32 Off, U32 Len)
    80. {
    81. U32 *pSource32, *pDestin32;
    82. U16 *pSource16, *pDestin16;
    83. U8 *pSource8, *pDestin8;
    84. // printf("ReadOff - pDest: %lX, Off: %lX, Len: %lu\n", (U32)pDest, Off, Len);
    85. // fflush(stdout);
    86. pSource32 = (U32 *) (iDriver[Unit].StartAddr + Off);
    87. pDestin32 = (U32 *) pDest;
    88. if (Len >= 4)
    89. {
    90. while (Len >= 4)
    91. {
    92. *pDestin32++ = *pSource32++;
    93. Len -= 4;
    94. }
    95. if (Len == 0) return 0;
    96. }
    97. if (Len >= 2)
    98. {
    99. pSource16 = (U16 *) pSource32;
    100. pDestin16 = (U16 *) pDestin32;
    101. while (Len >= 2)
    102. {
    103. *pDestin16++ = *pSource16++;
    104. Len -= 2;
    105. }
    106. if (Len == 0) return 0;
    107. pSource32 = (U32 *) pSource16;
    108. pDestin32 = (U32 *) pDestin16;
    109. }
    110. if (Len >= 1)
    111. {
    112. pSource8 = (U8 *) pSource32;
    113. pDestin8 = (U8 *) pDestin32;
    114. while (Len--) *pDestin8++ = *pSource8++;
    115. }
    116. return 0;
    117. }
    118. static int EraseSector(U8 Unit, unsigned int SectorIndex)
    119. {
    120. // printf("EraseSector - SectorIndex: %u\n", SectorIndex);
    121. // fflush(stdout);
    122. OS_EnterRegion();
    123. NORFLASHSectorErase(SectorIndex);
    124. OS_LeaveRegion();
    125. return 0;
    126. }
    127. static void GetSectorInfo(U8 Unit, unsigned int SectorIndex, U32 * pOff, U32 * pLen)
    128. {
    129. // volatile int x, y, z ,w;
    130. //
    131. // if ((SectorIndex >= 512) || (pOff == NULL) || (pLen == NULL))
    132. // {
    133. // x = SectorIndex;
    134. // y = (int)pOff;
    135. // z = (int)pLen;
    136. // w = SectorIndex;
    137. // return;
    138. // }
    139. // printf("GetSectorInfo - SectorIndex: %u, pOff: %lX, pLen: %lX\n", SectorIndex, (U32)pOff, (U32)pLen);
    140. // fflush(stdout);
    141. *pOff = SectorIndex * 4096;
    142. *pLen = 4096;
    143. }
    144. static int GetNumSectors(U8 Unit)
    145. {
    146. // printf("GetNumSectors\n");
    147. // fflush(stdout);
    148. return (iDriver[Unit].NumBytes / 4096);
    149. }
    150. static void Configure(U8 Unit, U32 BaseAddr, U32 StartAddr, U32 NumBytes)
    151. {
    152. // printf("Configure\n");
    153. // fflush(stdout);
    154. iDriver[Unit].BaseAddr = BaseAddr;
    155. iDriver[Unit].StartAddr = StartAddr;
    156. iDriver[Unit].NumBytes = NumBytes;
    157. }
    158. static void OnSelectPhy(U8 Unit)
    159. {
    160. // printf("OnSelectPhy\n");
    161. // fflush(stdout);
    162. }
    163. static void DeInit(U8 Unit)
    164. {
    165. // printf("DeInit\n");
    166. // fflush(stdout);
    167. }
    Display All


    When I write a file with the size of the drive it is saved normally.
    But if I delete the file and write again, there is a Hardware Fault.
    This hardware fault is caused by pLen parameter of GetSectorInfo routine that is 0.



    Could anyone help me?

    The post was edited 2 times, last by leonarff ().

  • Hello leonarff,

    In some cases, the NOR driver needs to know only the address of a physical sector
    and it calls GetSectorInfo() with the pLen parameter set to NULL.
    You can avoid the Hardware Fault error by validating the pLen parameter before dereferencing it.

    C Source Code

    1. if (pLen) {
    2. *pLen = 4096;
    3. }


    Best regards,
    Marius