#include <string.h>
#include "osp_task.h"
//#include "osp_type_def.h"
#include "err_num.h"
#include "osp_msg.h"
//#include "osp_sw_queue.h"
#include "osp_timer.h"
#include "osp_sem.h"
#include "osp_mem.h"
#include "osp_io.h"
#include "smartos.h"
#include "ucp_printf.h"
#include "ucp_tick.h"
#include "spu_shell.h"

#define DE_ONE_VALUE    (1)

int g_task_id_table[TASK_MAX]  = {0};
uint8_t g_taskid_num           = 0;

int g_prio_array[TASK_ID_MAX]    = {0};
int g_task_id_array[TASK_ID_MAX] = {0};
int *g_tcb_handler_tbl[TASK_ID_MAX] = {NULL};

static uint8_t su8_del_task_err_idx = 0;

#ifdef UCP_TICK_ENABLE
extern osp_msg_tick_info st_tick_info;
#endif

#ifdef OSP_TASK_DBG_ENABLE
osp_task_dbg_info_t gst_osp_task_dbg_info[TASK_ID_MAX];
#endif

/* 任务模块初始化函数 */
void osp_task_init(void)
{
    memset(g_task_id_table,   0, (TASK_MAX*sizeof(int)));
    memset(g_prio_array,      0, sizeof(g_prio_array));
    memset(g_task_id_array,   0, sizeof(g_task_id_array));
    memset(g_tcb_handler_tbl, 0, (TASK_ID_MAX*sizeof(int)));
    g_taskid_num = 0;

#ifdef OSP_TASK_DBG_ENABLE
    memset(&gst_osp_task_dbg_info, 0, sizeof(osp_task_dbg_info_t)*TASK_ID_MAX);
#endif

    spu_insert_cmd_ext("i_ape", (OSP_FUNCPTR)osp_show_task_info, "osp show task info", 0);

#ifdef OSP_MSG_DBG_ENABLE
    spu_insert_cmd_ext("e_ape", (OSP_FUNCPTR)osp_show_msg_info,  "osp show msg info", 0);

#ifdef UCP_OSP_DBG_HW_CNT_ENABLE
    spu_insert_cmd_ext("em_ape", (OSP_FUNCPTR)osp_show_msg_dbg_info_by_coreid_taskid, "osp show msg by id", 2);
#endif /* UCP_OSP_DBG_HW_CNT_ENABLE */

#endif /* OSP_MSG_DBG_ENABLE */

    return ;
}

/* 任务模块任务处理函数（操作系统回调后，回调各注册任务） */
static void osp_event_task(void *data)
{
    osp_tcb *tcb_val = (osp_tcb*)data;
    osp_msg_head *ptr = NULL;
    //(tcb_val->init_func == NULL)? 0:tcb_val->init_func();
    while(1)
    {
        osp_wait_sem(tcb_val->event_sem);
#ifdef UCP_TICK_ENABLE
        rdmcycle(&st_tick_info.u32_sem_wait_tick);
#endif
        osp_recv_msg(&ptr);

#ifdef UCP_TICK_ENABLE
        rdmcycle(&st_tick_info.u32_callback_tick);
#endif

#ifdef OSP_TASK_DBG_ENABLE
        tcb_val->run_times++;
        gst_osp_task_dbg_info[tcb_val->task_id].u32Call_before++;
#endif

        tcb_val->loop_fun(ptr->data, ptr->msg_size);

#ifdef OSP_TASK_DBG_ENABLE
        gst_osp_task_dbg_info[tcb_val->task_id].u32Call_after++;
#endif
    }
}

static void osp_mtimer_task(void *data)
{
    osp_tcb *tcb_val = (osp_tcb*)data;
    //osp_msg_head *ptr = NULLPTR;
    //(tcb_val->init_func == NULL)? 0:tcb_val->init_func();
    while(1)
    {
        osp_wait_sem(tcb_val->sem);  //本文件不要存在os 接口函数

#ifdef OSP_TASK_DBG_ENABLE
        tcb_val->run_times++;
        gst_osp_task_dbg_info[tcb_val->task_id].u32Call_before++;
#endif

        tcb_val->loop_fun(data);

#ifdef OSP_TASK_DBG_ENABLE
        gst_osp_task_dbg_info[tcb_val->task_id].u32Call_after++;
#endif
    }
}

static void osp_loop_task(void *data)
{
    osp_tcb *tcb_val = (osp_tcb*)data;
    //osp_msg_head *ptr = NULLPTR;
    //(tcb_val->init_func == NULL)? 0:tcb_val->init_func();
    while(1)
    {
        osp_delay_cycle(tcb_val->delay_cycle);
#ifdef OSP_TASK_DBG_ENABLE
        tcb_val->run_times++;
        gst_osp_task_dbg_info[tcb_val->task_id].u32Call_before++;
#endif

        tcb_val->loop_fun(data);

#ifdef OSP_TASK_DBG_ENABLE
        gst_osp_task_dbg_info[tcb_val->task_id].u32Call_after++;
#endif
        /*if(tcb_val->once_value != 0)
        {
             osp_del_task(tcb_val->priority);
        }*/
    }
}

static void osp_driver_task(void *data)
{
    osp_tcb *tcb_val = (osp_tcb*)data;
    osp_msg_head *ptr = NULL;
    //(tcb_val->init_func == NULL)? 0:tcb_val->init_func();
    while(1)
    {
        osp_delay_cycle(tcb_val->delay_cycle);
        osp_wait_sem(tcb_val->sem);  //本文件不要存在os 接口函数
        osp_wait_sem(tcb_val->event_sem);

        // 查表
        //osp_post_sem(task_id);
        if(tcb_val->task_type == OSP_EVENT_TYPE)
        {
            osp_recv_msg(&ptr);
            tcb_val->loop_fun(ptr->data, ptr->msg_size);
        }
        else
        {
            tcb_val->loop_fun(data);
        }
        
        if(tcb_val->once_value != 0)
        {
             osp_del_task(tcb_val->priority, 0);
        }
    }
}

