introiboad gravatar image

Posted 2016-12-22 13:35:41 +0200

blogs->nordicers

nRF5x support within the Zephyr Project RTOS

    No tags

image description

The Zephyr Project RTOS

The Zephyr Project RTOS is a recent effort by the Linux Foundation to provide the embedded world with a free, secure and fully-featured Real Time Operating System. It is designed from the ground up to be a modern, scalable, secure and responsive RTOS with a clear focus on IoT protocols and foundations. This open source RTOS is Apache 2.0 licensed and has a fully open development model

Recently Nordic contributed ports to all of our Cortex-M based ICs (nRF51, nRF52832 and nRF52840) as well as a fully featured, open source BLE Controller (Link Layer + HCI)that is highly optimized for the nRF5x family of ICs. This means that if you own any of the Nordic Development Kits for the nRF5x series you can clone, build and run Zephyr today and take advantage of all the features that it enables, including many standard BLE profiles, IPv6 over BLE, and a rich set of APIs and functionality that one would expect from a modern RTOS. On top of that every single line of code, including the BLE Host and Controller, are fully open source, allowing you to tweak and modify its behaviour or even extend it at will. You can even build your own controller and then use it to control it from an external Host stack or run the rest of the RTOS on your desktop computer using QEMU!

Here are some of the features that Zephyr supports:

Architectures:

  • ARM Cortex-Mx
  • Intel x86
  • ARC
  • Synopsys nios2
  • RISC-V
  • Tensilica Xtensa (upcoming)

Real-time kernel:

Device Drivers:

Bluetooth Low Energy:

Networking:

Build and debug:

  • Flexible and powerful configuration system based on Kconfig
  • GCC and Clang support
  • GDB and Segger RTT support

Running Zephyr on nRF5x

Zephyr currently supports the following Nordic ICs:

  • nRF51822 (all variants)
  • nRF52832
  • nRF52840

Additionally, there's built-in support for the following nRF5x-based boards:

Important note on custom or additional boards: If your board is similar to one of the above supported ones but does not include a 32KHz external crystal, you may have to include the following lines in your prj.conf:

CONFIG_CLOCK_CONTROL_NRF5_K32SRC_RC=y
CONFIG_CLOCK_CONTROL_NRF5_K32SRC_250PPM=y

Since the internal RC would then need to be used as the low frequency source.

Using the nRF52832 and the nRF52 DK as an example, let's go through the steps of building, flashing and running Zephyr on it. If you want to use the official documentation instead of following this guide, please refer to:

NOTE: This instructions are valid for macOS and Linux. To build on Windows please refer to the official documentation

First we need to obtain and install a toolchain. The following toolchains are supported:

  • Linux: Zephyr SDK, GCC ARM Embedded
  • macOS: GCC ARM Embedded

Assuming we go with GCC ARM Embedded and that you have a working native compiler and basic toolset on your machine, you can then follow the steps below:

1) Download and unpack GCC ARM Embedded to the folder of your choice. In this manual we will assume you've unpacked it in ~/gccarmemb/

2) Export the following environment variables:

$ export GCCARMEMB_TOOLCHAIN_PATH="~/gccarmemb/"
$ export ZEPHYR_GCC_VARIANT=gccarmemb

3) Clone the repository to obtain Zephyr's source code:

$ git clone https://github.com/zephyrproject-rtos/zephyr.git

4) At the root folder of your freshly cloned repository, run:

$ source zephyr-env.sh

5) Now you are ready to build. Let's start with a simple beacon example:

$ cd samples/bluetooth/beacon
$ make BOARD=nrf52_pca10040

6) To flash the image into the board you will need to download and install the JLink Software and Documentation Pack and the nRF5x command-line tools. Additional information about Segger J-Link in Nordic nRF5x boards can be found in the Nordic nRF5x Segger J-Link doc page

7) Now you are ready to use nrfjprog to erase and program the board:

$ nrfjprog --eraseall -f nrf52
$ nrfjprog --program outdir/nrf52_pca10040/zephyr.hex -f nrf52
$ nrfjprog --reset -f nrf52

8) When pluggin in the board, a serial communications port will have been detected by your operating system. Use your favourite terminal program to view the console output of the program you have just flashed (115k2, 8N1), for example:

