• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# coding:utf-8
3# Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import sys,string,re,os
17from ctypes import *
18from parse_basic import *
19from auto_class import *
20from config import *
21
22OS_TASK_STATUS_UNUSED = 0x0001
23OS_TASK_STATUS_SUSPEND = 0x0002
24OS_TASK_STATUS_READY = 0x0004
25OS_TASK_STATUS_PEND = 0x0008
26OS_TASK_STATUS_RUNNING = 0x0010
27OS_TASK_STATUS_DELAY = 0x0020
28OS_TASK_STATUS_TIMEOUT = 0x0040
29OS_TASK_STATUS_PEND_TIME = 0x0080
30OS_TASK_FLAG_DETACHED = 0x0001
31OS_TASK_FLAG_SYSTEM = 0x0002
32OS_SWTMR_STATUS_UNUSED = 0
33OS_SWTMR_STATUS_DELETING =1
34OS_SWTMR_STATUS_CREATED=2
35OS_SWTMR_STATUS_TICKING=3
36#ctypes.addressof(parameter) - ctypes.addressof(parent_structure)
37
38
39def _los_List_get_all_node(list_addr):
40    node_list=[]
41    node=parse_memory_2_class(list_addr,LOS_DL_LIST,sizeof(LOS_DL_LIST))
42    if node:
43        while node.pstNext!=list_addr:
44            node_list.append(node.pstNext)
45            node = parse_memory_2_class(node.pstNext,LOS_DL_LIST,sizeof(LOS_DL_LIST))
46    return (DEFINE_SUCCESS,node_list)
47
48def _addr_in_2_function_name(addr):
49    name=parse_addr_in_2_function_name(addr)
50    if name==None:
51        return hex(addr)
52    else:
53        return name
54
55class _PhaseLiteosCtrl:
56    def __init__(self):
57        self.core=None
58        self.info_fd = sys.__stdout__
59        self.task_cnt=None
60        self.tcb_array = []
61        self.ext_task_list=[]
62
63        self.heap_start = None
64        self.heap_end = None
65        self.heap_head = None
66        self.queue_cnt = LOSCFG_BASE_IPC_QUEUE_LIMIT
67        self.queue_array=[]
68        self.queue_ext_info=[]
69        self.timer_cnt = LOSCFG_BASE_CORE_SWTMR_LIMIT
70        self.timer_array=[]
71        self.timer_ext_info=[]
72        self.sem_cnt=LOSCFG_BASE_IPC_SEM_LIMIT
73        self.sem_array=[]
74        self.sem_ext_info=[]
75
76        self.excInfo=None
77
78        self.isr_ext_info=None
79        self.version=None
80
81    class _ExtPercpu:
82        def __init__(self):
83            self.handle_addr = None
84            self.per_cpu=None
85            self.g_tickCount=None
86            self.g_sysClock=None
87            self.g_tickPerSecond=None
88            self.g_cycle2NsScale=None
89            self.task_wait_addr=[]
90            self.timer_wait_addr=[]
91            self.g_intCount=None
92
93    class _ExtTaskInfo:
94        def __init__(self):
95            self.handle_addr=None
96            self.pend_addr=None
97            self.name='unknown'
98            self.buttom=0
99            self.peek_used=0
100            self.over=0
101            self.status_str=None
102            self.enter_name = 'unknown'
103            self.task_context = None
104            self.take_sem = None
105
106    class _ExtTimerInfo:
107        def __init__(self):
108            self.handle_addr=None
109            self.func_name=None
110
111    class _ExtSemInfo:
112        def __init__(self):
113            self.handle_addr=None
114            self.pend_task_list=[]
115
116    class _ExtQueueInfo:
117        def __init__(self):
118            self.handle_addr=None
119            self.pend_read_task_list = []
120            self.pend_write_task_list =[]
121
122    class ExtIsrInfo:
123        def __init__(self):
124            self.isr_cnt = LOSCFG_PLATFORM_HWI_LIMIT
125            self.g_hwiForm=None
126
127    def make_isr_info(self):
128        self.isr_ext_info = self.ExtIsrInfo()
129        addr = parse_get_symbol_addr('g_hwiForm')
130        if self.version == 207:
131            self.isr_ext_info.g_hwiForm = parse_memory_2_class(addr,HwiHandleInfo*self.isr_ext_info.isr_cnt,sizeof(HwiHandleInfo*self.isr_ext_info.isr_cnt))
132        elif self.version == 208:
133            self.isr_ext_info.g_hwiForm = parse_memory_2_class(addr,HwiHandleInfo*self.isr_ext_info.isr_cnt,sizeof(HwiHandleInfo*self.isr_ext_info.isr_cnt))
134
135    def print_isr_info(self):
136        print("\r\n--------------------content of 中断信息:--------------------",file=self.info_fd)
137        if self.version == 207:
138            for hwi in self.isr_ext_info.g_hwiForm:
139                if hwi.hook!=0 or hwi.respCount!=0:
140                    print("%s[0x%x][call_cnt=%d]"%(_addr_in_2_function_name(hwi.hook),hwi.hook,hwi.respCount),file=self.info_fd)
141        elif self.version == 208:
142            for hwi in self.isr_ext_info.g_hwiForm:
143                if hwi.hook!=0 or hwi.respCount!=0:
144                    print("%s[0x%x][call_cnt=%d]"%(_addr_in_2_function_name(hwi.hook),hwi.hook,hwi.respCount),file=self.info_fd)
145
146    def make_per_cpu_info(self):
147        self.core=self._ExtPercpu()
148        self.core.handle_addr = parse_get_symbol_addr('g_percpu')
149        self.core.per_cpu = parse_memory_2_class(self.core.handle_addr,Percpu,sizeof(Percpu))
150
151        addr = parse_get_symbol_addr('g_tickCount')
152        if addr:
153            obj=parse_memory_2_class(addr,c_ulonglong,sizeof(c_ulonglong))
154            self.core.g_tickCount=obj.value
155
156        addr = parse_get_symbol_addr('g_sysClock')
157        if addr:
158            obj=parse_memory_2_class(addr,c_uint,sizeof(c_uint))
159            self.core.g_sysClock=obj.value
160
161        addr = parse_get_symbol_addr('g_intCount')
162        if addr:
163            obj=parse_memory_2_class(addr,c_uint,sizeof(c_uint))
164            self.core.g_intCount=obj.value
165
166        addr = parse_get_symbol_addr('g_tickPerSecond')
167        if addr:
168            obj=parse_memory_2_class(addr,c_uint,sizeof(c_uint))
169            self.core.g_tickPerSecond=obj.value
170
171        addr = parse_get_symbol_addr('g_cycle2NsScale')
172        if addr:
173            obj=parse_memory_2_class(addr,c_double,sizeof(c_double))
174            self.core.g_cycle2NsScale=obj.value
175        (ret,self.core.task_wait_addr) = _los_List_get_all_node(self.core.per_cpu.taskSortLink.sortLink)
176
177        (ret,self.core.timer_wait_addr) = _los_List_get_all_node(self.core.per_cpu.swtmrSortLink.sortLink)
178
179    def print_per_cpu_info(self):
180        print("\r\n--------------------content of 调度信息汇总:--------------------",file=self.info_fd)
181        print("说明:taskLockCnt锁任务嵌套次数",file=self.info_fd)
182        if self.core.g_cycle2NsScale:
183            print("g_tickCount=%ull,g_sysClock=%u,g_tickPerSecond=%u,g_cycle2NsScale=%f"%(self.core.g_tickCount,self.core.g_sysClock,self.core.g_tickPerSecond,self.core.g_cycle2NsScale),file=self.info_fd)
184        else:
185            print("g_tickCount=%ull,g_sysClock=%u,g_tickPerSecond=%u"%(self.core.g_tickCount,self.core.g_sysClock,self.core.g_tickPerSecond),file=self.info_fd)
186
187        uapi_print_ctypes_obj('schedule',self.core.per_cpu,self.info_fd)
188
189        delay_tick=0
190        for x in self.core.task_wait_addr:
191            x = x-ctype_member_offset('sortList.sortLinkNode',LosTaskCB)
192            i=0
193            while i< self.task_cnt:
194                tcb=self.tcb_array[i]
195                ext_info=self.ext_task_list[i]
196                if ext_info.handle_addr==x:
197                    delay_tick=delay_tick+tcb.sortList.idxRollNum
198                    print("任务等待剩余时间:%s[%d][剩余时间 delay=%d tick][idxRollNum=%d]"%(ext_info.name,tcb.taskId,delay_tick,tcb.sortList.idxRollNum),file=self.info_fd)
199                i=i+1
200
201        delay_tick=0
202        for x in self.core.timer_wait_addr:
203            x = x-ctype_member_offset('sortList.sortLinkNode',LosSwtmrCB)
204            i=0
205            while i< self.timer_cnt:
206                timer=self.timer_array[i]
207                ext_info=self.timer_ext_info[i]
208                if ext_info.handle_addr==x:
209                    delay_tick=delay_tick+timer.sortList.idxRollNum
210                    print("定时器到期剩余时间:%s[%d][剩余时间=%d tick][idxRollNum=%d]"%(ext_info.func_name,timer.timerId,delay_tick,timer.sortList.idxRollNum),file=self.info_fd)
211                i=i+1
212
213    def make_task_info(self):
214        addr = parse_get_symbol_addr('g_taskMaxNum')
215        obj=parse_memory_2_class(addr,c_uint,4)
216        self.task_cnt = obj.value
217
218        addr = parse_get_symbol_addr('g_osTaskCBArray')
219        obj=parse_memory_2_class(addr,c_uint,4)
220        addr=obj.value
221        i=0
222        while i < self.task_cnt:
223            ext_info = self._ExtTaskInfo()
224            obj=parse_memory_2_class(addr,LosTaskCB,sizeof(LosTaskCB))
225            self.tcb_array.append(obj)
226            self.ext_task_list.append(ext_info)
227            ext_info.handle_addr=addr
228            ext_info.pend_addr = ext_info.handle_addr+ctype_member_offset('pendList',LosTaskCB)
229            addr=addr+sizeof(LosTaskCB)
230            i=i+1
231        self._make_task_extra_info()
232
233    def _task_status_2_string(self,status):
234        str=''
235        if (status&OS_TASK_STATUS_UNUSED):
236            str=str+"unused,"
237        if (status&OS_TASK_STATUS_RUNNING):
238            str=str+'runing,'
239        if (status&OS_TASK_STATUS_READY):
240            str=str+'ready,'
241        if (status&OS_TASK_STATUS_SUSPEND):
242            str=str+'suspend,'
243        if (status&OS_TASK_STATUS_PEND):
244            str=str+'pend,'
245        if (status&OS_TASK_STATUS_DELAY):
246            str=str+'delay,'
247        if (status&OS_TASK_STATUS_TIMEOUT):
248            str=str+'timeout,'
249        if (status&OS_TASK_STATUS_PEND_TIME):
250            str=str+'pendtime,'
251        return str
252
253    def _make_task_extra_info(self):
254        i=0
255        while i < self.task_cnt:
256            tcb = self.tcb_array[i]
257            ext_info=self.ext_task_list[i]
258            if tcb.taskStatus & OS_TASK_STATUS_UNUSED: #未使用任务返回
259                i=i+1
260                continue;
261
262            ext_info.buttom = tcb.topOfStack+tcb.stackSize #计算栈buttom
263            ext_info.status_str = self._task_status_2_string(tcb.taskStatus)
264            if tcb.taskSem!=0:
265                ext_info.take_sem = parse_memory_2_class(tcb.taskSem,LosSemCB,sizeof(LosSemCB))
266
267            #生成taskname
268            addr=tcb.taskName
269            str = parse_memory_2_string(addr,32)
270            if str!=None:
271                ext_info.name=str
272
273            #判断栈是否溢出
274            obj = parse_memory_2_class(tcb.topOfStack,c_uint,sizeof(c_uint))
275            if obj.value==0xCCCCCCCC:
276                ext_info.over=0
277            else:
278                ext_info.over=1
279
280            #计算栈峰值
281            addr = tcb.topOfStack+4
282            while addr < ext_info.buttom:
283                obj = parse_memory_2_class(addr,c_uint,sizeof(c_uint))
284                if obj.value != 0xCACACACA:
285                    break
286                addr+=4
287            ext_info.peek_used = ext_info.buttom-addr
288
289            enter_name=parse_addr_2_function_name(tcb.taskEntry)
290            if enter_name!=None:
291                ext_info.enter_name = enter_name
292            if self.version == 207:
293                ext_info.task_context=parse_memory_2_class(tcb.stackPointer,TaskContext,sizeof(TaskContext))
294            elif self.version == 208:
295                ext_info.task_context=parse_memory_2_class(tcb.stackPointer,TaskContext,sizeof(TaskContext))
296            else:
297                ext_info.task_context=parse_memory_2_class(tcb.stackPointer,td_u32,sizeof(td_u32))
298            i=i+1
299
300    def print_task_short_info(self):
301        print("\r\n--------------------content of 任务信息摘要:--------------------",file=self.info_fd)
302        print('%4s|%20s|%4s|%10s|%10s|%s|%10s|%10s|%10s|%4s|%15s|'%('id','task_name','pri','stackSize','topOfStack','ButtomOfStack','sp','cur_used','peak_used','ovf','status'),file=self.info_fd)
303        i=0
304        while i < self.task_cnt:
305            tcb = self.tcb_array[i]
306            ext_info = self.ext_task_list[i]
307            if not tcb.taskStatus & OS_TASK_STATUS_UNUSED:
308                print('%4d|%20s|%4d|0x%08x|0x%08x|0x%08x   |0x%08x|0x%08x|0x%08x|%4d|%15s|'
309                    %(i,ext_info.name,tcb.priority,tcb.stackSize,tcb.topOfStack,ext_info.buttom,tcb.stackPointer,0,ext_info.peek_used,ext_info.over,ext_info.status_str),file=self.info_fd)
310            i=i+1
311
312    def print_task_detail_info(self):
313        print("\r\n--------------------content of 任务详细信息:--------------------",file=self.info_fd)
314        print("说明:tcb任务控制块信息,context:任务上下文的寄存器信息,backtrace 栈回溯",file=self.info_fd)
315        i=0
316        while i < self.task_cnt:
317            print('',file=self.info_fd)
318            tcb = self.tcb_array[i]
319            uapi_print_ctypes_obj('tcb',tcb,self.info_fd)
320            ext_info = self.ext_task_list[i]
321            i=i+1
322            if tcb.taskStatus & OS_TASK_STATUS_UNUSED:
323                continue
324            #打印寄存器信息
325            print("[TASK]%s 寄存器:"%(ext_info.name),file=self.info_fd)
326            uapi_print_ctypes_obj('context',ext_info.task_context,self.info_fd)
327
328            #打印back_trace
329            print("[TASK]%s 栈回溯:"%(ext_info.name),file=self.info_fd)
330            if self.version == 207:
331                sp = tcb.stackPointer+sizeof(TaskContext)
332            elif self.version == 208:
333                sp = tcb.stackPointer+sizeof(TaskContext)
334            else:
335                sp = tcb.stackPointer
336            self.stack_back_trace(sp,tcb.topOfStack + tcb.stackSize)
337            print("[TASK]%s 其它状态:"%(ext_info.name),file=self.info_fd)
338            if ext_info.take_sem:
339                print("[waitting_sem][id=0x%08x]"%(ext_info.take_sem.semId),file=self.info_fd)
340
341    def make_heap_info(self):
342        addr = parse_get_symbol_addr('m_aucSysMem0')
343        obj=parse_memory_2_class(addr,c_uint,4)
344        self.heap_start=obj.value
345        if self.version == 207:
346            self.heap_head=parse_memory_2_class(self.heap_start,LosMemPoolInfo,sizeof(LosMemPoolInfo))
347            if self.heap_head:
348                self.heap_end = self.heap_start + self.heap_head.size
349        elif self.version == 208:
350            self.heap_head=parse_memory_2_class(self.heap_start,LosMemPoolInfo,sizeof(LosMemPoolInfo))
351            if self.heap_head:
352                self.heap_end = self.heap_start + self.heap_head.size
353
354
355    def print_heap_info(self):
356        print("--------------------content of 内存堆信息:--------------------",file=self.info_fd)
357        self.print_heap_head_info()
358        self.print_heap_from_head()
359        self.print_heap_from_tail()
360
361    def print_heap_head_info(self):
362        pass
363
364    def print_heap_from_head(self):
365        print("从头遍历内存池:",file=self.info_fd)
366        print("说明:node内存节点地址,usr用户空间地址(申请对齐内存场景不准),size内存大小,used是否占用",file=self.info_fd)
367        if self.heap_head:
368            addr = self.heap_head.head
369            while addr >= self.heap_start and addr <= self.heap_end:
370                node = parse_memory_2_class(addr,LosHeapNode,sizeof(LosHeapNode))
371                if(node.size==0):
372                    break;
373                str="[node=0x%x][usr=0x%x][prev=0x%x][size=0x%x][used=%d]"%(addr,addr+8,node.prev,node.size,node.used)
374                if hasattr(LosHeapNode,'lr'):
375                    i=0
376                    while i< sizeof(node.lr)/sizeof(c_uint):
377                        str="%s[%s][0x%x]"%(str,_addr_in_2_function_name(node.lr[i]),node.lr[i])
378                        i=i+1
379                print(str,file=self.info_fd)
380                addr=addr+sizeof(LosHeapNode)+node.size
381
382    def print_heap_from_tail(self):
383        print("从尾遍历内存池:",file=self.info_fd)
384        print("说明:node内存节点地址,usr用户空间地址(申请对齐内存场景不准),size内存大小,used是否占用",file=self.info_fd)
385        if self.heap_head:
386            addr = self.heap_head.tail
387            while addr >= self.heap_start and addr <= self.heap_end:
388                node = parse_memory_2_class(addr,LosHeapNode,sizeof(LosHeapNode))
389                str="[node][addr=0x%x][usr=0x%x][prev=0x%x][size=0x%x][used=%d]"%(addr,addr+8,node.prev,node.size,node.used)
390                print(str,file=self.info_fd)
391                if addr==self.heap_head.head:
392                    break
393                addr=node.prev
394
395    def make_queue_info(self):
396        addr = parse_get_u32_symbol_val('g_osAllQueue')
397        i=0
398        while i< self.queue_cnt:
399            ext_info=self._ExtQueueInfo()
400            obj=parse_memory_2_class(addr,LosQueueCB,sizeof(LosQueueCB))
401            ext_info.handle_addr=addr
402            self.queue_array.append(obj)
403            self.queue_ext_info.append(ext_info)
404            addr=addr+sizeof(LosQueueCB)
405            i=i+1
406        self._make_queue_ext_info()
407
408    def _make_queue_ext_info(self):
409        i=0
410        while i< self.queue_cnt:
411            queue=self.queue_array[i]
412            ext_info=self.queue_ext_info[i]
413            if queue and queue.queueState==1: #used
414                if self.version == 207:
415                    (ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB))
416                elif self.version == 208:
417                    (ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB))
418                else:
419                    (ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB) + 4)
420                for node_addr in addr_list:
421                    ext_info.pend_read_task_list.append(node_addr)
422                if self.version == 207:
423                    (ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB)+sizeof(LOS_DL_LIST))
424                elif self.version == 208:
425                    (ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB)+sizeof(LOS_DL_LIST))
426                else:
427                    (ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('readWriteList',LosQueueCB) + 4 + sizeof(LOS_DL_LIST))
428                for node_addr in addr_list:
429                    ext_info.pend_write_task_list.append(node_addr)
430            i=i+1
431
432    def print_queue_info(self):
433        print("\r\n--------------------content of 消息队列信息:--------------------",file=self.info_fd)
434        print("说明:queueHandle队列的内存空间,queueLen队列长度,queueSize单个节点大小,queueId队列id,readWriteableCnt[0]当前队列中有几个数据,readWriteableCnt[1]当前队列中有几个剩余空间",file=self.info_fd)
435        print("",file=self.info_fd)
436        i=0
437        while i< self.queue_cnt:
438            queue=self.queue_array[i]
439            ext_info=self.queue_ext_info[i]
440            if queue.queueState==1:
441                uapi_print_ctypes_obj('queue',queue,self.info_fd)
442                list=self.get_pending_task(ext_info.pend_read_task_list)
443                print("等待读该消息队列的任务ID:",list,file=self.info_fd)
444                list=self.get_pending_task(ext_info.pend_write_task_list)
445                print("等待写该消息队列的任务ID:",list,file=self.info_fd)
446                print("",file=self.info_fd)
447            i=i+1
448
449    def _make_timer_ext_info(self):
450        i=0
451        while i< self.timer_cnt:
452            timer=self.timer_array[i]
453            ext_info=self.timer_ext_info[i]
454            if timer.state==OS_SWTMR_STATUS_UNUSED or timer.state==OS_SWTMR_STATUS_DELETING:
455                i=i+1
456                continue
457            ext_info.func_name = parse_addr_2_function_name(timer.handler)
458            i=i+1
459
460    def make_timer_info(self):
461        addr = parse_get_u32_symbol_val('g_osSwtmrCBArray')
462        i=0
463        while i< self.timer_cnt:
464            obj=parse_memory_2_class(addr,LosSwtmrCB,sizeof(LosSwtmrCB))
465            ext_info=self._ExtTimerInfo()
466            self.timer_ext_info.append(ext_info)
467            self.timer_array.append(obj)
468            ext_info.handle_addr=addr
469
470            addr=addr+sizeof(LosSwtmrCB)
471            i=i+1
472        self._make_timer_ext_info()
473
474    def print_timer_info(self):
475        print("--------------------content of 定时器信息:--------------------",file=self.info_fd)
476        print("说明:timer_id定时器id,handler回调函数的地址(已解析),state(0:未使用 1:删除 2:创建 3:执行中),mode(1:周期 2:单次)",file=self.info_fd)
477        print("\t overrun周期性定时器执行次数,arg用户参数,inProcess到期已添加到待执行队列",file=self.info_fd)
478        print('',file=self.info_fd)
479        i=0
480        while i< self.timer_cnt:
481            timer=self.timer_array[i]
482            ext_info=self.timer_ext_info[i]
483            if timer.state==OS_SWTMR_STATUS_UNUSED or timer.state==OS_SWTMR_STATUS_DELETING:
484                i=i+1
485                continue
486            print("timer_id=%d %s[0x%x]"%(timer.timerId,ext_info.func_name,timer.handler),file=self.info_fd)
487            uapi_print_ctypes_obj('timer',timer,self.info_fd)
488            print('',file=self.info_fd)
489            i=i+1
490
491    def _make_sem_extra_info(self):
492        i=0
493        while i< self.sem_cnt:
494            sem=self.sem_array[i]
495            ext_info=self.sem_ext_info[i]
496            if sem.semStat==1: #used
497                (ret,addr_list)=_los_List_get_all_node(ext_info.handle_addr + ctype_member_offset('semList',LosSemCB))
498                for node_addr in addr_list:
499                    ext_info.pend_task_list.append(node_addr)
500            i=i+1
501
502    def make_sem_info(self):
503        addr = parse_get_u32_symbol_val('g_osAllSem')
504        i=0
505        while i< self.sem_cnt:
506            ext_info=self._ExtSemInfo()
507            obj=parse_memory_2_class(addr,LosSemCB,sizeof(LosSemCB))
508            ext_info.handle_addr=addr
509            self.sem_array.append(obj)
510            self.sem_ext_info.append(ext_info)
511            addr=addr+sizeof(LosSemCB)
512            i=i+1
513        self._make_sem_extra_info()
514
515    def get_pending_task(self,addr_list):
516        list=[]
517        for addr in addr_list:
518            i=0
519            while i < self.task_cnt:
520                ext_task = self.ext_task_list[i]
521                tcb = self.tcb_array[i]
522                if addr== ext_task.pend_addr:
523                    list.append(tcb.taskId)
524                i=i+1
525        return list
526
527    def print_sem_info(self):
528        print("--------------------content of 信号量:--------------------",file=self.info_fd)
529        print("说明:semType(0:计数信号量 1:互斥信号量),semCount剩余信号量个数",file=self.info_fd)
530        print("",file=self.info_fd)
531        i=0
532        while i< self.sem_cnt:
533            sem=self.sem_array[i]
534            ext_info=self.sem_ext_info[i]
535            if sem.semStat:
536                uapi_print_ctypes_obj('sem',sem,self.info_fd)
537                list=self.get_pending_task(ext_info.pend_task_list)
538                print("等待该信号量的任务ID:",list,file=self.info_fd)
539                print('',file=self.info_fd)
540            i=i+1
541
542    def make_crash_info(self):
543        addr = parse_get_symbol_addr('g_excInfo')
544        self.excInfo = parse_memory_2_class(addr,ExcInfo,sizeof(ExcInfo))
545
546    def print_crash_info(self):
547        print("--------------------content of 死机信息:--------------------",file=self.info_fd)
548        uapi_print_ctypes_obj('g_excInfo',self.excInfo,self.info_fd)
549        if self.excInfo.context!=0:
550            obj=parse_memory_2_class(self.excInfo.context,ExcContext,sizeof(ExcContext))
551            uapi_print_ctypes_obj('context',obj,self.info_fd)
552            if self.version == 207:
553                self.stack_back_trace(obj.taskContext.sp+sizeof(TaskContext),obj.taskContext.sp+0x1000)
554            elif self.version == 208:
555                self.stack_back_trace(obj.taskContext.sp+sizeof(TaskContext),obj.taskContext.sp+0x1000)
556            else:
557                self.stack_back_trace(obj.SP, obj.SP + 0x1000)
558
559
560
561    def stack_back_trace(self,start_addr,end_addr):
562        sp=start_addr
563        while sp < end_addr:
564            obj=parse_memory_2_class(sp,c_uint,sizeof(c_uint))
565            if obj:
566                name = parse_addr_in_2_function_name(obj.value-4)
567                if name:
568                    print("[BACK Trace][addr=0x%08x][val=0x%08x]%s"%(sp,obj.value,name),file=self.info_fd)
569                else:
570                    pass
571                    #print("[BACK Trace][addr=0x%08x][val=0x%08x]"%(sp,obj.value),file=self.info_fd)
572
573            sp=sp+4
574
575_g_parse_liteos_ctrl=_PhaseLiteosCtrl()
576def make_liteos_info():
577    try:
578        _g_parse_liteos_ctrl.make_per_cpu_info()
579    except:
580        print("[EXCEPTION]make_per_cpu_info fail.")
581    try:
582        _g_parse_liteos_ctrl.make_task_info()
583    except:
584        print("[EXCEPTION]make_task_info fail.")
585    if _g_parse_liteos_ctrl.version != 208:
586        try:
587            _g_parse_liteos_ctrl.make_queue_info()
588        except:
589            print("[EXCEPTION]make_queue_info fail.")
590        try:
591            _g_parse_liteos_ctrl.make_heap_info()
592        except:
593            print("[EXCEPTION]make_heap_info fail.")
594        try:
595            _g_parse_liteos_ctrl.make_timer_info()
596        except:
597            print("[EXCEPTION]make_timer_info fail.")
598    try:
599        _g_parse_liteos_ctrl.make_sem_info()
600    except:
601        print("[EXCEPTION]make_sem_info fail.")
602    try:
603        _g_parse_liteos_ctrl.make_crash_info()
604    except:
605        print("[EXCEPTION]make_crash_info fail.")
606    try:
607        _g_parse_liteos_ctrl.make_isr_info()
608    except:
609        print("[EXCEPTION]make_isr_info fail.")
610
611def print_liteos_info():
612    try:
613        _g_parse_liteos_ctrl.print_isr_info()
614    except:
615        print("[EXCEPTION]print_isr_info fail.")
616    try:
617        _g_parse_liteos_ctrl.print_per_cpu_info()
618    except:
619        print("[EXCEPTION]print_per_cpu_info fail.")
620    if _g_parse_liteos_ctrl.version != 208:
621        try:
622            _g_parse_liteos_ctrl.print_queue_info()
623        except:
624            print("[EXCEPTION]print_queue_info fail.")
625        try:
626            _g_parse_liteos_ctrl.print_timer_info()
627        except:
628            print("[EXCEPTION]print_timer_info fail.")
629        try:
630            _g_parse_liteos_ctrl.print_heap_info()
631        except:
632            print("[EXCEPTION]print_heap_info fail.")
633    try:
634        _g_parse_liteos_ctrl.print_sem_info()
635    except:
636        print("[EXCEPTION]print_sem_info fail.")
637    try:
638        _g_parse_liteos_ctrl.print_task_short_info()
639    except:
640        print("[EXCEPTION]print_task_short_info fail.")
641    try:
642        _g_parse_liteos_ctrl.print_task_detail_info()
643    except:
644        print("[EXCEPTION]print_task_detail_info fail.")
645    try:
646        _g_parse_liteos_ctrl.print_crash_info()
647    except:
648        print("[EXCEPTION]print_crash_info fail.")
649
650def parse_liteos206_info(log_fp):
651    _g_parse_liteos_ctrl.info_fd = log_fp
652    _g_parse_liteos_ctrl.version = 206
653    make_liteos_info()
654    print_liteos_info()
655
656def parse_liteos207_info(log_fp):
657    _g_parse_liteos_ctrl.info_fd = log_fp
658    _g_parse_liteos_ctrl.version = 207
659    make_liteos_info()
660    print_liteos_info()
661
662def parse_liteos208_info(log_fp):
663    _g_parse_liteos_ctrl.info_fd = log_fp
664    _g_parse_liteos_ctrl.version = 208
665    make_liteos_info()
666    print_liteos_info()
667
668'''
669context.mstatus(mcause)=0x80207800
670context.mepc=0x12530
671context.tp=0xcacacaca
672context.sp=0xcacacaca
673context.s11=0x4040404--未压栈(中断场景)
674context.s10=0x5050505--未压栈
675context.s9=0x6060606--未压栈
676context.s8=0x7070707--未压栈
677context.s7=0x8080808--未压栈
678context.s6=0x9090909--未压栈
679context.s5=0x80206088--未压栈
680context.s4=0x20008000--未压栈
681context.s3=0x80206080--未压栈
682context.s2=0x200079dc--未压栈
683context.s1=0x0--未压栈
684context.s0=0x20007a74--未压栈
685
686context.t6=0x4040404
687context.t5=0x5050505
688context.t4=0x6060606
689context.t3=0x7070707
690context.a7=0x8080808
691context.a6=0x9090909
692context.a5=0xa0a0a0a
693context.a4=0xb0b0b0b
694context.a3=0xc0c0c0c
695context.a2=0xd0d0d0d
696context.a1=0xe0e0e0e
697context.a0=0xf0f0f0f
698context.t2=0x10101010
699context.t1=0x11111111
700context.t0=0x12121212
701context.ra=0x13131313
702
703context.fs11=0x20202020--(进中断)未压栈
704context.fs10=0x21212121--未压栈
705context.fs9=0x22222222--未压栈
706context.fs8=0x23232323--未压栈
707context.fs7=0x24242424--未压栈
708context.fs6=0x25252525--未压栈
709context.fs5=0x26262626--未压栈
710context.fs4=0x27272727--未压栈
711context.fs3=0x28282828--未压栈
712context.fs2=0x29292929--未压栈
713context.fs1=0x2a2a2a2a--未压栈
714context.fs0=0x2b2b2b2b--未压栈
715
716context.ft11=0x20202020
717context.ft10=0x21212121
718context.ft9=0x22222222
719context.ft8=0x23232323
720context.fa7=0x24242424
721context.fa6=0x25252525
722context.fa5=0x26262626
723context.fa4=0x27272727
724context.fa3=0x28282828
725context.fa2=0x80206088
726context.fa1=0x20008000
727context.fa0=0x80206080
728context.ft7=0x20009000
729context.ft6=0x20007ad4
730context.ft5=0x20007ad4
731context.ft4=0x11f5a
732context.ft3=0x32
733context.ft2=0x20007ad4
734context.ft1=0x20007a70
735context.ft0=0x117a2
736context.fcsr=0x0
737context.reserved[0]=0x0
738context.reserved[1]=0x20007a74
739context.reserved[2]=0x12530
740
741
742typedef struct {
743    uint32_t      ccause;
744    uint32_t      mcause;
745    uint32_t      mtval;
746    uint32_t      gp;
747    TaskContext taskContext;
748} ExcContext;
749
750typedef struct {
751    uint16_t phase;           /**< Exception occurrence phase: 0 indicates that the exception occurs during
752                             *   initialization, 1 indicates that the exception occurs during task, 2
753                             *   indicates that the exception occurs during interrupt, and 3 indicates that
754                             *   the exception occurs during exception.
755                             */
756    uint16_t type;            /**< Type of exception, refer to no. 1-19 listed above for exceptions */
757    uint32_t faultAddr;       /**< A precise address access error indicates the error access address where
758                             *   the exception occurred.
759                             */
760    uint32_t thrdPid;         /**< An exception occurs in the interrupt, indicating the interrupt number. An
761                             *   exception occurs in the task, indicating the task id, or 0xffffffff if it
762                             *   occurs during initialization
763                             */
764    uint16_t nestCnt;         /**< The number of nested exceptions, currently only support the first time the
765                             *   exception into the implementation of the registered hook function
766                             */
767    uint16_t reserved;        /**< Reserved */
768    ExcContext *context; /**< The hardware context at which an exception to an automatic stack floating point
769                             *   register occurs
770                             */
771} ExcInfo;
772'''
773