static void osp_osp_task(void *data)
{
    osp_tcb *tcb_val = (osp_tcb*)data;
    osp_msg_head *ptr = NULL;
    //(tcb_val->init_func == NULL)? 0:tcb_val->init_func();
    while(1)
    {
        osp_delay_cycle(tcb_val->delay_cycle);
        osp_wait_sem(tcb_val->sem);  //本文件不要存在os 接口函数
        osp_wait_sem(tcb_val->event_sem);

        // 查表
        //osp_post_sem(task_id);
        if(tcb_val->task_type == OSP_EVENT_TYPE)
        {
            osp_recv_msg(&ptr);
            tcb_val->loop_fun(ptr->data, ptr->msg_size);
        }
        else
        {
            tcb_val->loop_fun(data);
        }
        
        if(tcb_val->once_value != 0)
        {
             osp_del_task(tcb_val->priority, 0);
        }
    }
}

#if 0
static void osp_task_entry(void *data)
{
    osp_tcb *tcb_val = (osp_tcb*)data;
    osp_msg_head *ptr = NULLPTR;
    (tcb_val->init_func == NULLPTR)? 0:tcb_val->init_func();
    while(1)
    {
        osp_delay_cycle(tcb_val->delay_cycle);
        osp_wait_sem(tcb_val->sem);  //本文件不要存在os 接口函数
        osp_wait_sem(tcb_val->event_sem);

        // 查表
        //osp_post_sem(task_id);
        if(tcb_val->task_type == OSP_EVENT_TYPE)
        {
            osp_recv_msg(&ptr);
            tcb_val->loop_fun(ptr->data, ptr->msg_size);
        }
        else
        {
            tcb_val->loop_fun(data);
        }
        
        if(tcb_val->once_value != 0)
        {
             osp_del_task(tcb_val->priority);
        }
    }
}
#endif

