serial port programming

Programming, for all ages and all languages.
Post Reply
FlashBurn
Member
Member
Posts: 313
Joined: Fri Oct 20, 2006 10:14 am

serial port programming

Post by FlashBurn »

I want to port some linux code to my osloader (rmode), but I think linux has some standard timing values. Does anyone knows what are standard times to wait before/after you send a byte out of the com port and how long to wait for byte from the com port?

The thing is I try to get some hardware to work. You first send some "garbage" to wake the hardware up and then you start some starting protocol and I found out that I only get some data from the hardware if I wait for some time after sending and when I try to get some bytes from the hardware.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: serial port programming

Post by Brendan »

Hi,
FlashBurn wrote:The thing is I try to get some hardware to work. You first send some "garbage" to wake the hardware up and then you start some starting protocol and I found out that I only get some data from the hardware if I wait for some time after sending and when I try to get some bytes from the hardware.
Do you:
  • a) poll the "transmitter holding register empty" flag in the line control register and make sure the transmitter holding register is empty before attempting to send the next byte; or
    b) maintain a buffer of bytes to be sent and use the "transmitter holding register empty" interrupt to avoid wasting heaps of time polling; or
    c) shove bytes at the serial port as fast as the CPU can, while expecting the old/slow serial port to keep up? ;)
I'm guessing you tried the last option. I'd recommend using the second option if you can, but the first option is simpler and won't hurt performance too much if you don't send many bytes.

Note: the second option isn't too complex. The basic idea goes like this:

Code: Select all

sendByte(unsigned char new_byte) {
    disable_interrupts();
    if (my_FIFO_is_empty() && THR_is_empty() ) {
        send_byte_directly_to_serial_port(new_byte);
        return;
    }
    enable_interrupts();

    while (my_FIFO_is_full() ) {
        /* Wait for IRQ handler to create some more space */
    }

    disable_interrupts();
    add_byte_to_my_FIFO(new_byte);
    enable_interrupts();
}

/* Note: IRQ handler below uses an interrupt gate (interrupts disabled by CPU automatically) */

serial_port_IRQ_handler(void) {
    unsigned char byte;

    if( source_of_IRQ == THR_EMPTY) {
        if( my_FIFO_is_not_empty() ) {
            byte = get_byte_from_my_FIFO();
            send_byte_directly_to_serial_port(byte);
        }
    }
}
The idea here is to send bytes to the serial port as fast as possible, *without* making the caller wait until bytes are actually sent.

If you're planning to use this to display messages while the kernel boots (like I do), then polling can suck a lot. Using "9600 N81" it takes about 1 ms to send one byte, so for a string like "Hello World!" (12 characters) you can (hopefully) send the first byte immediately and the other 11 bytes take about 1 ms each (because you need to wait for the previous byte to finish being sent), so it takes at least 11.45 ms.

Now imagine what happens during OS boot, where you're alternating between sending bytes and doing other things. For example (using "9600 N81"), if you send 300 characters, then do 50 ms of other work, then send another 200 characters, then do 500 ms of other work - for polling it would take 1070 ms, but for IRQs it'd take 550 ms.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
FlashBurn
Member
Member
Posts: 313
Joined: Fri Oct 20, 2006 10:14 am

Re: serial port programming

Post by FlashBurn »

I´m still working on my loader and my 3rd stage :roll: So I don´t send debug msgs to another PC.

I will post it here when I´m done with what I want to do (it is some feaky stuff w/o real needing ;) ). I don´t like to use the interrupt method, because I don´t want to handle irqs in rmode and because the only thing that is running is my bootloader, I can use polling with the help of the FIFO buffers.

Reading the port with some timeout is working now, but the problem is writing (I hope so). So I will have a deeper look at the rs232 interface and I will try your 1st method, maybe it works. I also thought about sending a byte and looking how the regs have changed to see if I get some feedback if the byte has arrived.

The waiting is no problem, because I talk with some hardware and have to wait till it answers.
FlashBurn
Member
Member
Posts: 313
Joined: Fri Oct 20, 2006 10:14 am

Re: serial port programming

Post by FlashBurn »

Thanks, Brendan now it works as aspected! (it was the "transmitter holding register empty" flag)
Post Reply