#ifndef _ATTRTASK_H_
#define _ATTRTASK_H_
/* Includes ----------------------------------------------------------------- */
#include <cmsis_os2.h>

#include "FreeRTOS.h"
//#include "device\config.h"
#include "task.h"


/* Exported constants ------------------------------------------------------- */

/* 所有任务都要define一个“任务运行频率”和“初始化延时” */
#define TASK_FREQ_CTRL_CHASSIS (500u)
#define TASK_FREQ_CTRL_GIMBAL (500u)
#define TASK_FREQ_CTRL_SHOOT (500u)
#define TASK_FREQ_CTRL_CAP (100u)
#define TASK_FREQ_CTRL_COMMAND (500u)
#define TASK_FREQ_INFO (4u)
#define TASK_FREQ_MONITOR (2u)
#define TASK_FREQ_CAN (500u)
#define TASK_FREQ_AI (250u)
#define TASK_FREQ_REFEREE (1000u)

#define TASK_INIT_DELAY_INFO (500u)
#define TASK_INIT_DELAY_MONITOR (10)
#define TASK_INIT_DELAY_REFEREE (400u)
#define TASK_INIT_DELAY_AI (400u)

/* Exported defines --------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */

typedef struct {
  /* 各任务,也可以叫做线程 */
  struct {
	  osThreadId_t oled;	
    osThreadId_t can;		
    osThreadId_t rc;	
    osThreadId_t led;

    osThreadId_t left_gimbal;
    osThreadId_t right_gimbal; 
    osThreadId_t gimbal_rec; 
  
    osThreadId_t dji_motor; 
    osThreadId_t shoot; 
    osThreadId_t go;   
  } thread;
  
  /* 电机的反馈和输出 */
    struct {
		
    osMessageQueueId_t feedback_left;
    osMessageQueueId_t feedback_right;
    osMessageQueueId_t cmd_left;
    osMessageQueueId_t cmd_right;

  } queue;
	
	
	/*互斥量*/
//	struct {
//		SemaphoreHandle_t remote_control;
//		SemaphoreHandle_t imu_eulr;
//		SemaphoreHandle_t imu_gyro;
//    struct {
//			SemaphoreHandle_t feedback_gimble;
//			SemaphoreHandle_t feedback_chassis;
//			SemaphoreHandle_t feedback_shoot;
//			SemaphoreHandle_t gimbal_output;
//			SemaphoreHandle_t chassis_output;
//			SemaphoreHandle_t shoot_output;
//            SemaphoreHandle_t er_2;
//		  }can;

//     SemaphoreHandle_t feedback_left;
//	 SemaphoreHandle_t feedback_right;
//     SemaphoreHandle_t cmd_left;
//	 SemaphoreHandle_t cmd_right;
//	} mutex;
	
/* 机器人状态 */
  struct {
    float battery;
    float vbat;
    float cpu_temp;
  } status;

 // Config_t cfg; /* 机器人配置 */

#ifdef DEBUG
  struct {
    UBaseType_t cli;
    UBaseType_t command;
    UBaseType_t ctrl_chassis;
    UBaseType_t ctrl_gimbal;
    UBaseType_t ctrl_shoot;
    UBaseType_t info;
    UBaseType_t monitor;
    UBaseType_t can;
    UBaseType_t atti_esti;
    UBaseType_t referee;
    UBaseType_t ai;
    UBaseType_t rc;
    UBaseType_t cap;
  } stack_water_mark; /* stack使用 */

  struct {
    float cli;
    float command;
    float ctrl_chassis;
    float ctrl_gimbal;
    float ctrl_shoot;
    float info;
    float monitor;
    float can;
    float atti_esti;
    float referee;
    float ai;
    float rc;
    float cap;
  } freq;  /* 任务运行频率 */

  struct {
    float cli;
    float command;
    float ctrl_chassis;
    float ctrl_gimbal;
    float ctrl_shoot;
    float info;
    float monitor;
    float can;
    float atti_esti;
    float referee;
    float ai;
    float rc;
    float cap;
  } last_up_time; /* 任务最近运行时间 */
#endif
} Task_Runtime_t;

/* 此处必须要声明extern一下 */
extern Task_Runtime_t task_runtime;

extern const osThreadAttr_t attr_init;

extern const osThreadAttr_t attr_led;
extern const osThreadAttr_t attr_command;
extern const osThreadAttr_t attr_right_gimbal;
extern const osThreadAttr_t attr_left_gimbal;
extern const osThreadAttr_t attr_can;
extern const osThreadAttr_t attr_gimbal_rec;

extern const osThreadAttr_t attr_bule;
extern const osThreadAttr_t attr_motor;
extern const osThreadAttr_t attr_shoot;
extern const osThreadAttr_t attr_go;

/* Exported functions prototypes -------------------------------------------- */
//声明一下任务
void Task_Init(void *argument);

void Task_Led(void *argument);

void Task_Motor(void *argument);

void Task_Shoot(void *argument);

void Task_Go(void *argument);

void Task_CtrlGimbal(void *argument);
void Task_Can(void *argument);
void Task_AttiEsti(void *argument);
void Task_Left_Gimbal(void *argument);
void Task_Right_Gimbal(void *argument);
void Task_Gimbal_Rec(void *argument);

#endif