Export to GitHub

btstack - issue #369

restructure run_loop slightly, better for MCUs


Posted on Jan 26, 2014 by Swift Dog

BTstack appears to be designed to be "the heart" of a embedded system, it forces the system to run in an infinite loop and all other tasks to be delegated to timer events.

This is not exactly ideal. Not every application works well in this fashion, especially when BT is added in as a secondary feature.

The problem can be solved by making a few simple changes:

execute_once should be public, not private/static

"extern const run_loop_t run_loop_embedded;" should not be declared in run_loop.c, it should be in run_loop.h instead. This way, I can add my own run_loop_custom.

most/all ARM Cortex M microcontrollers have a SysTick ISR that can be used for the timer. Personally, I implement my own global millisecond counter using that ISR. The timers in run_loop would benefit from using a user provided number, perhaps by registering a pointer? Either that, or make the static variable "system_tick" accessible externally so that my SysTick ISR can increment it.

Comment #1

Posted on Jan 28, 2014 by Swift Ox

(No comment was entered for this change.)

Comment #2

Posted on Feb 4, 2014 by Swift Ox

I've made embedded_execute_once public by exposing it in the run_loop.h for now (until a better approach if found)

Can you explain in more detail why extern const run_loop_t run_loop_embedded should be in run_lopo.h instead of run_loop.c. To add your own run loop type, you have to modify run_loop.c anyway, no?

timers: my idea was that your global timer can periodically call embedded_tick_handler(). the times in BTstack are in the seconds range (I think the shortest one is a 2 seconds timer in l2cap signaling). what benefit do you see if your local counter would be used (aside from saving 4 bytes)?

Comment #3

Posted on Feb 4, 2014 by Swift Dog

Ohhhhhh I'm supposed to store a function pointer to the result of hal_tick_set_handler's argument and call it?

Ok I didn't understand that bit before. Now that I actually understand your intention, I agree that it works, at the cost of a few bytes and cycles.

By the way, to me, every byte counts, every cycle counts. I am always in favor of setting things during compile time instead of run time.

Wouldn't it be much easier to just write one public function and tell us to "call this once every ms"? Is the stack really ever going to register more than one tick handler?

Comment #4

Posted on Feb 4, 2014 by Swift Ox

The one public function already exists: you can call embedded_tick_handler() periodically and provide it's period by the hal_tick_get_tick_period_in_ms().

lol. Just got BTstack running on an Arduino Mega Pro 3.3 and was wondering how to bridge between the Arduino's time functions (mainly millis()) and BTstack's tick counter. Without an extra timer, I would need to track changes to millis() and then call embedded_tick_handler - that's certainly not good.

I'll go with your suggestion and add a setter for the system tick.

other insights? :)

Comment #5

Posted on Feb 5, 2014 by Swift Dog

Ask your average Arduino user what a "function pointer" means, they won't be able to answer.

Arduino users will also be confused as hell when they call run_loop and everything just freezes.

Comment #6

Posted on Feb 6, 2014 by Swift Ox

With the tick setter and the public execute once, that's done, right?

Comment #7

Posted on Feb 6, 2014 by Swift Dog

Yea, it should be usable

Status: Fixed

Labels:
Type-Enhancement Priority-Medium