選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 

512 行
17 KiB

  1. /**
  2. *
  3. * \file
  4. *
  5. * \brief WINC3400 Flash Interface.
  6. *
  7. * Copyright (c) 2017-2018 Microchip Technology Inc. and its subsidiaries.
  8. *
  9. * \asf_license_start
  10. *
  11. * \page License
  12. *
  13. * Subject to your compliance with these terms, you may use Microchip
  14. * software and any derivatives exclusively with Microchip products.
  15. * It is your responsibility to comply with third party license terms applicable
  16. * to your use of third party software (including open source software) that
  17. * may accompany Microchip software.
  18. *
  19. * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
  20. * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
  21. * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
  22. * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
  23. * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
  24. * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
  25. * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
  26. * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
  27. * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
  28. * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
  29. * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
  30. *
  31. * \asf_license_stop
  32. *
  33. */
  34. /**@defgroup FLASHAPI FLASH
  35. */
  36. #ifndef __M2M_FLASH_H__
  37. #define __M2M_FLASH_H__
  38. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  39. INCLUDES
  40. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  41. #include "common/include/nm_common.h"
  42. #include "driver/include/m2m_types.h"
  43. /**@defgroup FlashDefs Defines
  44. * @ingroup FLASHAPI
  45. * @{*/
  46. /*! Bit 0 of u8Options parameter of @ref m2m_flash_updateimage.\n
  47. * Request to write new firmware image to WINC inactive partition. */
  48. #define FLASH_UPDATEIMAGE_OPTION_UPDATE NBIT0
  49. /*! Bit 1 of u8Options parameter of @ref m2m_flash_updateimage.\n
  50. * Request to mark image in WINC inactive partition as valid. If set along with
  51. * @ref FLASH_UPDATEIMAGE_OPTION_UPDATE, the image is not marked valid if the writing fails. */
  52. #define FLASH_UPDATEIMAGE_OPTION_VALIDATE NBIT1
  53. /*! Bit 2 of u8Options parameter of @ref m2m_flash_updateimage.\n
  54. * Request to switch the WINC active/inactive partitions. Use this to switch to a new image or to
  55. * revert to an old one. The switch only succeeds if the image has been marked valid. */
  56. #define FLASH_UPDATEIMAGE_OPTION_SWITCH NBIT2
  57. /*! Return success, transfer succeeded. */
  58. #define FLASH_SUCCESS 0
  59. /*! Return error. The parameters provided by the MCU application failed sanity checks. */
  60. #define FLASH_ERR_PARAM (-1)
  61. /*! Return error. An MCU application function of type @ref tpfDataAccessFn returned failure. */
  62. #define FLASH_ERR_LOCAL_ACCESS (-2)
  63. /*! Return error. There was an error while accessing WINC flash, or contents of WINC flash were not as expected. */
  64. #define FLASH_ERR_WINC_ACCESS (-3)
  65. /*! Return error. The transfer destination location was too small for the size of data to be transferred. */
  66. #define FLASH_ERR_SIZE (-4)
  67. /*! Return error. The data provided by the MCU application caused a failure. For example:\n
  68. * - An item could not be added to a WINC flash store because the identifier matched an existing item.
  69. * - An item could not be read or removed from a WINC flash store because the identifier did not match an existing item.
  70. * - A firmware image could not be written to WINC flash because it did not match the format of WINC firmware images. */
  71. #define FLASH_ERR_WINC_CONFLICT (-5)
  72. /*! Return error. The MCU application did not call @ref m2m_flash_init during Wi-Fi initialization. */
  73. #define FLASH_ERR_UNINIT (-6)
  74. /*! Return error. The module hit an internal error, such as insufficient heap memory. */
  75. #define FLASH_ERR_INTERNAL (-7)
  76. /**@}
  77. */
  78. /**@defgroup FlashEnums Enumeration/Typedefs
  79. * @ingroup FLASHAPI
  80. * @{*/
  81. /*!
  82. @enum tenuFlashDataFnCtl
  83. @brief Control parameter for @ref tpfDataAccessFn.
  84. */
  85. typedef enum {
  86. /*! Data access about to start. Check and save parameters as required, ready for subsequent
  87. * data accesses. */
  88. FLASH_DATA_FN_INITIALIZE,
  89. /*! Sequential data access, using parameters previously provided by FLASH_DATA_FN_INITIALIZE. */
  90. FLASH_DATA_FN_DATA,
  91. /*! Data access aborted. Did not complete and will not be continued. */
  92. FLASH_DATA_FN_TERMINATE,
  93. /*! Data access complete. */
  94. FLASH_DATA_FN_COMPLETE
  95. }tenuFlashDataFnCtl;
  96. /*!
  97. @enum tenuDataFnRW
  98. @brief Indicates whether data is to be read or written
  99. */
  100. typedef enum {
  101. /*! Read data from application memory. */
  102. FLASH_DATA_FN_READ,
  103. /*! Write data to application memory. */
  104. FLASH_DATA_FN_WRITE
  105. }tenuDataFnRW;
  106. /*!
  107. @enum tenuImageId
  108. @brief Indicates which image to access in WINC flash
  109. */
  110. typedef enum {
  111. /*! Access the image in the inactive partition. */
  112. FLASH_IMAGE_INACTIVE,
  113. /*! Access the image in the active partition. */
  114. FLASH_IMAGE_ACTIVE
  115. }tenuImageId;
  116. /*!
  117. @typedef \
  118. tpfDataAccessFn
  119. @brief
  120. A function of this type is used for local data access. It can be implemented to handle simple
  121. RAM access with pointer/length, or it can be implemented to handle access to external memory.
  122. Functions of this type are provided to the module via various function APIs.
  123. @see m2m_flash_rootcert_add
  124. @see m2m_flash_rootcert_read
  125. @see m2m_flash_rootcert_readidx
  126. @see m2m_flash_updateimage
  127. @see m2m_flash_readimage
  128. @param [in] enuCtl
  129. Control parameter.
  130. @param [in] pvStr
  131. Generic pointer to structure. The structure type depends on enuCtl:
  132. - @ref tstrDataAccessInitParamsApp if enuCtl is @ref FLASH_DATA_FN_INITIALIZE.
  133. - @ref tstrDataAccessParamsApp if enuCtl is @ref FLASH_DATA_FN_DATA.
  134. - @ref NULL if enuCtl is @ref FLASH_DATA_FN_TERMINATE or @ref FLASH_DATA_FN_COMPLETE.
  135. @note The function is typically called by the module multiple times during a data transfer:
  136. Once with @ref FLASH_DATA_FN_INITIALIZE, then multiple times with @ref FLASH_DATA_FN_DATA, then
  137. once with @ref FLASH_DATA_FN_COMPLETE.
  138. @return Zero for success. Non-zero otherwise.
  139. \section FlashExample1 Example
  140. This example illustrates an implementation of a function of type @ref tpfDataAccessFn. \n
  141. This example assumes the application's data buffer is in RAM, so we can use memcpy. Alternatively
  142. memcpy can be replaced by dedicated functions which read/write the application buffer.
  143. gpu8DataLocation is a pointer to the data buffer in RAM, set by the application. \n
  144. gu32DataSize is the size of the data buffer, set by the application.
  145. @code{.c}
  146. sint8 data_access_ptr(tenuFlashDataFnCtl enuCtl, void *pvStr)
  147. {
  148. // Return value.
  149. sint8 s8Ret = -1;
  150. // Fixed variables, set in case FLASH_DATA_FN_INITIALIZE, reset in case FLASH_DATA_FN_COMPLETE.
  151. static tenuDataFnRW enuRW;
  152. static uint8 *pu8Location = NULL;
  153. static uint32 u32BytesRemaining = 0;
  154. switch (enuCtl)
  155. {
  156. case FLASH_DATA_FN_INITIALIZE:
  157. if (pvStr != NULL)
  158. {
  159. tstrDataAccessInitParamsApp *init_params = (tstrDataAccessInitParamsApp*)pvStr;
  160. if (init_params->u32TotalSize > gu32DataSize)
  161. break;
  162. // Set fixed variables.
  163. enuRW = init_params->enuRW;
  164. pu8Location = gpu8DataLocation;
  165. u32BytesRemaining = init_params->u32TotalSize;
  166. s8Ret = 0;
  167. }
  168. break;
  169. case FLASH_DATA_FN_DATA:
  170. if ((pvStr != NULL) && (pu8Location != NULL))
  171. {
  172. tstrDataAccessParamsApp *params = (tstrDataAccessParamsApp*)pvStr;
  173. // Some sanity checks which should never fail.
  174. if (u32BytesRemaining < params->u32DataSize)
  175. break;
  176. if (params->pu8Data == NULL)
  177. break;
  178. switch (enuRW)
  179. {
  180. case FLASH_DATA_FN_WRITE:
  181. memcpy(pu8Location, params->pu8Data, params->u32DataSize);
  182. s8Ret = 0;
  183. break;
  184. case FLASH_DATA_FN_READ:
  185. memcpy(params->pu8Data, pu8Location, params->u32DataSize);
  186. s8Ret = 0;
  187. break;
  188. }
  189. // Update fixed variables for sequential access.
  190. pu8Location += params->u32DataSize;
  191. u32BytesRemaining -= params->u32DataSize;
  192. }
  193. break;
  194. case FLASH_DATA_FN_TERMINATE:
  195. case FLASH_DATA_FN_COMPLETE:
  196. // Reset fixed variables.
  197. pu8Location = NULL;
  198. u32BytesRemaining = 0;
  199. s8Ret = 0;
  200. break;
  201. }
  202. return s8Ret;
  203. }
  204. @endcode
  205. */
  206. typedef sint8 (*tpfDataAccessFn) (tenuFlashDataFnCtl enuCtl, void *pvStr);
  207. /*!
  208. @struct \
  209. tstrDataAccessInitParamsApp
  210. @brief
  211. This structure contains parameters for initializing a local data access (read or write).
  212. @see tpfDataAccessFn.
  213. */
  214. typedef struct {
  215. /*! Total size of data to be accessed in data location. */
  216. uint32 u32TotalSize;
  217. /*! Flags indicating type of data access (read or write). */
  218. tenuDataFnRW enuRW;
  219. }tstrDataAccessInitParamsApp;
  220. /*!
  221. @struct \
  222. tstrDataAccessParamsApp
  223. @brief
  224. This structure contains data for local data access (read or write).
  225. @see tpfDataAccessFn.
  226. */
  227. typedef struct {
  228. /*! Buffer to be written from or read to. */
  229. uint8 *pu8Data;
  230. /*! Size of data to be written or read. */
  231. uint32 u32DataSize;
  232. }tstrDataAccessParamsApp;
  233. /*!
  234. @struct \
  235. tstrFlashState
  236. @brief
  237. This structure contains information about an attempted transfer.
  238. @see m2m_flash_init
  239. */
  240. typedef struct {
  241. /*! Last access attempt. Identifier provided by MCU application. 0 if info not available. */
  242. uint16 u16LastAccessId;
  243. /*! Was the last access attempt successful? */
  244. uint8 u8Success;
  245. /*! Did the last access attempt result in modified WINC flash? */
  246. uint8 u8Changed;
  247. /*! Has the module been initialized? */
  248. uint8 u8Init;
  249. /*! Has the module been initialized more recently than the module last reset the WINC? */
  250. uint8 u8Reset;
  251. }tstrFlashState;
  252. /**@}
  253. */
  254. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  255. FUNCTION PROTOTYPES
  256. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  257. /** \defgroup FLASHFUNCTIONS Functions
  258. * @ingroup FLASHAPI
  259. */
  260. /**@{*/
  261. /*!
  262. @fn \
  263. sint8 m2m_flash_updateimage(uint8 u8Options, uint16 u16Id, tpfDataAccessFn pfSourceFn, uint32 u32SourceSize);
  264. @brief Write/validate/switch a WINC firmware image.
  265. @param [in] u8Options
  266. Flags indicating the required combination of write / validate / switch.
  267. @param [in] u16Id
  268. Transfer identifier, not interpreted by this module.
  269. @param [in] pfSourceFn
  270. Function for the module to call to obtain the image from the MCU application.
  271. @param [in] u32SourceSize
  272. Size of the image being provided by the MCU application.
  273. @see FLASH_UPDATEIMAGE_OPTION_UPDATE
  274. @see FLASH_UPDATEIMAGE_OPTION_VALIDATE
  275. @see FLASH_UPDATEIMAGE_OPTION_SWITCH
  276. @return Zero indicates success.
  277. Negative values indicate failure.
  278. */
  279. sint8 m2m_flash_updateimage(uint8 u8Options, uint16 u16Id, tpfDataAccessFn pfSourceFn, uint32 u32SourceSize);
  280. /*!
  281. @fn \
  282. sint8 m2m_flash_readimage(tenuImageId enuImageId, uint16 u16Id, tpfDataAccessFn pfDestFn, uint32 u32DestSize);
  283. @brief Read a WINC firmware image.
  284. @param [in] enuImageId
  285. Which partition to read image from.
  286. @param [in] u16Id
  287. Transfer identifier, not interpreted by this module.
  288. @param [in] pfDestFn
  289. Function for the module to call to send the image to the MCU application.
  290. @param [in] u32DestSize
  291. Size of the memory available to the MCU application for storing the image.
  292. @return Zero indicates success.
  293. Negative values indicate failure.
  294. */
  295. sint8 m2m_flash_readimage(tenuImageId enuImageId, uint16 u16Id, tpfDataAccessFn pfDestFn, uint32 u32DestSize);
  296. /*!
  297. @fn \
  298. sint8 m2m_flash_rootcert_add(uint16 u16Id, tpfDataAccessFn pfSourceFn, uint32 u32SourceSize);
  299. @brief Add an entry to the WINC TLS root certificate store.
  300. @param [in] u16Id
  301. Transfer identifier, not interpreted by this module.
  302. @param [in] pfSourceFn
  303. Function for the module to call to obtain the certificate entry from the MCU application.
  304. @param [in] u32SourceSize
  305. Size of the certificate entry being provided by the MCU application.
  306. @note The data location to be accessed via pfSourceFn
  307. contains the entry to be added. The format of a TLS root certificate entry is:
  308. @code{.c}
  309. Name Offset Length Contents
  310. Header 0 36 tstrRootCertEntryHeader
  311. Key 36 KeyLength Public key and padding
  312. Padding 36+KeyLength PadLength 0xFF
  313. @endcode
  314. For RSA public keys, the format of Key is:
  315. @code{.c}
  316. Name Offset Length
  317. Modulus 36 ModLength RSA modulus, with leading 0s stripped off
  318. Exponent 36+ModLength ExpLength Public exponent, with leading 0s stripped off
  319. @endcode
  320. In this case PadLength is the amount of padding that would be required for 4-byte alignment of Modulus
  321. plus the amount of padding that would be required for 4-byte alignment of Exponent.\n
  322. For ECDSA public keys, the format of Key is:
  323. @code{.c}
  324. Name Offset Length
  325. X Coord 36 CoordLength Public key X-coordinate
  326. Y Coord 36+CoordLength CoordLength Public key Y-coordinate
  327. @endcode
  328. In this case PadLength is the amount of padding that would be required for 4-byte alignment of X Coord
  329. plus the amount of padding that would be required for 4-byte alignment of Y Coord.
  330. @return Zero indicates success.
  331. Negative values indicate failure.
  332. */
  333. sint8 m2m_flash_rootcert_add(uint16 u16Id, tpfDataAccessFn pfFn, uint32 u32Size);
  334. /*!
  335. @fn \
  336. sint8 m2m_flash_rootcert_remove(uint16 u16Id, uint8 *pu8Identifier, uint32 u32IdentifierSz);
  337. @brief Remove an entry from the WINC TLS root certificate store.
  338. @param [in] u16Id
  339. Transfer identifier, not interpreted by this module.
  340. @param [in] pu8Identifier
  341. Identifier for the entry to be removed. This is the SHA1 digest of the certificate issuer name.
  342. @param [in] u32IdentifierSz
  343. Size of the identifier (20).
  344. @return Zero indicates success.
  345. Negative values indicate failure.
  346. */
  347. sint8 m2m_flash_rootcert_remove(uint16 u16Id, uint8 *pu8Identifier, uint32 u32IdentifierSz);
  348. /*!
  349. @fn \
  350. sint8 m2m_flash_rootcert_read(uint16 u16Id, tpfDataAccessFn pfDestFn, uint32 u32DestSize, uint8 *pu8Identifier, uint32 u32IdentifierSz);
  351. @brief Read an entry from the WINC TLS root certificate store, referenced by entry identifier.
  352. @param [in] u16Id
  353. Transfer identifier, not interpreted by this module.
  354. @param [in] pfDestFn
  355. Function for the module to call to send the certificate entry to the MCU application.
  356. @param [in] u32DestSize
  357. Size of the memory available to the MCU application for storing the entry.
  358. @param [in] pu8Identifier
  359. Identifier for the entry to be read. This is the SHA1 digest of the certificate issuer name.
  360. @param [in] u32IdentifierSz
  361. Size of the identifier (20).
  362. @return Zero indicates success.
  363. Negative values indicate failure.
  364. */
  365. sint8 m2m_flash_rootcert_read(uint16 u16Id, tpfDataAccessFn pfDestFn, uint32 u32DestSize, uint8 *pu8Identifier, uint32 u32IdentifierSz);
  366. /*!
  367. @fn \
  368. sint8 m2m_flash_rootcert_readidx(uint16 u16Id, tpfDataAccessFn pfDestFn, uint32 u32DestSize, uint8 u8Index);
  369. @brief Read an entry from the WINC TLS root certificate store, referenced by entry index.
  370. @param [in] u16Id
  371. Transfer identifier, not interpreted by this module.
  372. @param [in] pfDestFn
  373. Function for the module to call to send the certificate entry to the MCU application.
  374. @param [in] u32DestSize
  375. Size of the memory available to the MCU application for storing the entry.
  376. @param [in] u8Index
  377. Zero-based index of the entry to be read.
  378. @return Zero indicates success.
  379. Negative values indicate failure.
  380. */
  381. sint8 m2m_flash_rootcert_readidx(uint16 u16Id, tpfDataAccessFn pfDestFn, uint32 u32DestSize, uint8 u8Index);
  382. /*!
  383. @fn \
  384. void m2m_flash_get_state(tstrFlashState *pstrState);
  385. @brief Get information about the module current state and about the most recent access attempt.
  386. @param [out] pstrState
  387. Module state and most recent access attempt info.
  388. @return None.
  389. */
  390. void m2m_flash_get_state(tstrFlashState *pstrState);
  391. /*!
  392. @fn \
  393. sint8 m2m_flash_init(void);
  394. @brief Initialize the module.
  395. @warning This API must be called at a particular point during MCU application initialization.
  396. @see m2m_wifi_init
  397. @see m2m_wifi_init_hold
  398. @see m2m_wifi_init_start
  399. \section FlashExample2 Example
  400. This example demonstrates how to add @ref m2m_flash_init and @ref m2m_flash_get_state
  401. to MCU application initialization code.
  402. Original code:
  403. @code{.c}
  404. {
  405. tstrWifiInitParam param = {...}
  406. sint8 status = 0;
  407. status = m2m_wifi_init(param);
  408. if (status != 0)
  409. {
  410. // Wifi init failed.
  411. }
  412. }
  413. @endcode
  414. New code:
  415. @code{.c}
  416. {
  417. tstrWifiInitParam param = {...}
  418. sint8 status = 0;
  419. status = m2m_wifi_init_hold();
  420. if (status == 0)
  421. {
  422. tstrFlashState strFlashState;
  423. m2m_flash_get_state(&strFlashState);
  424. printf("FlashAccess:%x:%d%d\n", strFlashState.u16LastAccessId, strFlashState.u8Success, strFlashState.u8Changed);
  425. switch (strFlashState.u16LastAccessId)
  426. {
  427. // Application code dependent on meaning of u16LastAccessId.
  428. }
  429. m2m_flash_init();
  430. status = m2m_wifi_init_start(param);
  431. }
  432. if (status != 0)
  433. {
  434. // Wifi init failed.
  435. }
  436. }
  437. @endcode
  438. @return Zero for successful initialization of module. Negative value otherwise.
  439. */
  440. sint8 m2m_flash_init(void);
  441. /**@}*/
  442. #endif /* __M2M_FLASH_H__ */