Skip to content

Commit

Permalink
Add support for EMAC backhaul driver
Browse files Browse the repository at this point in the history
This depends on work in progress on the feature-emac branch of mbed OS.
  • Loading branch information
kjbracey committed Feb 13, 2018
1 parent 02ddd5e commit 0579173
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 31 deletions.
42 changes: 33 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,21 @@ The target platform is the hardware on which the border router runs. There are n

If you wish to write your own target, follow the instructions in [Adding target support to mbed OS 5](https://docs.mbed.com/docs/mbed-os-handbook/en/latest/advanced/porting_guide/).

The border router requires backhaul and RF drivers to be provided for Nanostack. The backhaul is either SLIP or Ethernet. Currently, there are drivers for the following backhauls:

* [K64F Ethernet](https://github.com/ARMmbed/sal-nanostack-driver-k64f-eth)
* [NUCLEO_F429ZI Ethernet](https://github.com/ARMmbed/sal-nanostack-driver-stm32-eth)
* [SLIP driver](https://github.com/ARMmbed/sal-stack-nanostack-slip)

And following RF drivers:
The border router requires an RF driver to be provided for Nanostack. Currently, there are the following drivers:

* [Atmel AT86RF233](https://github.com/ARMmbed/atmel-rf-driver)
* [Atmel AT86RF212B](https://github.com/ARMmbed/atmel-rf-driver)
* [STM Spirit1](https://github.com/ARMmbed/stm-spirit1-rf-driver)
* [NXP MCR20A](https://github.com/ARMmbed/mcr20a-rf-driver)

The backhaul is either SLIP or Ethernet. For Ethernet either an mbed OS "EMAC"
driver can be used, or a native Nanostack driver. Currently, there are Nanostack drivers
for the following backhauls:

* [K64F Ethernet](https://github.com/ARMmbed/sal-nanostack-driver-k64f-eth)
* [NUCLEO_F429ZI Ethernet](https://github.com/ARMmbed/sal-nanostack-driver-stm32-eth)
* [SLIP driver](https://github.com/ARMmbed/sal-stack-nanostack-slip)

The existing drivers are found in the `drivers/` folder. More drivers can be linked in.

See [Notes on different hardware](https://github.com/ARMmbed/mbed-os-example-mesh-minimal/blob/master/Hardware.md) to see known combinations that work.
Expand Down Expand Up @@ -148,7 +150,7 @@ The Nanostack border router application can be connected to a backhaul network.
```
"config": {
"backhaul-driver": {
"help": "options are ETH, SLIP",
"help": "options are ETH, SLIP, EMAC",
"value": "ETH"
},
"backhaul-mac-src": {
Expand All @@ -164,7 +166,9 @@ The Nanostack border router application can be connected to a backhaul network.
}
```

You can select your preferred option through the configuration file (field `backhaul-driver` in the `config` section). The value `SLIP` includes the SLIP driver, while the value `ETH` compiles the border router application with Ethernet backhaul support. You can define the MAC address on the backhaul interface manually (field `backhaul-mac-src` value `CONFIG`). Alternatively, you can use the MAC address provided by the development board (field `backhaul-mac-src` value `BOARD`). By default, the backhaul driver is set to `ETH` and the MAC address source is `BOARD`.
You can select your preferred option through the configuration file (field `backhaul-driver` in the `config` section). The value `SLIP` includes the SLIP driver, while the value `ETH` compiles the border router application with Nanostack native Ethernet backhaul support. `EMAC` uses the board's default mbed OS EMAC driver.

You can define the MAC address on the backhaul interface manually (field `backhaul-mac-src` value `CONFIG`). Alternatively, you can use the MAC address provided by the development board (field `backhaul-mac-src` value `BOARD`). By default, the backhaul driver is set to `ETH` and the MAC address source is `BOARD`.

You can also set the backhaul bootstrap mode (field `backhaul-dynamic-bootstrap`). By default, the bootstrap mode is set to true, which means the autonomous mode. With the autonomous mode, the border router learns the prefix information automatically from an IPv6 gateway in the Ethernet/SLIP segment. When the parameter is set to false, it enables you to set up a manual configuration of `backhaul-prefix` and `backhaul-default-route`.

Expand Down Expand Up @@ -193,6 +197,26 @@ An example configuration for the SLIP driver:
}
```

#### Note on EMAC backhaul

When `backhaul_driver` is set to `EMAC`, the border router will use the target's default EMAC driver, as supplied by `EMAC::get_default_instance` - the same driver that a default-constructed `EthernetInterface` would use, so in principle it should work on any board where `EthernetInterface` works.

To use a different EMAC, add a definition of `EMAC::get_default_instance` to the application - this will override any default supplied by the target board.

For Wi-Fi or other more complex EMAC drivers, some integration will be required, and the driver must be structured to permit use. The following should work if the driver is derived from `EMACInterface`, and it follows its design guidelines:

```
EMAC &EMAC::get_default_instance() {
static MyWiFiInterface wifi;
static bool configured;
if (!configured) {
wifi.set_credentials(...);
configured = true;
}
return wifi.get_emac();
}
```

### Switching the RF shield

By default, the application uses an Atmel AT86RF233/212B RF driver. You can alternatively use any RF driver provided in the `drivers/` folder or link in your own driver. You can set the configuration for the RF driver in the `json` file.
Expand Down
3 changes: 2 additions & 1 deletion configs/6lowpan_Atmel_RF.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"value": "ATMEL"
},
"backhaul-driver": {
"help": "options are ETH, SLIP",
"help": "options are ETH, SLIP, EMAC",
"value": "ETH"
},
"mesh-mode": {
Expand Down Expand Up @@ -70,6 +70,7 @@
"*": {
"target.features_add": ["NANOSTACK", "LOWPAN_BORDER_ROUTER", "COMMON_PAL"],
"target.features_remove": ["LWIP"],
"nsapi.default-stack": "NANOSTACK",
"mbed-trace.enable": 1,
"nanostack.configuration": "lowpan_border_router",
"platform.stdio-convert-newlines": true,
Expand Down
3 changes: 2 additions & 1 deletion configs/6lowpan_Spirit1_RF.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"value": "SPIRIT1"
},
"backhaul-driver": {
"help": "options are ETH, SLIP",
"help": "options are ETH, SLIP, EMAC",
"value": "ETH"
},
"mesh-mode": {
Expand Down Expand Up @@ -71,6 +71,7 @@
"target.features_add": ["NANOSTACK", "LOWPAN_BORDER_ROUTER", "COMMON_PAL"],
"target.features_remove": ["LWIP"],
"spirit1.mac-address": "{0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7}",
"nsapi.default-stack": "NANOSTACK",
"mbed-trace.enable": 1,
"nanostack.configuration": "lowpan_border_router",
"platform.stdio-convert-newlines": true,
Expand Down
3 changes: 2 additions & 1 deletion configs/Thread_Atmel_RF.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"value": "ATMEL"
},
"backhaul-driver": {
"help": "options are ETH, SLIP",
"help": "options are ETH, SLIP, EMAC",
"value": "ETH"
},
"mesh-mode": {
Expand Down Expand Up @@ -53,6 +53,7 @@
"*": {
"target.features_add": ["NANOSTACK", "COMMON_PAL", "THREAD_BORDER_ROUTER"],
"target.features_remove": ["LWIP"],
"nsapi.default-stack": "NANOSTACK",
"mbed-trace.enable": 1,
"nanostack.configuration": "thread_border_router",
"platform.stdio-convert-newlines": true,
Expand Down
3 changes: 2 additions & 1 deletion configs/Thread_SLIP_Atmel_RF.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"value": "ATMEL"
},
"backhaul-driver": {
"help": "options are ETH, SLIP",
"help": "options are ETH, SLIP, EMAC",
"value": "SLIP"
},
"mesh-mode": {
Expand Down Expand Up @@ -55,6 +55,7 @@
"*": {
"target.features_add": ["NANOSTACK", "COMMON_PAL", "THREAD_BORDER_ROUTER"],
"target.features_remove": ["LWIP"],
"nsapi.default-stack": "NANOSTACK",
"mbed-trace.enable": 1,
"nanostack.configuration": "thread_border_router",
"platform.stdio-convert-newlines": true,
Expand Down
3 changes: 2 additions & 1 deletion mbed_app.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"value": "ATMEL"
},
"backhaul-driver": {
"help": "options are ETH, SLIP",
"help": "options are ETH, SLIP, EMAC",
"value": "ETH"
},
"mesh-mode": {
Expand Down Expand Up @@ -66,6 +66,7 @@
"*": {
"target.features_add": ["NANOSTACK", "LOWPAN_BORDER_ROUTER", "COMMON_PAL"],
"target.features_remove": ["LWIP"],
"nsapi.default-stack": "NANOSTACK",
"mbed-trace.enable": 1,
"nanostack.configuration": "lowpan_border_router",
"platform.stdio-convert-newlines": true,
Expand Down
73 changes: 58 additions & 15 deletions source/border_router_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
#include "drivers/eth_driver.h"
#include "sal-stack-nanostack-slip/Slip.h"

#include "Nanostack.h"
#include "NanostackEthernetInterface.h"
#include "MeshInterfaceNanostack.h"
#include "EMAC.h"

#ifdef MBED_CONF_APP_DEBUG_TRACE
#if MBED_CONF_APP_DEBUG_TRACE == 1
#define APP_TRACE_LEVEL TRACE_ACTIVE_LEVEL_DEBUG
Expand All @@ -19,6 +24,7 @@
#endif //MBED_CONF_APP_DEBUG_TRACE

#include "ns_hal_init.h"
#include "mesh_system.h"
#include "cmsis_os.h"
#include "arm_hal_interrupt.h"

Expand All @@ -28,9 +34,18 @@

#define APP_DEFINED_HEAP_SIZE MBED_CONF_APP_HEAP_SIZE
static uint8_t app_stack_heap[APP_DEFINED_HEAP_SIZE];
static uint8_t mac[6] = {0};
static mem_stat_t heap_info;

#define BOARD 1
#define CONFIG 2
#if MBED_CONF_APP_BACKHAUL_MAC_SRC == BOARD
static uint8_t mac[6];
#elif MBED_CONF_APP_BACKHAUL_MAC_SRC == CONFIG
static const uint8_t mac[] = MBED_CONF_APP_BACKHAUL_MAC;
#else
#error "MAC address not defined"
#endif

static DigitalOut led1(MBED_CONF_APP_LED);

static Ticker led_ticker;
Expand All @@ -50,15 +65,27 @@ static void trace_printer(const char *str)
printf("%s\n", str);
}

#define ETH 1
#define SLIP 2
#define EMAC 3
#if MBED_CONF_APP_BACKHAUL_DRIVER == EMAC
static void (*emac_actual_cb)(uint8_t, int8_t);
static int8_t emac_driver_id;
static void emac_link_cb(bool up)
{
if (emac_actual_cb) {
emac_actual_cb(up, emac_driver_id);
}
}
#endif

/**
* \brief Initializes the SLIP MAC backhaul driver.
* This function is called by the border router module.
*/
void backhaul_driver_init(void (*backhaul_driver_status_cb)(uint8_t, int8_t))
{
// Values allowed in "backhaul-driver" option
#define ETH 0
#define SLIP 1
#if MBED_CONF_APP_BACKHAUL_DRIVER == SLIP
SlipMACDriver *pslipmacdriver;
int8_t slipdrv_id = -1;
Expand Down Expand Up @@ -87,14 +114,38 @@ void backhaul_driver_init(void (*backhaul_driver_status_cb)(uint8_t, int8_t))
}

tr_error("Backhaul driver init failed, retval = %d", slipdrv_id);
#elif MBED_CONF_APP_BACKHAUL_DRIVER == EMAC
#undef EMAC
tr_info("Using EMAC backhaul driver...");
EMAC &emac = EMAC::get_default_instance();

Nanostack::EthernetInterface *ns_if;
#if MBED_CONF_APP_BACKHAUL_MAC_SRC == BOARD
/* Let the core code choose address - either from board or EMAC (for
* ETH and SLIP we pass in the board address already in mac[]) */
nsapi_error_t err = Nanostack::get_instance().add_ethernet_interface(emac, true, &ns_if);
/* Read back what they chose into our mac[] */
ns_if->get_mac_address(mac);
#else
nsapi_error_t err = Nanostack::get_instance().add_ethernet_interface(emac, true, &ns_if, mac);
#endif
if (err < 0) {
tr_error("Backhaul driver init failed, retval = %d", err);
} else {
emac_actual_cb = backhaul_driver_status_cb;
emac_driver_id = ns_if->get_driver_id();
emac.set_link_state_cb(emac_link_cb);
}
#elif MBED_CONF_APP_BACKHAUL_DRIVER == ETH
tr_info("Using ETH backhaul driver...");
arm_eth_phy_device_register(mac, backhaul_driver_status_cb);
return;
#else
#error "Unsupported backhaul driver"
#endif

#undef SLIP
#undef ETH
#undef EMAC
}

/**
Expand All @@ -110,20 +161,12 @@ int main(int argc, char **argv)
mbed_trace_print_function_set(trace_printer);
mbed_trace_config_set(TRACE_MODE_COLOR | APP_TRACE_LEVEL | TRACE_CARRIAGE_RETURN);

// Have to let mesh_system do net_init_core in case we use
// Nanostack::add_ethernet_interface()
mesh_system_init();

#define BOARD 0
#define CONFIG 1
#if MBED_CONF_APP_BACKHAUL_MAC_SRC == BOARD
/* Setting the MAC Address from UID.
* Takes UID Mid low and UID low and shuffles them around. */
mbed_mac_address((char *)mac);
#elif MBED_CONF_APP_BACKHAUL_MAC_SRC == CONFIG
const uint8_t mac48[] = MBED_CONF_APP_BACKHAUL_MAC;
for (uint32_t i = 0; i < sizeof(mac); ++i) {
mac[i] = mac48[i];
}
#else
#error "MAC address not defined"
#endif

if (MBED_CONF_APP_LED != NC) {
Expand Down
1 change: 0 additions & 1 deletion source/borderrouter_tasklet.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ static void load_config(void);

void border_router_tasklet_start(void)
{
net_init_core();
/* initialize Radio module*/
net_6lowpan_id = rf_interface_init();

Expand Down
1 change: 0 additions & 1 deletion source/borderrouter_thread_tasklet.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,6 @@ void thread_rf_init()

void border_router_tasklet_start(void)
{
net_init_core();
thread_rf_init();
protocol_stats_start(&nwk_stats);

Expand Down

0 comments on commit 0579173

Please sign in to comment.