
1. delete call osp_signal_init() 2. Test: 2.1 spu_case0_arm_case0_cpri: Pass 2.2 spu_case14_arm_case20_cpri: Pass 2.3 spu_case20_arm_case20_cpri: Pass 2.4 spu_case21_arm_case21_cpri: Pass 2.5 spu_case34_arm_case5: Pass 2.6 spu_case44_arm_case5: Pass 2.7 spu_case20_arm_case20_task_ok: Pass 2.8 spu_case20_arm_case20_task_ng: Pass
628 lines
13 KiB
C
628 lines
13 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
#include <termios.h>
|
|
|
|
#define _GNU_SOURCE
|
|
#include <dlfcn.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <stdarg.h>
|
|
#include <execinfo.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
|
|
|
|
#include "osp.h"
|
|
|
|
|
|
|
|
#define IOSIZE (32*1024*1024)
|
|
void *g_SemDeadFunc;
|
|
|
|
int32_t osp_signal_init(void);
|
|
|
|
uint32_t *gOspPrintLevel = NULL;
|
|
|
|
|
|
/*keep DbgOut with order !*/
|
|
void *g_DbgOutSem = 0;
|
|
|
|
char DbgBuf[MAX_DBGINFO_LEN] = {0};
|
|
static OSP_FUNCPTR gpfunc[DeadFuncNum] = {0};
|
|
|
|
|
|
|
|
int32_t osp_task_dbg_out_enable(uint32_t taskid)
|
|
{
|
|
gOspTask[taskid].dbg_out_is_enable = 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int32_t osp_task_dbg_out_disable(uint32_t taskid)
|
|
{
|
|
gOspTask[taskid].dbg_out_is_enable = 0;
|
|
return 0;
|
|
}
|
|
|
|
int32_t osp_task_dbg_out_enable_all(void)
|
|
{
|
|
int32_t i;
|
|
|
|
for (i = 0; i < OSP_MAX_TASK; i++)
|
|
{
|
|
if (gOspTask[i].Active)
|
|
{
|
|
osp_task_dbg_out_enable(i);
|
|
}
|
|
}
|
|
return OSP_OK;
|
|
}
|
|
|
|
int32_t osp_task_dbg_out_disable_all(void)
|
|
{
|
|
int32_t i;
|
|
|
|
for (i = 0; i < OSP_MAX_TASK; i++)
|
|
{
|
|
if (gOspTask[i].Active)
|
|
{
|
|
osp_task_dbg_out_disable(i);
|
|
}
|
|
}
|
|
return OSP_OK;
|
|
}
|
|
|
|
|
|
|
|
int32_t osp_task_dbg_is_log(uint32_t taskid)
|
|
{
|
|
return gOspTask[taskid].dbg_out2log_is_enable;
|
|
}
|
|
int32_t osp_task_dbg_out2log_disable_all(void)
|
|
{
|
|
int32_t i;
|
|
|
|
for (i = 0; i < OSP_MAX_TASK; i++)
|
|
{
|
|
if (gOspTask[i].Active)
|
|
{
|
|
osp_task_dbg_out2log_disable(i);
|
|
}
|
|
}
|
|
return OSP_OK;
|
|
|
|
}
|
|
int32_t osp_task_dbg_out2log_disable(uint32_t taskid)
|
|
{
|
|
gOspTask[taskid].dbg_out2log_is_enable = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
int32_t osp_task_dbg_out2log_enable_all(void)
|
|
{
|
|
int32_t i;
|
|
for (i = 0; i < OSP_MAX_TASK; i++)
|
|
{
|
|
if (!osp_task_is_shell(i))
|
|
osp_task_dbg_out2log_enable(i);
|
|
}
|
|
return OSP_OK;
|
|
|
|
}
|
|
|
|
int32_t osp_task_dbg_out2log_enable(uint32_t taskid)
|
|
{
|
|
gOspTask[taskid].dbg_out2log_is_enable = 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int32_t osp_task_dbg_out_is_enable(uint32_t taskid)
|
|
{
|
|
return gOspTask[taskid].dbg_out_is_enable;
|
|
}
|
|
|
|
|
|
void osp_local_shell_out_main(Osp_Msg_Head *pMsg)
|
|
{
|
|
|
|
|
|
if (osp_local_shell_task_is_reged())
|
|
{
|
|
osp_print(MSG_HEAD_TO_COMM(pMsg), MSG_DADA_LEN(pMsg));
|
|
}
|
|
|
|
//osp_net_shell_out(pMsg);
|
|
|
|
osp_free_msg(pMsg);
|
|
}
|
|
|
|
|
|
void osp_debug_out_set_level(int32_t level)
|
|
{
|
|
*gOspPrintLevel = level;
|
|
}
|
|
|
|
|
|
OSP_STATUS osp_debug_out(int32_t level, char *fmt,...)
|
|
{
|
|
va_list vl;
|
|
Osp_Msg_Head *pMsg;
|
|
int32_t buflen = 0;
|
|
|
|
if (!osp_is_init_done())
|
|
{
|
|
/*to makesure osp_debug_out can be useful anytime*/
|
|
char *pbuf = malloc(MAX_DBGINFO_LEN);
|
|
if (NULL != pbuf)
|
|
{
|
|
|
|
va_start(vl, fmt);
|
|
buflen = vsnprintf(pbuf + buflen, MAX_DBGINFO_LEN - buflen, fmt, vl);
|
|
va_end(vl);
|
|
printf("%s\n", pbuf);
|
|
free(pbuf);
|
|
}
|
|
return OSP_OK;
|
|
|
|
}
|
|
|
|
|
|
if ((NULL == gOspPrintLevel) && (*gOspPrintLevel < level))
|
|
return (OSP_ERROR);
|
|
if (!osp_task_dbg_out_is_enable(CURRENT_TASKID))
|
|
return (OSP_ERROR);
|
|
|
|
if (NULL == g_DbgOutSem)
|
|
{
|
|
return OSP_ERROR;
|
|
}
|
|
|
|
osp_sem_take(g_DbgOutSem, -1);
|
|
if ((osp_task_dbg_is_log(CURRENT_TASKID)) && (CMD_DEBUG_LEVEL != level))
|
|
{
|
|
char *pbuf = DbgBuf;
|
|
va_start(vl, fmt);
|
|
buflen = vsnprintf(pbuf, MAX_DBGINFO_LEN, fmt, vl);
|
|
va_end(vl);
|
|
pbuf[buflen] = '\0';
|
|
osp_dbg_log(pbuf, buflen);
|
|
osp_sem_give(g_DbgOutSem);
|
|
return OSP_OK;
|
|
}
|
|
|
|
pMsg = osp_alloc_msg_print_log();
|
|
if (NULL == pMsg)
|
|
{
|
|
/*to makesure osp_debug_out can be useful anytime*/
|
|
char *pbuf = DbgBuf;
|
|
|
|
va_start(vl, fmt);
|
|
buflen = vsnprintf(pbuf, MAX_DBGINFO_LEN, fmt, vl);
|
|
va_end(vl);
|
|
printf("%s", pbuf);
|
|
|
|
osp_sem_give(g_DbgOutSem);
|
|
return OSP_ERROR;
|
|
}
|
|
|
|
va_start(vl, fmt);
|
|
buflen = vsnprintf(MSG_HEAD_TO_COMM(pMsg), MAX_DBGINFO_LEN, fmt, vl);
|
|
va_end(vl);
|
|
|
|
|
|
|
|
|
|
pMsg->DstId = localshellout;
|
|
pMsg->SrcId = CURRENT_TASKID;
|
|
|
|
pMsg->MsgSize = buflen + MSG_HEAD_SIZE;
|
|
osp_send_msg(pMsg);
|
|
osp_sem_give(g_DbgOutSem);
|
|
|
|
return (OSP_OK);
|
|
}
|
|
OSP_STATUS osp_debug_out_with_time(int32_t level, char *fmt,...)
|
|
{
|
|
va_list vl;
|
|
Osp_Msg_Head *pMsg;
|
|
int32_t buflen = 0;
|
|
OSP_RTCTIME osptime;
|
|
|
|
|
|
|
|
if (!osp_is_init_done())
|
|
{
|
|
/*to makesure osp_debug_out can be useful anytime*/
|
|
char *pbuf = malloc(MAX_DBGINFO_LEN);
|
|
if (NULL != pbuf)
|
|
{
|
|
osp_get_rtc_time(&osptime);
|
|
|
|
buflen = snprintf((char *)pbuf, (size_t)(MAX_DBGINFO_LEN), \
|
|
"[%04d/%02d/%02d-%02d:%02d:%02d:%02d]", \
|
|
osptime.year, osptime.month, osptime.day, \
|
|
osptime.hour, osptime.minute, osptime.second, osptime.usecond);
|
|
|
|
va_start(vl, fmt);
|
|
buflen = vsnprintf(pbuf+buflen, MAX_DBGINFO_LEN-buflen, fmt, vl);
|
|
va_end(vl);
|
|
printf("%s", pbuf);
|
|
free(pbuf);
|
|
}
|
|
return OSP_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((gOspPrintLevel) && (*gOspPrintLevel < level))
|
|
{
|
|
return (OSP_ERROR);
|
|
}
|
|
if (!osp_task_dbg_out_is_enable(CURRENT_TASKID))
|
|
{
|
|
return (OSP_ERROR);
|
|
}
|
|
if (NULL == g_DbgOutSem)
|
|
{
|
|
return OSP_ERROR;
|
|
}
|
|
|
|
osp_sem_take(g_DbgOutSem, -1);
|
|
if (osp_task_dbg_is_log(CURRENT_TASKID))
|
|
{
|
|
char *pbuf = DbgBuf;
|
|
|
|
/*to makesure osp_debug_out_with_time can be useful anytime*/
|
|
|
|
|
|
osp_get_rtc_time(&osptime);
|
|
|
|
buflen = snprintf((char *)pbuf, (size_t)(MAX_DBGINFO_LEN), \
|
|
"[%04d/%02d/%02d-%02d:%02d:%02d:%02d]", \
|
|
osptime.year, osptime.month, osptime.day, \
|
|
osptime.hour, osptime.minute, osptime.second, osptime.usecond);
|
|
va_start(vl, fmt);
|
|
buflen += vsnprintf(pbuf+buflen, MAX_DBGINFO_LEN, fmt, vl);
|
|
va_end(vl);
|
|
pbuf[buflen] = '\0';
|
|
osp_dbg_log(pbuf, buflen);
|
|
|
|
|
|
osp_sem_give(g_DbgOutSem);
|
|
return OSP_OK;
|
|
|
|
}
|
|
|
|
pMsg = osp_alloc_msg_print_log();
|
|
if (NULL == pMsg)
|
|
{
|
|
|
|
/*to makesure osp_debug_out_with_time can be useful anytime*/
|
|
char *pbuf = DbgBuf;
|
|
|
|
osp_get_rtc_time(&osptime);
|
|
|
|
buflen = snprintf((char *)pbuf, (size_t)(MAX_DBGINFO_LEN), \
|
|
"[%04d/%02d/%02d-%02d:%02d:%02d:%02d]", \
|
|
osptime.year, osptime.month, osptime.day, \
|
|
osptime.hour, osptime.minute, osptime.second, osptime.usecond);
|
|
|
|
va_start(vl, fmt);
|
|
buflen = vsnprintf(pbuf + buflen, MAX_DBGINFO_LEN, fmt, vl);
|
|
va_end(vl);
|
|
printf("%s",pbuf);
|
|
|
|
|
|
osp_sem_give(g_DbgOutSem);
|
|
return OSP_OK;
|
|
}
|
|
|
|
|
|
osp_get_rtc_time(&osptime);
|
|
buflen = snprintf((char *)MSG_HEAD_TO_COMM(pMsg), (size_t)(MAX_DBGINFO_LEN), \
|
|
"[%04d/%02d/%02d-%02d:%02d:%02d:%02d]", \
|
|
osptime.year, osptime.month, osptime.day, \
|
|
osptime.hour, osptime.minute, osptime.second, osptime.usecond);
|
|
|
|
|
|
va_start(vl, fmt);
|
|
buflen += vsnprintf(MSG_HEAD_TO_COMM(pMsg) + buflen, MAX_DBGINFO_LEN - buflen, fmt, vl);
|
|
va_end(vl);
|
|
|
|
|
|
pMsg->DstId = localshellout;
|
|
pMsg->SrcId = CURRENT_TASKID;
|
|
|
|
pMsg->MsgSize = buflen + MSG_HEAD_SIZE;
|
|
osp_send_msg(pMsg);
|
|
|
|
osp_sem_give(g_DbgOutSem);
|
|
return (OSP_OK);
|
|
}
|
|
|
|
OSP_STATUS osp_print(char *pbuf, uint32_t len)
|
|
{
|
|
if ((NULL == pbuf) || (0 == len))
|
|
{
|
|
return OSP_ERROR;
|
|
}
|
|
printf("%s", pbuf);
|
|
fflush(stdout);
|
|
|
|
return OSP_OK;
|
|
}
|
|
|
|
int32_t osp_shell_dis_mem(int32_t num, uint64_t addr)
|
|
{
|
|
uint32_t *p = (uint32_t *)addr;
|
|
int32_t i;
|
|
char *pbuf;
|
|
int32_t len = 0;
|
|
|
|
if (NULL == p)
|
|
{
|
|
return -1;
|
|
}
|
|
if ((num * 4) > MAX_DBGINFO_LEN)
|
|
{
|
|
osp_debug_out(CMD_DEBUG_LEVEL, "mux display memsize : %d\r\n", (MAX_DBGINFO_LEN / 4));
|
|
return -1;
|
|
}
|
|
|
|
pbuf = malloc(MAX_DBGINFO_LEN);
|
|
if (NULL == pbuf)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < num; i++)
|
|
{
|
|
if ((i & 0x3) == 0)
|
|
len += sprintf(pbuf + len, "%p : \t", p+i);
|
|
len += sprintf(pbuf + len, "0x%08x\t", p[i]);
|
|
|
|
if ((i & 0x3) == 0x3)
|
|
len += sprintf(pbuf + len, "%c", '\n');
|
|
}
|
|
pbuf[len] = '\0';
|
|
osp_debug_out(CMD_DEBUG_LEVEL, "%s", pbuf);
|
|
free(pbuf);
|
|
|
|
return OSP_OK;
|
|
}
|
|
|
|
|
|
int32_t osp_shell_set_mem(int32_t val, uint64_t addr)
|
|
{
|
|
uint32_t *p = (uint32_t *)addr;
|
|
if (NULL == p)
|
|
return -1;
|
|
*p = val;
|
|
|
|
return OSP_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t osp_local_shell_in_main()
|
|
{
|
|
return OSP_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void osp_debug_init(void)
|
|
{
|
|
|
|
g_DbgOutSem = osp_get_init_mem(sizeof(lx_sem_t));
|
|
gOspPrintLevel = (uint32_t *)osp_get_init_mem(sizeof(uint32_t));
|
|
|
|
|
|
if (0 == g_ProcessId)
|
|
{
|
|
*gOspPrintLevel = DBG_DEBUG_LEVEL;
|
|
osp_semsm_create(g_DbgOutSem);
|
|
}
|
|
//osp_signal_init();
|
|
|
|
}
|
|
|
|
void osp_signal_action_trace(int32_t nr, siginfo_t *info, void *void_context)
|
|
{
|
|
void *trace[100] = {0};
|
|
int32_t trace_size = 0;
|
|
char **messages = NULL;
|
|
int32_t i;
|
|
|
|
trace_size = backtrace(trace, 100);
|
|
messages = (char **)backtrace_symbols(trace, trace_size);
|
|
|
|
for (i = 0; i < trace_size; ++i)
|
|
{
|
|
osp_debug_out(CMD_DEBUG_LEVEL, "[bt] %s\n", messages[i]);
|
|
}
|
|
return;
|
|
}
|
|
void osp_signal_action_suspend(int32_t nr, siginfo_t *info, void *void_context)
|
|
{
|
|
sigset_t SigSet;
|
|
int32_t Sig;
|
|
|
|
(void)sigemptyset(&SigSet);
|
|
(void)sigaddset(&SigSet,OSP_TASK_SIGNAL_RESUME);
|
|
// osp_debug_out(CMD_DEBUG_LEVEL, "task:%d suspend\n", CURRENT_TASKID);
|
|
TASK_STATE(CURRENT_TASKID)= TASK_SUSPEND;
|
|
(void)sigwait(&SigSet, &Sig);
|
|
TASK_STATE(CURRENT_TASKID)= TASK_RUNNING;
|
|
// osp_debug_out(CMD_DEBUG_LEVEL, "task:%d resume\n", CURRENT_TASKID);
|
|
|
|
}
|
|
void osp_signal_action_resume(int32_t nr, siginfo_t *info, void *void_context)
|
|
{
|
|
}
|
|
void osp_signal_action_except(int32_t nr, siginfo_t *info, void *void_context)
|
|
{
|
|
osp_assert(0);
|
|
}
|
|
|
|
|
|
int32_t osp_signal_init(void)
|
|
{
|
|
|
|
struct sigaction act;
|
|
|
|
act.sa_sigaction = &osp_signal_action_trace;
|
|
act.sa_flags = SA_SIGINFO;
|
|
|
|
if (sigaction(OSP_TASK_SIGNAL_TRACE, &act, NULL) < 0) {
|
|
osp_assert(0);
|
|
}
|
|
|
|
act.sa_sigaction = &osp_signal_action_suspend;
|
|
act.sa_flags = SA_SIGINFO;
|
|
|
|
if (sigaction(OSP_TASK_SIGNAL_SUSPEND, &act, NULL) < 0) {
|
|
osp_assert(0);
|
|
}
|
|
act.sa_sigaction = &osp_signal_action_resume;
|
|
act.sa_flags = SA_SIGINFO;
|
|
|
|
if (sigaction(OSP_TASK_SIGNAL_RESUME, &act, NULL) < 0) {
|
|
osp_assert(0);
|
|
}
|
|
|
|
act.sa_sigaction = &osp_signal_action_except ;
|
|
act.sa_flags = SA_SIGINFO;
|
|
|
|
if (sigaction(OSP_TASK_SIGNAL_SEGV, &act, NULL) < 0) {
|
|
osp_assert(0);
|
|
}
|
|
|
|
act.sa_sigaction = &osp_signal_action_except ;
|
|
act.sa_flags = SA_SIGINFO;
|
|
|
|
if (sigaction(OSP_TASK_SIGNAL_BUSSERR, &act, NULL) < 0) {
|
|
osp_assert(0);
|
|
}
|
|
|
|
signal(SIGTTOU, SIG_IGN);
|
|
g_SemDeadFunc = osp_semm_create();
|
|
|
|
return OSP_OK;
|
|
|
|
}
|
|
int32_t osp_trace_task(uint32_t Id)
|
|
{
|
|
if (gOspTask[Id].PhreadId)
|
|
{
|
|
(void)pthread_kill(TASK_THREADID(Id),OSP_TASK_SIGNAL_TRACE);
|
|
}
|
|
return OSP_OK;
|
|
}
|
|
int32_t osp_suspend_task(uint32_t Id)
|
|
{
|
|
if (gOspTask[Id].PhreadId)
|
|
{
|
|
(void)pthread_kill(TASK_THREADID(Id),OSP_TASK_SIGNAL_SUSPEND);
|
|
}
|
|
return OSP_ERROR;
|
|
}
|
|
|
|
int32_t osp_resume_task(uint32_t Id)
|
|
{
|
|
if (gOspTask[Id].PhreadId)
|
|
{
|
|
(void)pthread_kill(TASK_THREADID(Id),OSP_TASK_SIGNAL_RESUME);
|
|
}
|
|
return OSP_ERROR;
|
|
}
|
|
|
|
void osp_set_dbg_cmdlev(void)
|
|
{
|
|
osp_debug_out_set_level(CMD_DEBUG_LEVEL);
|
|
}
|
|
|
|
void osp_set_dbg_errlev(void)
|
|
{
|
|
osp_debug_out_set_level(ERR_DEBUG_LEVEL);
|
|
}
|
|
|
|
void osp_set_dbg_crunlev(void)
|
|
{
|
|
osp_debug_out_set_level(RUN_DEBUG_LEVEL);
|
|
}
|
|
|
|
void osp_set_dbg_cwarlev(void)
|
|
{
|
|
osp_debug_out_set_level(WARNING_DEBUG_LEVEL);
|
|
}
|
|
|
|
int32_t osp_reg_dead_func(OSP_FUNCPTR pfunc)
|
|
{
|
|
|
|
osp_sem_take(g_SemDeadFunc, -1);
|
|
{
|
|
static int32_t num = 0;
|
|
|
|
if ((NULL == pfunc)||(num == (DeadFuncNum-1)))
|
|
{
|
|
osp_sem_give(g_SemDeadFunc);
|
|
return OSP_ERROR;
|
|
}
|
|
|
|
gpfunc[num++] = pfunc;
|
|
osp_sem_give(g_SemDeadFunc);
|
|
return 0 ;
|
|
}
|
|
|
|
}
|
|
void osp_run_dead_func(void)
|
|
{
|
|
int32_t i=0;
|
|
for (i = 0; i < DeadFuncNum; i++)
|
|
{
|
|
if (gpfunc[i])
|
|
gpfunc[i]();
|
|
else
|
|
break;
|
|
}
|
|
osp_debug_out_with_time(CMD_DEBUG_LEVEL,"%d DeadFunc called!\r\n", i);
|
|
}
|
|
void osp_assert(int32_t val)
|
|
{
|
|
|
|
if (val == 0)
|
|
{
|
|
osp_run_dead_func();
|
|
/*to make sure deadmsg has been recorded! anyway this shuld to change in reliable way,todoa*/
|
|
usleep(100);
|
|
|
|
|
|
osp_trace_task(CURRENT_TASKID);
|
|
osp_fflush_all_logfile();
|
|
osp_suspend_task(CURRENT_TASKID);
|
|
while (1);
|
|
}
|
|
|
|
}
|
|
|
|
|