微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

esp32 在等待 XQueueRecieve 监视 uart 中断时崩溃

如何解决esp32 在等待 XQueueRecieve 监视 uart 中断时崩溃

(编辑):解决了,我试图在两个不同的任务中同时访问 uart ringbuffer 并且从未释放输出。改变它现在消除了崩溃。

因此,当它运行时,我会等待来自 uart 的任何输入以终止正在运行的进程;但是,当我提供该输入时,系统会中止并重新启动......有什么明显明显的突出显示吗?

我知道它看起来像很多代码,但我发布了所有与上下文相关的内容。要查看的核心点是:app_main(void)、run_time 和 uart_Stop_ISR。

这里是主要的:

void app_main(void)
{
setbuf(stdout,NULL);//ensures that printf statements are not buffered waiting for carriage returns.

configureUart();
NED_Var *bubba_Data=malloc(sizeof(NED_Var));
initStruct(bubba_Data);//sets initial values of the structure

printStructData(bubba_Data);//prints the struct values

isr_semaphore = xSemaphoreCreateBinary();


vTaskDelay(pdMS_TO_TICKS(1000));


xTaskCreate(startmenu,"start menu",2048,&bubba_Data,2,NULL);
vTaskDelay(10);

xTaskCreate(uart_Stop_ISR,"uart isr",1024,4,NULL);
vTaskDelay(10);

for(;;)
{
  vTaskDelay(10);//needed to give idle task time to reset the WDT
}

free(bubba_Data);
}

这是使用的任务/功能/结构: 这个结构包含几乎所有有价值的东西。

typedef struct NED_Var
{
  uint32_t date_time;
  char *DUT;
  uint32_t SN;
  double idleVoltage;
  uint32_t freq;
  bool atxClampEn;
  uint8_t stop;

} NED_Var;

我使用 esp32 的读/写字节函数重写了一个 uart 输入,因为 scanf 是一个“no-go”。

/*************************************************************
 * Function: uint8_t* bubba_RX
 * 
 * Description: allows the user to utilize the uart in a more simplified fashion
 * 
 * Arguments: nothing
 * 
 * Returns: a uint8_t* item
 * 
 * Notes: The esp32 requires use of non standard uart serial read/write interfaces
 *        Therefore this function makes using them simpler,and provides a more standard feel
 * 
 ***/
uint8_t* bubba_RX()
{
    uint8_t *data = (uint8_t *) malloc(sizeof(char));
    uint8_t *data2= (uint8_t *) malloc(BUF_SIZE);

      for(int i=0; data[0] != 13; i++)
      {
        int len = uart_read_bytes(UART_NUM_0,data,sizeof(char),portMAX_DELAY);
        uart_write_bytes(UART_NUM_0,(const char *) data,len);
        data2[i]=data[0];
        data2[i+1]=0;
      }
      
      // printf("Data2 is: %s\n",(char*)data2);//for debugging

      return data2;
      
}

配置设备 uart 的简单功能,很确定此时它主要是多余的,因为认设置可以工作。

/*************************************************************
 * Function: void configureUart
 * 
 * Description: Configures the Uart device for serial communication
 * 
 * Arguments: none.
 * 
 * Returns: nothing
 * 
 * Notes: Must be called in order to use any sort of serial communication.
 * 
 ***/
void configureUart()
{
    uart_config_t uart_config = {//this allows the user to configure the uart however they might need. default is typically fine
      .baud_rate = 115200,.data_bits = UART_DATA_8_BITS,.parity    = UART_PARITY_disABLE,.stop_bits = UART_STOP_BITS_1,.flow_ctrl = UART_HW_FLOWCTRL_disABLE,.source_clk = UART_SCLK_APB,};
  
  ESP_ERROR_CHECK(uart_driver_install(UART_NUM_0,BUF_SIZE * 2,BUF_SIZE*2,20,&uart0_queue,0));
  ESP_ERROR_CHECK(uart_param_config(UART_NUM_0,&uart_config));
  ESP_ERROR_CHECK(uart_set_pin(UART_NUM_0,ECHO_TEST_TXD,ECHO_TEST_RXD,ECHO_TEST_RTS,ECHO_TEST_CTS));

  
}

