#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_CTRL_CMD (500u)
#define TASK_FREQ_NUC (500u)
#define TASK_FREQ_CAN (1000u)
#define TASK_FREQ_R12DS (1000u)
#define TASK_FREQ_DR16 (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 dr16;		
	  osThreadId_t r12ds;  
    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;/*姿态结算得到的欧拉角*/
				
		 
      }raw;
      osMessageQueueId_t chassis;
      osMessageQueueId_t status;
    } cmd;
        /* can任务放入、读取,电机或电容的输入输出 */
    struct {
      struct {
        osMessageQueueId_t chassis6020;
        osMessageQueueId_t chassis5065;
				osMessageQueueId_t chassis3508;
				osMessageQueueId_t pitch6020;
      } output;
      struct {
		     osMessageQueueId_t CAN_feedback;//包括底盘,云台6020,3508,5065,sick,can上设备数据
      } feedback;
    } can;
  } msgq;
	
	/*互斥量*/
	struct {
		SemaphoreHandle_t imu_eulr;
	} mutex;

	
  
	Config_t config; /* 机器人参数 */
  
	
	
#ifdef DEBUG
  struct {
    UBaseType_t chassis;
    UBaseType_t can;
    UBaseType_t atti_esti;
		UBaseType_t dr16;
		UBaseType_t r12ds;

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

  struct {
    float chassis;
    float can;
    float atti_esti;
    float r12ds;
		float dr16;

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

  struct {
    float chassis;
    float can;
    float atti_esti;
    float r12ds;
		float dr16;

    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_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_dr16;

//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_can(void *argument);

void Task_cmd(void *argument);

void Task_nuc(void *argument);


void Task_error_detect(void *argument);

void Task_r12ds(void *argument);

void Task_dr16(void *argument);
#endif