2019-11-01 11:16:09 +08:00

189 lines
7.3 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
*********************************************************************************************************
*
* 模块名称 : 在线升级固件。
* 文件名称 : modbus_iap.c
* 版 本 : V1.0
* 说 明 :
*
* 修改记录 :
* 版本号 日期 作者 说明
* V1.0 2013-02-01 armfly 正式发布
*
* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com
*
*********************************************************************************************************
*/
#include "bsp.h"
#include "main.h"
#include "modbus_iap.h"
#include "param.h"
#include "modbus_slave.h"
uint32_t g_FlashAddr = 0; /* CPU当前写入的地址 */
static uint8_t s_Databuf[1024]; /* 升级程序buf。接收到1024个字节一次性写入cpu flash */
uint32_t g_DataLen = 0; /* 最后一包包长 */
uint8_t g_Upgrade = 0;
uint8_t g_Erase = 0; /* APP应用区代码擦除标志 */
/*
*********************************************************************************************************
* 函 数 名: WriteRegValue
* 功能说明: 读取保持寄存器的值
* 形 参: reg_addr 寄存器地址
* reg_value 寄存器值
* 返 回 值: 1表示OK 0表示错误
*********************************************************************************************************
*/
extern uint8_t g_fReset;
extern uint8_t g_fBaud;
uint8_t IAP_Write06H(uint16_t reg_addr, uint16_t reg_value)
{
switch (reg_addr)
{
case BOOT_UPGRADE_FLAG: /* 程序升级标志寄存器 */
g_Upgrade = reg_value;
if (reg_value == 0) /* 升级结束 */
{
if (bsp_WriteCpuFlash(g_FlashAddr, s_Databuf, g_DataLen) == 0) /* 写最后一包数据(先读取组成新的1K数据再写入) */
{
//DispMessage("程序升级成功!");
g_tParam.UpgradeFlag = 0x55AAA55A;
return 1;
}
else
{
return 0;
}
}
break;
case BOOT_BAUD: /* 波特率寄存器 */
break;
case SYS_RESET: /* 系统复位 */
// FLASH_EraseSector(ADDR_FLASH_SECTOR_3, VoltageRange_3);
// FLASH_EraseSector(ADDR_FLASH_SECTOR_4, VoltageRange_3);
// FLASH_EraseSector(ADDR_FLASH_SECTOR_5, VoltageRange_3);
// FLASH_EraseSector(ADDR_FLASH_SECTOR_6, VoltageRange_3);
// FLASH_EraseSector(ADDR_FLASH_SECTOR_7, VoltageRange_3);
// FLASH_EraseSector(ADDR_FLASH_SECTOR_8, VoltageRange_3);
// FLASH_EraseSector(ADDR_FLASH_SECTOR_9, VoltageRange_3);
// FLASH_EraseSector(ADDR_FLASH_SECTOR_10, VoltageRange_3);
// FLASH_EraseSector(ADDR_FLASH_SECTOR_11, VoltageRange_3);
break;
default:
return 0; /* 参数异常,返回 0 */
}
return 1; /* 成功 */
}
/*
*********************************************************************************************************
* 函 数 名: MODS_15H
* 功能说明: 写文件
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
extern uint8_t g_Erase;
void MODS_15H(void)
{
/*
主机发送:
11 从机地址
15 功能码
00 请求数据长度
01 子请求x参考类型
00 子请求x文件号
01 子请求x记录号
9A 子请求x记录长度
9B 子请求x记录数据
18 校验高字节
FC 校验低字节
从机响应:
11 从机地址
15 功能码
00 请求数据长度
01 子请求x参考类型
00 子请求x文件号
01 子请求x记录号
9A 子请求x记录长度
9B 子请求x记录数据
18 校验高字节
FC 校验低字节
*/
uint8_t i;
// uint8_t DateLen; /* 请求数据长度 */
// uint8_t Type; /* 参考类型 */
// uint16_t FileID; /* 文件号 */
uint16_t RecordID; /* 记录号 */
uint16_t RecordLen; /* 记录长度 */
uint32_t Packet; /* 第几包数据 */
static uint16_t s_LenBak; /* 记录之前的数据长度,如果长度与之前的不同,则认为是最后一包数据,需要写入 */
uint32_t Cpu_Offset; /* CPU地址偏移 */
// char buf[50];
g_tModS.RspCode = RSP_OK;
// DateLen = g_tModS.RxBuf[2];
// Type = g_tModS.RxBuf[3];
// FileID = BEBufToUint16(&g_tModS.RxBuf[4]); /* 子请求x文件号 */
RecordID = BEBufToUint16(&g_tModS.RxBuf[6]); /* 子请求x记录号 */
RecordLen = BEBufToUint16(&g_tModS.RxBuf[8]); /* 子请求x记录长度 */
if (RecordID == 0) /* 第一包数据就把flash写入地址设为基地址,同时擦除应用区代码 */
{
//g_FlashAddr = APPLICATION_ADDRESS;
g_Erase = 1;
s_LenBak = RecordLen; /* 第1包的数据长度认为是收到每包的长度 */
}
Packet = RecordID + 1;
Cpu_Offset = RecordID * s_LenBak / 1024 * 1024; /* CPU写入的偏移地址 */
g_FlashAddr = APP_BUF_ADDR + Cpu_Offset; /* 下一包数据写入的位置1024的整数倍 */
memcpy(&s_Databuf[(RecordID * s_LenBak) % 1024], &g_tModS.RxBuf[10], RecordLen); /* 组成1K数据再写入CPU flash */
if ((Packet * s_LenBak) % 1024 != 0) /* 判断当前数据包是否满足1K的整数倍 */
{
g_DataLen = ((RecordID * s_LenBak) % 1024) + RecordLen; /* 记录当前需要写入的包长 */
}
else /* 满足1K的整数倍此时才开始将1K数据写入CPU flash */
{
if (bsp_WriteCpuFlash(g_FlashAddr, s_Databuf, 1024) == 0) /* 每次写入1024个字节 */
{
// sprintf(buf, "进度:%d%%", RecordID * s_LenBak * 100 % 1024);
// DispMessage(buf);
//DispMessage("程序升级中...");
g_tModS.RspCode = RSP_OK;
}
else
{
g_tModS.RspCode = RSP_ERR_WRITE; /* 写入失败 */
goto err_ret;
}
}
err_ret:
if (g_tModS.RspCode == RSP_OK) /* 正确应答 */
{
g_tModS.TxCount = 0;
for (i = 0; i < 10; i++)
{
g_tModS.TxBuf[g_tModS.TxCount++] = g_tModS.RxBuf[i]; /* 应答数据包 */
}
MODS_SendWithCRC(g_tModS.TxBuf, g_tModS.TxCount);
}
else
{
MODS_SendAckErr(g_tModS.RspCode); /* 告诉主机命令错误 */
}
}
/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/