/*
    静态任务注册
*/
int osp_task_reg(osp_task_inf *task_array, osp_task_ext_inf *task_ext_array, int apeid)
{
    void   (*ptask_fun)(void *);
    osp_task_inf *osp_task_ptr = task_array;
    osp_tcb *tcb_handle = NULL;
    char *stack_down = NULL;
    char *stack_top = NULL;
    osp_task_ext_inf *local_ext_info_p = task_ext_array;
    int ret = 0;

    while(osp_task_ptr->end_flag != 0xffff)
    //while(osp_task_ptr->apeid_bitmap != 0xffff)
    {
#if 0
        if(osp_task_ptr->ape_id != apeid)
        //if((osp_task_ptr->apeid_bitmap&(1<<apeid)) == 0)
        {
            osp_task_ptr++;
            continue;
        }
#endif
        /*task parameter validity check*/
        if(osp_task_ptr->task_entry == NULL)
        {
            UCP_PRINT_ERROR("task entry is none\n\r");
            return -OSP_PAR_ILL;
        }
        if(osp_task_ptr->task_id > TASK_ID_MAX)
        {
            UCP_PRINT_ERROR("task id is error\n\r");
            return -OSP_PAR_ILL;
        }
        if(osp_task_ptr->task_prio > PRIO_MIN)
        {
            UCP_PRINT_ERROR("task PRIO is error\n\r");
            return -OSP_PAR_ILL;
        }
        if(osp_task_ptr->task_stack_size > M_STACK_SIZE)
        {
            UCP_PRINT_ERROR("task stack size is to large\n\r");
            return -OSP_PAR_ILL;
        }
        if(g_prio_array[osp_task_ptr->task_prio] != 0)
        {
            UCP_PRINT_ERROR("task prio is repeat\n\r");
            UCP_PRINT_ERROR("task register failed passed\n\r");
            osp_task_ptr++;
            continue;
        }
        g_prio_array[osp_task_ptr->task_id] = osp_task_ptr->task_prio;
        if(g_task_id_array[osp_task_ptr->task_prio] != 0)
        {
            UCP_PRINT_ERROR("task id is repeat\n\r");
            UCP_PRINT_ERROR("task register failed passed\n\r");
            osp_task_ptr++;
            continue;
        }
        g_task_id_array[osp_task_ptr->task_prio] = osp_task_ptr->task_id;

        stack_down = (char*)osp_malloc(osp_task_ptr->task_stack_size+12);
        if(stack_down == NULL)
        {
            UCP_PRINT_ERROR("task 0x%08x stack alloc failed\n\r",osp_task_ptr->task_id);
            goto malloc_stack_failed;
        }
        *(int*)stack_down = LOW_VALUE0;
        stack_down += 4;
        stack_top = stack_down + osp_task_ptr->task_stack_size;
        *((int*)(stack_top + 4)) = TOP_VALUE0;
        tcb_handle = (osp_tcb*)osp_malloc(sizeof(osp_tcb));
        if(tcb_handle == NULL)
        {
            UCP_PRINT_ERROR("task 0x%08x tcb alloc failed\n\r",osp_task_ptr->task_id);
            goto tcb_malloc_failed;
        }
        memset((void*)tcb_handle, 0, sizeof(osp_tcb));
        local_ext_info_p = task_ext_array;
        while(local_ext_info_p->end_flag != 0xffff)
        //while(local_ext_info_p->apeid_bitmap != 0xffff)
        {
            if(osp_task_ptr->end_flag == local_ext_info_p->end_flag)
            //if((osp_task_ptr->apeid_bitmap&(1<<apeid)) == (local_ext_info_p->apeid_bitmap&(1<<apeid)))
            {
                if(osp_task_ptr->task_id == local_ext_info_p->task_id)
                {
                    tcb_handle->delay_cycle = local_ext_info_p->delay_value;   // 如果为0 不会delay
                    if((local_ext_info_p->sem_value != 0)
                        &&  ((local_ext_info_p->task_type == OSP_TIMER_TYPE)
                           ||(local_ext_info_p->task_type == OSP_DRIVER_TYPE)
                           ||(local_ext_info_p->task_type == OSP_OSP_TYPE)))
                    {
                        tcb_handle->sem = osp_create_sem(0);
                    }
                    else if(local_ext_info_p->sem_value != 0&&(local_ext_info_p->task_type == OSP_EVENT_TYPE))
                    {
                        tcb_handle->event_sem = osp_create_sem(0);
                        tcb_handle->que_head = (osp_sw_queue*)osp_malloc(sizeof(osp_sw_queue));
                        if (NULL == tcb_handle->que_head)
                        {
                            UCP_PRINT_ERROR("task 0x%08x sw_que alloc failed\n\r",osp_task_ptr->task_id);
                            osp_delete_sem(tcb_handle->event_sem);
                            osp_free((stack_down-4));
                            osp_free((char*)tcb_handle);
                            return -OSP_MEM_FULL;
                        }
                        if (OSP_OK != osp_sw_queue_int(tcb_handle->que_head))
                        {
                            UCP_PRINT_ERROR("task 0x%08x sw_que alloc failed\n\r", osp_task_ptr->task_id);
                            osp_delete_sem(tcb_handle->event_sem);
                            osp_free((stack_down-4));
                            osp_free((char*)tcb_handle);
                            return -1;
                        }
                        //memset(tcb_handle->que_head, 0, sizeof(osp_sw_queue));
                    }
                    tcb_handle->task_type = local_ext_info_p->task_type;
                    tcb_handle->once_value = local_ext_info_p->once_value;
                    break;
                }
            }
            local_ext_info_p++;
        }
        if(local_ext_info_p->end_flag == 0xffff)
        //if(local_ext_info_p->apeid_bitmap == 0xffff)
        {
            // 系统平台设置默认扩展参数
            tcb_handle->delay_cycle = 1;
            tcb_handle->sem = NULL;
            tcb_handle->event_sem = NULL;
            tcb_handle->task_type = OSP_NORMAL_TYPE;
            tcb_handle->once_value = 0;
        }
        g_task_id_table[g_taskid_num] = osp_task_ptr->task_id;
        g_taskid_num++;
        tcb_handle->task_id = osp_task_ptr->task_id;
        tcb_handle->priority = osp_task_ptr->task_prio;
        tcb_handle->stack_size = osp_task_ptr->task_stack_size;
        tcb_handle->stack_top = (UINTPTR)stack_top;
        tcb_handle->stack_down = (UINTPTR)stack_down;
        tcb_handle->init_func = osp_task_ptr->task_init;
        tcb_handle->loop_fun = osp_task_ptr->task_entry;
        //tcb_handle->que = NULLPTR;
        tcb_handle->data = osp_task_ptr->task_prio;
        STRCPY((char*)tcb_handle->task_name, (const char*)osp_task_ptr->task_name);
        //tcb_handle->task_name = osp_task_ptr->task_name;
        g_tcb_handler_tbl[tcb_handle->task_id] = (int*)tcb_handle;

        switch(local_ext_info_p->task_type)
        {
            case OSP_NORMAL_TYPE:
            {
                ptask_fun = osp_loop_task;
                break;
            }
            case OSP_EVENT_TYPE:
            {
                ptask_fun = osp_event_task;
                break;
            }
            case OSP_TIMER_TYPE:
            {
                ptask_fun = osp_mtimer_task;
                break;
            }
            case OSP_DRIVER_TYPE:
            {
                ptask_fun = osp_driver_task;
                break;
            }
            case OSP_OSP_TYPE:
            {
                ptask_fun = osp_osp_task;
                break;
            }
        }
        UCP_PRINT_LOG("task_id = 0x%08x.\r\n", tcb_handle->task_id);
        ret = smart_task_create ((void*)ptask_fun,
                     (void *)tcb_handle,
                     (uint32_t  *)stack_top,
                     tcb_handle->priority,
                     tcb_handle->task_id,
                     (uint32_t  *)stack_down,
                     tcb_handle->stack_size);
        if (0 != ret)
        {
            debug_write(DBG_DDR_ERR_IDX(apeid, 25), ret);
            if (OSP_EVENT_TYPE == local_ext_info_p->task_type)
            {
                osp_free((char*)(tcb_handle->que_head));
                osp_delete_sem(tcb_handle->event_sem);
            }
            else
            {
                osp_delete_sem(tcb_handle->sem);
            }
            osp_free((stack_down-4));
            osp_free((char*)tcb_handle);
            return -1;
        }
        if (0 != ret)
        {
            debug_write(DBG_DDR_ERR_IDX(apeid, 25), ret);
        }
        UCP_PRINT_LOG("task_id = 0x%08x, smart_task_create return :0x%08x.\r\n", tcb_handle->task_id, ret);
#if 0
        OSTaskCreateExt ((void *)osp_task_entry, /// osp_event_task/ osp_timer_task/osp_driver_task/osp_ops_task
            (void *)tcb_handle,
            (OS_STK  *)stack_top,
            tcb_handle->priority,
            tcb_handle->task_id,
            (OS_STK  *)stack_down,
            tcb_handle->stack_size,
            (void *)0,
             0);
#endif
        osp_task_ptr++;
        continue;
tcb_malloc_failed:
    osp_free(stack_down);
malloc_stack_failed:
    g_prio_array[osp_task_ptr->task_id] = 0;
    g_task_id_array[osp_task_ptr->task_prio] = 0;

        osp_task_ptr++;
    }
    return OSP_OK;
}

