前言
- 最近在看线程部分,发现,list_thread 不能查看各个线程的栈地址
- 熟悉了内核对象的操作,了解了RT-Thread 线程的结构体,可以写个测试代码查看线程栈地址
RT-Thread线程结构体
- RT-Thread 线程结构体相对较为复杂,包含较多的成员。
- 具体可以查看:<rtdef.h>中的:struct rt_thread 结构体
- 线程栈地址,就是rt_thread中的:
/* stack point and entry */
void *sp; /**< stack point */
void *entry; /**< entry */
void *parameter; /**< parameter */
void *stack_addr; /**< stack address */
rt_uint32_t stack_size; /**< stack size */
仿照list_thread编写测试代码
void dump_thread_ex(void)
{
rt_uint8_t index = 0;
rt_uint8_t obj_size = 0;
int thread_cnt = rt_object_get_length(RT_Object_Class_Thread);
rt_kprintf("%s: thread count = %d\n", __func__, thread_cnt);
char *thread_buf = rt_malloc(thread_cnt * 4);
if (thread_buf == RT_NULL)
{
rt_kprintf("%s: malloc failed!\n", __func__);
return;
}
rt_object_t* obj_pointers = (rt_object_t *)thread_buf;
obj_size = rt_object_get_pointers(RT_Object_Class_Thread, obj_pointers, thread_cnt);
rt_kprintf("object init : object size=%d\n", obj_size);
rt_kprintf("| name | pri | status | stack addr | stack size | used | remain tick | err |\n");
rt_kprintf("+------------+-----+--------+------------+------------+------+-------------+-----+\n");
for (index = 0; index < obj_size; index++)
{
rt_thread_t ptr_t = (rt_thread_t)obj_pointers[index];
if (obj_pointers[index] == RT_NULL)
{
break;
}
rt_uint8_t *ptr = (rt_uint8_t *)ptr_t->stack_addr;
while (*ptr == '#')
ptr ++;
rt_uint8_t stack_used_percent = (ptr_t->stack_size - ((rt_ubase_t) ptr - (rt_ubase_t) ptr_t->stack_addr))
* 100/ ptr_t->stack_size;
rt_kprintf("| %10s | %3d ", obj_pointers[index]->name, ptr_t->current_priority);
rt_uint8_t stat = (ptr_t->stat & RT_THREAD_STAT_MASK);
if (stat == RT_THREAD_READY)
rt_kprintf("| ready ");
else if (stat == RT_THREAD_SUSPEND)
rt_kprintf("| suspend");
else if (stat == RT_THREAD_INIT)
rt_kprintf("| init ");
else if (stat == RT_THREAD_CLOSE)
rt_kprintf("| close ");
else if (stat == RT_THREAD_RUNNING)
rt_kprintf("| running");
rt_kprintf("| 0x%08x | 0x%08x | %02d%% | 0x%08x | %03d |\n", ptr_t->stack_addr,
ptr_t->stack_size, stack_used_percent, ptr_t->remaining_tick, ptr_t->error);
}
rt_kprintf("+------------+-----+--------+------------+------------+------+-------------+-----+\n");
rt_free(thread_buf);
}
MSH_CMD_EXPORT(dump_thread_ex, list thread ex);
运行效果
msh />dump_thread_ex
dump_thread_ex: thread count = 5
object init : object size=5
| name | pri | flag | type | stack addr | stack size | used | remain tick |
+------------+-----+------+------+------------+------------+------+-------------+
| tshell | 20 | 0 | 0x01 | 0x20008a70 | 0x00001000 | 07% | 0x00000008 |
| usbd | 8 | 0 | 0x81 | 0x20002714 | 0x00001000 | 04% | 0x00000014 |
| ulog_async | 30 | 0 | 0x01 | 0x20005e98 | 0x00001000 | 34% | 0x00000009 |
| alarmsvc | 10 | 0 | 0x01 | 0x20004c80 | 0x00000800 | 07% | 0x00000005 |
| tidle0 | 31 | 0 | 0x81 | 0x20001c24 | 0x00000800 | 06% | 0x00000006 |
+------------+-----+------+------+------------+------------+------+-------------+
msh />list_th
list_thread
msh />list_thread
thread pri status sp stack size max used left tick error
---------------- --- ------- ---------- ---------- ------ ---------- ---
tshell 20 running 0x0000013c 0x00001000 12% 0x00000009 000
usbd 8 suspend 0x000000a8 0x00001000 04% 0x00000014 000
ulog_async 30 suspend 0x0000007c 0x00001000 34% 0x0000000b 000
alarmsvc 10 suspend 0x0000009c 0x00000800 07% 0x00000005 000
tidle0 31 ready 0x00000078 0x00000800 06% 0x00000012 000
msh />
- 了解线程栈,明白线程栈地址的分配,可以用于调试排查内存溢出等错误。
总结
- 需要继续研究RT-Thread 线程的结构与操作方法
- 通过内核对象,了解线程栈的查看方法
- 熟悉RT-Thread 内核对象的查看方法,如list_device