5 years, 12 months ago.

Serial Tx interrupt going to fire excessive while nothing send.

Hi mbed-friends!

I use a Nucleo-F746ZG and Mbed OS 5.8.3, and use the offline mbed toolchain, GCC_ARM, and eclipse. But I also tried this on a Nucleo-F446RE, with the same result. Just to rule out some bug with a particular platform.

In a library, I use Serial2. I enable the interrupts in main, calling library functions for that, like below.

    wait(1.0);
    test.initRxIrq();
    wait(5.0);
    test.initTxIrq(); // After this one, the Rx interrupt no longer works
    wait(5.0);

The Rx-Interrupt just works fine, but as soon as I enable the Tx-Interrupt, it start generating interrupts very fast, even while no characters are sent. The Rx-Interrupt no longer works (probably because of the high Tx-Interrupt rate).

Some code snippets...

void Modbus::initTxIrq(void)
{
    tx_in  = 0;
    tx_out = 0;
    modbusSerial.attach(this, &Modbus::txInterrupt, Serial::TxIrq);
}

void Modbus::initRxIrq(void)
{
    rx_in  = 0;
    rx_out = 0;
    modbusSerial.attach(this, &Modbus::rxInterrupt, Serial::RxIrq);
}

void Modbus::txInterrupt()
{
    ledB = !ledB;
    // Note: We shouldn't have to clear the TX interrupt
    while ((modbusSerial.writeable()) && (tx_in != tx_out)) {
        modbusSerial.putc(tx_buffer[tx_out]);
        tx_out = (tx_out + 1) % buffer_size;             // Increase circular tx_out pointer
    }
}

void Modbus::rxInterrupt()
{
    ledB = !ledB;	// Works just fine
    // Note: you need to actually read from the serial to clear the RX interrupt
    while ((modbusSerial.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) {
        rx_buffer[rx_in] = modbusSerial.getc();
        rx_in = (rx_in + 1) % buffer_size;             // Increase circular rx_in pointer
    }
}

I tried to disable the interrupt within the ISR, and then enable it once I add something to the buffer, using the corresponding line below. But the Rx interrupt doesn't work , also not if Tx interrupts are disabled this way.

    USART2->CR1 &= ~USART_CR1_TXEIE;    // Disable Tx interrupts
    USART2->CR1 |= USART_CR1_TXEIE;    // Enable Tx interrupts

Tx interrupts worked fine with Mbed 2.

Has anybody seen this before? What could I try to solve this?

Best regards, Jack.

Code snippets looks good, so something suspicions is in target implementation. Those 2 targets you tried share some part of serial, b ut interrupts are for each family own implementation.

Similar to what you are after is in UARTSerial (already having buffer and interrupts).

posted by Martin Kojtal 07 May 2018

Hi Martin, Thank you very much! I will try find some time to make a very minimal program using above. I didn't discover UARTSerial before, and will have a look at it later on.

posted by Jack Berkhout 07 May 2018

Hi, I have the exact same problem. Did you find how to fix it ?

posted by Nicolas Mathon 30 Oct 2018
Be the first to answer this question.