$ minicom -D /dev/ttyACM0 -b 115200

9) Use any device capable of scanning to make sure Zephyr's beacon is advertising correctly

Building a BLE Controller

Using Zephyr's built-in, Nordic-contributed, BLE Controller you can actually turn any of your nRF5x-based boards into a fully featured, standard BLE Controller than you can use with external protocol stacks. The Controller supports nRF51 and nRF52, and you can configure it to support any number of connections in any role.

To do so, you only need to compile the hci_uart sample:

$ cd samples/bluetooth/hci_uart
$ make BOARD=nrf52_pca10040

After that, you can flash the .hex file to your board and you already have a fully-featured BLE Controller ready to accept HCI commands. The UART settings are as follows:

  • Baudrate: 1Mbit/s
  • 8 bits, no parity, 1 stop bit
  • Hardware Flow Control (RTS/CTS) enabled

Using the BLE Controller with Linux's BlueZ

Once you have built and flashed a BLE Controller to your Development Kit, you can even try it out with Linux's built-in Bluetooth stack, BlueZ! Here's a short guide to achieving that:

1) First of all make sure you have a recent Linux kernel installed (at least 4.6) and a modern (5.42+) version of the BlueZ userspace tools. For some of the tools, and depending on what your distribution bundles, you might need to compile BlueZ from scratch. To do so issue the following commands:

$ git clone git://git.kernel.org/pub/scm/bluetooth/bluez.git
$ ./bootstrap-configure --disable-android --disable-midi
$ make

You can then find btattach, btmgt and btproxy in the tools/ folder and btmon in the monitor/ folder.

2) Compile and flash the hci_uart example as shown above

3) On a separate terminal, open btmon to be able to observe all HCI traffic between BlueZ and the controller:

$ sudo btmon

3) Open another terminal, attach the controller to the system:

$ sudo btattach -B /dev/ttyACM0 -S 1000000 -P h4

4) Open a third terminal and open btmgt:

$ sudo btmgmt --index 0

NOTE: the "--index" option is the controller index. Depending on whether you already had one or more controllers connected this could be a number from 0 to N.

5) From the btmgmt console assign any random static address to the controller:

[hci0]# static-addr FF:02:03:04:05:FF

6) Power on the controller:

[hci0]# auto-power

7) Now you are ready to do whatever you want with it, you could for example scan for devices:

[hci0]# find -l

image description

Additional documentation can be found in the btmon, btattach and btmgmt man pages.

Using the BLE Controller build to run the RTOS from QEMU

Another useful feature of Zephyr is the possibility to run all or part of its codebase from QEMU, allowing you to develop and debug directly on your computer, no flashing or remote debugger required.

To enable BLE development with QEMU, first follow the instructions on the section above to build and flash a BLE Controller build onto your Development Kit. Additionally you will need to install the Zephyr SDK to compile for QEMU, since you cannot use GCC ARM Embedded at this point for it. To install the SDK (Linux only) follow the steps detailed here.

1) Make sure you have a recent Linux kernel installed (at least 4.6) and a modern (5.42+) version of the BlueZ userspace tools.

2) Compile and flash the hci_uart example as shown above

3) On a separate terminal, open btmon to be able to observe all HCI traffic between BlueZ and the controller:

$ sudo btmon

3) Open another terminal, attach the controller to the system in raw mode (note the -R):

$ sudo btattach -B /dev/ttyACM0 -S 1000000 -R

4) In yet another terminal, open an instance of btproxy, which will expose the controller to QEMU:

$ sudo btproxy -i 0 -u

NOTE: Replace -i 0 with the index corresponding to your Zephyr-based BLE Controller

5) Open a fourth terminal and choose any of the bluetooth samples available, in this case we'll try the peripheral_hr one:

$ cd samples/bluetooth/peripheral_hr

6) Finally you are ready to compile for QEMU and run:

$ make qemu

At this point you are running the application, RTOS and the Bluetooth Host on QEMU locally on your development computer, but the controller on the nRF5x on the Development Kit. They interface using standard HCI, and you will see all traffic being sent between the two in your btmon window.

image description

Happy coding! If you try Zephyr out on the nRF5x and have feedback for us, please feel free to leave a comment in the blog post or tweet to us at @NordicTweets.

