alejoseb / Modbus-STM32-HAL-FreeRTOS

Modbus TCP and RTU, Master and Slave for STM32 using Cube HAL and FreeRTOS
GNU Lesser General Public License v2.1
576 stars 191 forks source link

UART Debugging log on the same UART as Modbus #107

Closed Olgidos closed 4 months ago

Olgidos commented 4 months ago

Is there an easy fix, so that I can send debug messages via the same UART interface from differen RTOS tasks like this:

        HAL_GPIO_WritePin(UART_Enable_GPIO_Port, UART_Enable_Pin, GPIO_PIN_SET);
        hstatus = HAL_UART_Transmit(gHuart, (uint8_t*) ptr, len, 100);
        HAL_GPIO_WritePin(UART_Enable_GPIO_Port, UART_Enable_Pin, GPIO_PIN_RESET);

it currently works until I get the first Modbus request, then both the debug log and modbus stops working, even so no task is hanging.

i also tried to use semaphores:

int _write(int fd, char *ptr, int len) {

    QueueHandle_t semaphoreHandle = (QueueHandle_t)ModbusH.ModBusSphrHandle;
    // Take the semaphore

    HAL_StatusTypeDef hstatus;
    if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {

     if (xSemaphoreTake(semaphoreHandle, (TickType_t)100) == pdTRUE) {
        //prevent switching
         taskENTER_CRITICAL();
         __disable_irq();

        HAL_GPIO_WritePin(UART_Enable_GPIO_Port, UART_Enable_Pin, GPIO_PIN_SET);
        hstatus = HAL_UART_Transmit(gHuart, (uint8_t*) ptr, len, 100);
        HAL_GPIO_WritePin(UART_Enable_GPIO_Port, UART_Enable_Pin, GPIO_PIN_RESET);

        xSemaphoreGive(semaphoreHandle);
         taskEXIT_CRITICAL();
         __enable_irq();
        //till here
     }
        if (hstatus == HAL_OK)
            return len;
        else
            return EIO;
    }
        errno = EBADF;
        return -1;

}
alejoseb commented 4 months ago

I would not call a "fix" but rather a hack what you need here, and for sure it would break Modbus. This protocol is time sensitive and uses states to handle the telegrams according to a master-slave architecture not compatible with your modifications. Eventually it could work, but you need to first stop the serial port an reconfigure it for Modbus after every debug message.

Instead, I recommend you to explore overloading the Modbus protocol itself, you can for example have a specific memory area were you dump debug messages and then you retrieve that using the multi-register read function, but always maintaining the master-slave architecture.

Olgidos commented 4 months ago

Ok I see. This sounds quite error prone and I already expected that it would be unlikely to get it to work. Then I will try it this way.