/*
    动态任务注册
*/
/* 
 create fail see:#20 
 cause of failure：
    0x10: no task entry
    0x11: task id error(too big)
    0x12: priority error
    0x13: stack size error(too big)
    0x14: task id exist
    0x15: task priority exist
    0x16: stack alloc failed
    0x17: tcb alloc failed
    0x18: sem create failed(no event task)
    0x19: sem create failed(event task)
    0x1a: sw_que alloc failed(event task)
    0x1b: sw_que init failed(event task)
    0x1c: timer point is overflow(timer task)
    0x1d: os create task failed
    0x1e: task_init return error
 #21: task id
*/
int osp_task_create(osp_task_info_ex *t_info_val)
{
#ifdef UCP_TICK_ENABLE
    uint32_t clockBegin,clockEnd;
    int32_t  clockCnt;
    rdmcycle(&clockBegin);
#endif
    static uint8_t su8_index = 0;
    osp_tcb *tcb_handle = NULL;
    char *stack_down = NULL;
    char *stack_top = NULL;
    void   (*ptask_fun)(void *);
    int  ret = -1;

    /* 任务主函数不能为空 */
    if(t_info_val->task_entry == NULL)
    {
        UCP_PRINT_ERROR("task(%d) entry is none", t_info_val->task_id);
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 20), 0x10);
        debug_write(OSP_DEBUG_POT(g_ape_id, 21), t_info_val->task_id);
#endif
        return -OSP_PAR_ILL;
    }

    /* 若任务有初始化函数，先执行初始化函数 */
    if (t_info_val->task_init != NULL)
    {
        if (-1 == t_info_val->task_init())
        //if (-1 == ret)
        {
#ifdef OSP_DEBUG_TEST
            debug_write(OSP_DEBUG_POT(g_ape_id, 20), 0x1e);
            debug_write(OSP_DEBUG_POT(g_ape_id, 21), t_info_val->task_id);
#endif
            return -OSP_TASK_INIT_ERR;
        }
    }

    if(t_info_val->task_id > TASK_ID_MAX)
    {
        UCP_PRINT_ERROR("task(%d) id is error", t_info_val->task_id);
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 20), 0x11);
        debug_write(OSP_DEBUG_POT(g_ape_id, 21), t_info_val->task_id);
#endif
        return -OSP_PAR_ILL;
    }
    if(t_info_val->task_prio > PRIO_MIN)
    {
        UCP_PRINT_ERROR("task(%d) PRIO is error", t_info_val->task_id);
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 20), 0x12);
        debug_write(OSP_DEBUG_POT(g_ape_id, 21), t_info_val->task_id);
#endif
        return -OSP_PAR_ILL;
    }
    if(t_info_val->stack_size > M_STACK_SIZE)
    {
        UCP_PRINT_ERROR("task(%d) stack size is to large", t_info_val->task_id);
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 20), 0x13);
        debug_write(OSP_DEBUG_POT(g_ape_id, 21), t_info_val->task_id);
#endif
        return -OSP_PAR_ILL;
    }
    if(g_prio_array[t_info_val->task_id] != 0)
    {
        UCP_PRINT_ERROR("task(%d) prio is repeat", t_info_val->task_id);
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 20), 0x14);
        debug_write(OSP_DEBUG_POT(g_ape_id, 21), t_info_val->task_id);
#endif
        return -OSP_PAR_REP;
    }
    g_prio_array[t_info_val->task_id] = t_info_val->task_prio;
    if(g_task_id_array[t_info_val->task_prio] != 0)
    {
        UCP_PRINT_ERROR("task(%d) id is repeat",t_info_val->task_id);
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 20), 0x15);
        debug_write(OSP_DEBUG_POT(g_ape_id, 21), t_info_val->task_id);
#endif
        return -OSP_PAR_REP;
    }
    g_task_id_array[t_info_val->task_prio] = t_info_val->task_id;
    stack_down = (char*)osp_malloc((t_info_val->stack_size + 12));
    if(stack_down == NULL)
    {
        UCP_PRINT_ERROR("task(%d) stack alloc failed",t_info_val->task_id);
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 20), 0x16);
        debug_write(OSP_DEBUG_POT(g_ape_id, 21), t_info_val->task_id);
#endif
        goto alloc_stack_failed;
    }
    *(int*)stack_down = LOW_VALUE0;
    stack_down += 4;
    stack_top = stack_down + t_info_val->stack_size;
    *((int*)(stack_top + 4)) = TOP_VALUE0;
    tcb_handle = (osp_tcb*)osp_malloc(sizeof(osp_tcb));
    if(tcb_handle == NULL)
    {
        UCP_PRINT_ERROR("task(%d) tcb alloc failed",t_info_val->task_id);
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 20), 0x17);
        debug_write(OSP_DEBUG_POT(g_ape_id, 21), t_info_val->task_id);