Also if you want to get involved with Zephyr, or simply need help as a user, you can join the Zephyr mailing list or join the #zephyrproject IRC channel.

26 comments

raju_ga153 gravatar image

Posted Dec. 22, 2016, 6:42 p.m.

It's very interesting to see this. If you can provide details on running IOT examples Like COAP-Server/Client or MQTT, it would be good starting point to newbie like me.

Thanks, Raju

introiboad gravatar image

Posted Dec. 22, 2016, 7:18 p.m.

@Raju: there are examples in samples/net, they are compiled and flashed just like the beacon one in the post. For more help and information, you should join the community on IRC and/or the mailing list.

raju_ga153 gravatar image

Posted Dec. 23, 2016, 6:40 p.m.

Hi Carles,

I have build and flashed "/samples/net/coap_server" example on my "nrf52_pca10040" board. I am able to see following UART messages. But, Nothing discovered with "sudo hcitool lescan" on my Linux PC. What could be the reason.

Starting ETSI IoT Plugtests Server uIP buffer: 1280 LL header: 0 IP+UDP header: 48 REST max chunk: 64 net: net_tx_fiber (0x20007730): Starting TX fiber (stack 1024 bytes) net: net_rx_fiber (0x20007330): Starting RX fiber (stack 1024 bytes) net: net_timer_fiber (0x20007b30): Starting net timer fiber (stack 1536 bytes) net: net_driver_slip_open (0x20006b30): Initialized slip driver net (0x20007b30): timer fiber stack real size 1536 unused 1304 usage 128/1432 (8 %) init_app: run coap server net: net_set_mac (0x20006b30): MAC 5e:25:e2:15:1:1 net: net_set_mac (0x20006b30): Tentative link-local IPv6 address fe80::5c25:e2ff:fe15:101

raju_ga153 gravatar image

Posted Dec. 24, 2016, 1:40 p.m.

I realize that default net interface is "slip", then changed to "bt" using following command and followed remaining steps as above.

make BOARD=nrf52_pca10040 NET_IFACE=bt

Below is the log information from UART. Here, getting Hard-fault while initializing "coap_server".

Starting ETSI IoT Plugtests Server
uIP buffer: 1280
LL header: 0 IP+UDP header: 48 REST max chunk: 64 net: net_tx_fiber (0x20009928): Starting TX fiber (stack 1024 bytes) net: net_rx_fiber (0x20009d28): Starting RX fiber (stack 1024 bytes) net: net_timer_fiber (0x2000a128): Starting net timer fiber (stack 1536 bytes) net (0x2000a128): timer fiber stack real size 1536 unused 1304 usage 128/1432 (8 %) init_app: run coap server * BUS FAULT * Executing thread ID (thread): 0x2000ac28 Faulting instruction address: 0x00018dc0 Precise data bus error Address: 0x20095e10 Fatal fault in thread! Aborting. * HARD FAULT * Fault escalation (see below) * BUS FAULT * Executing thread ID (thread): 0x2000ac28 Faulting instruction address: 0x2000819c Precise data bus error Address: 0x20095e10 Fatal fault in ISR! Spinning...

overheat gravatar image

Posted Dec. 25, 2016, 5:27 a.m.

Zephyr use open source BT stack. Is it possible use NRF5x + zephyr to make a BT/BLE dual mode chip?

knttn gravatar image

Posted Dec. 27, 2016, 10:38 a.m.

Aaron,

No, the nRF5x chips from Nordic support BLE radio PHY only.

introiboad gravatar image

Posted Dec. 27, 2016, 3:24 p.m.

@raju: please follow-up in the mailing list or on IRC, since there are many more people there to help out in this sort of issues. You might have to wait until devs are back from the Christmas break though.

metch gravatar image

Posted Jan. 9, 2017, 8:44 a.m.

@introiboad The link to the Zephy getting started guide is 404. You should replace it with this one: https://www.zephyrproject.org/doc/latest/getting_started/getting_started.html

All the documentation links should also be updated because the doc version is missing in the URL.

Thanks for the nice post. It looks very interesting, especially the QEMU part.

introiboad gravatar image

