How to write a module in OpenWSN firmware
OpenWSN firmware C code is written in module manner. It's similar with object-oriented programming, though C is not an object language. This structure keeps the code clear and expandable. This is usually used when you want to add a new feature to the code. To write in such way, first thing is to think about what variable that the feature should be maintained, what services that the feature can serve and what's the relationship with other modules in the code (e.g. the each layer protocol has a module corresponded).
In this page, you will learn how to implement the feature into OpenWSN firmware and how to integrate it into python simulation. To make things easier, we will use neighbors as an example. neighbors is a module that manages mote's neighbor information. The source code is located at openwsn-fw/openstack/02b-MAChigh/.
Write Source Code
There are two mainly part to implement a new feature. 1. the variable that this feature required to maintain. 2. the interface that this feature serves.The first thing to do is add two files into your project. For example, neighbors.c and neighbors.h.
create module variable
The new module variable type needs to be defined in neighbors.h file. When define a new module variable type, the type name has to be ended with suffix of vars_t. For example, neighbors_vars_t is the name of neighbors module type, like this:
typedef struct { neighborRow_t neighbors[MAXNUMNEIGHBORS]; dagrank_t myDAGrank; uint8_t debugRow; icmpv6rpl_dio_ht* dio; //keep it global to be able to debug correctly. } neighbors_vars_t;
Then you need to define a global variable in neighbors.c file, like this:
neighbors_vars_t neighbors_vars;
add module functions
The module functions are the interface that the feature what's other modules to call. The initial function is usually required to set the default value of module variables. For example: neighbors_init is the initial functions name of adaptive_sync module. The name of the functions need to begin with the module name with an underline following. For example the initial function is started with neighbors_.
Define the functions that other modules may call them in header file (.h file). If the function is used by the module itself, declare it in source file (.c file). All the functions are implemented in source file.
Integrate into simulation system
To make the simulation compilation works, there are 4 files that required to modify: openwsnmodule_obj.h, openwsnmodule.c, SConscript and SConscript.env.
Modify openwsnmodule_obj.h file
add following code in openwsnmodule_obj.h.
#include "neighbors_obj.h"
add following code in openwsnmodule_obj.h file.
neighbors_vars_t neighbors_vars;
Modify openwsnmodule.c file
add following code in openwsnmodule.c file
PyObject* neighbors_vars;
add following code in openwsnmodule.c file
// neighbors_vars neighbors_vars = PyDict_New(); // TODO PyDict_SetItemString(returnVal, "neighbors_vars", neighbors_vars);
Modify SConscript file
add following code in SConscript file
os.path.join('02b-MAChigh','neighbors.c'),
add following code in SConscript file
os.path.join('02b-MAChigh','neighbors.h'),
Modify SConscript.env file
add following code in SConscript.env file
'neighbors_vars',
add all functions implemented in your source file in SConscript.env file
# neighbors 'neighbors_init', 'neighbors_getMyDAGrank', 'neighbors_getNumNeighbors', 'neighbors_getPreferredParentEui64', 'neighbors_getKANeighbor', 'neighbors_isStableNeighbor', 'neighbors_isPreferredParent', 'neighbors_isNeighborWithLowerDAGrank', 'neighbors_isNeighborWithHigherDAGrank', 'neighbors_indicateRx', 'neighbors_indicateTx', 'neighbors_indicateRxDIO', 'neighbors_getNeighbor', 'neighbors_updateMyDAGrankAndNeighborPreference', 'neighbors_removeOld', 'debugPrint_neighbors', 'registerNewNeighbor', 'isNeighbor', 'removeNeighbor', 'isThisRowMatching', 'neighbors_setMyDAGrank',
Add header file in SConscript.env
'neighbors',
Test
If everything works, you can use following command to test whether it works:
scons board=python toolchain=gcc oos_openwsn -c scons board=python toolchain=gcc oos_openwsn
If you saw the following information, congratulations! it works.
Archiving build\python_gcc\bsp\boards\libbsp.a Indexing build\python_gcc\bsp\boards\libbsp.a gcc -shared -o build\python_gcc\projects\common\oos_openwsn.pyd build\python_gcc\projects\common\03o os_openwsn\03oos_openwsn_obj.o build\python_gcc\projects\common\03oos_openwsn\openwsnmodule_obj.o -L C:\Python27\libs -Lbuild\python_gcc\bsp\boards -Lbuild\python_gcc\kernel\openos -Lbuild\python_gcc\d rivers -Lbuild\python_gcc\openstack -Lbuild\python_gcc\openapps -lopenstack -lopenapps -lkernel -ldr ivers -lbsp -lpython27 -Wl,--out-implib,build\python_gcc\projects\common\liboos_openwsn.a scons: done building targets.
If you see something else, you need check whether you have done everything mentioned above. If you meet any problem with this tutorial, don't hesitate to contact Tengfei Chang!