|
发表于 2013-10-28 15:03:32
|
显示全部楼层
本帖最后由 Gorgon_Meducer 于 2013-10-28 15:07 编辑
我一般是用EzPort来写程序,所以不需要特别的设置,直接就会把对应的Bit给写上的。
只是说实话,用户的IAP部分编写起来要跳过关键的Security设置部分,这里不做好,
后面会很痛苦。另外K系列默认是从0x00000000启动的,虽然能修改Vector Table的
位置,但是意味着IAP必须占据头部的VectorTable的头8个字节……同时,用户程序
的VectorTable的头8个字节也要被IAP自动劫持后处理掉。这些细节都挺麻烦的。
以下是我IAP代码的参考片段,专门处理这类问题,以供参考:
- /*! \brief bootloader command handler
- *! \param pchStream data block
- *! \param hwSize data block size
- *! \retval 0 failed in parsing
- *! \retval none-zero-size reply data size
- */
- uint_fast16_t cmd_flash_write(uint8_t *pchStream, uint_fast16_t hwLength)
- {
- uint_fast32_t hwAddress = TYPE_CONVERT(&pchStream[2], uint16_t); //!< address
- uint_fast16_t hwSize = TYPE_CONVERT(&pchStream[4], uint16_t); //!< size
- uint8_t *pchSrc = &pchStream[6]; //!< data
- do {
- //! protect the reset vector and stack address
- if (hwAddress < 0x0008) {
- //! protected area
- uint_fast8_t chDelta = MIN((0x0008 - hwAddress), hwSize);
- uint_fast16_t hwOrigionAddress = hwAddress;
-
- //! save overlap data to protected are
- uint8_t chOrigionValue[8];
- uint_fast8_t hwCounter = 0;
- for (;hwCounter < chDelta;hwCounter++) {
- chOrigionValue[hwCounter]= *pchSrc++;
- }
-
- extern uint32_t __CRITICAL_VECTOR_EXCHANGE_AREA__[];
- //! write flash
- if (!FLASH_WRITE(hwOrigionAddress + (uint32_t)__CRITICAL_VECTOR_EXCHANGE_AREA__, chOrigionValue, chDelta)) {
- SET_IAP_REPLY(IAP_RSP_ERROR);
- break;
- }
- //! update information
- hwSize -= chDelta;
- hwAddress = 0x0008;
- }
- if (hwSize > 0) {
-
- //! protect system configuration flash
- if (hwAddress >= FLASH_CONFIG_START && hwAddress < FLASH_CONFIG_END) {
- //! start address invade the system configuration area
- uint_fast16_t hwDelta = FLASH_CONFIG_END - hwAddress;
-
- hwAddress = FLASH_CONFIG_END;
- hwDelta = MIN(hwSize,hwDelta);
- hwSize -= hwDelta;
- pchSrc += hwDelta;
- } else if (hwAddress < FLASH_CONFIG_START) {
- if (hwAddress + hwSize <= FLASH_CONFIG_END) {
- hwSize = FLASH_CONFIG_START - hwAddress;
- } else if (hwAddress + hwSize > FLASH_CONFIG_END) {
- //! write memory block before the protection area
- uint_fast16_t hwTempSize = FLASH_CONFIG_START - hwAddress;
- if (!FLASH_WRITE(hwAddress, pchSrc, hwTempSize)) {
- SET_IAP_REPLY(IAP_RSP_ERROR);
- break;
- }
- hwAddress = FLASH_CONFIG_END;
- pchSrc += (hwTempSize + (FLASH_CONFIG_END - FLASH_CONFIG_START));
- hwSize -= (hwTempSize + (FLASH_CONFIG_END - FLASH_CONFIG_START));
- }
- }
- }
- if (hwSize > 0) {
- //! protect bootloader area
- if (hwAddress >= IAP_BOOTLOADER_ADDRESS) {
- //! bootloader overlap
- SET_IAP_REPLY(IAP_RSP_ERROR_BL_OVERLAP);
- break;
- } else if ((hwAddress + hwSize) > IAP_BOOTLOADER_ADDRESS) {
- /*! \note invade into bootloader area, we just write as more memory as
- *! possible.
- */
- hwSize = IAP_BOOTLOADER_ADDRESS - hwAddress;
-
- //! write memory block
- if (!FLASH_WRITE(hwAddress, pchSrc, hwSize)) {
- SET_IAP_REPLY(IAP_RSP_ERROR);
- break;
- }
-
- //! bootloader overlap
- SET_IAP_REPLY(IAP_RSP_ERROR_BL_OVERLAP);
- break;
- }
- //! normal area
- if (!FLASH_WRITE(hwAddress, pchSrc, hwSize)) {
- SET_IAP_REPLY(IAP_RSP_ERROR);
- break;
- }
- }
- //! send reply ok
- SET_IAP_REPLY(IAP_RSP_OK);
- } while (false);
- return 1;
- }
复制代码 |
|