如何解决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 举报,一经查实,本站将立刻删除。