#endif
        goto tcb_alloc_failed;
    }
    memset(tcb_handle, 0, sizeof(osp_tcb));

    tcb_handle->delay_cycle = t_info_val->delay_value;
    //if((t_attr_val->sem_value != 0) && (t_attr_val->task_type == OSP_TIMER_TYPE))
    if ((t_info_val->task_type == OSP_TIMER_TYPE) || (t_info_val->task_type == OSP_DRIVER_TYPE) || (t_info_val->task_type == OSP_OSP_TYPE))
    {
        tcb_handle->sem = osp_create_sem(0);
        if (NULL == tcb_handle->sem)
        {
            UCP_PRINT_ERROR("task(%d) create sem error", t_info_val->task_id);
#ifdef OSP_DEBUG_TEST
            debug_write(OSP_DEBUG_POT(g_ape_id, 20), 0x18);
            debug_write(OSP_DEBUG_POT(g_ape_id, 21), t_info_val->task_id);
#endif
            osp_free((stack_down-4));
            osp_free((char*)tcb_handle);
            return -1;
        }
    }
    //else if((t_attr_val->sem_value != 0) && (t_attr_val->task_type == OSP_EVENT_TYPE))
    if (t_info_val->task_type == OSP_EVENT_TYPE)
    {
        tcb_handle->event_sem = osp_create_sem(0);
        if (NULL == tcb_handle->event_sem)
        {
            UCP_PRINT_ERROR("task(%d) create sem error", t_info_val->task_id);
#ifdef OSP_DEBUG_TEST
            debug_write(OSP_DEBUG_POT(g_ape_id, 20), 0x19);
            debug_write(OSP_DEBUG_POT(g_ape_id, 21), t_info_val->task_id);
#endif
            osp_free((stack_down-4));
            osp_free((char*)tcb_handle);
            return -1;
        }
        tcb_handle->que_head = (osp_sw_queue*)osp_malloc(sizeof(osp_sw_queue));
        if (NULL == tcb_handle->que_head)
        {
            UCP_PRINT_ERROR("task(%d) sw_que alloc failed", t_info_val->task_id);
#ifdef OSP_DEBUG_TEST
            debug_write(OSP_DEBUG_POT(g_ape_id, 20), 0x1a);
            debug_write(OSP_DEBUG_POT(g_ape_id, 21), t_info_val->task_id);
#endif
            osp_delete_sem(tcb_handle->event_sem);
            osp_free((stack_down-4));
            osp_free((char*)tcb_handle);
            return -1;
        }
        if (OSP_OK != osp_sw_queue_int(tcb_handle->que_head))
        {
            UCP_PRINT_ERROR("task(%d) sw_que init failed", t_info_val->task_id);
#ifdef OSP_DEBUG_TEST
            debug_write(OSP_DEBUG_POT(g_ape_id, 20), 0x1b);
            debug_write(OSP_DEBUG_POT(g_ape_id, 21), t_info_val->task_id);
#endif
            osp_delete_sem(tcb_handle->event_sem);
            osp_free((char*)(tcb_handle->que_head));
            osp_free((stack_down-4));
            osp_free((char*)tcb_handle);
            return -1;
        }
        //memset(tcb_handle->que_head, 0, sizeof(osp_sw_queue));
    }
    tcb_handle->task_type = t_info_val->task_type;
    tcb_handle->once_value = DE_ONE_VALUE;
    tcb_handle->task_id = t_info_val->task_id;
    tcb_handle->priority = t_info_val->task_prio;
    tcb_handle->stack_size = t_info_val->stack_size;
    tcb_handle->stack_top = (UINTPTR)stack_top;
    tcb_handle->stack_down = (UINTPTR)stack_down;
    tcb_handle->init_func = t_info_val->task_init;
    tcb_handle->loop_fun = t_info_val->task_entry;
    tcb_handle->data = t_info_val->task_prio;
    strncpy(tcb_handle->task_name, (const char*)t_info_val->task_name, (OSP_TASK_NAME_LEN-1));
    g_tcb_handler_tbl[tcb_handle->task_id] = (int*)tcb_handle;

    //if((t_info_val->t_off != 0)&&(t_info_val->s_bitmap != 0))
    if((OSP_TIMER_TYPE == t_info_val->task_type) && (t_info_val->s_bitmap != 0))
    {
        if(g_osp_timer_desc_idx >= OSP_TIMER_COUNTS)
        {
#ifdef OSP_DEBUG_TEST
            debug_write(OSP_DEBUG_POT(g_ape_id, 20), 0x1c);
            debug_write(OSP_DEBUG_POT(g_ape_id, 21), t_info_val->task_id);
#endif
            UCP_PRINT_ERROR("task(%d) timer point is overflow\n\r", t_info_val->task_id);
            osp_delete_sem(tcb_handle->sem);
            osp_free((stack_down-4));
            osp_free((char*)tcb_handle);
            return -1;
        }
        g_osp_timer_desc[g_osp_timer_desc_idx].task_id       = t_info_val->task_id;
        g_osp_timer_desc[g_osp_timer_desc_idx].slot_bitmap   = t_info_val->s_bitmap;
        g_osp_timer_desc[g_osp_timer_desc_idx].t_offset      = t_info_val->t_off;
        g_osp_timer_desc_idx++;
    }

    g_task_id_table[g_taskid_num] = t_info_val->task_id;
    g_taskid_num++;
    switch(t_info_val->task_type)
    {
        case OSP_NORMAL_TYPE:
        {
            ptask_fun = osp_loop_task;
            break;
        }
        case OSP_EVENT_TYPE:
        {
            ptask_fun = osp_event_task;
            break;
        }
        case OSP_TIMER_TYPE:
        {
            ptask_fun = osp_mtimer_task;
            break;
        }
        case OSP_DRIVER_TYPE:
        {
            ptask_fun = osp_driver_task;
            break;
        }
        case OSP_OSP_TYPE:
        {
            ptask_fun = osp_osp_task;
            break;
        }
    }
    ret = smart_task_create ((void*)ptask_fun,
                            (void *)tcb_handle,
                            (uint32_t  *)stack_top,
                            tcb_handle->priority,
                            tcb_handle->task_id,
                            (uint32_t  *)stack_down,
                            tcb_handle->stack_size);
    if (0 != ret)
    {
        debug_write(DBG_DDR_ERR_IDX(g_ape_id, 26), ret);
        if (OSP_EVENT_TYPE == t_info_val->task_type)
        {
            osp_free((char*)(tcb_handle->que_head));
            osp_delete_sem(tcb_handle->event_sem);
        }
        else
        {
            osp_delete_sem(tcb_handle->sem);
        }
        osp_free((stack_down-4));
        osp_free((char*)tcb_handle);
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 20), 0x1d);
        debug_write(OSP_DEBUG_POT(g_ape_id, 21), t_info_val->task_id);