初始化我的结构以使用合理的值

/*************************************************************
 * Function: void initStruct
 * 
 * Description: Initializes the structure to "sane" values
 * 
 * Arguments: Ned_Var * struct
 * 
 * Returns: nothing
 * 
 * Notes: This comes up upon POR every time
 * 
 ***/
void initStruct(NED_Var *param)
{
  param->date_time=0; 
  param->freq=10000; 
  param->SN=0;
  param->DUT=(char*)malloc(512); 
  param->DUT="XAmple6666";
  param->idleVoltage=2.1; 
  param->atxClampEn=false;
  param->stop=1;
  }

允许用户向结构体输入数据,我知道我需要添加输入过滤器

/*************************************************************
 * Function: void getStructData
 * 
 * Description: allows the user to enter operational points
 * 
 * Arguments: Ned_Var * struct
 * 
 * Returns: nothing
 * 
 * Notes: This comes up upon POR to allow initial setup of the test enviroment
 * 
 ***/
void getStructData(NED_Var *param) 
{
  printf("\nEnter the date: ");
  param->date_time=atoi((char*)bubba_RX());
  printf("\nEnter data for serial number: ");
  param->SN=atoi((char*)bubba_RX());
  printf("\nEnter data for DUT: ");
  param->DUT=(char*)bubba_RX();
  printf("\nEnter data for Idle Voltage: ");
  param->idleVoltage=atof((char*)bubba_RX());
  printf("\nEnter data for frequency: ");
  param->freq=atof((char*)bubba_RX());
  printf("\nEnter data for ATX_En 1 or 0: "); 
  param->atxClampEn=atoi((char*)bubba_RX());
}

打印出当前的结构值

/*************************************************************
 * Function: printStructData
 * 
 * Description: Prints the passed struct data
 * 
 * Arguments: Ned_Var * struct
 * 
 * Returns: nothing
 * 
 * Notes:
 * 
 ***/
void printStructData(NED_Var *param)
{
  printf("\n\nThe struct data is: ");
  printf("\n Date: %08d",param->date_time);
  printf("\n S/N: %d",param->SN); 
  printf("\n DUT: %s",param->DUT); 
  printf("\n Idle Voltage: %.2f",param->idleVoltage);
  printf("\n ATX Clamp Enable: %s",(param->atxClampEn ? "true":"false"));
  printf("\n Frequency: %d\n",param->freq);
}

允许用户更新结构中的单个项目

/*************************************************************
 * Function: void updateParam
 * 
 * Description: Allows the user to update a single parameter of Ned Var Struct
 * 
 * Arguments: Ned_Var * struct
 * 
 * Returns: nothing
 * 
 * Notes:
 * 
 ***/
 
