Skip to content

Commit 0735689

Browse files
committed
mgmt: mcumgr: grp: os_mgmt: Add memory pool statistics command support
Adds support for the memory pool statistics (mpstat) command, which will list details on various memory heaps on the device Signed-off-by: Jamie McCrae <[email protected]>
1 parent e655a2f commit 0735689

File tree

3 files changed

+121
-0
lines changed

3 files changed

+121
-0
lines changed

include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ enum os_mgmt_err_code_t {
6161

6262
/** Query was recognized but there is no valid value for the response. */
6363
OS_MGMT_ERR_QUERY_RESPONSE_VALUE_NOT_VALID,
64+
65+
/** Heap statistic fetch failed. */
66+
OS_MGMT_ERR_HEAP_STATS_FETCH_FAILED,
6467
};
6568

6669
/**

subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,26 @@ config MCUMGR_GRP_OS_TASKSTAT_STACK_INFO
137137

138138
endif
139139

140+
config MCUMGR_GRP_OS_MPSTAT
141+
bool "Support for memory pool statistics command"
142+
depends on SYS_HEAP_RUNTIME_STATS
143+
depends on SYS_HEAP_ARRAY_SIZE > 0
144+
select MCUMGR_SMP_CBOR_MIN_ENCODING_LEVEL_2
145+
select MCUMGR_SMP_CBOR_MIN_ENCODING_LEVEL_3 if ZCBOR_CANONICAL
146+
help
147+
The memory pool statistics (mpstat) command will list the various heap memory pools
148+
on the device, including sizes, free space and minimum amount of free space.
149+
150+
config MCUMGR_GRP_OS_MPSTAT_ONLY_SUPPORTED_STATS
151+
bool "Send only data gathered by Zephyr"
152+
depends on MCUMGR_GRP_OS_MPSTAT
153+
default y
154+
help
155+
Response will not include the "blksiz" field which Zephyr does not support (as it has a
156+
value of 1). Enable this if your client software is able to process "mpstat" response
157+
without the "blksiz" field for each memory pool. Enabling this option will slightly
158+
reduce code size.
159+
140160
config MCUMGR_GRP_OS_ECHO
141161
bool "Support for echo command"
142162
default y

subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525

2626
#include <mgmt/mcumgr/util/zcbor_bulk.h>
2727

28+
#ifdef CONFIG_MCUMGR_GRP_OS_MPSTAT
29+
#include <zephyr/sys/sys_heap.h>
30+
#include <mgmt/mcumgr/transport/smp_internal.h>
31+
#endif
32+
2833
#ifdef CONFIG_REBOOT
2934
#include <zephyr/sys/reboot.h>
3035
#endif
@@ -145,6 +150,22 @@ struct datetime_parser {
145150
extern uint8_t *MCUMGR_GRP_OS_INFO_BUILD_DATE_TIME;
146151
#endif
147152

153+
#ifdef CONFIG_MCUMGR_GRP_OS_MPSTAT
154+
/* Specifies the maximum characters in the memory pool ID, allowing up to 999 outputs */
155+
#define MPSTAT_ID_KEY_SIZE 4
156+
157+
#ifdef CONFIG_MCUMGR_GRP_OS_MPSTAT_ONLY_SUPPORTED_STATS
158+
/* Number of items per memory pool output */
159+
#define MPSTAT_KEY_MAP_ENTRIES 3
160+
#else
161+
/* Number of items per memory pool output */
162+
#define MPSTAT_KEY_MAP_ENTRIES 4
163+
164+
/* Specifies the block size of memory pools, zephyr used byte-level allocation */
165+
#define MPSTAT_BLOCK_SIZE 1
166+
#endif
167+
#endif
168+
148169
/**
149170
* Command handler: os echo
150171
*/
@@ -355,6 +376,76 @@ static int os_mgmt_taskstat_read(struct smp_streamer *ctxt)
355376
}
356377
#endif /* CONFIG_MCUMGR_GRP_OS_TASKSTAT */
357378