#endif
        return -1;
    }
    UCP_PRINT_LOG("smart_task_create return:%d, task_id=%d, num=%d", ret, tcb_handle->task_id, g_taskid_num);
#ifdef OSP_DEBUG_TEST
    debug_write(OSP_DEBUG_POT(g_ape_id, 22), ret);
    debug_write(OSP_DEBUG_POT(g_ape_id, 23), t_info_val->task_id);
#endif
    if (su8_index < 5)
    {
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, (225+su8_index)), t_info_val->task_id);
        debug_write(OSP_DEBUG_POT(g_ape_id, (230+su8_index)), stack_top);
        debug_write(OSP_DEBUG_POT(g_ape_id, (235+su8_index)), stack_down);
#endif
    }
    su8_index++;

#ifdef UCP_TICK_ENABLE
    rdmcycle(&clockEnd);
    clockCnt = clockEnd - clockBegin;
    debug_write(OSP_DEBUG_POT(g_ape_id, 200), clockCnt);
#endif

#if 0
    OSTaskCreateExt ((void *)osp_task_entry,
        (void *)tcb_handle,
        (OS_STK  *)stack_top,
        tcb_handle->priority,
        tcb_handle->task_id,
        (OS_STK  *)stack_down,
        tcb_handle->stack_size,
        (void *)0,
         0);
#endif

    return 0;

tcb_alloc_failed:
    osp_free(stack_down);
alloc_stack_failed:
    g_prio_array[t_info_val->task_id] = 0;
    g_task_id_array[t_info_val->task_prio] = 0;

    return -1;
}

/*
 delete timer task
    delete fail see:#13
    cause of failure：
        0x20: no tcb_handle
        0x21: no task priority
        0x22: os delete task failed
    #14: task id
*/
void osp_del_timer_task(int task_id)
{
    uint8_t u8_loop   = 0;
    int     task_prio = 0;
    int     ret       = 0;
    osp_tcb *tcb_handle = NULL;

    /* 通过任务ID找到任务控制块信息 */
    tcb_handle = (osp_tcb*)g_tcb_handler_tbl[task_id];
    if(NULL == tcb_handle)
    {
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 13), 0x20);
        debug_write(OSP_DEBUG_POT(g_ape_id, 14), task_id);
#endif
        UCP_PRINT_ERROR("osp_del_timer_task: no tcb_handle(task_id=%d)", task_id);
        return ;
    }

    task_prio = g_prio_array[task_id];
    if (task_prio <= 0)
    {
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 13), 0x21);
        debug_write(OSP_DEBUG_POT(g_ape_id, 14), task_id);
#endif
        UCP_PRINT_ERROR("osp_del_timer_task: no task_prio(task_id=%d)", task_id);
        return ;
    }

    ret = smart_task_del(task_prio);      /* 删除任务 */
    if (OSP_OK != ret)
    {
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 13), 0x22);
        debug_write(OSP_DEBUG_POT(g_ape_id, 14), task_id);
#endif
        debug_write(DBG_DDR_ERR_IDX(g_ape_id, 47), ret);
        debug_write(DBG_DDR_ERR_IDX(g_ape_id, 112+su8_del_task_err_idx), task_prio);
        su8_del_task_err_idx = (su8_del_task_err_idx+1)&0xF;

        UCP_PRINT_ERROR("osp_del_timer_task: os return(%d)(task_id=%d)", ret, task_id);
        return ;
    }

    g_task_id_array[task_prio] = 0;  /* 通过优先级清任务列表 */
    g_prio_array[task_id]      = 0;  /* 通过任务ID清优先级列表 */
    osp_free((char*)((tcb_handle->stack_down)-4));  /* 释放栈空间 */
    osp_delete_sem(tcb_handle->sem);            /* 删除信号量 */
    osp_free((char*)tcb_handle);                    /* 释放任务控制块 */
    g_tcb_handler_tbl[task_id] = NULL;

    for (u8_loop = 0; u8_loop < g_taskid_num; u8_loop++)
    {
        if (task_id == g_task_id_table[u8_loop])
        {
            g_task_id_table[u8_loop] = 0;
            memmove(&(g_task_id_table[u8_loop]), &(g_task_id_table[u8_loop+1]), sizeof(int)*(g_taskid_num-u8_loop-1));
            g_taskid_num--;
            break;
        }
    }
    //smart_task_del(task_prio);      /* 删除任务 */
    return ;
}

/* 任务删除
 * 需要删除的内存如下：
 * 1. 任务的栈空间
 * 2. 任务的控制块空间
 * 3. 任务的相关信号量
 * 4. 任务的相关软队列
 * 5. 任务的相关列表：任务优先级列表+任务ID列表
 * 6. 定时点任务的相关列表
*/
/*
 delete task
    delete fail see:#24
    cause of failure：
        0x30: task id not exsit
        0x31: tcb handler not exsit
        0x32: prio id error
        0x33: os delete task failed
    #25: task id
*/

void osp_del_task(int prio, int scsId)
{
#ifdef UCP_TICK_ENABLE
    uint32_t clockBegin,clockEnd;
    int32_t  clockCnt;
    rdmcycle(&clockBegin);
#endif

    uint8_t u8_loop = 0;
    int task_id = 0;
    int ret     = 0;
    osp_tcb *tcb_handle = NULL;

    task_id = g_task_id_array[prio];
    if (0 == task_id)
    {
        /* 任务不存在 */
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 24), 0x30);
        debug_write(OSP_DEBUG_POT(g_ape_id, 25), task_id);
