#ifndef USER_TASK_H
#define USER_TASK_H

/* Includes ----------------------------------------------------------------- */

#include <cmsis_os2.h>

#include "freertos_mpool.h" 
#include "FreeRTOS.h"
#include "task.h"
#include  "config.h"
/* Exported constants ------------------------------------------------------- */

/* 所有任务都要定义自己的任务运行频率 */

// 分配的频率该如何给定?
#define TASK_FREQ_CHASSIS (900u)
#define TASK_FREQ_UP (900u)

#define TASK_FREQ_CTRL_CMD (500u)
#define TASK_FREQ_NUC (500u)
#define TASK_FREQ_CAN (1000u)
#define TASK_FREQ_RC (1000u)

#define TASK_FREQ_ERROR_DTC (3u)

#define DEBUG

#define TASK_INIT_DELAY_NUC (500u)

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

typedef struct {
  /* 任务 */
  struct {
    osThreadId_t atti_esti;
		osThreadId_t chassis;
		osThreadId_t up;

		osThreadId_t rc;		
    osThreadId_t can;
		osThreadId_t cmd;
    osThreadId_t nuc;
		osThreadId_t error_detect;
  } thread;

	/* 队列 */
  struct {
    struct {
      osMessageQueueId_t accl;     /* IMU读取 */
      osMessageQueueId_t gyro;     /* IMU读取 */
      osMessageQueueId_t eulr; /* 姿态结算得到欧拉角 */
    } imu;	
     /* 控制指令 */
    struct {
      struct {
        osMessageQueueId_t rc;
        osMessageQueueId_t nuc; //
        osMessageQueueId_t eulr;/*姿态结算得到的欧拉角*/
				osMessageQueueId_t nuc_send; //给nuc发
		 
      }raw;
			
			/*控制分离*/
      osMessageQueueId_t UP_cmd_ctrl_t;
			osMessageQueueId_t CHASSIS_cmd_ctrl_t;
			
      osMessageQueueId_t status;
    } cmd;
        /* can任务放入、读取，电机或电容的输入输出 */
    struct {
      struct {

        osMessageQueueId_t shoot5065;
				osMessageQueueId_t chassis3508;
				osMessageQueueId_t up_dribble_3508;
				osMessageQueueId_t up_shoot_3508;
      } output;
      struct {
				/*均包括所有数据，选择调用*/
				 osMessageQueueId_t UP_CAN_feedback;//上层
		     osMessageQueueId_t CHASSIS_CAN_feedback;//底盘
				
      } feedback;
			osMessageQueueId_t msg_raw;
    } can;
  } msgq;
	
	/*互斥量*/
	struct {
		SemaphoreHandle_t imu_eulr;
	} mutex;

	
  
	Config_t config; /* 机器人参数 */
  
	
	
#ifdef DEBUG
  struct {
    UBaseType_t chassis;
		UBaseType_t up;

    UBaseType_t can;
    UBaseType_t atti_esti;
		UBaseType_t rc;

    UBaseType_t cmd;
    UBaseType_t nuc;
		UBaseType_t error_detect;
		
  } stack_water_mark; /* stack使用 */

  struct {
    float chassis;
    float can;
    float atti_esti;
    float rc;
		float up;

    float cmd;
    float nuc;
		float error_detect;
  } freq; /* 任务运行频率 */

  struct {
    float chassis;
    float can;
    float atti_esti;
    float rc;
		float up;

    float cmd;
    float nuc;
		float error_detect;
  } last_up_time; /* 任务上一次运行的时间 */
#endif
} Task_Runtime_t;

extern Task_Runtime_t task_runtime;

extern const osThreadAttr_t attr_init;

extern const osThreadAttr_t attr_atti_esti;

extern const osThreadAttr_t attr_up;

extern const osThreadAttr_t attr_chassis;

extern const osThreadAttr_t attr_can;

extern const osThreadAttr_t attr_cmd;

extern const osThreadAttr_t attr_nuc;

extern const osThreadAttr_t attr_error_detect;

extern const osThreadAttr_t attr_rc;

//extern const osThreadAttr_t attr_r12ds;

/* Exported functions prototypes -------------------------------------------- */
void Task_Init(void *argument);

void Task_AttiEsti(void *argument);

void Task_Chassis(void *argument);

void Task_up(void *argument);

void Task_can(void *argument);

void Task_cmd(void *argument);

void Task_nuc(void *argument);

void Task_error_detect(void *argument);

void Task_rc(void *argument);
#endif
