Application development guide
There is a single commit (commit:64805071) that contains an example application that might be a good starting point to start development. I did my best to make it as simple as possible, but here you may find some additional comments.
Template (example_app.c)
NOTE: There is a slight mistake, the header file (example_app.h) is not
necessary and not used anywhere.
There are two main concepts that may help you understand the way
application works.
Events
Freewatch applications are event-driven - they receive information about
what is going on, so they have a chance to respond appropriately. An
example of action that results in event reception is a button press or
sensor interrupt. Afterwards, you may decide to redraw a part of user
interface, update internal state or save data - depending on what has
happened. Available event types are listed in src/sw/common/event.h.
Events are transferred from the operating system to applications via
queue. Typically, there is one main loop that receives them and lets you
decide what should happen next.
If you expect events from sensors, you should configure them to generate
interrupts. Enabling unnecessary interrupt sources results in redundant
events and may decrease both performance and battery life. It is a good
practice to react only to events that you expect and really handle in
the code.
Widgets
Widgets are parts of the graphical user interface, such as buttons, checkboxes, scrollbars, etc. They have a visible representation and are expected to react to events.
Do not forget to add the new file to Makefile.
Menu entry
To make your application visible in the main menu, choose the right submenu (or create a new one) and an entry in sw/freertos/apps/src/menu_struct.c:
{ APP, &example_icon, { .app = &example } },
The three fields indicate:
- APP stands for application type entry
- &example_icon is pointer to a structure containing icon data (or NULL if there is no icon); more details below
- structure dependent on entry type; for applications it stores a pointer to your application structure
Example submenu entry:
{ SUBMENU, NULL, { .submenu = &sub_menu } },
explained:
- SUBMENU is the entry type
- NULL means that there is no icon (but you can have one for submenus too)
- the last field is a structure with a pointer to the submenu (menu_list type) that should be activated
There is also a special entry that servers as the sentinel:
{ END, NULL, { NULL } }
You should have one at the end of each submenu, otherwise baaaad things will happen - I promise.
Icon (and other graphics)
To decorate an entry in menu with an icon, you need to create a 16x16
pixels bitmap (.bmp format) and put it to sw/bitmaps/ folder. Afterwards
run the bmp2rle.py script. It will convert the new bitmap to a C
structure that may be used as icon (bitmaps.{c,h} files). You can add
any graphics you would like to use in your app in the same way.
If your file is named graphic.bmp, then the created structure will be
called graphic (struct rle_bitmap type) - this is what you type in
menu entry in the icon field (prefixed by &, as in the example above).
The last small change is to add your application structure in
sw/freertos/apps/app_list.h, so it could be accessible to the menu
code.
More examples
If you seek more, then have a look at clock application (sw/freertos/apps/clock.c) or menu (sw/freertos/apps/menu.c). I recommend starting with the clock app, it is easier to follow.