void updateParam(NED_Var *param)
{
  printf("\n---------------------------------------------\n");
  printf("Select the parameter you would like to update:\n");
  printf("1) Date,currently: %d\n",param->date_time);
  printf("2) S/N,param->SN);
  printf("3) DUT,currently: %s\n",param->DUT);
  printf("4) Idle Voltage,currently: %.2f\n",param->idleVoltage);
  printf("5) ATX_Clamp_En,param->atxClampEn ? "true":"false");
  printf("6) Frequency,param->freq);
  uint8_t result=atoi((char*)bubba_RX());

  switch (result)
  {
    case 1:
      printf("\n Enter the new Date: ");
      param->date_time=atoi((char*)bubba_RX());
      break;
    case 2:
      printf("\n Enter the new S/N: ");
      param->SN=atoi((char*)bubba_RX());
      break;
    case 3:
      printf("\n Enter the new DUT: ");
      param->DUT=(char*)bubba_RX();
      break;
    case 4:
      printf("\n Enter the new Idle Voltage: ");
      param->idleVoltage=atof((char*)bubba_RX());
      break;
    case 5:
      printf("\n ATX Clamp En enter 1 or 0(True/False): ");
      param->atxClampEn=atoi((char*)bubba_RX());
      break;
    case 6:
      printf("\n Enter the new frequency: ");
      param->freq=atoi((char*)bubba_RX());
      break;

    default:
    printf("That was not a valid option,please start again\n");
      //break;
  } 
}

打印当前结构值

/*************************************************************
 * Function: printStructData
 * 
 * Description: Outputs a menu that lets users adjust settings or begin testing
 * 
 * Arguments: a Void param that must actually be a Ned_Var * struct
 * 
 * Returns: nothing
 * 
 * Notes: FreeRtos requires its functions to be void function(void *param),otherwise we would directly pass the Ned_Var * struct
 * 
 ***/
void startmenu(void *param)
{
  NED_Var *tmp_pnt=param;
  // SemaphoreHandle_t beginTest = xSemaphoreCreateBinary();
  // if(beginTest != NULL)
  //   printf("\nSemaphore created successfully\n");
  // vTaskDelay(pdMS_TO_TICKS(500));

  for(;;)
  {
    uart_flush_input(UART_NUM_0);
    fflush(stdout);
    vTaskDelay(10);
    printf("\nWould you like to begin testing?(y/n)\n");
    uint8_t *response = bubba_RX();
    
    switch ((uint8_t) *response)
    {
      case 89: //user entered "Y"
      case 121://user entered "y"
        printf("Are you sure you would like to begin?(y/n)\n");
        response=bubba_RX();
        tmp_pnt->stop=1;
        if(strcmp((char*)response,"y"))
        {
          // xSemaphoreGive(beginTask); //tells the interface to release control to the lower priority task that runs the test 
          
          runTime(param);       
        } 
        break;

      case 78: //user entered "N"
      case 110://user entered "n"
        printf("\nWould you like to update one or more parameters?(one/more)\n");
                response=bubba_RX();
        if(strcmp((char*)response,"one"))
        {
          updateParam(param);
      
        }
        else
        getStructData(param);
        
        break;

      default:
        printf("\n %s is not a valid entry\n",(char*)response);
        vTaskDelay(pdMS_TO_TICKS(1000));
        break;
    }
  }
}

只是一个startmenu 函数启动以输出运行时信息的函数。该函数提供了解锁等待uart输入结束本次测试的任务的信号量。

/*************************************************************
 * Function: void runTime
 * 
 * Description: takes a semaphor when the test is ready to begin and outputs the runtime data specified in the header file
 * 
 * Arguments: a Void param that must actually be a Ned_Var * struct
 * 
 * Returns: nothing
 * 
 * Notes: this function can only be started when called by the higher priority task
 * 
 ***/
void runTime(void *param)
{
  NED_Var* temp_pnt=param;
  temp_pnt->stop=1;
  xSemaphoreGive(isr_semaphore);
  printf("\r pulse Voltage: %f.2|Test Time: %s| Hit Any Key to Exit",12.21,"tbd");
  while ((temp_pnt->stop)!=0)   
  {
    vTaskDelay(pdMS_TO_TICKS(500)); 
  }     
    printf("\n Outside of the while loop Now\n"); 
}

等待uart输入结束测试的函数

/*************************************************************
 * Function: void IRAM_ATTR uart_Stop_ISR
 * 
 * Description: waits for a semaphore to get started then blocks at a queue waiting for input
 * 
 * Arguments: a Void param that must actually be a Ned_Var * struct
 * 
 * Returns: nothing
 * 
 * Notes: n/a
 * 
 ***/
void IRAM_ATTR uart_Stop_ISR(void *param)
{
  NED_Var* temp_pnt=param;
  uart_event_t event;
   for(;;)
  {
    xSemaphoreTake(isr_semaphore,portMAX_DELAY);
    xQueueReset(uart0_queue); 
    vTaskDelay(pdMS_TO_TICKS(3000));
    if(xQueueReceive(uart0_queue,&event,portMAX_DELAY))
    {
      if(event.type == UART_DATA)
      {
        temp_pnt->stop=0;
        vTaskDelay(pdMS_TO_TICKS(1000));
      }   
    }
  }
}
 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。