View previous topic :: View next topic |
Author |
Message |
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
Serial ISR Management - SOLVED |
Posted: Sun Nov 06, 2016 11:25 am |
|
|
Hi all,
I'm developing a small PIC/ESP8266 webserver.
Its running fine and stable but I'm trying to find a way to better manage the incoming page requests.
Right now i need a serial buffer of 600+ Characters to store the incoming page requests, especially when using the POST methods...
In order to reduce the buffer needed i was thinking of adding some logic within the ISR to change its behavior or filter some data out by simply ignoring some characters.. the serial COM is at 9600 so i "have some time" with my fast clock.
My question is what is better to use IF logic or a Switch - both controlled by a 1 bit flag.
Basically have 2 different ISR codes selected by a flag.
G. _________________ CCS PCM 5.078 & CCS PCH 5.093
Last edited by Gabriel on Mon Nov 07, 2016 7:42 am; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 06, 2016 12:50 pm |
|
|
Make a test program. Look at the .LST file. The if() code, shown in bold
below, is substantially shorter than the switch-case code:
Quote: |
.................... if(bit_flag)
000C6: BTFSS 1A.0
000C8: BRA 00D0
.................... temp = 1;
000CA: MOVLW 01
000CC: MOVWF temp
000CE: BRA 00D2
.................... else
.................... temp = 0;
000D0: CLRF temp
....................
.................... switch(bit_flag)
000D2: MOVLW 00
000D4: BTFSC bit_flag
000D6: MOVLW 01
000D8: XORLW 00
000DA: BZ 00E2
000DC: XORLW 01
000DE: BZ 00E8
000E0: BRA 00EA
.................... {
.................... case 0:
.................... temp = 1;
000E2: MOVLW 01
000E4: MOVWF temp
.................... break;
000E6: BRA 00EA
.................... case 1:
.................... temp = 0;
000E8: CLRF temp
.................... break;
.................... }
|
Test program:
Code: |
#include <18F46K22.h>
#fuses INTRC_IO,NOWDT
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)
#int_rda
void rda_isr(void)
{
int1 bit_flag;
int8 temp;
int8 value;
if(bit_flag)
temp = 1;
else
temp = 0;
switch(bit_flag)
{
case 0:
temp = 1;
break;
case 1:
temp = 0;
break;
}
value = getc();
}
//======================================
void main(void)
{
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(TRUE);
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19548
|
|
Posted: Sun Nov 06, 2016 1:27 pm |
|
|
Generally, switch becomes more efficient when there are a lot of cases.
It'll change to using a jump table. However there must not be a 'default' case (so to handle a range of values, test that you are inside the range before the switch). For a small number of cases, the simple 'if' is faster. |
|
|
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
Posted: Mon Nov 07, 2016 7:42 am |
|
|
Great answers as usual.
I went ahead and made the code using a switch since i believed it to be quicker, prior to reading this.
I'll be changing that today to IFs.
Thanks for the help.
G. _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19548
|
|
Posted: Mon Nov 07, 2016 11:11 am |
|
|
As a comment consider a third approach.
Have a simple small circular buffer in the ISR.
Have a state based 'parser' that is called each time you go round the main code loop.
Your circular buffer only needs to hold the characters that may (worst case) arrive in the loop time of the main code.
Then your parser can be advancing through decode states, moving stuff to it's target destinations etc., without having to worry too much about optimisation. |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Thu Nov 10, 2016 1:45 am |
|
|
Ttelmah
Can you give an example code?
With my limited knowledge can't imagine how to do what you are proposing.
Best wishes
Joe |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19548
|
|
Posted: Thu Nov 10, 2016 2:50 am |
|
|
Problem is that the specifics depend very much on the nature of the data.
However most of my systems have one or more 'walking parsers'. When the main loop arrives at these, it checks if there is data available for this, and if so enters the parser. The parser may be a state machine walking through character patterns, or a routine building an identification string that is then checked against a table. Once a pattern is recognised, it shifts to the 'store where required', or 'perform this action' states. In each case though it only stays in the parser for as long as data is available. If the data runs out, it notes 'where it is', and returns to the main code. When the main loop arrives back at this point again, if data has arrived, it carries on from where it was. Either looking for patterns or storing data. Obviously once the data is complete, this then advances to the 'do what is required with it' state. The key point is you never 'wait' for data. The waits are done by returning to the main loop, while interrupt code accepts data if it arrives.
Now doing this you can have multiple parsers all 'running at once' in the main loop. All the buffers for each have to do is ensure they can hold the data for the worst case time, when perhaps all the other parsers have seen something.
On a current system, I have USB, three serials, I2C slave, SPI master, time based events, all happening in the same loop. One serial is 'master only', but the others can potentially see data arriving at any time. In each case short jobs are done in each, but anything involving waiting, is done by setting a counter which is decremented by an interrupt, and returning to the main loop until this expires. So things that leave the loop, all involve events like data arriving, counter expiring, etc.. When there is no data, you once again return to the loop. This is how you generate 'cooperative multi-tasking', on little chips like the PIC. |
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Thu Nov 10, 2016 7:29 am |
|
|
Thanks Ttelmah
Will try to understand
Best wishes
Joe |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
gjs_rsdi
Joined: 06 Feb 2006 Posts: 468 Location: Bali
|
|
Posted: Thu Nov 10, 2016 7:29 pm |
|
|
Thanks PCM programmer, I copy the code so I can learn how it works
Best wishes
Joe |
|
|
|