Hi Wolfgang,

On 26/10/11 18:00, Wolfgang Denk wrote:
> Dear Graeme,
> 
> In message 
> <calbutckq_bgpozquozzqnu01v41y+uwo8ellnqse15d30p5...@mail.gmail.com> you 
> wrote:
>>
>> Well, I have the feeling than an console API might be in order. The way
>> U-Boot is structured at the moment, serial I/O is kind of taken for
>> granted to 'just exist' and nobody needs to really be self-aware that
>> they use it...
> 
> Indeed. All we need is a working set of srdin/stdout/stderr.  Keep in
> mind that anything couldbe attached - not only a serial line.
> 
>>           ... The same cannot be said of users of USB and Network -
>> Net is a good example - all 'users' of net call NetLoop() which does
>> an eth_init()...do stuff...eth_halt()
> 
> Driver API...
> 
>> So maybe a serial API which 'users' must 'wake up' and 'sleep'...
> 
> Arghhh...
> 
>>  - console_configure() - Set parameters (port, baud rate etc)
>>  - console_wake() - Prepare the console (could be serial, USB, netconsole)
>>  - console_flush() - Throw away any buffered characters
>>  - console_getc(), console_putc(), console_tstc() - Self explainatory
>>  - console_sleep() - Shut the console down (send XOFF, turn of USB etc)
> 
> Forget it.  We will not have a separate and completely non-standard "serial 
> API".
> If anything gets changed here, then in the context of a general driver
> API cleanup, or at least based on a design for such a generic driver
> API.

Funny, I wrote that without the code in front of me. But look at this...

struct serial_device {
        char name[NAMESIZE];

        int  (*init) (void);
        int  (*uninit) (void);
        void (*setbrg) (void);
        int (*getc) (void);
        int (*tstc) (void);
        void (*putc) (const char c);
        void (*puts) (const char *s);
#if CONFIG_POST & CONFIG_SYS_POST_UART
        void (*loop) (int);
#endif

        struct serial_device *next;
};

and

struct stdio_dev {
        int     flags;          /* Device flags: input/output/system    */
        int     ext;            /* Supported extensions                 */
        char    name[16]        /* Device name                          */

/* GENERAL functions */

        int (*start) (void);    /* To start the device          */
        int (*stop) (void);     /* To stop the device           */

/* OUTPUT functions */

        void (*putc) (const char c);    /* To put a char        */
        void (*puts) (const char *s);   /* To put a string      */

/* INPUT functions */

        int (*tstc) (void);             /* To test if a char is ready...*/
        int (*getc) (void);             /* To get that char             */

/* Other functions */

        void *priv;                     /* Private extensions           */
        struct list_head list;
};

and

void serial_stdio_init (void)
{
        struct stdio_dev dev;
        struct serial_device *s = serial_devices;

        while (s) {
                memset (&dev, 0, sizeof (dev));

                strcpy (dev.name, s->name);
                dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT;

                dev.start = s->init;
                dev.stop = s->uninit;
                dev.putc = s->putc;
                dev.puts = s->puts;
                dev.getc = s->getc;
                dev.tstc = s->tstc;

                stdio_register (&dev);

                s = s->next;
        }
}

and mpc512x has this gem

int close_port(int num)
{
        struct stdio_dev *port;
        int ret;
        char name[7];

        if (num < 0 || num > 11)
                return -1;

        sprintf(name, "psc%d", num);
        port = stdio_get_by_name(name);
        if (!port)
                return -1;

        ret = port->stop();
        clear_bit(num, &initialized);

        return ret;
}

stdio_dev->start() is called in console_setfile() which is called by
console_init_r(). stdio_dev->stop() is never called apart from in the above
mpc512x example.

As I said, stdio is, unlike other devices, taken for granted - It gets
setup during console_init_r() and is assumed to be in-volatile from then on.

So the hooks are already there - All that would be needed is a hook to
allow console users to ultimately call stdio_dev->start when they want to
start using stdio and stdio_dev->stop when they are finished. Of course the
physical device itself is hidden and could be serial, USB, Ethernet, VGA,
Braille display - whatever.

Hmmm, stdio_open() and stdio_close()

>> UART like your SPI example. The command line interpreter calls
>> console_sleep() to release the serial UART resource before the command
>> which uses the multiplexed device wakes that device, does it's thing and
>> shuts the device down before returning to the command line interpreter
>> which wakes up the serial UART...
> 
> Sorry, but that's crappy by design.

When resources are tight - The eNET board has 8-bit CF ports instead of 16
bit because of board space and FPGA limitation which necessitated a slight
mod to the Linux CF driver. Crappy yes, but hey, when given lemons

Regards,

Graeme
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to