379+
#ifdef CONFIG_MCUMGR_GRP_OS_MPSTAT
380+
/**
381+
* Command handler: os mpstat
382+
*/
383+
static int os_mgmt_mpstat_read(struct smp_streamer *ctxt)
384+
{
385+
zcbor_state_t *zse = ctxt->writer->zs;
386+
struct sys_heap **heap;
387+
uint8_t key[MPSTAT_ID_KEY_SIZE] = { 0 };
388+
int heap_elements;
389+
int i = 0;
390+
bool ok;
391+
392+
heap_elements = sys_heap_array_get(&heap);
393+
ok = zcbor_tstr_put_lit(zse, "tasks") &&
394+
zcbor_map_start_encode(zse, heap_elements);
395+
396+
if (!ok) {
397+
goto end;
398+
}
399+
400+
while (i < heap_elements) {
401+
struct sys_memory_stats heap_stats;
402+
uint32_t heap_total_size;
403+
int rc;
404+
uint8_t key_size;
405+
406+
rc = sys_heap_runtime_stats_get(heap[i], &heap_stats);
407+
408+
if (rc != 0) {
409+
ok = smp_mgmt_reset_zse(ctxt) &&
410+
smp_add_cmd_err(zse, MGMT_GROUP_ID_OS,
411+
OS_MGMT_ERR_HEAP_STATS_FETCH_FAILED);
412+
LOG_ERR("Failed to get heap stats from address %p: %d", heap[i], rc);
413+
goto end;
414+
}
415+
416+
key_size = u8_to_dec(key, sizeof(key), i);
417+
heap_total_size = heap_stats.allocated_bytes + heap_stats.free_bytes;
418+
419+
ok = zcbor_tstr_encode_ptr(zse, key, (size_t)key_size) &&
420+
zcbor_map_start_encode(zse, MPSTAT_KEY_MAP_ENTRIES) &&
421+
#ifndef CONFIG_MCUMGR_GRP_OS_MPSTAT_ONLY_SUPPORTED_STATS
422+
zcbor_tstr_put_lit(zse, "blksiz") &&
423+
zcbor_uint32_put(zse, MPSTAT_BLOCK_SIZE) &&
424+
#endif
425+
zcbor_tstr_put_lit(zse, "nblks") &&
426+
zcbor_uint32_put(zse, heap_total_size) &&
427+
zcbor_tstr_put_lit(zse, "nfree") &&
428+
zcbor_uint32_put(zse, heap_stats.free_bytes) &&
429+
zcbor_tstr_put_lit(zse, "min") &&
430+
zcbor_uint32_put(zse, (heap_total_size - heap_stats.max_allocated_bytes)) &&
431+
zcbor_map_end_encode(zse, MPSTAT_KEY_MAP_ENTRIES);
432+
433+
if (!ok) {
434+
break;
435+
}
436+
437+
++i;
438+
}
439+
440+
if (ok == true) {
441+
ok = zcbor_map_end_encode(zse, heap_elements);
442+
}
443+
444+
end:
445+
return MGMT_RETURN_CHECK(ok);
446+
}
447+
#endif /* CONFIG_MCUMGR_GRP_OS_MPSTAT */
448+
358449
#ifdef CONFIG_REBOOT
359450
/**
360451
* Command handler: os reset
@@ -1117,6 +1208,7 @@ static int os_mgmt_translate_error_code(uint16_t err)
11171208
case OS_MGMT_ERR_QUERY_YIELDS_NO_ANSWER:
11181209
case OS_MGMT_ERR_RTC_NOT_SET:
11191210
case OS_MGMT_ERR_QUERY_RESPONSE_VALUE_NOT_VALID:
1211+
case OS_MGMT_ERR_HEAP_STATS_FETCH_FAILED:
11201212
rc = MGMT_ERR_ENOENT;
11211213
break;
11221214

@@ -1142,6 +1234,12 @@ static const struct mgmt_handler os_mgmt_group_handlers[] = {
11421234
},
11431235
#endif
11441236

1237+
#ifdef CONFIG_MCUMGR_GRP_OS_MPSTAT
1238+
[OS_MGMT_ID_MPSTAT] = {
1239+
os_mgmt_mpstat_read, NULL
1240+
},
1241+
#endif
1242+
11451243
#ifdef CONFIG_MCUMGR_GRP_OS_DATETIME
11461244
[OS_MGMT_ID_DATETIME_STR] = {
11471245
os_mgmt_datetime_read, os_mgmt_datetime_write

0 commit comments

Comments
 (0)