Hello,
I’m runnig a STM32L476VGT with FreeRTOS V9.0.0 with serveral tasks. At my GNSS-task I want to receive GNSS-data from a MAX-M8 from ublox in DMA-mode.
The problem is that it works fine in the first loop and it gives the GNSS-data back. But in the second loop of the main-task an undefinded interrupt occure and the code jump into the default-handler in startup_stm32l476xx.s.
HALUARTReceiveDMA(huartgnss, uartrxbuf, GNSSUARTBUFSIZE);
“HAL
UARTReceive
DMA” returns a “HALOK” and I get my GNSS-data in a correct form. But in the second run an undefined interrupt occurs.
When I use another receive-function like
** HAL
UARTReceive(huart
gnss, uartrx
buf, GNSSUART
BUFSIZE, GNSSUART
RECTIMEOUT);**
which uses the blocking-mode instead of DMA-mode, the undefined interrupt doesn’t occure.
Why do I post the problem in the freetos-forum?
I work with “Eclipse Oxygen” and use the “FreeRTOS”-plugin, which give me in the “Task List”-window an good overview about the current task-states. When I use “HAL
UARTReceive_DMA” the gnss-task is in “suspend”-state and when I want to wake it with “osThreadResume(gnssTaskHandle);” the undefinded interrupt occure.
So, here are my questions:
Should I pay attention to something special when I use DMA-transfer in a task?
Does FreeRTOS have an other way to handle with DMA?
Can I avoid such problems when I use events instead of interrupts?
Addtionally, here are my important code parts, which don’t working:
~~~
void MainTask(void const * argument)
{
while(1) {
osThreadResume(gnssTaskHandle);
modem_init();
modem_connect_flag = modem_connect();
if(modem_connect_flag == MODEM_STATE_IS_CONNECTED) {
gnss.timestamp = entras_get_epoch();
if (gnss_gga.fix != fix_invalid) {
gnss.latitude = (double)gnss_gga.latitude/GNSS_PRESERVE_POS;
gnss.longitude = (double)gnss_gga.longitude/GNSS_PRESERVE_POS;
}
modem_checkConnection();
}
modem_shutdown();
osDelay(SERVER_SEND_INTERVAL);
}
}
void StartGnssTask(void const * argument)
{
/* USER CODE BEGIN StartGnssTask */
gnss_init();
while(1) {
osThreadSuspend(NULL);
osThreadResume(mainTaskHandle);
if (gnss_get_data(&gnss_gga) == GNSS_STATUS_FIX) {
status.gnss_ok++;
}
else {
status.gnss_err++;
osDelay(GNSS_DELAY_RETRY);
}
}
/* USER CODE END StartGnssTask */
}
gnss
statust gnss
getdata(gga
datat *data) {
uint8_t uart_rx_buf[GNSS_UART_BUFSIZE] = {0};
char *gga_str = NULL;
char *zda_str = NULL;
data->fix = fix_invalid;
while (1) {
while (gga_str == NULL) {
fill_memory(uart_rx_buf, GNSS_UART_BUFSIZE, MEM_FILL_ZERO, 0);
/* START Receive Function */
rx_state = HAL_UART_Receive_DMA(huart_gnss, uart_rx_buf, GNSS_UART_BUFSIZE);
/* END Receive Function */
if (rx_state == HAL_TIMEOUT || rx_state == HAL_ERROR) {
return GNSS_STATUS_NO_COM;
}
zda_str = strstr((char *)uart_rx_buf, "$GNZDA");
gga_str = strstr((char *)uart_rx_buf, "$GNGGA");
}
gga_str = NULL;
zda_str = NULL;
osDelay(GNSS_TIME_BETWEEN_NEXT_FIX);
return GNSS_STATUS_OK;
}
}
~~~