关于HC32F460看门狗的使用问题
最近在学习使用HC32F460单片机,想使用IAP功能远程升级程序,APP程序设置的flash地址是0x8000~0x78000,现在遇到的问题是,APP程序加入看门狗复位功能代码,程序不加载icg.c文件,看门狗功能就不正常,加载icg.c文件,编译生成不了bin文件,不知道怎么解决,请问论坛的大神们帮忙指点一下。。。。 这个没遇到过 weifeng90 发表于 2021-5-7 07:16这个没遇到过
我这边测试了下 ,程序工程不添加icg.c文件,看门狗复位功能也正常,可能昨天没有测试好,谢谢。 请问下,你的IAP调好了吗? 调好了。 学习了。感谢楼主的分享。
持续关注楼主的**。
方便分享下IAP代码吗?我最近也在调试 楼主,我也在调试F460的iap功能,为什么我从BOOT跳转到APP之后,APP不响应中断呀,Boot跳转app之前没有开启任何中断,也用了enIrqResign 函数注销掉了所有的中断,app可还是不响应中断,APP起始地址0x6000。。其中Boot区加载了ICG,APP里面没有加载ICG 地址空间超过了吧,两个功能理论上是不应该冲突的。 /******************************************************************************/
/** \file iap.c
**
** - 2019-05-291.0yangjpFirst version for IAP function.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "iap.h"
#include "led.h"
#include "flash.h"
#include "usart.h"
#include "time0.h"
#include "modem.h"
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
uint32_t JumpAddress;
func_ptr_t JumpToApplication;
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
static en_result_t IAP_JumpToApp(uint32_t u32Addr);
static void IAP_ResetConfig(void);
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief UART receive byte.
**
** \param u8RxData Pointer to Rx data.
**
** \retval Ok Receive data finished.
** \retval Error Don't receive data.
**
******************************************************************************/
void IAP_Main(void)
{
uint32_t u32AppFlag;
en_result_t enRet;
while (1)
{
enRet = Modem_Process(BOOT_WAIT_TIME);
if ((enRet == Ok) || (enRet == ErrorTimeout))
{
u32AppFlag = *(__IO uint32_t *)BOOT_PARA_ADDRESS;
if ((0xFFFF != u32AppFlag))
{
if (Error == IAP_JumpToApp(APP_ADDRESS))
{
LED0_OFF();
LED1_ON();
}
}
else
{
LED0_ON();
LED1_ON();
}
}
else
{
LED1_OFF();
LED0_ON();
}
}
}
/**
*******************************************************************************
** \brief IAP main function
**
** \param u32Addr APP address
**
** \retval Error APP address error
**
******************************************************************************/
static en_result_t IAP_JumpToApp(uint32_t u32Addr)
{
uint32_t u32StackTop = *((__IO uint32_t *)u32Addr);
/* Check if user code is programmed starting from address "u32Addr" */
/* Check stack top pointer. */
if ((u32StackTop > SRAM_BASE) && (u32StackTop <= (SRAM_BASE + RAM_SIZE)))
{
IAP_ResetConfig();
/* Jump to user application */
JumpAddress = *(__IO uint32_t *)(u32Addr + 4);
JumpToApplication = (func_ptr_t)JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t *)u32Addr);
JumpToApplication();
}
return Error;
}
void SystemClock_DeInit(void)
{
uint32_t u32Timeout = 0u;
/* Unlock CMU. */
ENABLE_CLOCK_REG_WRITE();
/* Close fcg0~fcg3. */
M4_MSTP->FCG0 = 0xFFFFFAEE;
M4_MSTP->FCG1 = 0xFFFFFFFF;
M4_MSTP->FCG2 = 0xFFFFFFFF;
M4_MSTP->FCG3 = 0xFFFFFFFF;
/* Wait stable after close fcg. */
u32Timeout = CLK_STABLE_TIME;
while (u32Timeout--);
M4_SYSREG->CMU_CKSWR = SYSCLK_SEL_MRC;
u32Timeout = CLK_STABLE_TIME;
while (u32Timeout--);
/* Set CMU registers to default value. */
M4_SYSREG->CMU_XTALCFGR = (uint8_t)0x00;
M4_SYSREG->CMU_XTALCR = (uint8_t)0x01;
M4_SYSREG->CMU_PLLCFGR= (uint32_t)0x11101300;
M4_SYSREG->CMU_PLLCR = (uint8_t)0x01;
M4_SYSREG->CMU_SCFGR = (uint32_t)0x00;
u32Timeout = CLK_STABLE_TIME;
while (u32Timeout--);
EFM_SetWaitCycle(0x0u);
u32Timeout = CLK_STABLE_TIME;
while (u32Timeout--);
/* Lock CMU. */
DISABLE_CLOCK_REG_WRITE();
}
/**
*******************************************************************************
** \brief Boot reset configure
**
** \param None
**
** \retval None
**
******************************************************************************/
static void IAP_ResetConfig(void)
{
LED_DeInit();
Timer_DeInit();
UART_DeInit();
SystemClock_DeInit();
}
/******************************************************************************
* EOF (not truncated)
*****************************************************************************/
/******************************************************************************/
/** \file iap.h
**
** - 2019-05-291.0yangjpFirst version for IAP function.
**
******************************************************************************/
#ifndef __IAP_H__
#define __IAP_H__
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32_common.h"
/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Global pre-processor symbols/macros ('#define')
******************************************************************************/
#define BOOT_SIZE FLASH_SECTOR_SIZE*10
#define BOOT_PARA_ADDRESS (FLASH_BASE + BOOT_SIZE - 4u)
#define APP_FLAG ((uint32_t)0x67890123)
#define APP_ADDRESS (FLASH_BASE + BOOT_SIZE)
#define BOOT_WAIT_TIME 5000 //ms
#define DIV_PCLK0S (0x0ul << 0u)
#define DIV_PCLK1S (0x1ul << 4u)
#define DIV_PCLK2S (0x2ul << 8u)
#define DIV_PCLK3S (0x2ul << 12u)
#define DIV_PCLK4S (0x1ul << 16u)
#define DIV_EXCKS (0x1ul << 20u)
#define DIV_HCLKS (0x0ul << 24u)
#define CMU_SCFGR_DIV ((uint32_t)(DIV_PCLK0S | DIV_PCLK1S | DIV_PCLK2S | \
DIV_PCLK3S | DIV_PCLK4S | DIV_EXCKS | DIV_HCLKS))
#define XTAL_LOW_DRIV (0x2ul << 4u)
#define XTAL_OSC_MODE (0x0ul)
#define XTAL_FAST_DRIV (0x1ul << 7u)
#define XTAL_CONFIG ((uint8_t)(XTAL_LOW_DRIV | XTAL_OSC_MODE | XTAL_FAST_DRIV))
#define XTAL_STABLE_FLAG ((uint8_t)(0x1ul << 3u))
#define MPLLM_DIV_1 (0x0ul)
#define MPLL_SRC_XTAL (0x0ul << 7u)
#define MPLLN_MUL_42 (0x29ul << 8u)
#define MPLLR_DIV_16 (0xFul << 20u)
#define MPLLQ_DIV_16 (0xFul << 24u)
#define MPLLP_DIV_2 (0x1ul << 28u)
#define MPLL_CONFIG ((uint32_t)(MPLLM_DIV_1 | MPLL_SRC_XTAL | MPLLN_MUL_42 |\
MPLLR_DIV_16 | MPLLQ_DIV_16 | MPLLP_DIV_2))
#define MPLL_STABLE_FLAG ((uint8_t)(0x1ul << 5u))
#define SYSCLK_SEL_MRC ((uint8_t)0x1)
#define SYSCLK_SEL_MPLL ((uint8_t)0x5)
#define CLK_STABLE_TIME (0x1000ul)
/* Unlock or lock registers of CMU. */
#define ENABLE_CLOCK_REG_WRITE() M4_SYSREG->PWR_FPRC = 0xa501
#define DISABLE_CLOCK_REG_WRITE() M4_SYSREG->PWR_FPRC = 0xa500
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
/*******************************************************************************
Global function prototypes (definition in C source)
******************************************************************************/
//void IAP_Init(void);
void IAP_Main(void);
#ifdef __cplusplus
}
#endif
#endif /* __IAP_H__ */
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "modem.h"
#include "iap.h"
#include "flash.h"
#include "usart.h"
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
uint8_t u8FrameData;
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
static uint16_t Cal_CRC16(const uint8_t *pu8Data, uint32_t u32ByteLen);
static uint16_t FLASH_PageNumber(uint32_t u32Size);
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
* @briefUpdate CRC16 for input byte
* @paramcrc_in input value
* @paraminput byte
* @retval None
*/
uint16_t Update_CRC16(uint16_t crc_in, uint8_t byte)
{
uint32_t crc = crc_in;
uint32_t in = byte | 0x100;
do
{
crc <<= 1;
in <<= 1;
if (in & 0x100)
++crc;
if (crc & 0x10000)
crc ^= 0x1021;
}
while (!(in & 0x10000));
return crc & 0xffffu;
}
/**
* @briefCal CRC16 for Packet
* @paramdata
* @paramlength
* @retval None
*/
uint16_t Cal_CRC16(const uint8_t* p_data, uint32_t size)
{
uint32_t crc = 0;
const uint8_t* dataEnd = p_data + size;
while (p_data < dataEnd)
crc = Update_CRC16(crc, *p_data++);
crc = Update_CRC16(crc, 0);
crc = Update_CRC16(crc, 0);
return crc & 0xffffu;
}
/**
*******************************************************************************
** \brief Modem receive frame
**
** \param u8RxBuff Pointer to Rx buffer.
** \param u16RxLength Pointer to receive data length.
** \param u32Timeout Communication process timeout
**
** \retval Ok Receive finished
** \retval Error Receive error
**
******************************************************************************/
en_result_t Modem_RecvFrame(uint8_t *u8RxBuff, uint16_t *u16RxLength, uint32_t u32Timeout)
{
uint16_t u16PacketSize = 0u;
uint16_t u16Crc16;
*u16RxLength = 0u;
if (Ok == UART_RecvData((uint8_t *)&u8RxBuff, 1, u32Timeout))
{
if ((FRAME_HEAD == u8RxBuff) &&
(Ok == UART_RecvData((uint8_t *)&u8RxBuff, 2, u32Timeout)))
{
if ((u8RxBuff == (u8RxBuff ^ FRAME_NUM_XOR_BYTE)) &&
(Ok == UART_RecvData(&u8RxBuff, 2, u32Timeout)))
{
u16PacketSize = *((uint16_t *)&u8RxBuff);
if (((u16PacketSize >= PACKET_MIN_SIZE) && (u16PacketSize <= PACKET_MAX_SIZE)) &&
(Ok == UART_RecvData(&u8RxBuff, u16PacketSize + 2, u32Timeout)))
{
u16Crc16 = *((uint16_t *)&u8RxBuff);
if (Cal_CRC16(&u8RxBuff, u16PacketSize) == u16Crc16)
{
*u16RxLength = u16PacketSize;
return Ok;
}
}
}
}
}
return Error;
}
/**
*******************************************************************************
** \brief Modem send frame
**
** \param u8TxBuff Pointer to Tx buffer.
** \param u16TxLength Send buffer data length.
**
** \retval None
**
******************************************************************************/
void Modem_SendFrame(uint8_t *u8TxBuff, uint16_t u16TxLength)
{
uint16_t u16Crc16;
u8TxBuff = u16TxLength & 0x00FF;
u8TxBuff = u16TxLength >> 8;
u16Crc16 = Cal_CRC16(&u8TxBuff, u16TxLength);
u8TxBuff = u16Crc16 & 0x00FF;
u8TxBuff = u16Crc16 >> 8;
UART_SendData(&u8TxBuff, FRAME_PACKET_INDEX + u16TxLength + 2);
}
/**
*******************************************************************************
** \brief Modem process
**
** \param u32Timeout Communication process timeout(ms)
**
** \retval Ok Communication done
** \retval ErrorTimeout Communication timeout
** \retval Error Communication error
**
******************************************************************************/
en_result_t Modem_Process(uint32_t u32Timeout)
{
uint8_t u8Ret;
uint8_t u8CommFlag = 0u, u8FlashAddrValid;
uint32_t u32TimeoutCnt = 0u;
uint16_t u16PacketLength, u16DataLength;
uint32_t u32FlashAddr;
uint8_t u8Cmd, u8Cnt;
uint16_t u16PageNum;
uint32_t u32Temp;
while (1)
{
if (u32TimeoutCnt >= u32Timeout)
{
if (u8CommFlag == 0u) // No communication
{
return ErrorTimeout;
}
else
{
return Error;
}
}
if (Ok == Modem_RecvFrame(&u8FrameData, &u16PacketLength, FRAME_RECV_TIMEOUT))
{
u32TimeoutCnt = 0u;
u8CommFlag = 1u;
u8Cmd = u8FrameData;
u16DataLength = u16PacketLength - PACKET_INSTRUCT_SEGMENT_SIZE;
if (PACKET_CMD_TYPE_DATA == u8FrameData)
{
u32FlashAddr = *((uint32_t *)&u8FrameData);
if ((u32FlashAddr >= (FLASH_BASE + BOOT_SIZE)) && (u32FlashAddr < (FLASH_BASE + FLASH_SIZE)))
{
u8FlashAddrValid = 1u;
}
else
{
u8FlashAddrValid = 0u;
}
}
switch (u8Cmd)
{
case PACKET_CMD_HANDSHAKE:
u8FrameData = PACKET_ACK_OK;
Modem_SendFrame(&u8FrameData, PACKET_INSTRUCT_SEGMENT_SIZE);
break;
case PACKET_CMD_JUMP_TO_APP:
u32Temp = APP_FLAG;
EFM_WriteFlash(BOOT_PARA_ADDRESS, (uint8_t *)&u32Temp, 4);
u8FrameData = PACKET_ACK_OK;
Modem_SendFrame(&u8FrameData, PACKET_INSTRUCT_SEGMENT_SIZE);
return Ok;
case PACKET_CMD_APP_DOWNLOAD:
if (1u == u8FlashAddrValid)
{
u8Ret = EFM_WriteFlash(u32FlashAddr, (uint8_t *)&u8FrameData, u16DataLength);
if (EfmError == u8Ret)
{
u8FrameData = PACKET_ACK_ERROR;
}
else
{
u8FrameData = PACKET_ACK_OK;
}
}
else
{
u8FrameData = PACKET_ACK_ADDR_ERROR;
}
Modem_SendFrame(&u8FrameData, PACKET_INSTRUCT_SEGMENT_SIZE);
break;
case PACKET_CMD_APP_UPLOAD:
if (1u == u8FlashAddrValid)
{
u32Temp = *((uint32_t *)&u8FrameData);
if (u32Temp > PACKET_DATA_SEGMENT_SIZE)
{
u32Temp = PACKET_DATA_SEGMENT_SIZE;
}
u8Ret = EFM_ReadFlashByte(u32FlashAddr, (uint8_t *)&u8FrameData, u32Temp);
if (EfmError == u8Ret)
{
u8FrameData = PACKET_ACK_ERROR;
}
else
{
u8FrameData = PACKET_ACK_OK;
}
Modem_SendFrame(&u8FrameData, PACKET_INSTRUCT_SEGMENT_SIZE + u32Temp);
}
else
{
u8FrameData = PACKET_ACK_ADDR_ERROR;
Modem_SendFrame(&u8FrameData, PACKET_INSTRUCT_SEGMENT_SIZE);
}
break;
case PACKET_CMD_ERASE_FLASH:
if (1u == u8FlashAddrValid)
{
u32Temp = *((uint32_t *)&u8FrameData);
u16PageNum = FLASH_PageNumber(u32Temp);
for (u8Cnt=0; u8Cnt<u16PageNum; u8Cnt++)
{
u8Ret = EFM_EraseSector(u32FlashAddr + (u8Cnt * FLASH_SECTOR_SIZE));
if (EfmError == u8Ret)
{
u8FrameData = PACKET_ACK_ERROR;
break;
}
}
if (EfmOk == u8Ret)
{
u8FrameData = PACKET_ACK_OK;
}
}
else
{
u8FrameData = PACKET_ACK_ADDR_ERROR;
}
Modem_SendFrame(&u8FrameData, PACKET_INSTRUCT_SEGMENT_SIZE);
break;
default:
break;
}
}
else
{
u32TimeoutCnt += FRAME_RECV_TIMEOUT;
}
}
}
/**
*******************************************************************************
** \brief Calculate how many sectors are included in a given size.
**
******************************************************************************/
static uint16_t FLASH_PageNumber(uint32_t u32Size)
{
uint16_t u32PageNum = u32Size / FLASH_SECTOR_SIZE;
if ((u32Size % FLASH_SECTOR_SIZE) != 0)
{
u32PageNum += 1u;
}
return u32PageNum;
}
/******************************************************************************
* EOF (not truncated)
*****************************************************************************/
/** \file modem.h
**
** - 2019-05-291.0yangjpFirst version for modem function.
**
******************************************************************************/
#ifndef __MODEM_H__
#define __MODEM_H__
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32_common.h"
/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
/**
*******************************************************************************
** \brief Packet status enumeration
******************************************************************************/
typedef enum
{
PACKET_ACK_OK = 0x00,
PACKET_ACK_ERROR = 0x01,
PACKET_ACK_ABORT = 0x02,
PACKET_ACK_TIMEOUT = 0x03,
PACKET_ACK_ADDR_ERROR = 0x04,
} en_packet_status_t;
/**
*******************************************************************************
** \brief Packet command enumeration
******************************************************************************/
typedef enum
{
PACKET_CMD_HANDSHAKE = 0x20,
PACKET_CMD_JUMP_TO_APP = 0x21,
PACKET_CMD_APP_DOWNLOAD = 0x22,
PACKET_CMD_APP_UPLOAD = 0x23,
PACKET_CMD_ERASE_FLASH = 0x24,
} en_packet_cmd_t;
/**
*******************************************************************************
** \brief Packet command type enumeration
******************************************************************************/
typedef enum
{
PACKET_CMD_TYPE_CONTROL = 0x11,
PACKET_CMD_TYPE_DATA = 0x12,
} en_packet_cmd_type_t;
/*******************************************************************************
* Global pre-processor symbols/macros ('#define')
******************************************************************************/
#define FRAME_HEAD 0xAC
/* Frame and packet size */
#define PACKET_INSTRUCT_SEGMENT_SIZE 12
#define PACKET_DATA_SEGMENT_SIZE 512
#define PACKET_MIN_SIZE PACKET_INSTRUCT_SEGMENT_SIZE
#define PACKET_MAX_SIZE (PACKET_DATA_SEGMENT_SIZE + PACKET_INSTRUCT_SEGMENT_SIZE)
#define FRAME_SHELL_SIZE 0x07
/* Frame structure defines */
#define FRAME_HEAD_INDEX 0x00
#define FRAME_NUM_INDEX 0x01
#define FRAME_XORNUM_INDEX 0x02
#define FRAME_LENGTH_INDEX 0x03
#define FRAME_PACKET_INDEX 0x05
#define FRAME_RECV_TIMEOUT 5 // ms
#define FRAME_NUM_XOR_BYTE 0xFF
/* Packet structure defines */
#define PACKET_CMD_INDEX (FRAME_PACKET_INDEX + 0x00)
#define PACKET_TYPE_INDEX (FRAME_PACKET_INDEX + 0x01)
#define PACKET_RESULT_INDEX (FRAME_PACKET_INDEX + 0x01)
#define PACKET_ADDRESS_INDEX (FRAME_PACKET_INDEX + 0x02)
#define PACKET_DATA_INDEX (FRAME_PACKET_INDEX + PACKET_INSTRUCT_SEGMENT_SIZE)
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
/*******************************************************************************
Global function prototypes (definition in C source)
******************************************************************************/
en_result_t Modem_Process(uint32_t u32Timeout);
#ifdef __cplusplus
}
#endif
#endif /* __MODEM_H__ */
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/
enm 发表于 2021-5-19 09:21
方便分享下IAP代码吗?我最近也在调试
邮箱发我下 ,我发给你,论坛上传工程压缩包不成功。 lj592035536 发表于 2021-5-19 14:29
楼主,我也在调试F460的iap功能,为什么我从BOOT跳转到APP之后,APP不响应中断呀,Boot跳转app之前没有开启 ...
邮箱发我下 ,我发给你,论坛上传工程压缩包不成功。 lj592035536 发表于 2021-5-19 14:29
楼主,我也在调试F460的iap功能,为什么我从BOOT跳转到APP之后,APP不响应中断呀,Boot跳转app之前没有开启 ...
APP中断响应不了,可能是你的中断向量偏移地址没有设置正确,将你APP初始地址赋值给寄存器 SCB->VTOR应该就可以了。 便分享下IAP代码吗?我最近也在调试,跳转不了,谢谢楼主,邮箱是1151644124@qq.com 楼主还在吗?现在在调试IAP功能,能发一份参考一下吗?谢谢
463280658@qq.com 楼主还在吗?现在在调试IAP功能,能发一份参考一下吗?谢谢
774749459@qq.com
页:
[1]