CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Serial ISR Management - SOLVED

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

Serial ISR Management - SOLVED
PostPosted: Sun Nov 06, 2016 11:25 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Nov 06, 2016 12:50 pm     Reply with quote

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: 19338

View user's profile Send private message

PostPosted: Sun Nov 06, 2016 1:27 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Nov 07, 2016 7:42 am     Reply with quote

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: 19338

View user's profile Send private message

PostPosted: Mon Nov 07, 2016 11:11 am     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Thu Nov 10, 2016 1:45 am     Reply with quote

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: 19338

View user's profile Send private message

PostPosted: Thu Nov 10, 2016 2:50 am     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Thu Nov 10, 2016 7:29 am     Reply with quote

Thanks Ttelmah

Will try to understand

Best wishes
Joe
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Nov 10, 2016 11:02 am     Reply with quote

This post has links to two parsing routines, one by Ttelmah:
http://www.ccsinfo.com/forum/viewtopic.php?t=39462&start=4
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Thu Nov 10, 2016 7:29 pm     Reply with quote

Thanks PCM programmer, I copy the code so I can learn how it works

Best wishes
Joe
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group