Posted Jan. 9, 2017, 10:15 a.m.

@Cristopher: Thanks! Fixed

tdwebste gravatar image

Posted Jan. 12, 2017, 9:29 a.m.

Thank you for the detail walk through.

Is this the correct board for a project / evaluation of ble zephr

http://www.nordicsemi.com/eng/Products/nRF52840-Preview-DK

https://www.arrow.com/en/products/nrf52840-pdk/nordic-semiconductor?utm_source=octopart&utm_medium=buynow&utm_campaign=octopart

introiboad gravatar image

Posted Jan. 13, 2017, 11:30 a.m.

@tim: yes, Zephyr runs on the nRF52840 Preview DK, so you can use that as a development board for a Zephyr BLE project

robin gravatar image

Posted Jan. 14, 2017, 5:56 a.m.

Hi Carles,

I am able to build the HCI-UART project without problems, but now I would now like get the console log messages. Is this some option selected through "make menuconfig" or how?

If the HCI interface is using the UART (Pins 5-8 on PCA10040) then how is the console messages to be displayed?

I would also like to know how to build for debug: "make debug" or the like. I get error message saying "Debugging not supported with this board."

robin gravatar image

Posted Jan. 14, 2017, 7:47 a.m.

I am wondering if the answer to my first questions is to use RTT. I have looked in the source but don't see support for RTT, even though the PCA10040 supports it. Am I missing something?

I found the answer to my question 2 above: start "make menuconfig" then go to "Debugging Options". Select "Build kernel with debugging enabled". This will set CONFIG_DEBUG in .config file, which is then picked-up by root Makefile, which set flags to build with -Og.

introiboad gravatar image

Posted Jan. 14, 2017, 9:09 a.m.

@ Robin

https://wiki.zephyrproject.org/view/Nordic_nRF5x_Segger_J-Link#RTT_Console

You can then enable bluetooth logging and debug from menuconfig or by editing your .conf file. Additionally if you use a lot of RTT logging from interrupt context you will need to increase the interrupt stack size

robin gravatar image

Posted Jan. 16, 2017, 9:15 a.m.

Thanks for the info!

The version I initially started with was v1.6.0 as found at https://www.zephyrproject.org/downloads. This version, which I assume is the last "stable" version, does not have RTT support in it.

I have pulled sources from the repository's master (HEAD) as of yesterday and found that it has RTT support.

My initial impression of this cutting-edge version seems to be good, but I feel this is still not-stable version. I can accept this code in my project's early development phase, but I would like to know when the next stable version is scheduled for released?

Keep up the good work!!

introiboad gravatar image

Posted Jan. 16, 2017, 10:13 a.m.

@robin

My initial impression of this cutting-edge version seems to be good, but I feel this is still not-stable version. I can accept this code in my project's early development phase, but I would like to know when the next stable version is scheduled for released?

Releases happen every 3 months approximately, so it'd be towards the end of February.

Keep up the good work!!

Thank you!

raju_ga153 gravatar image

Posted Jan. 23, 2017, 6:01 p.m.

Hi Carles,

