How can set serial driver in interrupt mode?

Ricardo Derbes rmderbes at gmail.com
Wed Jul 8 10:56:04 UTC 2015


Hello.
I'm trying to build an rtems application for leon3 with apbuart in
interrupt mode, but polled mode is always used
My setup is:
RTEMS-4.10.2 (rtems-4.10-1.2.16-src.tar.bz2)
RCC-1.2.16 RTEMS-4.10, GCC 4.4.6
(sparc-rtems-4.10-gcc-4.4.6-1.2.16b-linux.tar.bz2)
Both from Gaisler's site.

The BSP is the default for RCC, leon3. (-qleon3)
My system.h file is:

#include <rtems.h>
#define CONFIGURE_INIT
#include <bsp.h>
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER

#define CONFIGURE_MAXIMUM_TASKS             4
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE

#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
#define CONFIGURE_EXTRA_TASK_STACKS    (3 * RTEMS_MINIMUM_STACK_SIZE)
#define CONFIGURE_MAXIMUM_DRIVERS 4

#include <rtems/confdefs.h>

#ifdef RTEMS_DRVMGR_STARTUP
    #ifdef LEON3
        #include <drvmgr/ambapp_bus.h>
        /* Add Timer and UART Driver */
        #ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
            #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GPTIMER
        #endif

        #ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
            #define CONFIGURE_DRIVER_AMBAPP_GAISLER_APBUART
        #endif

        /* APBUART0 */

        struct drvmgr_key grlib_drv_res_apbuart0[] =
        {
            { "mode",   KEY_TYPE_INT, { (unsigned int) 0 } },
            { "syscon", KEY_TYPE_INT, { (unsigned int) 1 } },
            { "dbgcon", KEY_TYPE_INT, { (unsigned int) 1 } },
            KEY_EMPTY
        };

        /*  APBUART1  */

        struct drvmgr_key grlib_drv_res_apbuart1[] =
        {
            { "mode",   KEY_TYPE_INT, { (unsigned int) 1 } },
            { "syscon", KEY_TYPE_INT, { (unsigned int) 0 } },
            { "dbgcon", KEY_TYPE_INT, { (unsigned int) 0 } },
            KEY_EMPTY
        };

        struct drvmgr_drv_res grlib_drv_resources[] =
        {
            {DRIVER_AMBAPP_GAISLER_APBUART_ID, 0, &grlib_drv_res_apbuart0[0]},
            {DRIVER_AMBAPP_GAISLER_APBUART_ID, 1, &grlib_drv_res_apbuart1[0]},
            RES_EMPTY
        };

    #endif
#include <drvmgr/drvmgr_confdefs.h>

And the code of my test application;
#include "system.h"
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>

#define BUFFSIZE  256

rtems_task Init(rtems_task_argument ignored)
{
    #define RXSIZE (ssize_t)1024
    int rxLen = 1;
    char rxBuf[RXSIZE];
    struct termios term;
    static char *uart_name = { "/dev/console_b" };
    int fd;
    int32_t outCons; /* console file descriptor */
    char outBuf[BUFFSIZE];
    uint32_t nRead;
    (void)(ignored);

    if( (outCons = open("/dev/console", O_RDWR | O_NOCTTY)) < 0 )
        exit(1);
    sprintf(outBuf, "Starting\n");
    write(outCons, outBuf, strlen(outBuf));

    if( (fd = open(uart_name, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0 )
    {
        sprintf(outBuf, "Error opening %s: [%d] %s\n", uart_name,
errno, strerror(errno));
        write(outCons, outBuf, strlen(outBuf));
        exit(1);
    }

    tcgetattr(fd, &term);
    cfsetospeed(&term, B115200);
    cfsetispeed(&term, B115200);
    term.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT
| ECHOCTL | ECHOKE | IEXTEN | ISIG);
    term.c_cflag |= (CLOCAL | CREAD);
    term.c_cflag |= CS8;
    term.c_oflag &= ~OPOST;
    term.c_iflag = IGNBRK;
    tcsetattr(fd, TCSANOW, &term);
    tcflush(fd, TCIOFLUSH);

    while (1)
    {
        rxLen = read(fd, rxBuf, RXSIZE);
        if( rxLen < 0)
        {
            sprintf(outBuf, "Error %d in read(): %s\n", errno, strerror(errno));
            write(outCons, outBuf, strlen(outBuf));
            exit(1);
        }
        nRead += rxLen;
        if(rxLen == 0)
            write(outCons, ".", 1);
        else
        {
            sprintf(outBuf, "\nnRead: %d\n", (int)nRead);
            write(outCons, outBuf, strlen(outBuf));
        }
    }
}

But debugging it, it always uses polled mode for apbuart[1] (and apbuart[0]
I've found that in function
apbuart_init1(struct drvmgr_dev *dev)
when it gets keys value for "mode", it returns NULL, so mode is
TERMIOS_POLLED and
so the callbacks to be used are rtems_termios_callbacks = Callbacks_poll.
How can I set up the serial driver in interrupt mode, without
modifying apbuart_cons.c code
and rebuild the BSP?
Thank you.


More information about the users mailing list