#include #include "cli.h" #include #include #include #include "bk_rtos_debug.h" #if CONFIG_PSRAM #include #endif /* Platform includes. */ #include "sys_driver.h" #include #if CONFIG_AON_RTC #include #include #endif void cli_memory_free_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) { uint32_t total_size,free_size,mini_size; CLI_LOGI("================Static memory================\r\n"); os_show_memory_config_info(); CLI_LOGI("================Dynamic memory================\r\n"); cmd_printf("%-5s %-5s %-5s %-5s %-5s\r\n", "name", "total", "free", "minimum", "peak"); total_size = rtos_get_total_heap_size(); free_size = rtos_get_free_heap_size(); mini_size = rtos_get_minimum_free_heap_size(); cmd_printf("heap\t%d\t%d\t%d\t%d\r\n", total_size,free_size,mini_size,total_size-mini_size); #if CONFIG_PSRAM_AS_SYS_MEMORY total_size = rtos_get_psram_total_heap_size(); free_size = rtos_get_psram_free_heap_size(); mini_size = rtos_get_psram_minimum_free_heap_size(); cmd_printf("psram\t%d\t%d\t%d\t%d\r\n", total_size,free_size,mini_size,total_size-mini_size); #endif } void cli_memory_set_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) { #if CONFIG_DEBUG_FIRMWARE uint32_t address, value; os_printf("cli_memory_set_cmd\r\n"); if (argc >= 3) { address = strtoll(argv[1], NULL, 16); value = strtoll(argv[2], NULL, 16); os_printf("memset,address: 0x%08X value: 0x%08X\r\n", address, value); os_write_word(address, value); } else { os_printf("memset \r\n"); } #endif } #if CONFIG_DEBUG_FIRMWARE const static uint32_t s_test_data[20] = { 0x00000000, 0x800102a0, 0x30021e44, 0x30034088, 0x5f696c63, 0x61727370, 0x616d5f6d, 0x636f6c6c, 0x646d635f, 0x00000000, 0x736d656d, 0x6b636174, 0x00696c63, 0x00000000, 0x00001ed9, 0x0000005c, 0x00010240, 0x12345678, 0x99887766, 0xaabbccdd }; __attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns"))) \ int32_t memtest_write_one_word(uint32_t addr, uint32_t count) { uint32_t i; uint32_t src_data = 0x30023456; uint32_t *p_uint32_dst = (uint32_t *)addr; for(i = 0; i < count; i++) { os_write_word(p_uint32_dst, src_data); src_data++; } return 0; } __attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns"))) \ int32_t memtest_wr(uint32_t addr, uint32_t count) { #if CONFIG_DEBUG_FIRMWARE int int_status = rtos_enter_critical(); os_printf("memtest_wr begin!!\r\n"); os_memcpy_word((uint32_t *)addr, &s_test_data[2], sizeof(s_test_data) - 8); bk_mem_dump("before test", addr - 8, sizeof(s_test_data)); memtest_write_one_word(addr, count); bk_mem_dump("after test", addr - 8, sizeof(s_test_data)); os_printf("memtest_wr done!!\r\n"); rtos_exit_critical(int_status); #endif //#if CONFIG_DEBUG_FIRMWARE return 0; } static void cli_memtest_wr_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) { uint32_t address, count; if (argc >= 3) { address = strtoll(argv[1], NULL, 16); count = strtoll(argv[2], NULL, 16); os_printf("memtest_wr,address: 0x%08X count: 0x%08X\r\n", address, count); (void)memtest_wr(address, count); } else { os_printf("memtest_wr \r\n"); } } #endif //#if CONFIG_DEBUG_FIRMWARE void cli_memory_stack_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) { #if CONFIG_FREERTOS GLOBAL_INT_DECLARATION(); GLOBAL_INT_DISABLE(); rtos_dump_stack_memory_usage(); GLOBAL_INT_RESTORE(); #endif } #if CONFIG_MEM_DEBUG && CONFIG_FREERTOS static void cli_memory_leak_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) { uint32_t start_tick = 0; uint32_t ticks_since_malloc = 0; uint32_t seconds_since_malloc = 0; char *task_name = NULL; if (argc >= 2) { seconds_since_malloc = os_strtoul(argv[1], NULL, 10); ticks_since_malloc = bk_get_ticks_per_second() * seconds_since_malloc; } if (argc >= 3) start_tick = os_strtoul(argv[2], NULL, 10); if (argc >= 4) task_name = argv[3]; os_dump_memory_stats(start_tick, ticks_since_malloc, task_name); } #endif #if CONFIG_PSRAM_AS_SYS_MEMORY && CONFIG_FREERTOS void cli_psram_malloc_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) { uint8_t *pstart; uint32_t length; if (argc != 2) { cmd_printf("Usage: psram_malloc .\r\n"); return; } length = strtoul(argv[1], NULL, 0); pstart = (uint8_t *)psram_malloc(length); cmd_printf("psram_malloc ret(%p).\r\n", pstart); } void cli_psram_free_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) { uint8_t *pstart; uint32_t start; if (argc != 2) { cmd_printf("Usage: psram_free .\r\n"); return; } start = strtoul(argv[1], NULL, 0); pstart = (uint8_t *)start; cmd_printf("psram_free addr(%p).\r\n", pstart); os_free(pstart); } void cli_psram_state_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) { bk_psram_heap_get_used_state(); } #endif //#if CONFIG_PSRAM_AS_SYS_MEMORY && CONFIG_FREERTOS int32_t mem_test(uint32_t address, uint32_t size, uint8_t quiet_mode) { uint32_t i; /**< 32bit test */ { uint32_t * p_uint32_t = (uint32_t *)address; for(i=0; i> 32), (u32)(saved_aon_time & 0xFFFFFFFF)); BK_DUMP_OUT("curr time: 0x%x:0x%08x\r\n", (u32)(cur_aon_time >> 32), (u32)(cur_aon_time & 0xFFFFFFFF)); BK_DUMP_OUT("diff time: 0x%x:0x%08x\r\n", (u32)(diff_time >> 32), (u32)(diff_time & 0xFFFFFFFF)); BK_DUMP_OUT("memtime end, time consume=%d ms\r\n", diff_ms); } int32_t mem_read_test(uint32_t src, uint32_t dst, uint32_t size) { #if CONFIG_DEBUG_FIRMWARE uint32_t i; uint32_t test_count = size/sizeof(uint32_t); os_memcpy_word((uint32_t *)dst, (uint32_t *)src, size); /**< 32bit test */ { uint32_t *p_uint32_src = (uint32_t *)src; uint32_t *p_uint32_dst = (uint32_t *)dst; for(i = 0; i < test_count; i++) { if( *p_uint32_src != *p_uint32_dst) { os_printf("32bit test fail @ 0x%08X\r\n!",(uint32_t)p_uint32_src); return -1; } p_uint32_src++; p_uint32_dst++; } os_printf("32bit test pass!!\r\n"); } /**< 16bit test */ { uint16_t *p_uint16_src = (uint16_t *)src; uint16_t *p_uint16_dst = (uint16_t *)dst; test_count = size/sizeof(uint16_t); for(i = 0; i < test_count; i++) { if( *p_uint16_src != *p_uint16_dst ) { os_printf("16bit test fail @ 0x%08X\r\nsystem halt!!!!!",(uint32_t)p_uint16_src); return -1; } p_uint16_src++; p_uint16_dst++; } os_printf("16bit test pass!!\r\n"); } /**< 8bit test */ { uint8_t *p_uint8_src = (uint8_t *)src; uint8_t *p_uint8_dst = (uint8_t *)dst; test_count = size/sizeof(uint8_t); for(i = 0; i < test_count; i++) { if( *p_uint8_src != *p_uint8_dst ) { os_printf("8bit test fail @ 0x%08X\r\n", (uint32_t)p_uint8_src); return -1; } p_uint8_src++; p_uint8_dst++; } os_printf("8bit test pass!!\r\n"); } /**< 32bit test write one address*/ { uint32_t *p_uint32_src = (uint32_t *)src; uint32_t *p_uint32_dst = (uint32_t *)dst; uint32_t *p_uint32_next = (uint32_t *)dst + 1; test_count = size/sizeof(uint32_t); for(i = 0; i < test_count; i++) { *p_uint32_dst = *p_uint32_src; if(*p_uint32_next != *(p_uint32_dst + 1)) { os_printf("32bit test write one address fail @ 0x%08X\r\n!",(uint32_t)p_uint32_next); os_printf("==== next o:%08X,next n:%08X\r\n!",*p_uint32_next, *(p_uint32_dst + 1)); return -1; } if( *p_uint32_src != *p_uint32_dst) { os_printf("32bit test write one address fail @ 0x%08X\r\n!",(uint32_t)p_uint32_src); os_printf("==== src:%08X,dest:%08X\r\n!",*p_uint32_src, *p_uint32_dst); return -1; } p_uint32_src++; } os_printf("32bit test write one address pass!!\r\n"); } #endif return 0; } static void cli_mem_test(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) { uint32_t address, size; if (argc >= 3) { address = strtoll(argv[1], NULL, 16); size = strtoll(argv[2], NULL, 16); os_printf("memtest,address: 0x%08X size: 0x%08X\r\n", address, size); mem_test(address, size, 0); } else if (argc == 1) { // auto_mem_test(); } else { os_printf("memtest \r\n"); } } static void cli_mem_time(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) { uint32_t address, count, mode; if (argc >= 4) { address = strtoll(argv[1], NULL, 16); count = strtoll(argv[2], NULL, 16); mode = strtoll(argv[3], NULL, 16); } else { os_printf("memtime <0:write,1:read> \r\n"); return; } os_printf("memtime, address: 0x%08X count: 0x%08X, read=%d\r\n", address, count, mode); mem_time((uint32_t *)address, count, mode); } static void cli_memread_test(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) { uint32_t src, dest, size; if (argc >= 4) { src = strtoll(argv[1], NULL, 16); dest = strtoll(argv[2], NULL, 16); size = strtoll(argv[3], NULL, 16); os_printf("memread, src: 0x%08X dest: 0x%08X size: 0x%08X\r\n", src, dest, size); mem_read_test(src, dest, size); } else { os_printf("memread \r\n"); } } #if CONFIG_MPU void mpu_cfg(int index, uint32_t rbar, uint32_t rlar); void mpu_init(void); static void cli_mpucfg_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) { uint32_t index = 0, rbar = 0, rlar = 0; if (argc >= 4) { index = strtoll(argv[1], NULL, 10); rbar = strtoll(argv[2], NULL, 16); rlar = strtoll(argv[3], NULL, 16); } else { os_printf("mpucfg \r\n"); return; } os_printf("mpucfg, index:%d rbar: 0x%08X rlar: 0x%08X.\r\n", index, rbar, rlar); mpu_cfg(index, rbar, rlar); } void mpu_clear(uint32_t rnr); static void cli_mpuclr_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) { uint32_t rnr; if (argc >= 2) { rnr = strtoll(argv[1], NULL, 10); } else { os_printf("mpuclr .\r\n"); return; } os_printf("mpuclr, rnr:%d.\r\n", rnr); mpu_clear(rnr); } void mpu_dump(void); static void cli_mpudump_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) { mpu_dump(); } #endif //#if CONFIG_MPU #define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ') static void dump_hex(const uint8_t *ptr, size_t buflen) { unsigned char *buf = (unsigned char*)ptr; int i, j; for (i=0; i= 3) { address = strtoll(argv[1], NULL, 16); size = strtoll(argv[2], NULL, 16); os_printf("dump,address: 0x%08X size: 0x%08X\r\n", address, size); if (argc == 3) { dump_hex((const uint8_t *)address, size); } else { bk_mem_dump("cli", address, size); } } else { os_printf("Usage: memdump .\r\n"); return; } } #define MEM_CMD_CNT (sizeof(s_mem_commands) / sizeof(struct cli_command)) static const struct cli_command s_mem_commands[] = { {"memstack", "show stack memory usage", cli_memory_stack_cmd}, {"memshow", "show free heap", cli_memory_free_cmd}, {"memdump", " ", cli_memory_dump_cmd}, {"memset", " [ ... ]", cli_memory_set_cmd}, #if CONFIG_MEM_DEBUG && CONFIG_FREERTOS {"memleak", "[show memleak", cli_memory_leak_cmd}, #endif #if CONFIG_DEBUG_FIRMWARE {"memtest", " ", cli_mem_test}, {"memtest_r", " ", cli_memread_test}, {"memtest_wr", " ", cli_memtest_wr_cmd}, {"memtime", " <0:write,1:read>", cli_mem_time}, #if CONFIG_MPU {"mpucfg", " ", cli_mpucfg_cmd}, {"mpuclr", "", cli_mpuclr_cmd}, {"mpudump", "dump mpu config", cli_mpudump_cmd}, #endif //#if CONFIG_MPU #endif //#if CONFIG_DEBUG_FIRMWARE #if CONFIG_PSRAM_AS_SYS_MEMORY && CONFIG_FREERTOS {"psram_malloc", "psram_malloc ", cli_psram_malloc_cmd}, {"psram_free", "psram_free ", cli_psram_free_cmd}, {"psram_state", "psram_state", cli_psram_state_cmd}, #endif }; int cli_mem_init(void) { return cli_register_commands(s_mem_commands, MEM_CMD_CNT); }