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.
serial port programming
Re: serial port programming
Hi,
Note: the second option isn't too complex. The basic idea goes like this:
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
Do you: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.
- 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?
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);
}
}
}
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.
Re: serial port programming
I´m still working on my loader and my 3rd stage 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.
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.
Re: serial port programming
Thanks, Brendan now it works as aspected! (it was the "transmitter holding register empty" flag)