I have filed an issue(https://lists.zephyrproject.org/archives/list/devel@lists.zephyrproject.org/thread/6AFLJ3PHMDXBZZVWZN2ESXR22U2UNFIQ/) in Mailing list and got it resolved. Now I am able to connect for "zoap_server" sample. But getting random address instead of static from Mac address.

As per "https://devzone.nordicsemi.com/question/6566/how-to-get-6-byte-mac-address-at-nrf51822/" this post we can have unique Mac address and it seems this is not mapped properly in Zephyr OS. Can we get this unique Mac address in Zephyr OS.

Thanks, Raju

sundar.subramaniyan gravatar image

Posted Feb. 3, 2017, 11:13 a.m.

Hi Carles,

I have filed an issue related to HCI UART sample from zephyr. I am able to get it working with the ttyACMx interface but I am not able to use the UART interface through an external USB-UART converter (FTDI232 with flow control pins connected). I saw in some zephyr wiki page about the bridged connectivity between in-built UART interface and the CDC USB ttyACMx interface. I want to be able to use the board powered with battery. Please let me know if there's some configuration available for this use case.

Here's the link to the issue: https://devzone.nordicsemi.com/question/112815/zephyr-hci-uart-on-nrf52dk-hci-interface-bring-up-fails/

Thanks.

ricsilvs gravatar image

Posted June 7, 2017, 1:04 p.m.

Maybe you could add this link: https://www.zephyrproject.org/doc/dts/device_tree.html to the tutorial, since it's necessary to install some packages depending on the OS.

Nilasstohr gravatar image

Posted June 29, 2017, 8:06 p.m.

Hello, It seems like all the central examples (zephyr bluetooth samples) will not compile, due to an error seem below:

... LINK zephyr.lnk subsys/built-in.o: In function ll_rl_pdu_adv_update': C:/msys64/home/nist/zephyr/subsys/bluetooth/controller/ll_sw/ll_filter.c:346: undefined reference toll_adv_set_get'

This happens only when compiling in window (msys2) following the guide below. On linux it works fine. https://www.zephyrproject.org/doc/getting_started/installation_win.html#installing-zephyr-win

how can i fix this?

any answer i very much appreciated. thanks

introiboad gravatar image

Posted June 29, 2017, 8:58 p.m.

@Nilasstohr: I just tried today and I don't seem to have this issue, with the current master (c84e90e7de2d776488bd852095b7b9c9210d3f2e). Could you try to fetch the latest master and try again? If the problem persists please join us at #zephyrproject on IRC (freenode.net), you can use this here: https://webchat.freenode.net/ and ask me there (carlesc).

Nilasstohr gravatar image

Posted June 29, 2017, 11:25 p.m.

Thank you for your fast answer, I have fetched the master and recompiled, the problem persist. I think I came closer to a reason which is seem below, I have also written this in the IRC.

For some reason the central samples (ex. central_hr) is depended on ll_adv.h and ll_adv.c but the library is never compiled.

This is seen by looking at the compile output for central_hr when running "make BOARD=nrf52840_pca10056". Comparing this to compiling the peripheral_hr, the compile output will have the line “CC subsys/bluetooth/controller/ll_sw/ll_adv.o”.

The ll_adv_set_get function are a part of ll_adv (which is not compiled in the central examples) this might be the reason for the compile error. The question is why my central examples compile like this way and how to change it?

I have not done anything beside following the guide below with a window 10 OS. https://www.zephyrproject.org/doc/getting_started/installation_win.html#installing-zephyr-win

introiboad gravatar image

Posted June 30, 2017, 9:19 a.m.

@Nilasstohr. I've tried repeatedly to reproduce this by building the central_hr example for nrf52840 on both Windows and Linux and I cannot reproduce. Could you please join IRC again and we can talk about it? Yesterday I didn't see your messages on IRC, was a bit late here.

Nilasstohr gravatar image

Posted June 30, 2017, 4:29 p.m.

solution for my compile error (thanks to Carles) is shared here:

Following the guide https://www.zephyrproject.org/doc/getting_started/installation_win.html#installing-zephyr-win

where the zephyr SDK is fetched with: git clone https://github.com/zephyrproject-rtos/zephyr.git

But in my case I got a compile error (see above). The reason for this was likely that an old zephyr version was fetched or a cleanup in the fetched version was needed for some reason. To fix the problem following three git commands are executed in the msys2 shell.

git fetch origin

git reset --hard origin/master (making sure local copy is identical to master repo version)

git clean -ffdx (clean up of output directories)

Nilasstohr gravatar image

Posted June 30, 2017, 4:59 p.m.

Hello again, I have a question about the configuration of the zephyr bluetooth stack. I need to do a proof of concept for the company were I work, where a nordic device should be both a central and a peripheral, I successfully did this with nordic sdk following one of the example.

The question is how to do this with zephyr?, looking through the source code in ex. central_hr and peripheral_hr it is not obvious were they are configured as central and peripheral (apart from seeing a start a scan and adv etc, is started)

thanks much in advance.

introiboad gravatar image

Posted June 30, 2017, 5:01 p.m.

@Nilasstohr. This is not quite the right forum to ask those questions, since Zephyr is not officially supported by Nordic yet. Please use the Zephyr mailing list or join us at #zephrproject or #zephyr-bt and we'll be happy to help you out there.

Sign in to comment.

Related posts by tag

No results