Ask Larry

Dear Larry,

I am using the Rabbit embedded web server but it is not very responsive. I am calling the http_handler() function in an infinite while loop with other functions that service my device. Can you give me some advice to speed up the web server?

Riley B. K.

Hello Riley,

The first thing to do is get some visibility into how often the http_handler() function is being called. The more often you call the handler function, the faster your web server will be. You can use the built-in timer variables to time your loop like this:

Timing a Loop

unsigned long time_0; 		//Use to time the while loop with MS_TIMER
time_0 = 0; 			//initialize to zero
while(1)
{
	printf("time elapsed = %lu\r",(MS_TIMER - time_0));
	http_handler();		//Drive the web server
	time_0 = MS_TIMER;

	//Your other code here
	Some_Function();
}

(Keep in mind that the printf() statements also slow down the loop and all these times are rough estimates. For more precise numbers you could run the loop 1000 times and take an average to see the elapsed time per loop.)

If this elapsed time between handler calls is too high your web server will be slow or may even stop altogether. One quick solution is to include an occasional http_handler() call in your other functions. This will ensure that you drive the web server even in a function that blocks.

Sneaking a handler call into your function

Some_Function()
{
	//your function code here

	http_handler();		//Drive the web server

	//more function code 
}

Another possibility is to use the built-in Dynamic C multitasking to schedule your function calls. Let’s look at a piece of code without any scheduling.

The Uncontrolled While Loop

unsigned long time_0; 		//Use to time the while loop with MS_TIMER
time_0 = 0; 			//initialize to zero
while(1)
{
	printf("time elapsed = %lu\r",(MS_TIMER - time_0));
	http_handler();		//Drive the web server
	time_0 = MS_TIMER;

	//Your other code here
	Some_Function();
}

Download Code

Timing this loop we might see that the http_handler() is called only every 250 mS. That is very slow and we can also use it to calculate a percentage of time dedicated to the web server. The http_handler() is very quick and if we assume it returns in 2 mS that means that the other function Some_Function() is taking 248 mS per call. With a bit of math, we can see how much time is dedicated to each function.

	Total loop time 		= 250 mS
	http_handler() time 	= 2 mS
	Some_Function 		= 248 mS

	http_handler() 		= 0.8%		2 mS / 250 mS per loop	= 0.008
	Some_Function() 	= 99.2%		248 mS / 250 mS per loop	= 0.992

By creating a schedule for our Some_Function() with a costate, we can change these percentages.

Adding a Costate to the Loop as a Throttle

unsigned long time_0; 		//Use to time the while loop with MS_TIMER
time_0 = 0; 			//initialize to zero
while(1)
{
	printf("time elapsed = %lu\r",(MS_TIMER - time_0));
	http_handler();		//Drive the web server
	time_0 = MS_TIMER;

	costate
	{
  		//schedule 100 mS between calls to Some_Function()
		waitfor(DelayMs (100));  
		Some_Function();
	}
}

Download Code

Now on a typical pass through the loop, the costate will drop us immediately back to the http_handler() function and the web server will be very responsive. On a set schedule we call Some_function() and instead of continuously slowing down the web server we use the costate as a throttle to give the web server more processor time.

Typical Loop without a call to Some_Function()

	Total loop time 					= 3 mS 
	http_handler() time 				= 2 mS
	costate without Some_Function() 	= 1 mS

	http_handler() 		= 66.6%			2 mS / 3 mS per loop	 = 0.666
	costate 				= 33.3%			1 mS / 3 mS per loop	= 0.333

Here are the two cases side by side for comparison over about 500 mS:

	Without throttling costate 		= 2 calls to http_handler()
	With throttling costate 		= 42-43 calls to http_handler()

This rough estimation shows that a costate improvement calls the web server 21 times more often than the original which makes an enormous difference in speed for the web server.

Best of all, you can combine the two methods for even better performance. By creating a schedule with a costate and including occasional http_handler() calls in your blocking functions you should be able to create an embedded design that has plenty of time for both interactive control and serving your web pages. I have attached two example programs that demonstrate how this throttling can work.

- Larry C.

Larry Cicchinelli is Rabbit’s Technical Support Manager. He has 30 years of embedded experience, and is considered one of the foremost authorities on Rabbit products. Larry and his staff offer comprehensive technical support to Rabbit customers.

Submit your questions for Larry via email at AskLarry@rabbit.com

Read more Ask Larry Answers