199 lines
6.6 KiB
C
199 lines
6.6 KiB
C
|
/***************************************************************************
|
||
|
*
|
||
|
* Copyright 2015-2019 BES.
|
||
|
* All rights reserved. All unpublished rights reserved.
|
||
|
*
|
||
|
* No part of this work may be used or reproduced in any form or by any
|
||
|
* means, or stored in a database or retrieval system, without prior written
|
||
|
* permission of BES.
|
||
|
*
|
||
|
* Use of this work is governed by a license granted by BES.
|
||
|
* This work contains confidential and proprietary information of
|
||
|
* BES. which is protected by copyright, trade secret,
|
||
|
* trademark and other intellectual property rights.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include "cmsis.h"
|
||
|
#include "coredump_section.h"
|
||
|
#include "hal_timer.h"
|
||
|
#include "hal_trace.h"
|
||
|
#include "hal_norflash.h"
|
||
|
#include "norflash_api.h"
|
||
|
|
||
|
/*
|
||
|
Usage:
|
||
|
arm-none-eabi-gdb elf_file -ex "target remote | ./tools/bins/lin64/CrashDebug --elf elf_file --dump coredump.dat"
|
||
|
*/
|
||
|
|
||
|
extern uint32_t __coredump_section_start;
|
||
|
extern uint32_t __coredump_section_end;
|
||
|
|
||
|
static const uint32_t coredump_flash_start_addr = (uint32_t)&__coredump_section_start;
|
||
|
static const uint32_t coredump_flash_end_addr = (uint32_t)&__coredump_section_end;
|
||
|
static uint32_t coredump_flash_addr_offset = (uint32_t)&__coredump_section_start;
|
||
|
|
||
|
void coredump_to_flash_init()
|
||
|
{
|
||
|
uint32_t block_size = 0;
|
||
|
uint32_t sector_size = 0;
|
||
|
uint32_t page_size = 0;
|
||
|
uint32_t buffer_len = 0;
|
||
|
enum NORFLASH_API_RET_T result;
|
||
|
|
||
|
hal_norflash_get_size(HAL_NORFLASH_ID_0,NULL, &block_size, §or_size, &page_size);
|
||
|
buffer_len = COREDUMP_SECTOR_SIZE;
|
||
|
TRACE(4,"%s: coredump_flash_start_addr = 0x%x, coredump_flash_end_addr = 0x%x, buff_len = 0x%x.",
|
||
|
__func__,
|
||
|
coredump_flash_start_addr,
|
||
|
coredump_flash_end_addr,
|
||
|
buffer_len);
|
||
|
|
||
|
result = norflash_api_register(
|
||
|
NORFLASH_API_MODULE_ID_COREDUMP,
|
||
|
HAL_NORFLASH_ID_0,
|
||
|
coredump_flash_start_addr,
|
||
|
coredump_flash_end_addr - coredump_flash_start_addr,
|
||
|
block_size,
|
||
|
sector_size,
|
||
|
page_size,
|
||
|
buffer_len,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
if(result == NORFLASH_API_OK)
|
||
|
{
|
||
|
TRACE(0,"coredump_to_flash_init ok.");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TRACE(1,"coredump_to_flash_init failed,result = %d.",result);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void core_dump_erase_section()
|
||
|
{
|
||
|
//erase whole core dump section
|
||
|
enum NORFLASH_API_RET_T ret = 0;
|
||
|
uint32_t lock;
|
||
|
do
|
||
|
{
|
||
|
lock = int_lock_global();
|
||
|
ret = norflash_api_erase(NORFLASH_API_MODULE_ID_COREDUMP, coredump_flash_addr_offset,
|
||
|
COREDUMP_SECTOR_SIZE, false);
|
||
|
int_unlock_global(lock);
|
||
|
if(ret != NORFLASH_API_OK)
|
||
|
{
|
||
|
TRACE(3,"%s:offset = 0x%x,ret = %d.",
|
||
|
__func__,coredump_flash_addr_offset,ret);
|
||
|
}
|
||
|
coredump_flash_addr_offset += COREDUMP_SECTOR_SIZE;
|
||
|
if (coredump_flash_addr_offset == coredump_flash_end_addr)
|
||
|
{
|
||
|
coredump_flash_addr_offset = coredump_flash_start_addr;
|
||
|
break;
|
||
|
}
|
||
|
} while (1);
|
||
|
}
|
||
|
|
||
|
int32_t core_dump_write_large(const uint8_t* ptr,uint32_t len)
|
||
|
{
|
||
|
enum NORFLASH_API_RET_T ret;
|
||
|
uint32_t write_len;
|
||
|
uint32_t remain_len = len;
|
||
|
uint32_t lock;
|
||
|
//TRACE(4,"%s offset = 0x%x ptr = 0x%x len=0x%x",__func__, coredump_flash_addr_offset, ptr, len);
|
||
|
do
|
||
|
{
|
||
|
if (coredump_flash_addr_offset % COREDUMP_SECTOR_SIZE != 0)
|
||
|
{
|
||
|
write_len = COREDUMP_SECTOR_SIZE - (coredump_flash_addr_offset - (coredump_flash_addr_offset & ~COREDUMP_SECTOR_SIZE_MASK));
|
||
|
lock = int_lock_global();
|
||
|
ret = norflash_api_write(NORFLASH_API_MODULE_ID_COREDUMP,
|
||
|
coredump_flash_addr_offset,
|
||
|
ptr,
|
||
|
write_len,
|
||
|
false);
|
||
|
int_unlock_global(lock);
|
||
|
if(ret != NORFLASH_API_OK)
|
||
|
{
|
||
|
TRACE(4,"%s: addr = 0x%x,write_len = 0x%x,ret = %d.",
|
||
|
__func__,coredump_flash_addr_offset,write_len,ret);
|
||
|
return (int32_t)ret;
|
||
|
}
|
||
|
coredump_flash_addr_offset += write_len;
|
||
|
ptr += write_len;
|
||
|
remain_len -= write_len;
|
||
|
}
|
||
|
|
||
|
if (remain_len < COREDUMP_SECTOR_SIZE)
|
||
|
{
|
||
|
lock = int_lock_global();
|
||
|
ret = norflash_api_write(NORFLASH_API_MODULE_ID_COREDUMP,
|
||
|
coredump_flash_addr_offset,
|
||
|
ptr,
|
||
|
remain_len,
|
||
|
false);
|
||
|
int_unlock_global(lock);
|
||
|
if(ret != NORFLASH_API_OK)
|
||
|
{
|
||
|
TRACE(4,"%s: addr = 0x%x,remain_len = 0x%x,ret = %d.",
|
||
|
__func__,coredump_flash_addr_offset,remain_len,ret);
|
||
|
return (int32_t)ret;
|
||
|
}
|
||
|
coredump_flash_addr_offset += remain_len;
|
||
|
ptr += remain_len;
|
||
|
remain_len = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lock = int_lock_global();
|
||
|
ret = norflash_api_write(NORFLASH_API_MODULE_ID_COREDUMP,
|
||
|
coredump_flash_addr_offset,
|
||
|
ptr,
|
||
|
COREDUMP_SECTOR_SIZE,
|
||
|
false);
|
||
|
int_unlock_global(lock);
|
||
|
if(ret != NORFLASH_API_OK)
|
||
|
{
|
||
|
TRACE(3,"%s: addr = 0x%x,ret = %d.",
|
||
|
__func__,coredump_flash_addr_offset,ret);
|
||
|
return (int32_t)ret;
|
||
|
}
|
||
|
coredump_flash_addr_offset += COREDUMP_SECTOR_SIZE;
|
||
|
ptr += COREDUMP_SECTOR_SIZE;
|
||
|
remain_len -= COREDUMP_SECTOR_SIZE;
|
||
|
}
|
||
|
} while (remain_len > 0);
|
||
|
//TRACE(3,"%s offset = 0x%x ptr = 0x%x",__func__, coredump_flash_addr_offset, ptr);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int32_t core_dump_write(const uint8_t* ptr,uint32_t len)
|
||
|
{
|
||
|
enum NORFLASH_API_RET_T ret;
|
||
|
uint32_t i;
|
||
|
uint32_t lock;
|
||
|
//TRACE(2,"%s: len = 0x%x", __func__,len);
|
||
|
//write by byte to avoid cross flash sector boundary
|
||
|
for (i = 0; i < len; i++)
|
||
|
{
|
||
|
lock = int_lock_global();
|
||
|
ret = norflash_api_write(NORFLASH_API_MODULE_ID_COREDUMP,
|
||
|
coredump_flash_addr_offset++,
|
||
|
ptr++,
|
||
|
1,
|
||
|
false);
|
||
|
int_unlock_global(lock);
|
||
|
if(ret != NORFLASH_API_OK)
|
||
|
{
|
||
|
TRACE(4,"%s: offset = 0x%x ret = %d ch =%02x",
|
||
|
__func__,coredump_flash_addr_offset,ret,*(ptr-1));
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|