#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丢�个��任务运行频率��和“初始化延时 1�7 */
//分配的频率该如何给定$1�7

#define TASK_FREQ_CHASSIS (500u)
#define TASK_FREQ_CTRL_CMD (500u)
#define TASK_FREQ_NUC (500u)
#define TASK_FREQ_CAN (1000u)
#define TASK_FREQ_ACTION (500u)
#define TASK_FREQ_NAVI (500u)
#define TASK_FREQ_CALCULATE (500u)
#define TASK_FREQ_REMOTE (1000u)
#define TASK_FREQ_PRINT (500u)

#define TASK_FREQ_ERROR_DTC (3u)

#define DEBUG


#define TASK_INIT_DELAY_ACTION (400u)

#define TASK_INIT_DELAY_NUC (500u)

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

typedef struct {
  /* 任务 */
  struct {
    osThreadId_t atti_esti;
		osThreadId_t chassis;
		osThreadId_t remote;
    osThreadId_t ai;
    osThreadId_t can;
		osThreadId_t cmd;
    osThreadId_t nuc;
    osThreadId_t action_ops;
    osThreadId_t calc;
    osThreadId_t navi;
		osThreadId_t error_detect;
  } thread;

	/* 队列 */
  struct {
    struct {
      osMessageQueueId_t accl;     /* IMU读取 */
      osMessageQueueId_t gyro;     /* IMU读取 */
      osMessageQueueId_t eulr; /* 姿��解算得到的欧拉规1�7 */
    } imu;	
     /* 控制指令 */
    struct {
      struct {
        osMessageQueueId_t rc;//dr16->cmd
        osMessageQueueId_t nuc;//nuc->cmd
        osMessageQueueId_t ops_9;//navi->cmd
      }raw;
      osMessageQueueId_t chassis;//cmd->chassis
      osMessageQueueId_t calc;//cmd->calc
    } cmd;
        /* can任务放入、读取,电机或电容的输入输出 */
    struct {
      struct {
        osMessageQueueId_t chassis6020;
        osMessageQueueId_t chassis5065;
				osMessageQueueId_t chassis3508;
				osMessageQueueId_t pitch6020;
      } output;
      struct {
        osMessageQueueId_t chassisfed6020;
        osMessageQueueId_t chassisfed5065;
				osMessageQueueId_t chassisfed3508;
				osMessageQueueId_t pitchfed6020;
        osMessageQueueId_t sickfed;

      } feedback;
    } can;
    struct {
      osMessageQueueId_t Chassis;
      osMessageQueueId_t Calc;
      osMessageQueueId_t Navi;
    } action;
  } msgq;
	
	/*互斥釄1�7*/
	struct {
		SemaphoreHandle_t imu_eulr;
	} mutex;

  Config_t config; /* 机器人参敄1�7 */
  
#ifdef DEBUG
  struct {
    UBaseType_t chassis;
    UBaseType_t can;
    UBaseType_t atti_esti;
		UBaseType_t dr16;
    UBaseType_t action;
    UBaseType_t calc;
    UBaseType_t navi;
    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 cmd;
    float nuc;
		float navi;
		float error_detect;
  } freq; /* 任务运行频率 */

  struct {
    float chassis;
    float can;
    float atti_esti;
    float ai;
    float r12ds;
    float cmd;
    float nuc;
		float error_detect;
  } last_up_time; /* 任务朢�近运行时闄1�7 */
#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_ops_9pos;

extern const osThreadAttr_t attr_calc;

extern const osThreadAttr_t attr_navi;

extern const osThreadAttr_t attr_error_detect;

extern const osThreadAttr_t attr_remote;
/* 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_action(void *argument);

void Task_calc(void *argument);

void Task_navi(void *argument);

void Task_error_detect(void *argument);

void Task_remote(void *argument);

#endif