2026-08-10 21:18:36 +08:00
|
|
|
|
/* reset_log.c - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC>ԭ<EFBFBD><D4AD> + <20>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* <EFBFBD>洢<EFBFBD><EFBFBD>W25Q64 0x100000 <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD> 4KB <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>10 <EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD>θ<EFBFBD><EFBFBD>ǣ<EFBFBD>
|
|
|
|
|
|
* д<EFBFBD><EFBFBD>һȦ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>¼<EFBFBD>ϡ<EFBFBD>裬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><EFBFBD>ԣ<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>䣺<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BOOT_SHARE <EFBFBD><EFBFBD><EFBFBD><EFBFBD> RAM<EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD><EFBFBD>ȸ<EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ź<EFBFBD>/<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ磩ʱ RAM ʧЧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD>ɶϵ<EFBFBD>˲<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>ṩ
|
|
|
|
|
|
* <EFBFBD><EFBFBD>PA0 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <10% <EFBFBD><EFBFBD>Ϊ<EFBFBD>ⲿ 12V <EFBFBD>Ͽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ 30s <EFBFBD>㹻д<EFBFBD>꣩<EFBFBD><EFBFBD>
|
|
|
|
|
|
* ԭ<EFBFBD><EFBFBD><EFBFBD>룺RCC->CSR <EFBFBD><EFBFBD> BL <EFBFBD><EFBFBD><EFBFBD><EFBFBD> BOOT_SHARE <EFBFBD><EFBFBD><EFBFBD><EFBFBD> APP<EFBFBD><EFBFBD>BL <EFBFBD><EFBFBD><EFBFBD>꼴<EFBFBD>壩<EFBFBD><EFBFBD>
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD>ϸ<EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD>ɸ<EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD> reset_log_mark() Ԥ<EFBFBD><EFBFBD>д<EFBFBD>롣
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include "reset_log.h"
|
|
|
|
|
|
#include "boot_share.h"
|
|
|
|
|
|
#include "log.h"
|
|
|
|
|
|
#include "main.h"
|
|
|
|
|
|
#include "app_loop.h"
|
2026-08-15 00:45:12 +08:00
|
|
|
|
#include "hlw8032.h"
|
2026-08-10 21:18:36 +08:00
|
|
|
|
#include "../W25Q64/w25q64.h"
|
|
|
|
|
|
#include "string.h"
|
|
|
|
|
|
|
|
|
|
|
|
#define RST_LOG_ADDR 0x100000u /* <20>ܿ<EFBFBD> OTA <20><>(0~0x81FFF) */
|
|
|
|
|
|
#define RST_LOG_SLOTS 10
|
|
|
|
|
|
#define RST_REC_MAGIC 0x5253544Cu /* 'RSTL' */
|
|
|
|
|
|
#define RST_REC_SIZE 32u
|
|
|
|
|
|
|
|
|
|
|
|
/* ÿ<><C3BF><EFBFBD><EFBFBD>¼<EFBFBD><C2BC>ռһ<D5BC><D2BB> 4KB <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>NOR Flash ֻ<><D6BB> 1->0 <20><>λ<EFBFBD><CEBB>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* <EFBFBD><EFBFBD> 10 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>ζ<EFBFBD><EFBFBD><EFBFBD> 9 <EFBFBD><EFBFBD><EFBFBD>ɼ<EFBFBD>¼<EFBFBD><EFBFBD>
|
|
|
|
|
|
* һ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<EFBFBD><EFBFBD> 11 <20><>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<EFBFBD><EFBFBD>W25Q64 <EFBFBD><EFBFBD> 8MB<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 10 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD> */
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
|
uint32_t magic; /* RST_REC_MAGIC */
|
|
|
|
|
|
uint32_t seq; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD><C5A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
|
|
|
uint8_t reason; /* RSN_x */
|
|
|
|
|
|
uint8_t boot_seen; /* 0xFF=<3D>¼<EFBFBD>¼<EFBFBD><C2BC><EFBFBD>ϵ<EFBFBD>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>´ο<C2B4><CEBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѻ<EFBFBD><D1BA><EFBFBD> 0x00<30><30>λ<EFBFBD><CEBB>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
|
|
|
uint8_t rsvd[2];
|
|
|
|
|
|
uint32_t uptime_sec; /* <20>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>0xFFFFFFFF=δ֪<CEB4><D6AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> RAM <20><>ʧ<EFBFBD><CAA7> */
|
|
|
|
|
|
uint16_t crc16; /* ǰ 14 <20>ֽ<EFBFBD><D6BD>ۼӺ<DBBC> */
|
|
|
|
|
|
uint8_t pad[16];
|
|
|
|
|
|
} rst_rec_t;
|
|
|
|
|
|
|
|
|
|
|
|
static const char *reason_str(uint8_t r)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (r) {
|
|
|
|
|
|
case RSN_POWER_ON: return "<EFBFBD>ϵ<EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
|
|
|
|
|
case RSN_PIN_RESET: return "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ";
|
|
|
|
|
|
case RSN_WATCHDOG: return "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ź<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
|
|
|
|
|
case RSN_KICKED: return "<EFBFBD><EFBFBD>ƽ̨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
|
|
|
|
|
case RSN_PING_TIMEOUT: return "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ)";
|
|
|
|
|
|
case RSN_NO_SERVICE: return "4G<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
|
|
|
|
|
case RSN_NO_SIM: return "<EFBFBD><EFBFBD>SIM<EFBFBD><EFBFBD>";
|
|
|
|
|
|
case RSN_OTA_UPDATE: return "OTA<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
|
|
|
|
|
case RSN_OTA_HEALTH: return "OTA<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>鳬ʱ";
|
|
|
|
|
|
case RSN_4G_FAIL: return "4G<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>";
|
|
|
|
|
|
case RSN_CMD_RESET: return "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>RESET<EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
|
|
|
|
|
case RSN_CMD_OTA: return "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>OTA<EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
|
|
|
|
|
case RSN_CMD_RECOVERY: return "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>RECOVERY<EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
|
|
|
|
|
case RSN_POWER_LOSS: return "<EFBFBD>ⲿ<EFBFBD>ϵ<EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD>¼)";
|
|
|
|
|
|
case RSN_4G_MODULE: return "4Gģ<EFBFBD><EFBFBD><EFBFBD>쳣<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
|
|
|
|
|
case RSN_SOFT_GENERIC: return "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ(δ<><CEB4><EFBFBD><EFBFBD>)";
|
|
|
|
|
|
default: return "δ֪";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static uint16_t rec_sum(const rst_rec_t *r)
|
|
|
|
|
|
{
|
|
|
|
|
|
const uint8_t *p = (const uint8_t *)r;
|
|
|
|
|
|
uint16_t s = 0;
|
|
|
|
|
|
for (int i = 0; i < 14; i++) s += p[i]; /* magic+seq+reason+boot_seen+rsvd+uptime */
|
|
|
|
|
|
return s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int rec_valid(const rst_rec_t *r)
|
|
|
|
|
|
{
|
|
|
|
|
|
return r->magic == RST_REC_MAGIC && r->crc16 == rec_sum(r);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void rec_read(uint8_t slot, rst_rec_t *r)
|
|
|
|
|
|
{
|
|
|
|
|
|
W25Q64_Read(RST_LOG_ADDR + (uint32_t)slot * W25Q64_SECTOR_SIZE, (uint8_t *)r, RST_REC_SIZE);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void rec_write(uint8_t slot, rst_rec_t *r)
|
|
|
|
|
|
{
|
|
|
|
|
|
r->crc16 = rec_sum(r);
|
|
|
|
|
|
/* ÿ<><C3BF><EFBFBD><EFBFBD>ռһ<D5BC><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>дǰ<D0B4>Ȳ<EFBFBD><C8B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>NOR ֻ<><D6BB> 1->0 <20><>λ<EFBFBD><CEBB> */
|
|
|
|
|
|
W25Q64_EraseRegion(RST_LOG_ADDR + (uint32_t)slot * W25Q64_SECTOR_SIZE, W25Q64_SECTOR_SIZE);
|
|
|
|
|
|
W25Q64_WriteBuffer(RST_LOG_ADDR + (uint32_t)slot * W25Q64_SECTOR_SIZE, (const uint8_t *)r, RST_REC_SIZE);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>¼<EFBFBD><C2BC><EFBFBD><EFBFBD> -1 */
|
|
|
|
|
|
static int find_newest(uint32_t *seq_out)
|
|
|
|
|
|
{
|
|
|
|
|
|
rst_rec_t r;
|
|
|
|
|
|
int best = -1;
|
|
|
|
|
|
uint32_t best_seq = 0;
|
|
|
|
|
|
for (uint8_t i = 0; i < RST_LOG_SLOTS; i++) {
|
|
|
|
|
|
rec_read(i, &r);
|
|
|
|
|
|
if (rec_valid(&r) && (best < 0 || (int32_t)(r.seq - best_seq) > 0)) {
|
|
|
|
|
|
best = i;
|
|
|
|
|
|
best_seq = r.seq;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (seq_out) *seq_out = best_seq;
|
|
|
|
|
|
return best;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* <><D7B7>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD>θ<EFBFBD><CEB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD> */
|
|
|
|
|
|
static void append_record(uint8_t reason, uint32_t uptime_sec)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t seq = 0;
|
|
|
|
|
|
int newest = find_newest(&seq);
|
|
|
|
|
|
int slot = (newest < 0) ? 0 : (newest + 1) % RST_LOG_SLOTS;
|
|
|
|
|
|
|
|
|
|
|
|
rst_rec_t r;
|
|
|
|
|
|
memset(&r, 0xFF, sizeof(r));
|
|
|
|
|
|
r.magic = RST_REC_MAGIC;
|
|
|
|
|
|
r.seq = seq + 1;
|
|
|
|
|
|
r.reason = reason;
|
|
|
|
|
|
r.boot_seen = 0xFF;
|
|
|
|
|
|
r.uptime_sec = uptime_sec;
|
|
|
|
|
|
rec_write((uint8_t)slot, &r);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λǰ<CEBB><C7B0><EFBFBD><EFBFBD>ϸ<EFBFBD><CFB8>ԭ<EFBFBD><EFBFBD><F2A3A8B9><EFBFBD> RAM<41><4D><EFBFBD>ȸ<EFBFBD>λ<EFBFBD><CEBB> APP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1> */
|
|
|
|
|
|
void reset_log_mark(uint8_t reason)
|
|
|
|
|
|
{
|
2026-08-15 00:45:12 +08:00
|
|
|
|
hlw8032_save(); /* <20>ƻ<EFBFBD><C6BB>ڸ<EFBFBD>λǰ<CEBB><C7B0><EFBFBD>ۼƵ<DBBC><C6B5><EFBFBD><EFBFBD><EFBFBD> EEPROM<4F><4D><EFBFBD>ޱ仯ʱ<E4BBAF>ղ<EFBFBD><D5B2><EFBFBD><EFBFBD><EFBFBD> */
|
2026-08-10 21:18:36 +08:00
|
|
|
|
BOOT_SHARE->pending_reason = reason;
|
|
|
|
|
|
boot_share_store();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> RAM<41><4D><EFBFBD>ȸ<EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
|
|
|
void reset_log_tick(uint32_t uptime_s)
|
|
|
|
|
|
{
|
|
|
|
|
|
BOOT_SHARE->uptime_sec = uptime_s;
|
|
|
|
|
|
boot_share_store();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* <20>ⲿ<EFBFBD>ϵ<EFBFBD>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD>PA0 <20>͵<EFBFBD><CDB5><EFBFBD> = 12V <20>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD>¼ */
|
|
|
|
|
|
void reset_log_power_loss(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t up = boot_share_valid() ? BOOT_SHARE->uptime_sec : 0xFFFFFFFFu;
|
|
|
|
|
|
uint32_t m = up / 60;
|
|
|
|
|
|
log_warn("> <20>ϵ<EFBFBD>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD><EFBFBD>ⲿ 12V <20>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1> %u<><75>%02uСʱ%02u<32><75>%02u<32><75>",
|
|
|
|
|
|
(unsigned)(m / 1440), (unsigned)((m % 1440) / 60), (unsigned)(m % 60), (unsigned)(up % 60));
|
|
|
|
|
|
append_record(RSN_POWER_LOSS, up);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*==== <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BL <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CSR + Ԥ<><D4A4>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɱ<EFBFBD><C9B1>μ<EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD> 10 <20><> ====*/
|
|
|
|
|
|
void reset_log_boot(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint8_t reason = RSN_UNKNOWN;
|
|
|
|
|
|
uint32_t up = 0xFFFFFFFFu;
|
|
|
|
|
|
int skip_new = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (boot_share_valid()) {
|
|
|
|
|
|
uint32_t csr = BOOT_SHARE->csr_flags;
|
|
|
|
|
|
up = BOOT_SHARE->uptime_sec; /* <20>ȸ<EFBFBD>λʱ<CEBB><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1> */
|
|
|
|
|
|
|
|
|
|
|
|
if ((csr & RCC_CSR_SFTRSTF) && BOOT_SHARE->pending_reason != 0) {
|
|
|
|
|
|
reason = (uint8_t)BOOT_SHARE->pending_reason;
|
|
|
|
|
|
} else if (csr & RCC_CSR_SFTRSTF) {
|
|
|
|
|
|
reason = RSN_SOFT_GENERIC;
|
|
|
|
|
|
} else if (csr & RCC_CSR_IWDGRSTF) {
|
|
|
|
|
|
reason = RSN_WATCHDOG;
|
|
|
|
|
|
} else if (csr & RCC_CSR_WWDGRSTF) {
|
|
|
|
|
|
reason = RSN_WATCHDOG;
|
|
|
|
|
|
} else if (csr & RCC_CSR_PINRSTF) {
|
|
|
|
|
|
reason = RSN_PIN_RESET;
|
|
|
|
|
|
} else if (csr & RCC_CSR_PORRSTF) {
|
|
|
|
|
|
reason = RSN_POWER_ON;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* <20>ϵ<EFBFBD>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>ѣ<EFBFBD><D1A3><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>ϵ<EFBFBD>ʱ<EFBFBD><CAB1>Ԥд<D4A4><D0B4>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>ο<EFBFBD><CEBF><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ+BL <EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t seq;
|
|
|
|
|
|
int newest = find_newest(&seq);
|
|
|
|
|
|
if (newest >= 0) {
|
|
|
|
|
|
rst_rec_t last;
|
|
|
|
|
|
rec_read((uint8_t)newest, &last);
|
|
|
|
|
|
if (last.reason == RSN_POWER_LOSS && last.boot_seen == 0xFF) {
|
|
|
|
|
|
last.boot_seen = 0x00;
|
|
|
|
|
|
rec_write((uint8_t)newest, &last); /* λ<><CEBB>ת 1->0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
|
|
|
skip_new = 1;
|
|
|
|
|
|
log_info("> <20>ϴ<EFBFBD>Ϊ<EFBFBD>ϵ<EFBFBD><CFB5>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD>Ѽ<EFBFBD>¼<EFBFBD><C2BC>");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!skip_new) {
|
|
|
|
|
|
append_record(reason, up);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* <20><><EFBFBD>ο<EFBFBD><CEBF><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> RAM ״̬<D7B4><CCAC><EFBFBD><EFBFBD>Ԥ<EFBFBD><D4A4>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>¼ƣ<C2BC> */
|
|
|
|
|
|
BOOT_SHARE->pending_reason = 0;
|
|
|
|
|
|
BOOT_SHARE->uptime_sec = 0;
|
|
|
|
|
|
BOOT_SHARE->magic = BOOT_SHARE_MAGIC;
|
|
|
|
|
|
boot_share_store();
|
|
|
|
|
|
|
|
|
|
|
|
/* <20><>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD> 10 <20><><EFBFBD><EFBFBD><EFBFBD>¡<EFBFBD><C2A1>ɣ<EFBFBD><C9A3><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD>Ź̶<C5B9> 1~10<31><30>[1] <20><><EFBFBD>£<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><F3B8B2B8><EFBFBD><EFBFBD>ɣ<EFBFBD> */
|
|
|
|
|
|
log_info("> <20><>ʷ<EFBFBD><CAB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>¡<EFBFBD><C2A1>ɣ<EFBFBD>:");
|
|
|
|
|
|
uint32_t newest_seq;
|
|
|
|
|
|
int newest = find_newest(&newest_seq);
|
|
|
|
|
|
if (newest < 0) {
|
|
|
|
|
|
log_info(" <20><><EFBFBD><EFBFBD>¼<EFBFBD><C2BC>");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
for (int i = 0; i < RST_LOG_SLOTS; i++) {
|
|
|
|
|
|
int slot = (newest - i + RST_LOG_SLOTS) % RST_LOG_SLOTS;
|
|
|
|
|
|
rst_rec_t r;
|
|
|
|
|
|
rec_read((uint8_t)slot, &r);
|
|
|
|
|
|
if (!rec_valid(&r)) continue;
|
|
|
|
|
|
if (r.uptime_sec == 0xFFFFFFFFu) {
|
|
|
|
|
|
log_info(" [%d] <20><><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD>: %s <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>: δ֪",
|
|
|
|
|
|
i + 1, reason_str(r.reason));
|
|
|
|
|
|
} else {
|
|
|
|
|
|
uint32_t m = r.uptime_sec / 60;
|
|
|
|
|
|
log_info(" [%d] <20><><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD>: %s <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>: %u<><75>%02uСʱ%02u<32><75>",
|
|
|
|
|
|
i + 1, reason_str(r.reason),
|
|
|
|
|
|
(unsigned)(m / 1440), (unsigned)((m % 1440) / 60), (unsigned)(m % 60));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|