UART interrupt for MCF5225x

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

UART interrupt for MCF5225x

1,059 次查看
ARQuattr
Contributor IV

I need to service a UART input within 5ms. Of course if I poll continuously (without delays) the other tasks would not run. The MQX timer resolution is 5ms so this isn't low enough to reliably respond to the UART if I simply poll every tick for new data. I thought that I should either reduce the timer resolution or implement an ISR to handle this.

 

In the first solution I assume I would need to increase BSP_ALARM_FREQUENCY from 200 (ticks per second), is this correct? I'm concerned though about how this will affect all the other kernel and timer functionality. Also it seems that the interrupt approach would be preferable and improve efficiency, but if this works it would obviously be much easier at least to start with.

 

To use an interrupt, I assume I would want to use the _int_install_isr call for the specific UART port interrupt vector (similar to how the “isr” MQX example replaces the timer isr)? I also assume that this would imply that I want to open the polled serial driver (not the interrupt-driven driver). Am I on the right track with this?

 

If I do this, is there a way to signal another task to process the data immediately (without waiting any ticks), or should I expect to process and respond to the serial data within the ISR?  Does the interrupt get triggered on the start bit, or after a full character is received?  Will I also see interrupts triggered when I send data?

 

Are there other potential solutions that I should consider?

 

Thank you

1 回复

606 次查看
trailman
Contributor V

Hi,

 

I suggest you to implement this as follows :

 

- add support for the interrupt driven serial driver to your MQX BSP by setting

BSPCFG_ENABLE_ITTYA   (or ITTYB ... depending on the serial port to use) to 1 in config/board_name/user_config.h

then rebuild your BSP. The driver will be installed at MQX startup

 

- in you application, create a task at higher priority than other tasks. In this task open the serial port, then do a read() on it. The read and so the task will sleep until a full character is received. At this moment, the task immediately run, assuming no other task of same or higher priority is already running. Example for second serial port :

    com2fd = fopen("ittyb:", (char_ptr)BSP_DEFAULT_IO_OPEN_MODE);

    while (1) {

         char buf;
         fread (&buf, 1, 1, com2fd);

         /// you can process character received here or wakeup another task
    }

 

- you can wakeup another task using a lightweight semaphore (_lwsem..) or process everything after the read, as show above

 

The UART+driver has a FIFO so If you fail to call fread() before several characters are received, they are not lost and will be read by subsequent fread() calls. I don't remember the FIFO size (16 or 64 maybe).

 

You may need to disable echo on serial line so that the equipement sending characters do not receive an echo of them back. For this

         _mqx_uint flags;

        ioctl(com2fd, IO_IOCTL_SERIAL_GET_FLAGS, (pointer)&flags);
        flags &= ~IO_SERIAL_ECHO;
        ioctl(com2fd, IO_IOCTL_SERIAL_SET_FLAGS, &flags);