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 {
145150extern 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