#endif
        UCP_PRINT_ERROR("osp_del_task: task_id=%d(prio=%d), not exsit.\r\n", task_id, prio);
        return ;
    }

    /* 通过任务ID找到任务控制块信息 */
    tcb_handle = (osp_tcb*)g_tcb_handler_tbl[task_id];
    if(NULL == tcb_handle)
    {
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 24), 0x31);
        debug_write(OSP_DEBUG_POT(g_ape_id, 25), task_id);
#endif
        UCP_PRINT_ERROR("osp_del_task: no tcb_handle(task_id=%d)", task_id);
        return ;
    }

    if (prio != tcb_handle->priority)
    {
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 24), 0x32);
        debug_write(OSP_DEBUG_POT(g_ape_id, 25), task_id);
#endif
        UCP_PRINT_ERROR("osp_del_task: prio id error(%d,%d)", prio, tcb_handle->priority);
        return ;
    }

    /* 根据消息类型分别处理 */
#if 0 /* osp_timer_unsync接口直接由物理层调用 */
    if (OSP_TIMER_TYPE == tcb_handle->task_type)
    {
        /* 只要删除定时点任务，那就清空所有定时点任务相关信息 */
        /* 先调用驱动接口，把定时点信息清除 */
        osp_timer_unsync(scsId);
        return ;
    }
    else 
#endif
    if (OSP_EVENT_TYPE == tcb_handle->task_type)
    {
        /* 删除任务 */
        ret = smart_task_del(prio);
        if (OSP_OK != ret)
        {
#ifdef OSP_DEBUG_TEST
            debug_write(OSP_DEBUG_POT(g_ape_id, 24), 0x33);
            debug_write(OSP_DEBUG_POT(g_ape_id, 25), task_id);
#endif
            debug_write(DBG_DDR_ERR_IDX(g_ape_id, 47), ret);
            debug_write(DBG_DDR_ERR_IDX(g_ape_id, 112+su8_del_task_err_idx), prio);
            su8_del_task_err_idx = (su8_del_task_err_idx+1)&0xF;

            UCP_PRINT_ERROR("osp_del_task: os return(%d)(task_id=%d)", ret, task_id);
            return ;
        }

        /* 事件任务，删除事件信号量和软件队列 */
        osp_delete_sem(tcb_handle->event_sem);
        osp_free((char*)tcb_handle->que_head);
    }
    else if (OSP_NORMAL_TYPE == tcb_handle->task_type)
    {
        /* 删除任务 */
        ret = smart_task_del(prio);
        if (OSP_OK != ret)
        {
#ifdef OSP_DEBUG_TEST
            debug_write(OSP_DEBUG_POT(g_ape_id, 24), 0x33);
            debug_write(OSP_DEBUG_POT(g_ape_id, 25), task_id);
#endif
            debug_write(DBG_DDR_ERR_IDX(g_ape_id, 47), ret);
            debug_write(DBG_DDR_ERR_IDX(g_ape_id, 112+su8_del_task_err_idx), prio);
            su8_del_task_err_idx = (su8_del_task_err_idx+1)&0xF;

            UCP_PRINT_ERROR("osp_del_task: os return(%d)(task_id=%d)", ret, task_id);
            return ;
        }
    }
    else if (OSP_TIMER_TYPE == tcb_handle->task_type)
    {
        /* 定时点任务单独删除 */
        return ;
    }
    else
    {
        /* 删除任务 */
        ret = smart_task_del(prio);
        if (OSP_OK != ret)
        {
#ifdef OSP_DEBUG_TEST
            debug_write(OSP_DEBUG_POT(g_ape_id, 24), 0x33);
            debug_write(OSP_DEBUG_POT(g_ape_id, 25), task_id);
#endif
            debug_write(DBG_DDR_ERR_IDX(g_ape_id, 47), ret);
            debug_write(DBG_DDR_ERR_IDX(g_ape_id, 112+su8_del_task_err_idx), prio);
            su8_del_task_err_idx = (su8_del_task_err_idx+1)&0xF;

            UCP_PRINT_ERROR("osp_del_task: os return(%d)(task_id=%d)", ret, task_id);
            return ;
        }

        /* 其他任务，删除信号量 */
        osp_delete_sem(tcb_handle->sem);
    }

    g_task_id_array[prio] = 0;  /* 通过优先级清任务列表 */
    g_prio_array[task_id] = 0;  /* 通过任务ID清优先级列表 */

    osp_free((char*)((tcb_handle->stack_down)-4));     /* 释放栈空间 */
    osp_free((char*)tcb_handle);  /* 释放任务控制块 */

    g_tcb_handler_tbl[task_id] = NULL;

    for (u8_loop = 0; u8_loop < g_taskid_num; u8_loop++)
    {
        if (task_id == g_task_id_table[u8_loop])
        {
            g_task_id_table[u8_loop] = 0;
            memmove(&(g_task_id_table[u8_loop]), &(g_task_id_table[u8_loop+1]), sizeof(int)*(g_taskid_num-u8_loop-1));
            g_taskid_num--;
            break;
        }
    }

    /* 删除任务 */
    //smart_task_del(prio);
#ifdef OSP_DEBUG_TEST
    debug_write(OSP_DEBUG_POT(g_ape_id, 33), task_id);
#endif

#ifdef UCP_TICK_ENABLE
    rdmcycle(&clockEnd);
    clockCnt = clockEnd - clockBegin;
    debug_write(OSP_DEBUG_POT(g_ape_id, 201), clockCnt);
#endif
    return ;
}

