View previous topic :: View next topic |
Author |
Message |
gustnado
Joined: 23 Apr 2005 Posts: 21 Location: Phoenix,AZ
|
How to tell if putc will block? |
Posted: Sat Apr 23, 2005 11:24 pm |
|
|
What is the best way to tell if a call to putc will have to wait? I know I could look at the UART status registers, but is there a better way? I don't want to call anything that will block my program - if it's going to block, I want to run background tasks and then check again.
Thanks in advance. _________________ The best weather is bad weather |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Apr 24, 2005 12:16 am |
|
|
The best way to answer this question is to write a test program
that uses putc(), and then look at the .LST file to see what the
compiler is doing.
Code: | #include <18F452.h>
#fuses XT, NOWDT, PUT, BROWNOUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//============================
void main()
{
putc(0x55);
while(1);
} |
Here is the section of the .LST for putc(). You can see that it's
testing bit 4 of register 0xF9E.
Code: | 0000 00312 ........ putc(0x55);
0020 0E55 00313 MOVLW 55
0022 A89E 00314 BTFSS F9E.4
0024 EF11 F000 00315 GOTO 0022
0028 6EAD 00316 MOVWF FAD
0000 00317 .......... |
Referring to the data sheet, we can see that 0xF9e is PIR1, and
bit 4 is the TXIF bit. Looking farther in the data sheet, you can
see a description of the TXIF bit in section 8.2.
Quote: |
bit 4 TXIF: USART Transmit Interrupt Flag bit
1 = The USART transmit buffer, TXREG, is empty (cleared when TXREG is written)
0 = The USART transmit buffer is full |
So if you don't want putc() to block, you need to test that bit before
you call putc().
Code: | #byte PIR1 = 0xF9E
#bit TXIF = PIR1.4
main()
{
char c;
if(TXIF)
putc(c);
else
// Do something else if the transmitter is not ready
while(1);
} |
My overall point is that this type of question is best answered by looking
at the .LST file and the data sheet. |
|
|
gustnado
Joined: 23 Apr 2005 Posts: 21 Location: Phoenix,AZ
|
Re: How to tell if putc will block? |
Posted: Sun Apr 24, 2005 9:04 am |
|
|
Thanks for the code example and technique. I will use it if I don't get a better one (see below). I suspect you have shown the only way to do it.
I was aware I could look at the UART. However, getc() has a routine (kbhit()) that will tell if it will block. I wondered if there were a corresponding C routine for putc, which would provide the same device configuration independence that kbhit() provides.
Again, thanks. _________________ The best weather is bad weather |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Apr 24, 2005 12:40 pm |
|
|
No, there isn't a kbhit-type of function for putc().
All the CCS functions are in listed the manual, or the Help file, or
the README.TXT file. To see if CCS has a certain function that
you want, look at these documents. Here are their locations:
Compiler Manual, revised on Feb. 2005:
http://www.ccsinfo.com/ccscmanual.zip
Help File:
C:\Program Files\Picc\Ccsc.hlp
Readme.txt File. This file has information on new functions:
C:\Program Files\PICC\Readme.txt |
|
|
gustnado
Joined: 23 Apr 2005 Posts: 21 Location: Phoenix,AZ
|
|
Posted: Sun Apr 24, 2005 1:30 pm |
|
|
I read the manual, suspected as much (although it would be easy to miss a function - there are a bunch of them).
Also, setjmp is not in the manual (that I could find - I have the Feb 2005 printed one here) but putc is, indicating that the manual is not complete. Hence I thought it worth asking.
Now we have a definitive answer: there is no kbhit equivalent for putc.
Thanks for the information. I will use assembly language to achieve my non-blocking putc. _________________ The best weather is bad weather |
|
|
jds-pic
Joined: 17 Sep 2003 Posts: 205
|
|
Posted: Sun Apr 24, 2005 1:41 pm |
|
|
gustnado wrote: | to achieve my non-blocking putc. |
on a limited-memory uC there is no such thing.
jds-pic
ps
you can use CCS C to develop an elastic store to mimic a non-blocking putc. |
|
|
gustnado
Joined: 23 Apr 2005 Posts: 21 Location: Phoenix,AZ
|
|
Posted: Sun Apr 24, 2005 2:26 pm |
|
|
I've been doing it for years on a Motorola 68HC705C8 which has less memory than the 18Fxx2 PICs.
I don't mean buffered putc, but rather one which allows other tasks to run while it is waiting for the UART to become free.
Here, the pseudo-code will be:
send_char
while ( putc_will_block )
run_background_tasks
putc
The clever printf in this compiler (which I am really liking) allows me to use this kind of non-blocking putc from the high level (printf). That's quite cool.
Receive buffering is a more important objective, and I thank you for reminding me of the need for it. _________________ The best weather is bad weather |
|
|
|