#ifndef __OSP_TASK_H__
#define __OSP_TASK_H__

#include "osp_type_def.h"
#include "osp_sw_queue.h"

#define TASK_MAX        (20)        //(64)  /* IM优化，单核最多任务个数：20个 */
#define TASK_ID_MAX     (64)
#define PRIO_MIN        (64)
#define M_STACK_SIZE    (8192)
#define TOP_VALUE0      (0x242424bd)
#define LOW_VALUE0      (0xab12abab)
#define OSP_TASK_NAME_LEN   (32)
#define TOP_STACK_GUARD0(top) ((*((int*)((char*)top+4)) == TOP_VALUE0) ? 0:1)
#define LOW_STACK_GUARD0(low) ((*((int*)(low)-1) == LOW_VALUE0) ? 0:1)

#define OSP_TASK_DBG_ENABLE

#ifdef OSP_TASK_DBG_ENABLE
typedef struct OSP_TASK_DBG_INFO
{
    uint32_t u32Call_before;
    uint32_t u32Call_after;
}osp_task_dbg_info_t;
#endif

/* 任务类型 */
typedef enum OSP_TASK_TYPE
{
    OSP_NORMAL_TYPE,    /* 周期性任务（普通任务） */
    OSP_TIMER_TYPE,     /* 定时点触发任务 */
    OSP_EVENT_TYPE,     /* 事件触发任务 */
    OSP_DRIVER_TYPE,    /* 驱动任务 */
    OSP_OSP_TYPE,       /* 平台任务 */
}task_type;

/* 函数类型*/
typedef void(*OSP_TASKENTRY_FUNC)();
typedef int(*OSP_TASKINIT_FUNC)(void);

typedef struct osp_task_data{
    uint32_t end_flag;      /* 0xffff --> end */
    uint32_t task_id;       /* 任务Id（计划整体统一） */
    int8_t  *task_name;     /* 任务名称(要求长度不能超过31字节) */
    uint32_t task_prio;     /* 任务优先级 */
    OSP_TASKINIT_FUNC  task_init;   /* 任务初始化 */
    OSP_TASKENTRY_FUNC task_entry;  /* 任务循环体 */
    uint32_t task_stack_size;       /* 堆栈大小 */
}osp_task_inf;

typedef struct osp_task_attr_struct{
    uint32_t task_id;    /* 任务Id（计划整体统一） */
    int8_t * task_name;  /* 任务名称(要求长度不能超过31字节) */
    uint32_t task_prio;  /* 任务优先级 */
    uint32_t task_type;  /* 任务类型如： OSP_NORMAL_TYPE等，其中定时点和消息的任务是阻塞方式 */
    uint32_t sem_value;  // 信号量（事件触发型需要）
    uint32_t delay_value;    /* 是否需要延时     为0不延时 ; 1 延时一个tick */
    OSP_TASKINIT_FUNC  task_init;  /* 任务初始化 */
    OSP_TASKENTRY_FUNC task_entry; /* 任务循环体 */
}osp_task_attr;

/* 任务信息结构体 */
typedef struct OSP_TASK_INFO_EX
{
    uint32_t task_id;       /* 任务Id（计划整体统一） */
    int8_t  *task_name;     /* 任务名称(要求长度不能超过31字节) */
    uint32_t task_prio;     /* 任务优先级 */
    uint32_t stack_size;    /* 堆栈大小 */
    uint32_t task_type;     /* 任务类型如： OSP_NORMAL_TYPE等，其中定时点和消息的任务是阻塞方式 */
    uint32_t delay_value;   /* 是否需要延时     为0不延时 ; 1 延时一个tick */
    uint32_t s_bitmap;      /* slot bit map */
    uint32_t t_off;         /* 偏移时间 */
    OSP_TASKINIT_FUNC  task_init;  /* 任务初始化 */
    OSP_TASKENTRY_FUNC task_entry; /* 任务循环体 */
}osp_task_info_ex;

extern int g_task_id_array[TASK_ID_MAX];
extern int g_task_id_table[TASK_MAX];
extern uint8_t g_taskid_num;
extern int *g_tcb_handler_tbl[TASK_ID_MAX];

#define TCB_GET(id)  (g_tcb_handler_tbl[id])

typedef struct osp_task_ext_com_struct{
    uint32_t end_flag;      /* 0xffff --> end */
    uint32_t task_id;    // 任务ID（全局统一定义）
    uint32_t task_type;  // 任务类型
    uint32_t sem_value;  // 信号量（事件触发型需要）
    uint32_t delay_value;    // 延迟时间（定时点任务/周期性任务）
    //uint32_t queue_value;
    uint32_t once_value; // 任务是否为单次任务 0: 不是一次性任务；非0：一次性任务
}osp_task_ext_inf;

typedef struct tcb_struct
{
    int task_id;    // 任务ID（全局统一定义）
    int priority;   // 任务优先级
    char task_name[OSP_TASK_NAME_LEN]; // 任务名称
    UINTPTR stack_top;  // 任务栈顶
    UINTPTR stack_down; // 任务栈底
    int stack_size;     // 任务栈大小
    int data;           // 数据
    int task_status;    // 任务状态
    int task_type;      // 任务类型
    int preem_times;
    int preem_task;
    int timeouts;
    int run_times;
    int delay_cycle;
    int once_value;
    sem_t *sem;
    sem_t *event_sem;
    int  (*init_func)(void);
    void (*loop_fun)();
    osp_sw_queue *que_head;  // dm space
    int  period;
}osp_tcb;

extern void osp_task_init(void);
extern int osp_task_create(osp_task_info_ex *t_info_val);

extern int osp_task_reg(osp_task_inf *task_array, osp_task_ext_inf *task_ext_array, int apeid);
extern void osp_del_timer_task(int task_id);
extern void osp_del_task(int prio, int scsId);
extern void osp_del_task_all(int scs_id);
extern void osp_delay_cycle(int cycle);

extern void *get_sw_queue_head(int task_id);
extern int osp_get_cur_task_id();

extern uint8_t osp_task_id_is_true(int task_id);
extern void osp_show_task_info(void);

#endif /* __OSP_TASK_H__ */

