Мои входящие значения находятся внутри пакетов данных. Мне нужно прочитать пакет, а затем использовать этот пакет для извлечения реальных значений. Я использовал некоторые побитовые операции и согласованный алгоритм заполнения байтов для формирования пакета.
На принимающей стороне при обнаружении входящего байта через 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;
}