debug: coredump: flash backend: add query/command to get raw data
Add a new coredump query and command type to retrieve the raw data stored to the flash backend Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
This commit is contained in:
parent
a3904bd991
commit
a727b8aaac
2 changed files with 156 additions and 1 deletions
|
@ -7,6 +7,9 @@
|
|||
#ifndef ZEPHYR_INCLUDE_DEBUG_COREDUMP_H_
|
||||
#define ZEPHYR_INCLUDE_DEBUG_COREDUMP_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Query ID */
|
||||
enum coredump_query_id {
|
||||
/*
|
||||
|
@ -24,6 +27,14 @@ enum coredump_query_id {
|
|||
*/
|
||||
COREDUMP_QUERY_HAS_STORED_DUMP,
|
||||
|
||||
/*
|
||||
* Returns coredump raw size from backend.
|
||||
* 0 if none.
|
||||
* -ENOTSUP if this query is not supported.
|
||||
* Otherwise, error code from backend.
|
||||
*/
|
||||
COREDUMP_QUERY_GET_STORED_DUMP_SIZE,
|
||||
|
||||
COREDUMP_QUERY_MAX
|
||||
};
|
||||
|
||||
|
@ -55,9 +66,41 @@ enum coredump_cmd_id {
|
|||
*/
|
||||
COREDUMP_CMD_ERASE_STORED_DUMP,
|
||||
|
||||
/*
|
||||
* Copy the raw stored coredump.
|
||||
*
|
||||
* Returns copied size if successful
|
||||
* 0 if stored coredump is not found
|
||||
* -ENOTSUP if this command is not supported.
|
||||
* Otherwise, error code from backend.
|
||||
*/
|
||||
COREDUMP_CMD_COPY_STORED_DUMP,
|
||||
|
||||
/*
|
||||
* Invalidate the stored coredump. This is faster than
|
||||
* erasing the whole partition.
|
||||
*
|
||||
* Returns 0 if successful.
|
||||
* -ENOTSUP if this command is not supported.
|
||||
* Otherwise, error code from backend.
|
||||
*/
|
||||
COREDUMP_CMD_INVALIDATE_STORED_DUMP,
|
||||
|
||||
COREDUMP_CMD_MAX
|
||||
};
|
||||
|
||||
/* Coredump copy command argument definition */
|
||||
struct coredump_cmd_copy_arg {
|
||||
/* Copy offset */
|
||||
off_t offset;
|
||||
|
||||
/* Copy destination buffer */
|
||||
uint8_t *buffer;
|
||||
|
||||
/* Copy length */
|
||||
size_t length;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DEBUG_COREDUMP
|
||||
|
||||
#include <zephyr/toolchain.h>
|
||||
|
|
|
@ -42,6 +42,7 @@ LOG_MODULE_REGISTER(coredump, CONFIG_KERNEL_LOG_LEVEL);
|
|||
|
||||
#define FLASH_WRITE_SIZE DT_PROP(FLASH_CONTROLLER, write_block_size)
|
||||
#define FLASH_BUF_SIZE FLASH_WRITE_SIZE
|
||||
#define FLASH_ERASE_SIZE DT_PROP(FLASH_CONTROLLER, erase_block_size)
|
||||
|
||||
#define FLASH_PARTITION FLASH_AREA_ID(coredump_partition)
|
||||
|
||||
|
@ -273,7 +274,100 @@ out:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Erase the stored coredump from flash partition.
|
||||
* @brief Get the stored coredump in flash partition.
|
||||
*
|
||||
* This reads the stored coredump data and copies the raw data
|
||||
* to the destination buffer.
|
||||
*
|
||||
* If the destination buffer is NULL, the offset and length are
|
||||
* ignored and the entire dump size is returned.
|
||||
*
|
||||
* @param off offset of partition to begin reading
|
||||
* @param dst buffer to read data into (can be NULL)
|
||||
* @param len number of bytes to read
|
||||
* @return dump size if successful; 0 if stored coredump is not found
|
||||
* or is not valid; error otherwise
|
||||
*/
|
||||
static int get_stored_dump(off_t off, uint8_t *dst, size_t len)
|
||||
{
|
||||
int ret;
|
||||
struct flash_hdr_t hdr;
|
||||
|
||||
ret = partition_open();
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Read header */
|
||||
ret = data_read(0, (uint8_t *)&hdr, sizeof(hdr), NULL, NULL);
|
||||
if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Verify header signature */
|
||||
if ((hdr.id[0] != 'C') && (hdr.id[1] != 'D')) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Error encountered while dumping, so non-existent */
|
||||
if (hdr.error != 0) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Return the dump size if no destination buffer available */
|
||||
if (!dst) {
|
||||
ret = (int)hdr.size;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Offset larger than dump size */
|
||||
if (off >= hdr.size) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Start reading the data, skip write-aligned header */
|
||||
off += ROUND_UP(sizeof(struct flash_hdr_t), FLASH_WRITE_SIZE);
|
||||
|
||||
ret = data_read(off, dst, len, NULL, NULL);
|
||||
if (ret == 0) {
|
||||
ret = (int)len;
|
||||
}
|
||||
out:
|
||||
partition_close();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Erase the stored coredump header from flash partition.
|
||||
*
|
||||
* This erases the stored coredump header from the flash partition,
|
||||
* invalidating the coredump data.
|
||||
*
|
||||
* @return 0 if successful; error otherwise
|
||||
*/
|
||||
static int erase_coredump_header(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = partition_open();
|
||||
if (ret == 0) {
|
||||
/* Erase header block */
|
||||
ret = flash_area_erase(backend_ctx.flash_area, 0,
|
||||
ROUND_UP(sizeof(struct flash_hdr_t),
|
||||
FLASH_ERASE_SIZE));
|
||||
}
|
||||
|
||||
partition_close();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Erase the stored coredump in flash partition.
|
||||
*
|
||||
* This erases the stored coredump data from the flash partition.
|
||||
*
|
||||
|
@ -458,6 +552,9 @@ static int coredump_flash_backend_query(enum coredump_query_id query_id,
|
|||
case COREDUMP_QUERY_HAS_STORED_DUMP:
|
||||
ret = process_stored_dump(cb_calc_buf_checksum, NULL);
|
||||
break;
|
||||
case COREDUMP_QUERY_GET_STORED_DUMP_SIZE:
|
||||
ret = get_stored_dump(0, NULL, 0);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOTSUP;
|
||||
break;
|
||||
|
@ -489,6 +586,21 @@ static int coredump_flash_backend_cmd(enum coredump_cmd_id cmd_id,
|
|||
case COREDUMP_CMD_ERASE_STORED_DUMP:
|
||||
ret = erase_flash_partition();
|
||||
break;
|
||||
case COREDUMP_CMD_COPY_STORED_DUMP:
|
||||
if (arg) {
|
||||
struct coredump_cmd_copy_arg *copy_arg
|
||||
= (struct coredump_cmd_copy_arg *)arg;
|
||||
|
||||
ret = get_stored_dump(copy_arg->offset,
|
||||
copy_arg->buffer,
|
||||
copy_arg->length);
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
}
|
||||
break;
|
||||
case COREDUMP_CMD_INVALIDATE_STORED_DUMP:
|
||||
ret = erase_coredump_header();
|
||||
break;
|
||||
default:
|
||||
ret = -ENOTSUP;
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue