我的传入值在数据包内部。我必须阅读该包,然后使用此包提取实际值。我使用了一些按位运算和“一致性字节填充算法”来形成一个包。
在接收方,当检测到Uart上有传入字节时,MCU将运行ISR。阅读包装。将其发送到解码器函数,该函数返回解码值的数组。
因为我要返回一个数组,所以我不得不使用 malloc 并且必须使用 free(xxx)函数。我学到了使用 free() 在ISR中是个坏主意。所以我以某种方式编辑了我的代码,并将free(xxx)放入了主循环。
在这里,您看到我的中断处理程序函数,该函数在每次成功读取后运行。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//{2,32,2,140,3,168,100,3,1,16,0} this is an example package.End byte is always 0 and there is no other possible occurrence of 0 in 1 package thanks to the COBS algoritm
count_dooku++; // this variable counts how many interrupt has occurred. Mostly usefull For debuging. If i use free() inside of this function count_dooku stops at 22 which means after reading 2 packages it stopped. If there is no free() interrupts keep working as they should
if (huart->Instance == USART1) //current UART
{
int a=0;
if (Rx_indx==0) {for (int i=0;i<30;i++) Rx_Buffer[i]=0;} //clear Rx_Buffer before receiving new data
if (Rx_data[0]!=a) //if received data different from package end byte 0 //
{
Transfer_cplt=0;// reset Transfer_cplt value to 0 since we are receiving new package
Rx_Buffer[Rx_indx++]=Rx_data[0]; //add data to Rx_Buffer
}
else //if received data = 0 which means end of the package
{
//now transfer completed, data is ready to read
if (Rx_indx==10) //check the lenght of the package if true continue
{
for( int i=0; i < 11; i++ ){
un_decoded_data[i]= *( Rx_Buffer + i ) ;
} copy package values from buffer to another array.
Transfer_cplt=1; // mission completed. Pakage is in "un_decoded_data"
}
Rx_indx=0; //reset index counter for new data
}
}
HAL_UART_Receive_IT(&huart1, Rx_data, 1); //activate UART receive interrupt every time
}
这是我的主循环:
int main(void)
{
__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE); //initialization of uart in stm32f4 hal library
while (1)
{
if (Transfer_cplt==1) //if buffer data succesfully transfered to un_decoded_data
{
UnStuffData(un_decoded_data, 11,destination) ; //this is Consistive overhead algortim for decoding package. No problem with this one bc it uses global values
predec_package= make_predec_package(destination); //this function takes decoded data and makes some bit wise operations. and returns array of values with pointer. So i used malloc and after i am done with it i have to free it (below)
free(destination); // this one is problem. Even if not in the ISR still related to ISR so still causing problems.
for( int i=0; i < 6; i++ ){
decoded_data[i]= *( predec_package + i ) ;
}
}
}}
以防万一我要添加返回数组并产生问题的函数。这是:
int16_t* make_predec_package( unsigned char *ptr){ //function takes array as input
int8_t n;
uint8_t temp_array[11] = {0}; //temporary array for calculations and also debugging
int16_t *temporary = calloc(8, sizeof(*temporary)); //temporary must be freed by caller
if(temporary)
{
for( int i=0; i < 11; i++ ){
temp_array[i] = *( ptr + i );
}
n = temp_array[0];
//here some bitwise calculations...
temporary[0] = (temp_array[1]*256 ) + temp_array[2]/4 ;
temporary[1] = (temp_array[3]*256 )+ temp_array[4]/ 4 ;
temporary[2]= temp_array[5];
temporary[3]= temp_array[6];
temporary[4]= temp_array[7];
temporary[5]= temp_array[8];
temporary[6]= temp_array[9];
temporary[7]= temp_array[10];
}
// i am returning fully decoded data array with pointer.
return temporary;
}
答案 0 :(得分:2)
不幸的是,这段代码很幼稚,应该从头开始重写。
您应尽可能减少ISR,并且它不应包含任何应用程序逻辑。从UART接收数据后,ISR应该将数据放在缓冲区中。首选的方法是根本不使用中断,而是使用DMA。
如果您的MCU上没有DMA,则必须提出一种环形缓冲区结构,该结构将充当从ISR到应用程序的FIFO。在读取期间,您需要某种保护方式,以确保读取时(竞争条件)ISR不会写入缓冲区。
由于UART通常非常慢,因此如果您从缓冲区中获取数据的代码比在UART上输入1 + 8 + 1位所需的时间更快,那么只需在读取期间禁用中断就足够了。
然后,最好使用最少的程序设计,将UART驱动程序与应用程序逻辑完全分开。
答案 1 :(得分:-1)
我无法理解free()出了什么问题;功能。 Howaver我建议您也将我们的输出作为指针参数。 经验:
make_predec_package(destination, predec_package);
代替
predec_package= make_predec_package(destination);
返回指针总是引起我所知道的问题。
以及该更改所涉及的函数内部
void make_predec_package( unsigned char *ptr, int16_t* predec_package){ //function takes array as input
int8_t n;
uint8_t temp_array[11] = {0}; //temporary array for calculations and also debugging
//int16_t *temporary = calloc(8, sizeof(*temporary));
for( int i=0; i < 11; i++ ){
temp_array[i] = *( ptr + i );
}
n = temp_array[0];
//here some bitwise calculations...
predec_package[0] = (temp_array[1]*256 ) + temp_array[2]/4 ;
predec_package[1] = (temp_array[3]*256 )+ temp_array[4]/ 4 ;
predec_package[2]= temp_array[5];
predec_package[3]= temp_array[6];
predec_package[4]= temp_array[7];
predec_package[5]= temp_array[8];
predec_package[6]= temp_array[9];
predec_package[7]= temp_array[10];
}
// i am returning fully decoded data array with pointer.
//return temporary;
}
只有我看不到您在哪里声明了“ predec_package”,因此请确保长度为right(8 <)的数组。