#if 0
void osp_del_task_all(int scs_id)
{
    uint8_t u8_task_loop  = 0;
    uint8_t u8_task_id    = 0;
    uint8_t u8_timer_falg = 0;   /*0: no timer task; 1: timer task*/
    osp_tcb *tcb_handle   = NULL;
    int     ret           = 0;

    for (u8_task_loop = 0; u8_task_loop < TASK_MAX; u8_task_loop++)
    {
        u8_task_id = g_task_id_array[u8_task_loop];

        if (0 == u8_task_id)
        {
            /* 任务不存在 */
            UCP_PRINT_ERROR("osp_del_task: task_id = 0x%08x(prio = 0x%08x), not exsit.\r\n", u8_task_id, u8_task_loop);
#ifdef OSP_DEBUG_TEST
            debug_write(OSP_DEBUG_POT(g_ape_id, 32), u8_task_id);
#endif
            continue;
            //return ;
        }

        /* 通过任务ID找到任务控制块信息 */
        tcb_handle = (osp_tcb*)g_tcb_handler_tbl[u8_task_id];

        /* 根据消息类型分别处理 */
        if (OSP_TIMER_TYPE == tcb_handle->task_type)
        {
            if (0 ==u8_timer_falg)
            {
                /* 只要删除定时点任务，那就清空所有定时点任务相关信息 */
                /* 先调用驱动接口，把定时点信息清除 */
                osp_timer_unsync_notask(scs_id);
                u8_timer_falg++;
            }
            osp_delete_sem(tcb_handle->sem);    /* 删除信号量 */
        }
        else if (OSP_EVENT_TYPE == tcb_handle->task_type)
        {
            /* 事件任务，删除事件信号量和软件队列 */
            osp_delete_sem(tcb_handle->event_sem);
            osp_free((char*)tcb_handle->que_head);
        }
        else if (OSP_NORMAL_TYPE == tcb_handle->task_type)
        {
            /* 无操作 */
        }
        else
        {
            /* 其他任务，删除信号量 */
            osp_delete_sem(tcb_handle->sem);
        }

        g_task_id_array[u8_task_loop] = 0;  /* 通过优先级清任务列表 */
        g_prio_array[u8_task_id]      = 0;  /* 通过任务ID清优先级列表 */
        osp_free((char*)((tcb_handle->stack_down)-4));  /* 释放栈空间 */
        osp_free((char*)tcb_handle);                    /* 释放任务控制块 */

        g_tcb_handler_tbl[u8_task_id] = NULL;

        ret = smart_task_del(u8_task_loop);      /* 删除任务 */
        if (OSP_OK != ret)
        {
            debug_write(DBG_DDR_ERR_IDX(g_ape_id, 47), ret);
            debug_write(DBG_DDR_ERR_IDX(g_ape_id, 112+su8_del_task_err_idx), u8_task_loop);
            su8_del_task_err_idx = (su8_del_task_err_idx+1)&0xF;
        }
#ifdef OSP_DEBUG_TEST
        debug_write(OSP_DEBUG_POT(g_ape_id, 33), u8_task_id);
#endif
    }

    g_taskid_num = 0;
    memset(g_task_id_table,   0, TASK_MAX*sizeof(int));
    memset(g_tcb_handler_tbl, 0, TASK_MAX*sizeof(int));
    memset(g_prio_array,      0, sizeof(g_prio_array));
    memset(g_task_id_array,   0, sizeof(g_task_id_array));
#ifdef OSP_TASK_DBG_ENABLE
    memset(&gst_osp_task_dbg_info, 0, sizeof(osp_task_dbg_info_t)*TASK_MAX);
#endif

    return ;
}
#endif

void osp_delay_cycle(int cycle)
{
    smart_tick_sleep(cycle);
}

void *get_sw_queue_head(int task_id)
{
    osp_tcb *l_tcb = (osp_tcb*)(TCB_GET(task_id));

    return l_tcb->que_head;
}

int osp_get_cur_task_id()
{
    int apeId = get_core_id();
    int task_pro = smart_get_curprio();
    if (0 >= task_pro)
    {
        debug_write(DBG_DDR_ERR_IDX(apeId, 24), task_pro);
    }

    return g_task_id_array[task_pro];
}

uint8_t osp_task_id_is_true(int task_id)
{
    if (g_prio_array[task_id] != 0)
    {
        return OSP_OK;
    }

    return OSP_ERROR;
}

void osp_show_task_info(void)
{
    uint8_t i;
    osp_tcb *tcb_val;
    char pbuf[2048];
    int st_top_s      = 0;
    int st_low_s      = 0;
    int stack_state   = 0;
    int len           = 0;
    uint8_t ucCoreId = 0;

    ucCoreId = get_core_id();

    len = sprintf(pbuf,"\n\r%-8s%-8s%-20s%10s%15s%8s%12s%12s%12s%15s%12s%12s%12s\n\r",
              "coreId", "Id",  "name","end_times","cpu-pri","type", "stacktop",  "stackdown",  "stacksize","stack_state", "run_times", "preem_task", "preem_times");    

    for(i = 0; i < g_taskid_num; i++, len=0)
    {
        tcb_val = (osp_tcb*)g_tcb_handler_tbl[g_task_id_table[i]];
        st_top_s = TOP_STACK_GUARD0(tcb_val->stack_top);
        st_low_s = LOW_STACK_GUARD0(tcb_val->stack_down);
        if((st_low_s == 0)&&(st_top_s == 0))
        {
            stack_state = 0;
        }
        else
        {
            stack_state = 1;
        }
        len += sprintf(pbuf +len,"%-8u%-5u%-20s%10u%17u%8u      0x%x     0x%x%12u\t%2u\t%12u%12u%12u\n\r",
            ucCoreId,tcb_val->task_id, tcb_val->task_name, gst_osp_task_dbg_info[g_task_id_table[i]].u32Call_after,tcb_val->priority,tcb_val->task_type, tcb_val->stack_top,  tcb_val->stack_down,
            tcb_val->stack_size, stack_state, tcb_val->run_times, tcb_val->preem_task, tcb_val->preem_times); 

        spu_shellinfo_to_arm(pbuf, len, UCP4008_OSP_SHELL);
    }

    return;
}

