Compare commits
188 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bdc3107d5c | ||
|
|
42925576c1 | ||
|
|
09dc926151 | ||
|
|
e1ed632096 | ||
|
|
89fc39329a | ||
|
|
705d21ab03 | ||
|
|
fd96574ed5 | ||
|
|
f2a60a4582 | ||
|
|
41de428817 | ||
|
|
22099d167c | ||
|
|
e180b7ac2a | ||
|
|
3f0e37d35a | ||
|
|
6b94e8924a | ||
|
|
79bd1068b8 | ||
|
|
75d045c7c7 | ||
|
|
f52cbff681 | ||
|
|
d031cd35c4 | ||
|
|
9be5966dc9 | ||
|
|
b64d567d7f | ||
|
|
79a1654fab | ||
|
|
1e27642ee1 | ||
|
|
f7a670b23f | ||
|
|
0edd41a4c7 | ||
|
|
9d405d324f | ||
|
|
3d2893cf85 | ||
|
|
85922c0445 | ||
|
|
1408adeae1 | ||
|
|
d043cf9ef3 | ||
|
|
3c6d43f47a | ||
|
|
5454df808e | ||
|
|
9507793a40 | ||
|
|
c5eac4e967 | ||
|
|
95b955a5a3 | ||
|
|
e3dc3570e6 | ||
|
|
aec071ef51 | ||
|
|
d111394b93 | ||
|
|
cc39120392 | ||
|
|
02c1608295 | ||
|
|
c7d05f4313 | ||
|
|
bc21d8f930 | ||
|
|
5eee2489e1 | ||
|
|
09b1994b69 | ||
|
|
8c569edfaa | ||
|
|
364087f3e9 | ||
|
|
6e135d0006 | ||
|
|
65a5d8f1a7 | ||
|
|
28b8276378 | ||
|
|
72ac3fd28d | ||
|
|
3cd73f3659 | ||
|
|
299886c217 | ||
|
|
d56fe4e0b8 | ||
|
|
db55abddd2 | ||
|
|
0c08b44b75 | ||
|
|
ed02201299 | ||
|
|
fdd8dc0695 | ||
|
|
732434fac6 | ||
|
|
da5c7b687f | ||
|
|
950b079bd5 | ||
|
|
8d22d84b51 | ||
|
|
b2a06f092b | ||
|
|
04f142c4b5 | ||
|
|
6352fc9974 | ||
|
|
e7693770d7 | ||
|
|
11ef22e5d1 | ||
|
|
985f842e62 | ||
|
|
c5940832ef | ||
|
|
746706d241 | ||
|
|
d626dc989e | ||
|
|
06a36923c6 | ||
|
|
4957db11fc | ||
|
|
e0ff3a5f27 | ||
|
|
fc65d6d55e | ||
|
|
63c630d5c5 | ||
|
|
3a122f5de9 | ||
|
|
44328f2cc4 | ||
|
|
6102147980 | ||
|
|
5ea4f57f5e | ||
|
|
b12d8d4783 | ||
|
|
df590c2fda | ||
|
|
c370a0d20a | ||
|
|
eb4a193a16 | ||
|
|
c3c5ae1279 | ||
|
|
8c4d0a5ee1 | ||
|
|
db533538d5 | ||
|
|
781ee1a07b | ||
|
|
b7831efb1d | ||
|
|
0e96819e5d | ||
|
|
fb9409a613 | ||
|
|
385e98021c | ||
|
|
17b5860cb9 | ||
|
|
36e5f2c27b | ||
|
|
b0b9843528 | ||
|
|
a80b619e43 | ||
|
|
c663bccbe8 | ||
|
|
fc5bd4a148 | ||
|
|
79d30afa0c | ||
|
|
78d4ef8588 | ||
|
|
2f3c55df90 | ||
|
|
6047e65888 | ||
|
|
2a2a05d071 | ||
|
|
9c04bde3cb | ||
|
|
5908d92933 | ||
|
|
f2522c21e0 | ||
|
|
4af670bfe6 | ||
|
|
5d8c87ec34 | ||
|
|
2fb42abdfb | ||
|
|
3a75363feb | ||
|
|
01b122edb8 | ||
|
|
24a8b683d0 | ||
|
|
30d44396af | ||
|
|
283807fa58 | ||
|
|
afa1e1f901 | ||
|
|
7202b6a360 | ||
|
|
b718528c04 | ||
|
|
eb22a4066f | ||
|
|
61b47ca838 | ||
|
|
0372e102ee | ||
|
|
5b0e0785dc | ||
|
|
2ac1921a74 | ||
|
|
b763cdf85e | ||
|
|
024c310002 | ||
|
|
2ad927c4db | ||
|
|
b2fa495bf2 | ||
|
|
19ccf83006 | ||
|
|
c1acfd049b | ||
|
|
bce0eb9d98 | ||
|
|
48cea0e9c1 | ||
|
|
612b9efb17 | ||
|
|
b6035cbc57 | ||
|
|
e79f9a1c4a | ||
|
|
46a38ee460 | ||
|
|
25281db44c | ||
|
|
f20dc053b5 | ||
|
|
4791c83864 | ||
|
|
03dc412517 | ||
|
|
ec8c508153 | ||
|
|
9b9f679b90 | ||
|
|
6b0903bcf9 | ||
|
|
3a8753d0fe | ||
|
|
dba515fd61 | ||
|
|
655b2bf361 | ||
|
|
460ffe7601 | ||
|
|
d17f16d8d7 | ||
|
|
1d32ad0dc3 | ||
|
|
7635965b1a | ||
|
|
781e6c388a | ||
|
|
9be5f9ebfd | ||
|
|
a976b8db67 | ||
|
|
26464f8caa | ||
|
|
177ab6e27e | ||
|
|
8c7f5cca69 | ||
|
|
ad6aa86df1 | ||
|
|
fea5778664 | ||
|
|
c8c6bee8a2 | ||
|
|
37e830a1da | ||
|
|
0d1db8fccd | ||
|
|
47c83debea | ||
|
|
91568e0137 | ||
|
|
1db37bb98b | ||
|
|
1f7e43569b | ||
|
|
217049d42f | ||
|
|
171b25f1cb | ||
|
|
009105706f | ||
|
|
62ddee16e6 | ||
|
|
e72156fa17 | ||
|
|
cb3569d412 | ||
|
|
f768b3e968 | ||
|
|
6bbd662ac0 | ||
|
|
4bbeabb359 | ||
|
|
63a9b84322 | ||
|
|
1d69c0cb67 | ||
|
|
d5318e79ca | ||
|
|
9088de298d | ||
|
|
33cbbd95c4 | ||
|
|
1a9c57a493 | ||
|
|
bf82f14d25 | ||
|
|
eba6eef71b | ||
|
|
9b4afd36fc | ||
|
|
10561731df | ||
|
|
cc8354a359 | ||
|
|
a4951b6b29 | ||
|
|
ab2159f52f | ||
|
|
7ef1c66593 | ||
|
|
1d66fab0c4 | ||
|
|
9fc3173c96 | ||
|
|
920f335d9f | ||
|
|
0c0ec4a0e2 | ||
|
|
cd98edf028 |
@@ -260,7 +260,6 @@ F: include/drivers/mvic.h
|
||||
|
||||
KERNEL CORE
|
||||
M: Benjamin Walsh <benjamin.walsh@windriver.com>
|
||||
M: Allan Stephens <allan.stephens@windriver.com>
|
||||
M: Andrew Boie <andrew.p.boie@intel.com>
|
||||
M: Andy Ross <andrew.j.ross@intel.com>
|
||||
S: Supported
|
||||
@@ -469,7 +468,6 @@ F: samples/usb
|
||||
|
||||
X86 ARCH
|
||||
M: Benjamin Walsh <benjamin.walsh@windriver.com>
|
||||
M: Allan Stephens <allan.stephens@windriver.com>
|
||||
M: Andrew Boie <andrew.p.boie@intel.com>
|
||||
S: Supported
|
||||
F: arch/x86/
|
||||
|
||||
4
Makefile
4
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION_MAJOR = 1
|
||||
VERSION_MINOR = 6
|
||||
PATCHLEVEL = 99
|
||||
VERSION_MINOR = 7
|
||||
PATCHLEVEL = 0
|
||||
VERSION_RESERVED = 0
|
||||
EXTRAVERSION =
|
||||
NAME = Zephyr Kernel
|
||||
|
||||
@@ -154,8 +154,9 @@ endif # GPIO
|
||||
if I2C
|
||||
|
||||
config I2C_QMSI
|
||||
def_bool y
|
||||
def_bool n
|
||||
|
||||
if I2C_QMSI
|
||||
config I2C_0
|
||||
def_bool y
|
||||
|
||||
@@ -189,9 +190,12 @@ config I2C_SDA_TX_HOLD
|
||||
config I2C_SDA_RX_HOLD
|
||||
default 24
|
||||
|
||||
endif
|
||||
|
||||
config I2C_QMSI_SS
|
||||
def_bool y
|
||||
|
||||
if I2C_QMSI_SS
|
||||
config I2C_SS_0
|
||||
def_bool y
|
||||
|
||||
@@ -216,6 +220,8 @@ config I2C_SS_SDA_SETUP
|
||||
config I2C_SS_SDA_HOLD
|
||||
default 10
|
||||
|
||||
endif
|
||||
|
||||
endif # I2C
|
||||
|
||||
if ADC
|
||||
@@ -223,11 +229,24 @@ config ADC_QMSI_SS
|
||||
def_bool y
|
||||
endif
|
||||
|
||||
if BLUETOOTH_H4
|
||||
|
||||
config BLUETOOTH_UART_ON_DEV_NAME
|
||||
default UART_QMSI_0_NAME
|
||||
|
||||
if UART_QMSI
|
||||
config UART_QMSI_0
|
||||
def_bool y
|
||||
|
||||
config UART_QMSI_0_BAUDRATE
|
||||
default 1000000
|
||||
|
||||
config UART_QMSI_0_HW_FC
|
||||
def_bool y
|
||||
|
||||
endif # BLUETOOTH_H4
|
||||
|
||||
if UART_QMSI
|
||||
|
||||
if UART_QMSI_0
|
||||
|
||||
config UART_QMSI_0_IRQ_PRI
|
||||
@@ -257,8 +276,9 @@ endif
|
||||
if SPI
|
||||
|
||||
config SPI_QMSI
|
||||
def_bool y
|
||||
def_bool n
|
||||
|
||||
if SPI_QMSI
|
||||
config SPI_0
|
||||
def_bool y
|
||||
|
||||
@@ -277,9 +297,12 @@ config SPI_1_NAME
|
||||
config SPI_1_IRQ_PRI
|
||||
default 1
|
||||
|
||||
endif
|
||||
|
||||
config SPI_QMSI_SS
|
||||
def_bool y
|
||||
|
||||
if SPI_QMSI_SS
|
||||
config SPI_SS_0
|
||||
def_bool y
|
||||
|
||||
@@ -298,6 +321,8 @@ config SPI_SS_1_NAME
|
||||
config SPI_SS_1_IRQ_PRI
|
||||
default 1
|
||||
|
||||
endif
|
||||
|
||||
endif # SPI
|
||||
|
||||
if AIO_COMPARATOR
|
||||
|
||||
@@ -186,10 +186,24 @@ config RTC_0_IRQ_PRI
|
||||
default 2
|
||||
endif # RTC
|
||||
|
||||
if UART_QMSI
|
||||
if BLUETOOTH_H4 || NBLE
|
||||
|
||||
config BLUETOOTH_UART_ON_DEV_NAME
|
||||
default UART_QMSI_0_NAME
|
||||
|
||||
config UART_QMSI_0
|
||||
def_bool y
|
||||
|
||||
config UART_QMSI_0_BAUDRATE
|
||||
default 1000000
|
||||
|
||||
config UART_QMSI_0_HW_FC
|
||||
def_bool y
|
||||
|
||||
endif # BLUETOOTH_H4 || NBLE
|
||||
|
||||
if UART_QMSI
|
||||
|
||||
if UART_QMSI_0
|
||||
|
||||
config UART_QMSI_0_IRQ_PRI
|
||||
|
||||
@@ -41,7 +41,7 @@ QUARK_SE_IPM_DEFINE(quark_se_ipm4, 4, QUARK_SE_IPM_INBOUND);
|
||||
#define QUARK_SE_IPM_CONSOLE_LINE_BUF_SIZE 80
|
||||
|
||||
static uint32_t ipm_console_ring_buf_data[CONFIG_QUARK_SE_IPM_CONSOLE_RING_BUF_SIZE32];
|
||||
static char __stack ipm_console_thread_stack[IPM_CONSOLE_STACK_SIZE];
|
||||
static char __stack ipm_console_thread_stack[CONFIG_IPM_CONSOLE_STACK_SIZE];
|
||||
static char ipm_console_line_buf[QUARK_SE_IPM_CONSOLE_LINE_BUF_SIZE];
|
||||
|
||||
static struct ipm_console_receiver_config_info quark_se_ipm_receiver_config = {
|
||||
|
||||
@@ -30,8 +30,12 @@ config SPI_CS_GPIO
|
||||
config SPI_0_CS_GPIO_PIN
|
||||
default 24
|
||||
|
||||
config SPI_0_CS_GPIO_PORT
|
||||
default "GPIO_2"
|
||||
|
||||
config SPI_FLASH_W25QXXDV_SPI_NAME
|
||||
default "SPI_0"
|
||||
default "SPI_2"
|
||||
|
||||
config SPI_FLASH_W25QXXDV_SPI_SLAVE
|
||||
default 1
|
||||
|
||||
|
||||
279
boards/arm/96b_carbon/doc/96b_carbon.rst
Normal file
279
boards/arm/96b_carbon/doc/96b_carbon.rst
Normal file
@@ -0,0 +1,279 @@
|
||||
.. _96b_carbon_board:
|
||||
|
||||
96Boards Carbon
|
||||
###############
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
Zephyr applications use the 96b_carbon configuration to run on the 96Boards
|
||||
Carbon hardware. It is based on the STMicroelectronics STM32F401RET Cortex-M4
|
||||
CPU and also contains a nRF51832 chip connected over SPI for BLE connectivity.
|
||||
|
||||
.. figure:: img/96b-carbon-front.png
|
||||
:width: 487px
|
||||
:align: center
|
||||
:alt: 96Boards Carbon
|
||||
|
||||
96Boards Carbon
|
||||
|
||||
Hardware
|
||||
********
|
||||
|
||||
96Boards Carbon provides the following hardware components:
|
||||
|
||||
- STM32F401RET6 in LQFP64 package
|
||||
- ARM®32-bit Cortex®-M4 CPU with FPU
|
||||
- 84 MHz max CPU frequency
|
||||
- VDD from 1.7 V to 3.6 V
|
||||
- 512 KB Flash
|
||||
- 96 KB SRAM
|
||||
- GPIO with external interrupt capability
|
||||
- 12-bit ADC with 16 channels
|
||||
- RTC
|
||||
- Advanced-control Timer
|
||||
- General Purpose Timers (7)
|
||||
- Watchdog Timers (2)
|
||||
- USART/UART (4)
|
||||
- I2C (3)
|
||||
- SPI (3)
|
||||
- SDIO
|
||||
- USB 2.0 OTG FS
|
||||
- DMA Controller
|
||||
- Bluetooth LE over SPI, provided by nRF51832
|
||||
|
||||
More information about STM32F401RE can be found here:
|
||||
- `STM32F401RE on www.st.com`_
|
||||
- `STM32F401 reference manual`_
|
||||
|
||||
Supported Features
|
||||
==================
|
||||
|
||||
The Zephyr 96b_carbon board configuration supports the following hardware
|
||||
features:
|
||||
|
||||
+-----------+------------+-------------------------------------+
|
||||
| Interface | Controller | Driver/Component |
|
||||
+===========+============+=====================================+
|
||||
| NVIC | on-chip | nested vector interrupt controller |
|
||||
+-----------+------------+-------------------------------------+
|
||||
| SYSTICK | on-chip | system clock |
|
||||
+-----------+------------+-------------------------------------+
|
||||
| UART | on-chip | serial port |
|
||||
+-----------+------------+-------------------------------------+
|
||||
| GPIO | on-chip | gpio |
|
||||
+-----------+------------+-------------------------------------+
|
||||
| PINMUX | on-chip | pinmux |
|
||||
+-----------+------------+-------------------------------------+
|
||||
| FLASH | on-chip | flash |
|
||||
+-----------+------------+-------------------------------------+
|
||||
| SPI | on-chip | spi |
|
||||
+-----------+------------+-------------------------------------+
|
||||
|
||||
More details about the board can be found at `96Boards website`_.
|
||||
|
||||
The default configuration can be found in the defconfig file:
|
||||
|
||||
``boards/arm/96b_carbon/96b_carbon_defconfig``
|
||||
|
||||
Pin Mapping
|
||||
===========
|
||||
|
||||
LED
|
||||
---
|
||||
|
||||
- LED1 / User1 LED = PD2
|
||||
- LED2 / User2 LED = PA15
|
||||
- LED3 / BT LED = PB5
|
||||
- LED4 / Power LED = VCC
|
||||
|
||||
Push buttons
|
||||
------------
|
||||
|
||||
- BUTTON = BOOT0 (SW1)
|
||||
- BUTTON = RST
|
||||
|
||||
External Connectors
|
||||
-------------------
|
||||
|
||||
Low Speed Header
|
||||
|
||||
+--------+-------------+----------------------+
|
||||
| PIN # | Signal Name | STM32F401 Functions |
|
||||
+========+=============+======================+
|
||||
| 1 | UART2_CTS | PA0 |
|
||||
+--------+-------------+----------------------+
|
||||
| 3 | UART2_TX | PA2 |
|
||||
+--------+-------------+----------------------+
|
||||
| 5 | UART2_RX | PA3 |
|
||||
+--------+-------------+----------------------+
|
||||
| 7 | UART2_RTS | PA1 |
|
||||
+--------+-------------+----------------------+
|
||||
| 9 | GND | GND |
|
||||
+--------+-------------+----------------------+
|
||||
| 11 | USB5V | USB5V |
|
||||
+--------+-------------+----------------------+
|
||||
| 13 | AIN12 | PC2 |
|
||||
+--------+-------------+----------------------+
|
||||
| 15 | AIN14 | PC4 |
|
||||
+--------+-------------+----------------------+
|
||||
| 17 | UART6_TX | PC6 |
|
||||
+--------+-------------+----------------------+
|
||||
| 19 | GPIO | PC8 |
|
||||
+--------+-------------+----------------------+
|
||||
| 21 | I2C1_SCL | PB6 |
|
||||
+--------+-------------+----------------------+
|
||||
| 23 | I2C1_SCA | PB7 |
|
||||
+--------+-------------+----------------------+
|
||||
| 25 | I2C2_SCA | PB3 |
|
||||
+--------+-------------+----------------------+
|
||||
| 27 | I2C2_SCL | PB10 |
|
||||
+--------+-------------+----------------------+
|
||||
| 29 | RST_BTN | RST_BTN |
|
||||
+--------+-------------+----------------------+
|
||||
|
||||
+--------+-------------+----------------------+
|
||||
| PIN # | Signal Name | STM32F401 Functions |
|
||||
+========+=============+======================+
|
||||
| 2 | SPI2_SS | PB12 |
|
||||
+--------+-------------+----------------------+
|
||||
| 4 | SPI2_MOSI | PB15 |
|
||||
+--------+-------------+----------------------+
|
||||
| 6 | SPI2_MISO | PB14 |
|
||||
+--------+-------------+----------------------+
|
||||
| 8 | SPI2_SCK | PB13 |
|
||||
+--------+-------------+----------------------+
|
||||
| 10 | GND | GND |
|
||||
+--------+-------------+----------------------+
|
||||
| 12 | VCC2 | VCC2 |
|
||||
+--------+-------------+----------------------+
|
||||
| 14 | AIN13 | PC3 |
|
||||
+--------+-------------+----------------------+
|
||||
| 16 | AIN15 | PC5 |
|
||||
+--------+-------------+----------------------+
|
||||
| 18 | UART6_RX | PC7 |
|
||||
+--------+-------------+----------------------+
|
||||
| 20 | GPIO | PC9 |
|
||||
+--------+-------------+----------------------+
|
||||
| 22 | I2C1_SCL | PB8 |
|
||||
+--------+-------------+----------------------+
|
||||
| 24 | I2C1_SDA | PB9 |
|
||||
+--------+-------------+----------------------+
|
||||
| 26 | AIN10 | PC0 |
|
||||
+--------+-------------+----------------------+
|
||||
| 28 | AIN11 | PC1 |
|
||||
+--------+-------------+----------------------+
|
||||
| 30 | NC | NC |
|
||||
+--------+-------------+----------------------+
|
||||
|
||||
System Clock
|
||||
============
|
||||
|
||||
STM32F4 has two external oscillators. The frequency of the slow clock is
|
||||
32.768 kHz. The frequency of the main clock is 16 MHz.
|
||||
|
||||
Flashing Zephyr onto 96Boards Carbon
|
||||
************************************
|
||||
|
||||
There are 2 main entry points for flashing STM32F4X SoCs, one using the ROM
|
||||
bootloader, and another by using the SWD debug port (which requires additional
|
||||
hardware). Flashing using the ROM bootloader requires a special activation
|
||||
pattern, which can be triggered by using the BOOT0 pin. The ROM bootloader
|
||||
supports flashing via USB (DFU), UART, I2C and SPI. You can read more about
|
||||
how to enable and use the ROM bootloader by checking the application
|
||||
note `AN2606`_, page 109.
|
||||
|
||||
Installing dfu-util
|
||||
===================
|
||||
|
||||
It is recommended to use at least v0.8 of `dfu-util`_. The package available in
|
||||
debian/ubuntu can be quite old, so you might have to build dfu-util from source.
|
||||
|
||||
Flashing an Application to 96Boards Carbon
|
||||
------------------------------------------
|
||||
|
||||
The sample application :ref:`hello_world` is being used in this tutorial:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$<zephyr_root_path>/samples/hello_world
|
||||
|
||||
To build the Zephyr kernel and application, enter:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cd <zephyr_root_path>
|
||||
$ source zephyr-env.sh
|
||||
$ cd $ZEPHYR_BASE/samples/hello_world/
|
||||
$ make BOARD=96b_carbon
|
||||
|
||||
Connect the micro-USB cable to the USB OTG Carbon port and to your computer.
|
||||
The board should power ON. Force the board into DFU mode by keeping the BOOT0
|
||||
switch pressed while pressing and releasing the RST switch.
|
||||
|
||||
Confirm that the board is in DFU mode:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo dfu-util -l
|
||||
dfu-util 0.8
|
||||
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
|
||||
Copyright 2010-2014 Tormod Volden and Stefan Schmidt
|
||||
This program is Free Software and has ABSOLUTELY NO WARRANTY
|
||||
Please report bugs to dfu-util@lists.gnumonks.org
|
||||
Found DFU: [0483:df11] ver=2200, devnum=15, cfg=1, intf=0, alt=3, name="@Device Feature/0xFFFF0000/01*004 e", serial="3574364C3034"
|
||||
Found DFU: [0483:df11] ver=2200, devnum=15, cfg=1, intf=0, alt=2, name="@OTP Memory /0x1FFF7800/01*512 e,01*016 e", serial="3574364C3034"
|
||||
Found DFU: [0483:df11] ver=2200, devnum=15, cfg=1, intf=0, alt=1, name="@Option Bytes /0x1FFFC000/01*016 e", serial="3574364C3034"
|
||||
Found DFU: [0483:df11] ver=2200, devnum=15, cfg=1, intf=0, alt=0, name="@Internal Flash /0x08000000/04*016Kg,01*064Kg,03*128Kg", serial="3574364C3034"
|
||||
Found Runtime: [05ac:8290] ver=0104, devnum=2, cfg=1, intf=5, alt=0, name="UNKNOWN", serial="UNKNOWN"
|
||||
|
||||
You should see following confirmation on your Linux host:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ dmesg
|
||||
usb 1-2.1: new full-speed USB device number 14 using xhci_hcd
|
||||
usb 1-2.1: New USB device found, idVendor=0483, idProduct=df11
|
||||
usb 1-2.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
|
||||
usb 1-2.1: Product: STM32 BOOTLOADER
|
||||
usb 1-2.1: Manufacturer: STMicroelectronics
|
||||
usb 1-2.1: SerialNumber: 3574364C3034
|
||||
|
||||
Flash a new application to the board:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo dfu-util -d [0483:df11] -a 0 -D outdir/96b_carbon/zephyr.bin -s 0x08000000
|
||||
|
||||
Connect the micro-USB cable to the USB UART (FTDI) port and to your computer.
|
||||
Run your favorite terminal program to listen for output.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ minicom -D <tty_device> -b 115200
|
||||
|
||||
Replace :code:`<tty_device>` with the port where the board 96Boards Carbon
|
||||
can be found. For example, under Linux, :code:`/dev/ttyUSB0`.
|
||||
The ``-b`` option sets baud rate ignoring the value from config.
|
||||
|
||||
Press the Reset button and you should see the the following message in your
|
||||
terminal:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
Hello World! arm
|
||||
|
||||
.. _dfu-util:
|
||||
http://dfu-util.sourceforge.net/build.html
|
||||
|
||||
.. _AN2606:
|
||||
http://www.st.com/content/ccc/resource/technical/document/application_note/b9/9b/16/3a/12/1e/40/0c/CD00167594.pdf/files/CD00167594.pdf/jcr:content/translations/en.CD00167594.pdf
|
||||
|
||||
.. _96Boards website:
|
||||
http://www.96boards.org/documentation
|
||||
|
||||
.. _STM32F401RE on www.st.com:
|
||||
http://www.st.com/en/microcontrollers/stm32f401re.html
|
||||
|
||||
.. _STM32F401 reference manual:
|
||||
http://www.st.com/resource/en/reference_manual/dm00096844.pdf
|
||||
BIN
boards/arm/96b_carbon/doc/img/96b-carbon-front.png
Normal file
BIN
boards/arm/96b_carbon/doc/img/96b-carbon-front.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
350
boards/arm/96b_nitrogen/doc/96b_nitrogen.rst
Normal file
350
boards/arm/96b_nitrogen/doc/96b_nitrogen.rst
Normal file
@@ -0,0 +1,350 @@
|
||||
.. _96b_nitrogen_board:
|
||||
|
||||
96Boards Nitrogen
|
||||
#################
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
Zephyr applications use the 96b_nitrogen board configuration to run on the
|
||||
96Boards Nitrogen hardware. It provides support for the Nordic Semiconductor
|
||||
nRF52832 ARM Cortex-M4F CPU.
|
||||
|
||||
.. figure:: img/96b-nitrogen-front.png
|
||||
:width: 487px
|
||||
:align: center
|
||||
:alt: 96Boards Nitrogen
|
||||
|
||||
96Boards Nitrogen
|
||||
|
||||
More information about the board can be found at the `seeed BLE Nitrogen`_
|
||||
website. The `Nordic Semiconductor Infocenter`_ contains the processor's
|
||||
information and the datasheet.
|
||||
|
||||
Hardware
|
||||
********
|
||||
|
||||
96Boards Nitrogen provides the following hardware components:
|
||||
|
||||
- nRF52832 microcontroller with 512kB Flash, 64kB RAM
|
||||
- ARM®32-bit Cortex®-M4 CPU with FPU
|
||||
- Bluetooth LE
|
||||
- NFC
|
||||
- LPC11U35 on board SWD debugger
|
||||
|
||||
- SWD debugger firmware
|
||||
- USB to UART
|
||||
- Drag and Drop firmware upgrade
|
||||
|
||||
- 7 LEDs
|
||||
|
||||
- USR1, BT, PWR, CDC, DAP, MSD, Battery charge
|
||||
|
||||
- SWD debug connectors
|
||||
|
||||
- nRF52832 SWD connector
|
||||
- nRF52832 Uart connector
|
||||
|
||||
- On board chip antenna
|
||||
- 1.8V work voltage
|
||||
- 2x20pin 2.0mm pitch Low speed connector
|
||||
|
||||
Supported Features
|
||||
==================
|
||||
|
||||
The Zephyr 96b_nitrogen board configuration supports the following hardware
|
||||
features:
|
||||
|
||||
+-----------+------------+--------------------------------------+
|
||||
| Interface | Controller | Driver/Component |
|
||||
+===========+============+======================================+
|
||||
| NVIC | on-chip | nested vectored interrupt controller |
|
||||
+-----------+------------+--------------------------------------+
|
||||
| RTC | on-chip | system clock |
|
||||
+-----------+------------+--------------------------------------+
|
||||
| UART | on-chip | serial port |
|
||||
+-----------+------------+--------------------------------------+
|
||||
| GPIO | on-chip | gpio |
|
||||
+-----------+------------+--------------------------------------+
|
||||
| FLASH | on-chip | flash |
|
||||
+-----------+------------+--------------------------------------+
|
||||
| RADIO | on-chip | bluetooth |
|
||||
+-----------+------------+--------------------------------------+
|
||||
| RTT | on-chip | console |
|
||||
+-----------+------------+--------------------------------------+
|
||||
|
||||
Other hardware features are not supported by the Zephyr kernel.
|
||||
See `Nordic Semiconductor Infocenter`_ for a complete list of nRF52-based
|
||||
board hardware features.
|
||||
|
||||
The default configuration can be found in the defconfig file:
|
||||
|
||||
``boards/arm/96b_nitrogen/96b_nitrogen_defconfig``
|
||||
|
||||
Pin Mapping
|
||||
===========
|
||||
|
||||
LED
|
||||
---
|
||||
|
||||
- LED1 / User LED (green) = P0.29
|
||||
- LED2 / BT LED (blue) = P0.28
|
||||
|
||||
Push buttons
|
||||
------------
|
||||
|
||||
- BUTTON = SW1 = P0.27
|
||||
|
||||
External Connectors
|
||||
-------------------
|
||||
|
||||
Low Speed Header
|
||||
|
||||
+--------+-------------+----------------------+
|
||||
| PIN # | Signal Name | nRF52832 Functions |
|
||||
+========+=============+======================+
|
||||
| 1 | GND | GND |
|
||||
+--------+-------------+----------------------+
|
||||
| 3 | UART CTS | P.014 / TRACEDATA[3] |
|
||||
+--------+-------------+----------------------+
|
||||
| 5 | UART TX | P0.13 |
|
||||
+--------+-------------+----------------------+
|
||||
| 7 | UART RX | P0.15 / TRACEDATA[2] |
|
||||
+--------+-------------+----------------------+
|
||||
| 9 | UART RTS | P0.12 |
|
||||
+--------+-------------+----------------------+
|
||||
| 11 | UART TX | P0.13 |
|
||||
+--------+-------------+----------------------+
|
||||
| 13 | UART RX | P0.15 / TRACEDATA[2] |
|
||||
+--------+-------------+----------------------+
|
||||
| 15 | P0.22 | P0.22 |
|
||||
+--------+-------------+----------------------+
|
||||
| 17 | P0.20 | P0.20 |
|
||||
+--------+-------------+----------------------+
|
||||
| 19 | N/A | N/A |
|
||||
+--------+-------------+----------------------+
|
||||
| 21 | N/A | N/A |
|
||||
+--------+-------------+----------------------+
|
||||
| 23 | P0.02 | P0.02 |
|
||||
+--------+-------------+----------------------+
|
||||
| 25 | P0.04 | P0.04 |
|
||||
+--------+-------------+----------------------+
|
||||
| 27 | P0.06 | P0.06 |
|
||||
+--------+-------------+----------------------+
|
||||
| 29 | P0.08 | P0.08 |
|
||||
+--------+-------------+----------------------+
|
||||
| 31 | P0.16 | P0.16 |
|
||||
+--------+-------------+----------------------+
|
||||
| 33 | P0.18 | P0.18 |
|
||||
+--------+-------------+----------------------+
|
||||
| 35 | VCC | |
|
||||
+--------+-------------+----------------------+
|
||||
| 37 | USB5V | |
|
||||
+--------+-------------+----------------------+
|
||||
| 39 | GND | GND |
|
||||
+--------+-------------+----------------------+
|
||||
|
||||
+--------+-------------+----------------------+
|
||||
| PIN # | Signal Name | nRF52832 Functions |
|
||||
+========+=============+======================+
|
||||
| 2 | GND | GND |
|
||||
+--------+-------------+----------------------+
|
||||
| 4 | PWR BTN | |
|
||||
+--------+-------------+----------------------+
|
||||
| 6 | RST BTN | P0.21 / RESET |
|
||||
+--------+-------------+----------------------+
|
||||
| 8 | P0.26 | P0.26 |
|
||||
+--------+-------------+----------------------+
|
||||
| 10 | P0.25 | P0.25 |
|
||||
+--------+-------------+----------------------+
|
||||
| 12 | P0.24 | P0.24 |
|
||||
+--------+-------------+----------------------+
|
||||
| 14 | P0.23 | P0.23 |
|
||||
+--------+-------------+----------------------+
|
||||
| 16 | N/A | N/A |
|
||||
+--------+-------------+----------------------+
|
||||
| 18 | N/A | PC7 |
|
||||
+--------+-------------+----------------------+
|
||||
| 20 | N/A | PC9 |
|
||||
+--------+-------------+----------------------+
|
||||
| 22 | N/A | PB8 |
|
||||
+--------+-------------+----------------------+
|
||||
| 24 | P0.03 | P0.03 |
|
||||
+--------+-------------+----------------------+
|
||||
| 26 | P0.05 | P0.05 |
|
||||
+--------+-------------+----------------------+
|
||||
| 28 | P0.07 | P0.07 |
|
||||
+--------+-------------+----------------------+
|
||||
| 30 | P0.11 | P0.11 |
|
||||
+--------+-------------+----------------------+
|
||||
| 32 | P0.17 | P0.17 |
|
||||
+--------+-------------+----------------------+
|
||||
| 34 | P0.19 | P0.19 |
|
||||
+--------+-------------+----------------------+
|
||||
| 36 | NC | |
|
||||
+--------+-------------+----------------------+
|
||||
| 38 | NC | |
|
||||
+--------+-------------+----------------------+
|
||||
| 40 | GND | GND |
|
||||
+--------+-------------+----------------------+
|
||||
|
||||
System Clock
|
||||
============
|
||||
|
||||
nRF52 has two external oscillators. The frequency of the slow clock is
|
||||
32.768 kHz. The frequency of the main clock is 32 MHz.
|
||||
|
||||
Flashing Zephyr onto 96Boards Nitrogen
|
||||
**************************************
|
||||
|
||||
The 96Boards Nitrogen board can be flashed via the `CMSIS DAP`_ interface,
|
||||
which is provided by the micro USB interface to the LPC11U35 chip.
|
||||
|
||||
Using the CMSIS-DAP interface, the board can be flashed via the USB storage
|
||||
interface (drag-and-drop) and also via `pyOCD`_.
|
||||
|
||||
Installing pyOCD
|
||||
================
|
||||
|
||||
The latest stable version of `pyOCD`_ can be installed via pip as follows:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pip install --pre -U pyocd
|
||||
|
||||
To install the latest development version (master branch), do the following:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pip install --pre -U git+https://github.com/mbedmicro/pyOCD.git#egg=pyOCD
|
||||
|
||||
You can then verify that your board is detected by pyOCD by running:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pyocd-flashtool -l
|
||||
|
||||
Common Errors
|
||||
-------------
|
||||
|
||||
No connected boards
|
||||
-------------------
|
||||
|
||||
If you don't use sudo when invoking pyocd-flashtool, you might get any of the
|
||||
following errors:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
No available boards are connected
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
No connected boards
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
Error: There is no board connected.
|
||||
|
||||
To fix the permission issue, simply add the following udev rule for the
|
||||
NXP LPC1768 interface:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ echo 'ATTR{idProduct}=="0204", ATTR{idVendor}=="0d28", MODE="0666", GROUP="plugdev"' > /etc/udev/rules.d/50-cmsis-dap.rules
|
||||
|
||||
Finally, unplug and plug the board again.
|
||||
|
||||
ValueError: The device has no langid
|
||||
------------------------------------
|
||||
|
||||
As described by `pyOCD issue 259`_, you might get the
|
||||
:code:`ValueError: The device has no langid` error when not running
|
||||
pyOCD as root (e.g. sudo).
|
||||
|
||||
To fix the above error, add the udev rule shown in the previous section
|
||||
and install a more recent version of pyOCD.
|
||||
|
||||
Flashing an Application to 96Boards Nitrogen
|
||||
============================================
|
||||
|
||||
The sample application :ref:`hello_world` is being used in this tutorial:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$<zephyr_root_path>/samples/hello_world
|
||||
|
||||
To build the Zephyr kernel and application, enter:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cd <zephyr_root_path>
|
||||
$ source zephyr-env.sh
|
||||
$ cd $ZEPHYR_BASE/samples/hello_world/
|
||||
$ make BOARD=96b_nitrogen
|
||||
|
||||
Connect the micro-USB cable to the 96Boards Nitrogen and to your computer.
|
||||
|
||||
Erase the flash memory in the nRF52832:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pyocd-flashtool -d debug -t nrf52 -ce
|
||||
|
||||
Flash the application using the pyocd-flashtool tool:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pyocd-flashtool -d debug -t nrf52 outdir/96b_nitrogen/zephyr.hex
|
||||
|
||||
Run your favorite terminal program to listen for output.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ minicom -D <tty_device> -b 115200
|
||||
|
||||
Replace :code:`<tty_device>` with the port where the board 96Boards Nitrogen
|
||||
can be found. For example, under Linux, :code:`/dev/ttyACM0`.
|
||||
The ``-b`` option sets baud rate ignoring the value from config.
|
||||
|
||||
Press the Reset button and you should see the the following message in your
|
||||
terminal:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
Hello World! arm
|
||||
|
||||
Debugging with GDB
|
||||
==================
|
||||
|
||||
To debug Zephyr with GDB launch the GDB server on a terminal:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pyocd-gdbserver
|
||||
|
||||
and then launch GDB against the .elf file you built:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ arm-none-eabi-gdb outdir/96b_nitrogen/zephyr.elf
|
||||
|
||||
And finally connect GDB to the GDB Server:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
(gdb) target remote localhost:3333
|
||||
|
||||
.. _pyOCD:
|
||||
https://github.com/mbedmicro/pyOCD
|
||||
|
||||
.. _CMSIS DAP:
|
||||
https://developer.mbed.org/handbook/CMSIS-DAP
|
||||
|
||||
.. _Nordic Semiconductor Infocenter:
|
||||
http://infocenter.nordicsemi.com/
|
||||
|
||||
.. _seeed BLE Nitrogen:
|
||||
http://wiki.seeed.cc/BLE_Nitrogen/
|
||||
|
||||
.. _pyOCD issue 259:
|
||||
https://github.com/mbedmicro/pyOCD/issues/259
|
||||
BIN
boards/arm/96b_nitrogen/doc/img/96b-nitrogen-front.png
Normal file
BIN
boards/arm/96b_nitrogen/doc/img/96b-nitrogen-front.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 328 KiB |
1
boards/arm/arduino_due/Makefile.board
Normal file
1
boards/arm/arduino_due/Makefile.board
Normal file
@@ -0,0 +1 @@
|
||||
FLASH_SCRIPT = bossa-flash.sh
|
||||
155
boards/arm/sam_e70_xplained/doc/sam_e70_xplained.rst
Normal file
155
boards/arm/sam_e70_xplained/doc/sam_e70_xplained.rst
Normal file
@@ -0,0 +1,155 @@
|
||||
.. _sam_e70_xplained:
|
||||
|
||||
SAM E70 Xplained
|
||||
################
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
The SAM E70 Xplained evaluation kit is a development platform to evaluate the
|
||||
Atmel SAM E70 series microcontrollers.
|
||||
|
||||
Hardware
|
||||
********
|
||||
|
||||
- ATSAME70Q21 ARM Cortex-M7 Processor
|
||||
- 12 MHz crystal oscillator
|
||||
- 32.768 kHz crystal oscillator (not populated)
|
||||
- AT24MAC402 EEPROM
|
||||
- IS42S16100E 16 Mb SDRAM
|
||||
- SD card connector
|
||||
- Ethernet port
|
||||
- Micro-AB USB device
|
||||
- Micro-AB USB debug interface supporting CMSIS-DAP, Virtual COM Port and Data
|
||||
Gateway Interface (DGI)
|
||||
- JTAG interface connector
|
||||
- One reset and one user pushbutton
|
||||
- One green user LED
|
||||
|
||||
Supported Features
|
||||
==================
|
||||
|
||||
The sam_e70_xplained board configuration supports the following hardware
|
||||
features:
|
||||
|
||||
+-----------+------------+-------------------------------------+
|
||||
| Interface | Controller | Driver/Component |
|
||||
+===========+============+=====================================+
|
||||
| NVIC | on-chip | nested vector interrupt controller |
|
||||
+-----------+------------+-------------------------------------+
|
||||
| SYSTICK | on-chip | systick |
|
||||
+-----------+------------+-------------------------------------+
|
||||
| USART | on-chip | serial port |
|
||||
+-----------+------------+-------------------------------------+
|
||||
| ETHERNET | on-chip | ethernet |
|
||||
+-----------+------------+-------------------------------------+
|
||||
|
||||
Other hardware features are not currently supported by Zephyr.
|
||||
|
||||
The default configuration can be found in the Kconfig
|
||||
:file:`boards/arm/sam_e70_xplained/sam_e70_xplained_defconfig`.
|
||||
|
||||
Connections and IOs
|
||||
===================
|
||||
|
||||
The `SAME70-XPLD User Guide`_ has detailed information about board connections.
|
||||
|
||||
System Clock
|
||||
============
|
||||
|
||||
The SAM E70 MCU is configured to use the 12 MHz external oscillator on the board
|
||||
with the on-chip PLL to generate a 300 MHz system clock.
|
||||
|
||||
Serial Port
|
||||
===========
|
||||
|
||||
The ATSAME70Q21 MCU has five UARTs and three USARTs. One of the USARTs is
|
||||
configured for the console and is available as a Virtual COM Port via EDBG USB
|
||||
chip.
|
||||
|
||||
Programming and Debugging
|
||||
*************************
|
||||
|
||||
Flashing
|
||||
========
|
||||
|
||||
Flashing the Zephyr project onto SAM E70 MCU requires the `OpenOCD tool`_.
|
||||
Support for Atmel SAM E microcontroller series was added in OpenOCD release
|
||||
0.10.0. The current OpenOCD version available in the Zephyr SDK is 0.9 and
|
||||
unfortunately it does not support Atmel SAM E microcontrollers. Since few, if
|
||||
any major Linux distributions currently offer OpenOCD version 0.10.0 as a
|
||||
package you will have to compile and install it yourself. Make sure to enable
|
||||
CMSIS-DAP support as this is the debugging interface used by the on board EDBG
|
||||
chip.
|
||||
|
||||
By default SAM E70 chip will boot SAM-BA bootloader located in the ROM, not the
|
||||
flashed image. This can be changed with SAM Boot Assistant (`SAM-BA`_) In-system
|
||||
Programmer from Atmel by reprogramming GPNVM1 (General-purpose NVM bit 1).
|
||||
This operation needs to be performed only once. If you do not need to debug
|
||||
your firmware you can also use SAM-BA instead of OpenOCD to flash your project.
|
||||
|
||||
#. Build the Zephyr kernel and the application:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cd $ZEPHYR_BASE/samples/hello_world/
|
||||
$ make BOARD=sam_e70_xplained
|
||||
|
||||
#. Connect the SAM E70 Xplained board to your host computer using the USB debug
|
||||
port.
|
||||
|
||||
#. Run your favorite terminal program to listen for output. Under Linux the
|
||||
terminal should be :code:`/dev/ttyACM0`. For example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ minicom -D /dev/ttyACM0 -o
|
||||
|
||||
The -o option tells minicom not to send the modem initialization
|
||||
string. Connection should be configured as follows:
|
||||
|
||||
- Speed: 115200
|
||||
- Data: 8 bits
|
||||
- Parity: None
|
||||
- Stop bits: 1
|
||||
|
||||
#. To flash the image, assuming the OpenOCD tool is already installed, enter:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ openocd -f board/atmel_same70_xplained.cfg -c "program outdir/sam_e70_xplained/zephyr.elf verify reset exit"
|
||||
|
||||
The command will also verify that the image was programmed correctly, reset
|
||||
the board and run the Zephyr application.
|
||||
|
||||
You should see "Hello World!" in your terminal.
|
||||
|
||||
Debugging
|
||||
=========
|
||||
|
||||
#. Connect the SAM E70 Xplained board to your host computer using the USB debug
|
||||
port.
|
||||
|
||||
#. Start GDB server on your host computer
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ openocd -f board/atmel_same70_xplained.cfg&
|
||||
|
||||
#. You can now use GDB remote debugging to connect to the target board. By
|
||||
default GDB server will listen on port 3333.
|
||||
|
||||
References
|
||||
**********
|
||||
|
||||
SAM E70 Product Page:
|
||||
http://www.atmel.com/products/microcontrollers/arm/sam-e.aspx
|
||||
|
||||
.. _SAME70-XPLD User Guide:
|
||||
http://www.atmel.com/Images/Atmel-44050-Cortex-M7-Microcontroller-SAM-E70-XPLD-Xplained_User-guide.pdf
|
||||
|
||||
.. _OpenOCD tool:
|
||||
http://openocd.org/
|
||||
|
||||
.. _SAM-BA:
|
||||
http://www.atmel.com/tools/ATMELSAM-BAIN-SYSTEMPROGRAMMER.aspx
|
||||
@@ -51,6 +51,9 @@ if FLASH && SPI
|
||||
config SPI_FLASH_W25QXXDV
|
||||
def_bool y
|
||||
|
||||
config GPIO
|
||||
def_bool y
|
||||
|
||||
config SPI_CS_GPIO
|
||||
def_bool y
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ config BLUETOOTH_UART_ON_DEV_NAME
|
||||
default UART_QMSI_0_NAME
|
||||
|
||||
config UART_QMSI_0_BAUDRATE
|
||||
default 115200
|
||||
default 1000000
|
||||
|
||||
config UART_QMSI_0_HW_FC
|
||||
def_bool y
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
CONFIG_MAIN_STACK_SIZE=2048
|
||||
CONFIG_IPM_CONSOLE_STACK_SIZE=2048
|
||||
CONFIG_XTENSA=y
|
||||
CONFIG_SIMULATOR_XTENSA=y
|
||||
CONFIG_CONSOLE=y
|
||||
|
||||
@@ -18,10 +18,10 @@ Documentation Notes
|
||||
|
||||
Zephyr Project content is written using the reStructuredText markup language
|
||||
(.rst file extension) with Sphinx extensions, and processed using sphinx to
|
||||
create a formatted standalone website. Developers can view this content either
|
||||
create a formatted stand-alone website. Developers can view this content either
|
||||
in its raw form as .rst markup files, or you can generate the HTML content and view it
|
||||
with a web browser directly on your workstations drive. This same .rst
|
||||
content is also fed into the Zephyr Project'ns public website documentation area
|
||||
content is also fed into the Zephyr Project's public website documentation area
|
||||
(with a different theme applied).
|
||||
|
||||
You can read details about reStructuredText and about Sphinx extensions from
|
||||
|
||||
@@ -398,7 +398,7 @@ entries manually, using the configuration menu is a preferred method.
|
||||
|
||||
.. note::
|
||||
|
||||
When a non-default entry is selected for options that are nonnumerical,
|
||||
When a non-default entry is selected for options that are non-numerical,
|
||||
an asterisk :kbd:`*` appears between the square brackets in the display.
|
||||
There is nothing added added the display when you select the option's
|
||||
default.
|
||||
@@ -555,6 +555,41 @@ context, navigate to: :file:`\$ZEPHYR_BASE/samples/philosophers/src`.
|
||||
obj-y = main.o
|
||||
|
||||
|
||||
Support for building third-party library code
|
||||
=============================================
|
||||
|
||||
It is possible to build library code outside the application's :file:`src`
|
||||
directory but it is important that both application and library code targets
|
||||
the same Application Binary Interface (ABI). On most architectures there are
|
||||
compiler flags that control the ABI targeted, making it important that both
|
||||
libraries and applications have certain compiler flags in common. It may also
|
||||
be useful for glue code to have access to Zephyr kernel header files.
|
||||
|
||||
To make it easier to integrate third-party components, the Zephyr build system
|
||||
includes a special build target, ``outputexports``, that takes a number of
|
||||
critical variables from the Zephyr build system and copies them into
|
||||
:file:`Makefile.export`. This allows the critical variables to be included by
|
||||
wrapper code for use in a third-party build system.
|
||||
|
||||
The following variables are recommended for use within the third-party build
|
||||
(see :file:`Makefile.export` for the complete list of exported variables):
|
||||
|
||||
* ``CROSS_COMPILE``, together with related convenience variables to call the
|
||||
cross-tools directly (including ``AR``, ``AS``, ``CC``, ``CXX``, ``CPP``
|
||||
and ``LD``).
|
||||
|
||||
* ``ARCH`` and ``BOARD``, together with several variables that identify the
|
||||
Zephyr kernel version.
|
||||
|
||||
* ``KBUILD_CFLAGS``, ``NOSTDINC_FLAGS`` and ``ZEPHYRINCLUDE`` all of which
|
||||
should normally be added, in that order, to ``CFLAGS`` (or
|
||||
``CXXFLAGS``).
|
||||
|
||||
* All kconfig variables, allowing features of the library code to be
|
||||
enabled/disabled automatically based on the Zephyr kernel configuration.
|
||||
|
||||
:file:`samples/static_lib` is a sample project that demonstrates
|
||||
some of these features.
|
||||
|
||||
Build an Application
|
||||
********************
|
||||
|
||||
@@ -217,7 +217,7 @@ Specific Remarks
|
||||
|
||||
* TinyCrypt ECC implementation is based on nano-ecc (see
|
||||
https://github.com/iSECPartners/nano-ecc) which in turn is based on
|
||||
mciro-ecc (see https://github.com/kmackay/micro-ecc). In the original
|
||||
micro-ecc (see https://github.com/kmackay/micro-ecc). In the original
|
||||
nano and micro-ecc documentation, there is an important remark about the
|
||||
way integers are represented:
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ Zephyr provides a set of device drivers for multiple boards. Each driver
|
||||
should support an interrupt-based implementation, rather than polling, unless
|
||||
the specific hardware does not provide any interrupt.
|
||||
|
||||
High-level calls accessed through devices's specific API, such as i2c.h
|
||||
High-level calls accessed through device-specific APIs, such as i2c.h
|
||||
or spi.h, are usually intended as synchronous. Thus, these calls should be
|
||||
blocking.
|
||||
|
||||
@@ -147,7 +147,7 @@ the normal course of operation (such as a storage device full). Bad
|
||||
parameters, programming errors, consistency checks, pathological/unrecoverable
|
||||
failures, etc., should be handled by assertions.
|
||||
|
||||
When it is appropriate to return error condtitions for the caller to check, 0
|
||||
When it is appropriate to return error conditions for the caller to check, 0
|
||||
should be returned on success and a POSIX errno.h code returned on failure.
|
||||
See https://wiki.zephyrproject.org/view/Coding_conventions#Return_Codes for
|
||||
details about this.
|
||||
@@ -280,7 +280,7 @@ executed. Any driver will specify one of five initialization levels:
|
||||
`PRE_KERNEL_2`
|
||||
Used for devices that rely on the initialization of devices initialized
|
||||
as part of the PRIMARY level. These devices cannot use any kernel
|
||||
services during configuration, since the kerne services are not yet
|
||||
services during configuration, since the kernel services are not yet
|
||||
available. Init functions at this level run on the interrupt stack.
|
||||
|
||||
`POST_KERNEL`
|
||||
|
||||
@@ -78,7 +78,7 @@ To build an example application follow these steps:
|
||||
|
||||
$ cd zephyr-project
|
||||
|
||||
#. Source the project environment file to set the project environtment
|
||||
#. Source the project environment file to set the project environment
|
||||
variables:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
@@ -8,8 +8,8 @@ This section describes how to set up a Linux development system.
|
||||
After completing these steps, you will be able to compile and run your Zephyr
|
||||
applications on the following Linux distributions:
|
||||
|
||||
* Ubuntu 14.04 LTS 64-bit
|
||||
* Fedora 22 64-bit
|
||||
* Ubuntu 16.04 LTS 64-bit
|
||||
* Fedora 25 64-bit
|
||||
|
||||
Where needed, alternative instructions are listed for Ubuntu and Fedora.
|
||||
|
||||
@@ -91,12 +91,13 @@ Follow these steps to install the SDK on your Linux host system.
|
||||
Visit the `Zephyr SDK archive`_ to find all available SDK versions,
|
||||
including the latest version.
|
||||
|
||||
Alternatively, you can use the following command to download the desired
|
||||
version, replacing <version> with the version number you wish to download.
|
||||
Alternatively, you can use the following command to download the
|
||||
desired version (*0.9* can be replaced with the version number you
|
||||
wish to download).
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ wget https://nexus.zephyrproject.org/content/repositories/releases/org/zephyrproject/zephyr-sdk/<version>-i686/zephyr-sdk-<version>-i686-setup.run
|
||||
$ wget https://nexus.zephyrproject.org/content/repositories/releases/org/zephyrproject/zephyr-sdk/0.9/zephyr-sdk-0.9-setup.run
|
||||
|
||||
#. Run the installation binary, follow this example:
|
||||
|
||||
@@ -107,9 +108,9 @@ Follow these steps to install the SDK on your Linux host system.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ chmod +x zephyr-sdk-<version>-i686-setup.run
|
||||
$ chmod +x zephyr-sdk-<version>-setup.run
|
||||
|
||||
$ ./zephyr-sdk-<version>-i686-setup.run
|
||||
$ ./zephyr-sdk-<version>-setup.run
|
||||
|
||||
There is no need for `sudo` if the SDK is installed in the current
|
||||
user's home directory.
|
||||
|
||||
@@ -94,7 +94,7 @@ Setting Up the Toolchain
|
||||
Creating a Case-sensitive File System
|
||||
=====================================
|
||||
|
||||
Building the compiler requires a case-senstive file system. Therefore, use
|
||||
Building the compiler requires a case-sensitive file system. Therefore, use
|
||||
:program:`diskutil` to create an 8 GB blank sparse image making sure you select
|
||||
case-sensitive file system (OS X Extended (Case-sensitive, Journaled) and
|
||||
mount it.
|
||||
|
||||
@@ -7,9 +7,7 @@ This section describes how to configure your development environment and
|
||||
to build Zephyr applications in a Microsoft Windows environment.
|
||||
|
||||
This guide was tested by compiling and running the Zephyr's sample
|
||||
applications on the following Windows version:
|
||||
|
||||
* Windows 8.1
|
||||
applications on Windows version 8.1 (and should work with Windows 10 as well).
|
||||
|
||||
Update Your Operating System
|
||||
****************************
|
||||
@@ -23,117 +21,106 @@ Installing Requirements and Dependencies
|
||||
****************************************
|
||||
|
||||
To install the software components required to build Zephyr applications on
|
||||
Windows, you will need to build or install a toolchain.
|
||||
Windows, you will need to build or install a toolchain:
|
||||
|
||||
Install :program:`GIT`. Go to `GIT Download`_ to obtain the latest copy of
|
||||
the software.
|
||||
1. Install :program:`GIT`. Go to `GIT Download`_ to obtain the latest copy of
|
||||
the software (2.12.0). Install into the :file:`C:\\Git` folder and use the
|
||||
default configuration options for the rest.
|
||||
|
||||
Install :program:`Python 2.7`. Go to `Python Download`_ to obtain the 2.7
|
||||
version of the software.
|
||||
2. Install :program:`Python 2.7`. Go to `Python Download`_ to obtain the
|
||||
software (version 2.7.13) and use the default installation options.
|
||||
|
||||
Install :program:`MinGW`. MinGW is the minimalist GNU development environment
|
||||
for native Windows applications. The Zephyr build system will execute on top of
|
||||
this tool set.
|
||||
3. Install :program:`MinGW`. MinGW is the minimalist GNU development environment
|
||||
for native Windows applications. The Zephyr build system will execute on top
|
||||
of this tool set. Visit the site `MinGW Home`_ and install the
|
||||
following packages with their installer `mingw-get-setup.exe` (you'll need
|
||||
to open the "All Packages" tab to enable installing the msys packages listed
|
||||
here):
|
||||
|
||||
To install :program:`MinGW`, visit the site `MinGW Home`_ and install the
|
||||
following packages with their installler `mingw-get-setup.exe`:
|
||||
* mingw-developer-toolkit
|
||||
* mingw32-base
|
||||
* msys-base
|
||||
* msys-binutils
|
||||
* msys-console
|
||||
* msys-w32api
|
||||
|
||||
* mingw-developer-toolkit
|
||||
* mingw32-base
|
||||
* msys-base
|
||||
* msys-binutils
|
||||
* msys-console
|
||||
* msys-w32api
|
||||
4. Launch the `MSYS console` from a cmd window. The installer does not create
|
||||
shortcuts for you so you'll need to run the script
|
||||
in :file:`C:\\MinGW\\msys\\1.0\\msys.bat.`
|
||||
|
||||
Launch the `MSYS console`. The installer does not create shortcuts for you,
|
||||
but the script to launch it is in :file:`C:\\MinGW\\msys\\1.0\\msys.bat.`.
|
||||
We need the following line in :file:`/etc/fstab`:
|
||||
5. The Zephyr build process has a dependency on the Pthread and GNU regex
|
||||
libraries. Msys provides its own GNU library implementation that can be
|
||||
downloaded from the MinGW and Msys official repository:
|
||||
`MinGW Repository`_ with the following commands:
|
||||
|
||||
.. code-block:: console
|
||||
.. code-block:: console
|
||||
|
||||
#Win32_Path Mount_Point
|
||||
c:/mingw /mingw
|
||||
mingw-get update
|
||||
mingw-get install libpthread msys-libregex-dev --all-related
|
||||
|
||||
The easiest way to do this is just copy the file :file:`fstab.sample` as
|
||||
:file:`fstab` and confirm that the these lines are in the new
|
||||
:file:`fstab` file.
|
||||
|
||||
.. code-block:: console
|
||||
When done, move libregex files (``libregex.a``, ``libregex.dll.a``,
|
||||
``libregex.la``)
|
||||
from ``C:\Git\mingw32\msys\1.0\lib`` to ``C:\Git\mingw32\lib``
|
||||
|
||||
$ cp /etc/fstab.sample /etc/fstab
|
||||
$ cat /etc/fstab
|
||||
6. We need to edit :file:`/etc/fstab` to create an entry mapping from the Win32
|
||||
path ``c:/mingw`` to the mount point ``/mingw``
|
||||
The easiest way to do this is just copy the file :file:`fstab.sample` as
|
||||
:file:`fstab` and ``cat /etc/fstab`` to confirm that the mapping was added.
|
||||
|
||||
Configure Python's folder location in the environmental variable :envvar:`PATH`
|
||||
and the installation path for MinGW.
|
||||
|
||||
.. note:: The format of the path for `PYTHON_PATH` must to be in the
|
||||
linux format. Default installation is in :file:`C:\\python27`,
|
||||
which would be written as :file:`/c/python27/`.
|
||||
7. The build system should be able to work with any toolchain installed in your
|
||||
system. For instance, the Zephyr build system was tested using the mingw
|
||||
MSYS console (as described below) with the toolchain
|
||||
provided with the ISSM 2016 (Intel System Studio for Microcontrollers)
|
||||
installation. Install ISSM from the Intel Developer Zone:
|
||||
`ISSM 2016 Download`_
|
||||
|
||||
.. code-block:: console
|
||||
.. note::
|
||||
|
||||
export PYTHON_PATH=/c/python27
|
||||
export PATH=$PATH:${PYTHON_PATH}
|
||||
export MINGW_DIR=/c/MinGW
|
||||
The ISSM toolset only supports development for Intel® Quark™
|
||||
Microcontrollers, for example, the Arduino 101 board. (Check out the
|
||||
"Zephyr Development Environment
|
||||
Setup" in this `Getting Started on Arduino 101 with ISSM`_ document.)
|
||||
Also, additional setup is required to use the ISSM GUI for
|
||||
development.
|
||||
|
||||
Pthread library
|
||||
===============
|
||||
8. From within the MSYS console, clone a copy of the Zephyr source into your
|
||||
home directory using Git:
|
||||
|
||||
The Zephyr OS build process has a dependency on the Pthread library.
|
||||
The required packages for Msys installation would normally provide it.
|
||||
However, if a minimal installation fails to provide the Pthread library,
|
||||
it can be installed with the following command:
|
||||
.. code-block:: console
|
||||
|
||||
.. code-block:: console
|
||||
cd ~
|
||||
git clone https://gerrit.zephyrproject.org/r/zephyr
|
||||
|
||||
mingw-get install libpthread
|
||||
9. Also within the MSYS console, set up environment variables for installed
|
||||
tools and for the Zephyr environment (using the provided shell script):
|
||||
|
||||
GNU Regex C library
|
||||
===================
|
||||
.. code-block:: console
|
||||
|
||||
The Zephyr build process has a dependency with the GNU regex library.
|
||||
Msys provides its own GNU library implementation that can be downloaded from the
|
||||
MinGW and Msys official repository: `MinGW Repository`_.
|
||||
Install the library from the Msys console interface with the following commands:
|
||||
export PATH=$PATH:/c/python27/
|
||||
export MINGW_DIR=/c/mingw
|
||||
export ZEPHYR_GCC_VARIANT=issm
|
||||
export ISSM_INSTALLATION_PATH=C:/IntelSWTools/ISSM_2016.1.067
|
||||
unset ZEPHYR_SDK_INSTALL_DIR
|
||||
source ~/zephyr/zephyr-env.sh
|
||||
|
||||
.. code-block:: console
|
||||
10. Finally, you can try building the :ref:`hello_world` sample to check things
|
||||
out. In this example, we'll build the hello_world sample for the Arduino
|
||||
101 board:
|
||||
|
||||
mingw-get update
|
||||
mingw-get install msys-libregex-dev --all-related
|
||||
.. code-block:: console
|
||||
|
||||
Update the following environment variables on your system to allow the C compiler
|
||||
and linker to find the library and headers:
|
||||
cd $ZEPHYR_BASE/samples/hello_world
|
||||
make board=arduino_101
|
||||
|
||||
.. code-block:: console
|
||||
This should check that all the tools and toolchain are setup correctly for
|
||||
your own Zephyr development.
|
||||
|
||||
export LIBRARY_PATH=$LIBRARY_PATH:/c/mingw/msys/1.0/lib
|
||||
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/c/mingw/msys/1.0/include
|
||||
|
||||
Toolchain Installation
|
||||
======================
|
||||
|
||||
The build system should be able to work with any toolchain installed in your system.
|
||||
|
||||
For instance, the Zephyr build system was tested with the toolchain provided with
|
||||
the ISSM 2016 (Intel System Studio for Microcontrollers) installation.
|
||||
|
||||
To install ISSM use the link provided to download from the Intel Developer Zone:
|
||||
`ISSM 2016 Download`_ and install it into your system.
|
||||
|
||||
Finally, configure your environment variables for the ISSM 2016 toolchain.
|
||||
For example, using the default installation path for ISSM:
|
||||
:file:`C:/IntelSWTools/ISSM_2016`
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
export ZEPHYR_GCC_VARIANT=issm
|
||||
export ISSM_INSTALLATION_PATH=C:/IntelSWTools/ISSM_2016
|
||||
|
||||
.. note:: The format of the location for the ISSM installation directory
|
||||
(e.g. :envvar:`ISSM_INSTALLATION_PATH`) must be in the windows format.
|
||||
|
||||
.. _GIT Download: https://git-scm.com/download/win
|
||||
.. _Python Download: https://www.python.org/downloads/
|
||||
.. _MinGW Home: http://www.mingw.org/
|
||||
.. _MinGW Repository: http://sourceforge.net/projects/mingw/files/
|
||||
.. _ISSM 2016 Download: https://software.intel.com/en-us/intel-system-studio-microcontrollers
|
||||
.. _Getting Started on Arduino 101 with ISSM: https://software.intel.com/en-us/articles/getting-started-arduino-101genuino-101-with-intel-system-studio-for-microcontrollers
|
||||
|
||||
69
doc/glossary.rst
Normal file
69
doc/glossary.rst
Normal file
@@ -0,0 +1,69 @@
|
||||
.. _glossary:
|
||||
|
||||
Glossary of Terms
|
||||
#################
|
||||
|
||||
.. glossary::
|
||||
:sorted:
|
||||
|
||||
API
|
||||
(Application Program Interface) A defined set of routines and protocols for
|
||||
building application software.
|
||||
|
||||
application
|
||||
The set of user-supplied files that the Zephyr build system uses
|
||||
to build an application image for a specified board configuration.
|
||||
It can contain application-specific code, kernel configuration settings,
|
||||
and at least one Makefile.
|
||||
The application's kernel configuration settings direct the build system
|
||||
to create a custom kernel that makes efficient use of the board's
|
||||
resources.
|
||||
An application can sometimes be built for more than one type of board
|
||||
configuration (including boards with different CPU architectures),
|
||||
if it does not require any board-specific capabilities.
|
||||
|
||||
application image
|
||||
A binary file that is loaded and executed by the board for which
|
||||
it was built.
|
||||
Each application image contains both the application's code and the
|
||||
Zephyr kernel code needed to support it. They are compiled as a single,
|
||||
fully-linked binary.
|
||||
Once an application image is loaded onto a board, the image takes control
|
||||
of the system, initializes it, and runs as the system's sole application.
|
||||
Both application code and kernel code execute as privileged code
|
||||
within a single shared address space.
|
||||
|
||||
board
|
||||
A target system with a defined set of devices and capabilities,
|
||||
which can load and execute an application image. It may be an actual
|
||||
hardware system or a simulated system running under QEMU.
|
||||
The Zephyr kernel supports a :ref:`variety of boards <boards>`.
|
||||
|
||||
board configuration
|
||||
A set of kernel configuration options that specify how the devices
|
||||
present on a board are used by the kernel.
|
||||
The Zephyr build system defines one or more board configurations
|
||||
for each board it supports. The kernel configuration settings that are
|
||||
specified by the build system can be over-ridden by the application,
|
||||
if desired.
|
||||
|
||||
IDT
|
||||
(Interrupt Descriptor Table) a data structure used by the x86
|
||||
architecture to implement an interrupt vector table. The IDT is used
|
||||
to determine the correct response to interrupts and exceptions.
|
||||
|
||||
ISR
|
||||
(Interrupt Service Routine) Also known as an interrupt handler, an ISR
|
||||
is a callback function whose execution is triggered by a hardware
|
||||
interrupt (or software interrupt instructions) and is used to handle
|
||||
high-priority conditions that require interrupting the current code
|
||||
executing on the processor.
|
||||
|
||||
kernel
|
||||
The set of Zephyr-supplied files that implement the Zephyr kernel,
|
||||
including its core services, device drivers, network stack, and so on.
|
||||
|
||||
XIP
|
||||
(eXecute In Place) a method of executing programs directly from long
|
||||
term storage rather than copying it into RAM, saving writable memory for
|
||||
dynamic data and not the static program code.
|
||||
@@ -42,6 +42,7 @@ Sections
|
||||
contribute/code.rst
|
||||
release-notes.rst
|
||||
LICENSING.rst
|
||||
glossary.rst
|
||||
|
||||
You can find further information on the `Zephyr Project Wiki`_.
|
||||
|
||||
@@ -53,6 +54,7 @@ Indices and Tables
|
||||
* :ref:`search`
|
||||
|
||||
.. _Zephyr Project Wiki: https://wiki.zephyrproject.org/view/Main_Page
|
||||
.. _Zephyr 1.7.0: https://www.zephyrproject.org/doc/1.7.0/
|
||||
.. _Zephyr 1.6.0: https://www.zephyrproject.org/doc/1.6.0/
|
||||
.. _Zephyr 1.5.0: https://www.zephyrproject.org/doc/1.5.0/
|
||||
.. _Zephyr 1.4.0: https://www.zephyrproject.org/doc/1.4.0/
|
||||
|
||||
@@ -64,50 +64,4 @@ small-footprint OSes:
|
||||
Fundamental Terms and Concepts
|
||||
******************************
|
||||
|
||||
This section outlines the basic terms used by the Zephyr kernel ecosystem.
|
||||
|
||||
:dfn:`kernel`
|
||||
The set of Zephyr-supplied files that implement the Zephyr kernel,
|
||||
including its core services, device drivers, network stack, and so on.
|
||||
|
||||
:dfn:`application`
|
||||
The set of user-supplied files that the Zephyr build system uses
|
||||
to build an application image for a specified board configuration.
|
||||
It can contain application-specific code, kernel configuration settings,
|
||||
and at least one Makefile.
|
||||
|
||||
The application's kernel configuration settings direct the build system
|
||||
to create a custom kernel that makes efficient use of the board's resources.
|
||||
|
||||
An application can sometimes be built for more than one type of board
|
||||
configuration (including boards with different CPU architectures),
|
||||
if it does not require any board-specific capabilities.
|
||||
|
||||
:dfn:`application image`
|
||||
A binary file that is loaded and executed by the board for which
|
||||
it was built.
|
||||
|
||||
Each application image contains both the application's code and the
|
||||
Zephyr kernel code needed to support it. They are compiled as a single,
|
||||
fully-linked binary.
|
||||
|
||||
Once an application image is loaded onto a board, the image takes control
|
||||
of the system, initializes it, and runs as the system's sole application.
|
||||
Both application code and kernel code execute as privileged code
|
||||
within a single shared address space.
|
||||
|
||||
:dfn:`board`
|
||||
A target system with a defined set of devices and capabilities,
|
||||
which can load and execute an application image. It may be an actual
|
||||
hardware system or a simulated system running under QEMU.
|
||||
|
||||
The Zephyr kernel supports a :ref:`variety of boards <boards>`.
|
||||
|
||||
:dfn:`board configuration`
|
||||
A set of kernel configuration options that specify how the devices
|
||||
present on a board are used by the kernel.
|
||||
|
||||
The Zephyr build system defines one or more board configurations
|
||||
for each board it supports. The kernel configuration settings that are
|
||||
specified by the build system can be over-ridden by the application,
|
||||
if desired.
|
||||
See :ref:`glossary`
|
||||
|
||||
@@ -418,7 +418,7 @@ where the maximum size of a message is known in advance.
|
||||
This technique can be used when the message data is actually located
|
||||
in a memory block supplied by the sending thread. The mailbox copies
|
||||
the data into the message buffer specified by the receiving thread, then
|
||||
frees the meessage block back to its memory pool. This allows
|
||||
frees the message block back to its memory pool. This allows
|
||||
a receiving thread to retrieve message data without having to know
|
||||
whether the data was sent using a message buffer or a message block.
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ in an asynchronous manner.
|
||||
.. note::
|
||||
A message queue can be used to transfer large data items, if desired.
|
||||
However, this can increase interrupt latency as interrupts are locked
|
||||
while a data item is written or read. It is usally preferable to transfer
|
||||
while a data item is written or read. It is usually preferable to transfer
|
||||
large data items by exchanging a pointer to the data item, rather than the
|
||||
data item itself. The kernel's memory map and memory pool object types
|
||||
can be helpful for data transfers of this sort.
|
||||
|
||||
@@ -4,7 +4,7 @@ Zephyr Kernel Primer (version 2)
|
||||
################################
|
||||
|
||||
This document provides a general introduction of the Zephyr kernel's
|
||||
key capabilties and services. Additional details can be found by consulting
|
||||
key capabilities and services. Additional details can be found by consulting
|
||||
the :ref:`api` and :ref:`application` documentation, and by examining
|
||||
the code in the Zephyr source tree.
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Interrupts
|
||||
##########
|
||||
|
||||
An :dfn:`interrupt service routine` (ISR) is a function that executes
|
||||
asychronously in response to a hardware or software interrupt.
|
||||
asynchronously in response to a hardware or software interrupt.
|
||||
An ISR normally preempts the execution of the current thread,
|
||||
allowing the response to occur with very low overhead.
|
||||
Thread execution resumes only once all ISR work has been completed.
|
||||
|
||||
@@ -9,8 +9,9 @@ This section describes other services provided by the kernel.
|
||||
:maxdepth: 1
|
||||
|
||||
interrupts.rst
|
||||
cpu_idle.rst
|
||||
atomic.rst
|
||||
float.rst
|
||||
polling.rst
|
||||
ring_buffers.rst
|
||||
float.rst
|
||||
cxx_support.rst
|
||||
cpu_idle.rst
|
||||
|
||||
291
doc/kernel/other/polling.rst
Normal file
291
doc/kernel/other/polling.rst
Normal file
@@ -0,0 +1,291 @@
|
||||
.. _polling_v2:
|
||||
|
||||
Polling API
|
||||
###########
|
||||
|
||||
The polling API is used to wait concurrently for any one of multiple conditions
|
||||
to be fulfilled.
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 2
|
||||
|
||||
Concepts
|
||||
********
|
||||
|
||||
The polling API's main function is :cpp:func:`k_poll()`, which is very similar
|
||||
in concept to the POSIX :cpp:func:`poll()` function, except that it operates on
|
||||
kernel objects rather than on file descriptors.
|
||||
|
||||
The polling API allows a single thread to wait concurrently for one or more
|
||||
conditions to be fulfilled without actively looking at each one individually.
|
||||
|
||||
There is a limited set of such conditions:
|
||||
|
||||
- a semaphore becomes available
|
||||
- a kernel FIFO contains data ready to be retrieved
|
||||
- a poll signal is raised
|
||||
|
||||
A thread that wants to wait on multiple conditions must define an array of
|
||||
**poll events**, one for each condition.
|
||||
|
||||
All events in the array must be initialized before the array can be polled on.
|
||||
|
||||
Each event must specify which **type** of condition must be satisfied so that
|
||||
its state is changed to signal the requested condition has been met.
|
||||
|
||||
Each event must specify what **kernel object** it wants the condition to be
|
||||
satisfied.
|
||||
|
||||
Each event must specify which **mode** of operation is used when the condition
|
||||
is satisfied.
|
||||
|
||||
Each event can optionally specify a **tag** to group multiple events together,
|
||||
to the user's discretion.
|
||||
|
||||
Apart from the kernel objects, there is also a **poll signal** pseudo-object
|
||||
type that be directly signaled.
|
||||
|
||||
The :cpp:func:`k_poll()` function returns as soon as one of the conditions it
|
||||
is waiting for is fulfilled. It is possible for more than one to be fulfilled
|
||||
when :cpp:func:`k_poll()` returns, if they were fulfilled before
|
||||
:cpp:func:`k_poll()` was called, or due to the preemptive multi-threading
|
||||
nature of the kernel. The caller must look at the state of all the poll events
|
||||
in the array to figured out which ones were fulfilled and what actions to take.
|
||||
|
||||
Currently, there is only one mode of operation available: the object is not
|
||||
acquired. As an example, this means that when :cpp:func:`k_poll()` returns and
|
||||
the poll event states that the semaphore is available, the caller of
|
||||
:cpp:func:`k_poll()` must then invoke :cpp:func:`k_sem_take()` to take
|
||||
ownership of the semaphore. If the semaphore is contested, there is no
|
||||
guarantee that it will be still available when :cpp:func:`k_sem_give()` is
|
||||
called.
|
||||
|
||||
Implementation
|
||||
**************
|
||||
|
||||
Using k_poll()
|
||||
==============
|
||||
|
||||
The main API is :cpp:func:`k_poll()`, which operates on an array of poll events
|
||||
of type :c:type:`struct k_poll_event`. Each entry in the array represents one
|
||||
event a call to :cpp:func:`k_poll()` will wait for its condition to be
|
||||
fulfilled.
|
||||
|
||||
They can be initialized using either the runtime initializers
|
||||
:c:macro:`K_POLL_EVENT_INITIALIZER()` or :cpp:func:`k_poll_event_init()`, or
|
||||
the static initializer :c:macro:`K_POLL_EVENT_STATIC_INITIALIZER()`. An object
|
||||
that matches the **type** specified must be passed to the initializers. The
|
||||
**mode** *must* be set to :c:macro:`K_POLL_MODE_NOTIFY_ONLY`. The state *must*
|
||||
be set to :c:macro:`K_POLL_STATE_NOT_READY` (the initializers take care of
|
||||
this). The user **tag** is optional and completely opaque to the API: it is
|
||||
there to help a user to group similar events together. Being optional, it is
|
||||
passed to the static initializer, but not the runtime ones for performance
|
||||
reasons. If using runtime initializers, the user must set it separately in the
|
||||
:c:type:`struct k_poll_event` data structure. If an event in the array is to be
|
||||
ignored, most likely temporarily, its type can be set to K_POLL_TYPE_IGNORE.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct k_poll_event events[2] = {
|
||||
K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE,
|
||||
K_POLL_MODE_NOTIFY_ONLY,
|
||||
&my_sem, 0),
|
||||
K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
|
||||
K_POLL_MODE_NOTIFY_ONLY,
|
||||
&my_fifo, 0),
|
||||
};
|
||||
|
||||
or at runtime
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct k_poll_event events[2];
|
||||
void some_init(void)
|
||||
{
|
||||
k_poll_event_init(K_POLL_TYPE_SEM_AVAILABLE,
|
||||
K_POLL_MODE_NOTIFY_ONLY,
|
||||
&my_sem);
|
||||
|
||||
k_poll_event_init(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
|
||||
K_POLL_MODE_NOTIFY_ONLY,
|
||||
&my_fifo);
|
||||
|
||||
// tags are left uninitialized if unused
|
||||
}
|
||||
|
||||
|
||||
After the events are initialized, the array can be passed to
|
||||
:cpp:func:`k_poll()`. A timeout can be specified to wait only for a specified
|
||||
amount of time, or the special values :c:macro:`K_NO_WAIT` and
|
||||
:c:macro:`K_FOREVER` to either not wait or wait until an event condition is
|
||||
satisfied and not sooner.
|
||||
|
||||
Only one thread can poll on a semaphore or a FIFO at a time. If a second thread
|
||||
tries to poll on the same semaphore or FIFO, :cpp:func:`k_poll()` immediately
|
||||
returns with the return value :c:macro:`-EADDRINUSE`. In that case, if other
|
||||
conditions passed to :cpp:func:`k_poll` were met, their state will be set in
|
||||
the corresponding poll event.
|
||||
|
||||
In case of success, :cpp:func:`k_poll()` returns 0. If it times out, it returns
|
||||
:c:macro:`-EAGAIN`.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
// assume there is no contention on this semaphore and FIFO
|
||||
// -EADDRINUSE will not occur; the semaphore and/or data will be available
|
||||
|
||||
void do_stuff(void)
|
||||
{
|
||||
rc = k_poll(events, 2, 1000);
|
||||
if (rc == 0) {
|
||||
if (events[0].state == K_POLL_STATE_SEM_AVAILABLE) {
|
||||
k_sem_take(events[0].sem, 0);
|
||||
} else if (events[1].state == K_POLL_STATE_FIFO_DATA_AVAILABLE) {
|
||||
data = k_fifo_get(events[1].fifo, 0);
|
||||
// handle data
|
||||
}
|
||||
} else {
|
||||
// handle timeout
|
||||
}
|
||||
}
|
||||
|
||||
When :cpp:func:`k_poll()` is called in a loop, the events state must be reset
|
||||
to :c:macro:`K_POLL_STATE_NOT_READY` by the user.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
void do_stuff(void)
|
||||
{
|
||||
for(;;) {
|
||||
rc = k_poll(events, 2, K_FOREVER);
|
||||
if (events[0].state == K_POLL_STATE_SEM_AVAILABLE) {
|
||||
k_sem_take(events[0].sem, 0);
|
||||
} else if (events[1].state == K_POLL_STATE_FIFO_DATA_AVAILABLE) {
|
||||
data = k_fifo_get(events[1].fifo, 0);
|
||||
// handle data
|
||||
}
|
||||
events[0].state = K_POLL_STATE_NOT_READY;
|
||||
events[1].state = K_POLL_STATE_NOT_READY;
|
||||
}
|
||||
}
|
||||
|
||||
Using k_poll_signal()
|
||||
=====================
|
||||
|
||||
One of the types of events is :c:macro:`K_POLL_TYPE_SIGNAL`: this is a "direct"
|
||||
signal to a poll event. This can be seen as a lightweight binary semaphore only
|
||||
one thread can wait for.
|
||||
|
||||
A poll signal is a separate object of type :c:type:`struct k_poll_signal` that
|
||||
must be attached to a k_poll_event, similar to a semaphore or FIFO. It must
|
||||
first be initialized either via :c:macro:`K_POLL_SIGNAL_INITIALIZER()` or
|
||||
:cpp:func:`k_poll_signal_init()`.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct k_poll_signal signal;
|
||||
void do_stuff(void)
|
||||
{
|
||||
k_poll_signal_init(&signal);
|
||||
}
|
||||
|
||||
It is signaled via the :cpp:func:`k_poll_signal()` function. This function
|
||||
takes a user **result** parameter that is opaque to the API and can be used to
|
||||
pass extra information to the thread waiting on the event.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct k_poll_signal signal;
|
||||
|
||||
// thread A
|
||||
void do_stuff(void)
|
||||
{
|
||||
k_poll_signal_init(&signal);
|
||||
|
||||
struct k_poll_event events[1] = {
|
||||
K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL,
|
||||
K_POLL_MODE_NOTIFY_ONLY,
|
||||
&signal);
|
||||
};
|
||||
|
||||
k_poll(events, 1, K_FOREVER);
|
||||
|
||||
if (events.signal->result == 0x1337) {
|
||||
// A-OK!
|
||||
} else {
|
||||
// weird error
|
||||
}
|
||||
}
|
||||
|
||||
// thread B
|
||||
void signal_do_stuff(void)
|
||||
{
|
||||
k_poll_signal(&signal, 0x1337);
|
||||
}
|
||||
|
||||
If the signal is to be polled in a loop, *both* its event state and its
|
||||
**signaled** field *must* be reset on each iteration if it has been signaled.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct k_poll_signal signal;
|
||||
void do_stuff(void)
|
||||
{
|
||||
k_poll_signal_init(&signal);
|
||||
|
||||
struct k_poll_event events[1] = {
|
||||
K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL,
|
||||
K_POLL_MODE_NOTIFY_ONLY,
|
||||
&signal);
|
||||
};
|
||||
|
||||
for (;;) {
|
||||
k_poll(events, 1, K_FOREVER);
|
||||
|
||||
if (events[0].signal->result == 0x1337) {
|
||||
// A-OK!
|
||||
} else {
|
||||
// weird error
|
||||
}
|
||||
|
||||
events[0].signal->signaled = 0;
|
||||
events[0].state = K_POLL_STATE_NOT_READY;
|
||||
}
|
||||
}
|
||||
|
||||
Suggested Uses
|
||||
**************
|
||||
|
||||
Use :cpp:func:`k_poll()` to consolidate multiple threads that would be pending
|
||||
on one object each, saving possibly large amounts of stack space.
|
||||
|
||||
Use a poll signal as a lightweight binary semaphore if only one thread pends on
|
||||
it.
|
||||
|
||||
.. note::
|
||||
Because objects are only signaled if no other thread is waiting for them to
|
||||
become available and only one thread can poll on a specific object, polling
|
||||
is best used when objects are not subject of contention between multiple
|
||||
threads, basically when a single thread operates as a main "server" or
|
||||
"dispatcher" for multiple objects and is the only one trying to acquire
|
||||
these objects.
|
||||
|
||||
Configuration Options
|
||||
*********************
|
||||
|
||||
Related configuration options:
|
||||
|
||||
* :option:`CONFIG_POLL`
|
||||
|
||||
APIs
|
||||
****
|
||||
|
||||
The following polling APIs are provided by :file:`kernel.h`:
|
||||
|
||||
* :c:macro:`K_POLL_EVENT_INITIALIZER`
|
||||
* :c:macro:`K_POLL_EVENT_STATIC_INITIALIZER`
|
||||
* :cpp:func:`k_poll_event_init()`
|
||||
* :cpp:func:`k_poll()`
|
||||
* :cpp:func:`k_poll_signal_init()`
|
||||
* :cpp:func:`k_poll_signal()`
|
||||
@@ -106,7 +106,7 @@ which can be accessed using efficient masking operations.
|
||||
/* Buffer with 2^8 (or 256) words */
|
||||
SYS_RING_BUF_DECLARE_POW2(my_ring_buf, 8);
|
||||
|
||||
The following code defines a ring buffer with an arbitraty-sized data buffer,
|
||||
The following code defines a ring buffer with an arbitrary-sized data buffer,
|
||||
which can be accessed using less efficient modulo operations.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
.. _glossary_v2:
|
||||
|
||||
Glossary of Terms [TBD]
|
||||
#######################
|
||||
|
||||
API (Application Program Interface)
|
||||
A defined set of routines and protocols for building software inputs
|
||||
and output mechanisms.
|
||||
|
||||
IDT (Interrupt Descriptor Table)
|
||||
[TBD]
|
||||
|
||||
ISR (Interrupt Service Routine)
|
||||
[TBD]
|
||||
|
||||
XIP (eXecute In Place)
|
||||
[TBD]
|
||||
@@ -25,5 +25,4 @@ include: fitness wearables, smart watches, and IoT wireless gateways.
|
||||
:maxdepth: 1
|
||||
|
||||
source_tree.rst
|
||||
glossary.rst
|
||||
changes.rst
|
||||
|
||||
@@ -83,7 +83,7 @@ thread's priority correctly reverts to its original non-elevated priority.
|
||||
The kernel does *not* fully support priority inheritance when a thread holds
|
||||
two or more mutexes simultaneously. This situation can result in the thread's
|
||||
priority not reverting to its original non-elevated priority when all mutexes
|
||||
have been released. It is recommended that a thread lcok only a single mutex
|
||||
have been released. It is recommended that a thread lock only a single mutex
|
||||
at a time when multiple mutexes are shared between threads of different
|
||||
priorities.
|
||||
|
||||
@@ -126,7 +126,7 @@ for the mutex to become available if it is already locked by another thread.
|
||||
k_mutex_lock(&my_mutex, K_FOREVER);
|
||||
|
||||
The following code waits up to 100 milliseconds for the mutex to become
|
||||
available, and gives a warning if the mutex does not become availablee.
|
||||
available, and gives a warning if the mutex does not become available.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ ranges:
|
||||
* preemptive threads: 0 to (:option:`CONFIG_NUM_PREEMPT_PRIORITIES` - 1)
|
||||
|
||||
For example, configuring 5 cooperative priorities and 10 preemptive priorities
|
||||
results in the ranages -5 to -1 and 0 to 9, respectively.
|
||||
results in the ranges -5 to -1 and 0 to 9, respectively.
|
||||
|
||||
Scheduling Algorithm
|
||||
====================
|
||||
|
||||
@@ -8,7 +8,7 @@ Legacy Applications Porting Guide
|
||||
|
||||
This document is still work in progress.
|
||||
|
||||
This guide will help you move your applications from the nanokerne/microkernel
|
||||
This guide will help you move your applications from the nanokernel/microkernel
|
||||
model to the unified kernel. The unified kernel was introduced with
|
||||
:ref:`zephyr_1.6` which was released late 2016.
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ When a device wants to signal the processor that there is some work to be done
|
||||
on its behalf, it raises an interrupt. When a thread does an operation that is
|
||||
not handled by the serial flow of the software itself, it raises an exception.
|
||||
Both, interrupts and exceptions, pass control to a handler. The handler is
|
||||
knowns as an :abbr:`ISR (Interrupt Service Routine)` in the case of
|
||||
known as an :abbr:`ISR (Interrupt Service Routine)` in the case of
|
||||
interrupts. The handler perform the work required the exception or the
|
||||
interrupt. For interrupts, that work is device-specific. For exceptions, it
|
||||
depends on the exception, but most often the core kernel itself is responsible
|
||||
|
||||
BIN
doc/porting/board/hierarchy.png
Normal file
BIN
doc/porting/board/hierarchy.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 107 KiB |
123
doc/porting/board_porting.rst
Normal file
123
doc/porting/board_porting.rst
Normal file
@@ -0,0 +1,123 @@
|
||||
.. _board_porting_guide:
|
||||
|
||||
Board Porting Guide
|
||||
###################
|
||||
|
||||
When building an application you must specify the target hardware and
|
||||
the exact board or model. Specifying the board name results in a binary that
|
||||
is suited for the target hardware by selecting the right Zephyr features and
|
||||
components and setting the right Zephyr configuration for that specific target
|
||||
hardware.
|
||||
|
||||
A board is defined as a special configuration of an SoC with possible additional
|
||||
components.
|
||||
For example, a board might have sensors and flash memory implemented as
|
||||
additional features on top of what the SoC provides. Such additional hardware is
|
||||
configured and referenced in the Zephyr board configuration.
|
||||
|
||||
The board implements at least one SoC and thus inherits all of the features
|
||||
that are provided by the SoC. When porting a board to Zephyr, you should
|
||||
first make sure the SoC is implemented in Zephyr.
|
||||
|
||||
Hardware Configuration Hierarchy
|
||||
********************************
|
||||
|
||||
Hardware definitions in Zephyr follow a well-defined hierarchy of configurations
|
||||
and layers, below are thelayers from top to bottom:
|
||||
|
||||
- Board
|
||||
- SoC
|
||||
- SoC Series
|
||||
- SoC Family
|
||||
- CPU Core
|
||||
- Architecture
|
||||
|
||||
This design contributes to code reuse and implementation of device drivers and
|
||||
features at the bottom of the hierarchy making a board configuration as simple
|
||||
as a selection of features that are implemented by the underlying layers. The
|
||||
figures below shows this hierarchy with a few example of boards currently
|
||||
available in the source tree:
|
||||
|
||||
.. figure:: board/hierarchy.png
|
||||
:width: 500px
|
||||
:align: center
|
||||
:alt: Configuration Hierarchy
|
||||
|
||||
Configuration Hierarchy
|
||||
|
||||
|
||||
Hierarchy Example
|
||||
|
||||
+------------+-----------+--------------+------------+--------------+---------+
|
||||
|Board |FRDM K64F |nRF52 NITROGEN|nRF51XX |Quark SE C1000|Arduino |
|
||||
| | | | |Devboard |101 |
|
||||
+============+===========+==============+============+==============+=========+
|
||||
|SOC |MK64F12 |nRF52832 |nRF51XX |Quark SE C1000|Curie |
|
||||
+------------+-----------+--------------+------------+--------------+---------+
|
||||
|SOC Series |Kinetis K6x|Nordic NRF52 |Nordic NRF51|Quark SE |Quark SE |
|
||||
| |Series | | | | |
|
||||
+------------+-----------+--------------+------------+--------------+---------+
|
||||
|SOC Family |NXP Kinetis|Nordic NRF5 |Nordic NRF5 |Quark |Quark |
|
||||
+------------+-----------+--------------+------------+--------------+---------+
|
||||
|CPU Core |Cortex-M4 |Cortex-M4 |Cortex-M0+ |Lakemount |Lakemount|
|
||||
+------------+-----------+--------------+------------+--------------+---------+
|
||||
|Architecture|ARM |ARM |ARM |x86 |x86 |
|
||||
+------------+-----------+--------------+------------+--------------+---------+
|
||||
|
||||
|
||||
Architecture
|
||||
============
|
||||
If your CPU architecture is already supported by Zephyr, there is no
|
||||
architecture work involved in porting to your board. If your CPU architecture
|
||||
is not supported by the Zephyr kernel, you can add support by following the
|
||||
instructions available at :ref:`architecture_porting_guide`.
|
||||
|
||||
CPU Core
|
||||
========
|
||||
|
||||
Some OS code depends on the CPU core that your board is using. For
|
||||
example, a given CPU core has a specific assembly language instruction set, and
|
||||
may require special cross compiler or compiler settings to use the appropriate
|
||||
instruction set.
|
||||
|
||||
If your CPU architecture is already supported by Zephyr, there is no CPU core
|
||||
work involved in porting to your platform or board. You need only to select the
|
||||
appropriate CPU in your configuration and the rest will be taken care of by the
|
||||
configuration system in Zephyr which will select the features implemented
|
||||
by the corresponding CPU.
|
||||
|
||||
Platform
|
||||
========
|
||||
|
||||
This layer implements most of the features that need porting and is split into
|
||||
three layers to allow for code reuse when dealing with implementations with
|
||||
slight differences.
|
||||
|
||||
SoC Family
|
||||
----------
|
||||
|
||||
This layer is a container of all SoCs of the same class that, for example
|
||||
implement one single type of CPU core but differ in peripherals and features.
|
||||
The base hardware will in most cases be the same across all SoCs and MCUs of
|
||||
this family.
|
||||
|
||||
SoC Series
|
||||
----------
|
||||
|
||||
Moving closer to the SoC, the series is derived from an SoC family. A series is
|
||||
defined by a feautre set that serves the purpose of distinguishing different
|
||||
SoCs belonging to the same family.
|
||||
|
||||
SoC
|
||||
---
|
||||
|
||||
Finally, an SoC is actual hardware component that is physically available on a
|
||||
board.
|
||||
|
||||
Board
|
||||
=====
|
||||
|
||||
A board implements an SoC with all its features, together with peripherals
|
||||
available on the board that differentiates the board with additional interfaces
|
||||
and features not available in the SoC.
|
||||
|
||||
@@ -10,4 +10,5 @@ architectures, SoCs and boards.
|
||||
:maxdepth: 1
|
||||
|
||||
arch.rst
|
||||
board_porting.rst
|
||||
application.rst
|
||||
|
||||
@@ -1,13 +1,473 @@
|
||||
Release Notes
|
||||
#############
|
||||
|
||||
.. _zephyr_1.7:
|
||||
|
||||
Zephyr Kernel 1.7.0
|
||||
********************
|
||||
|
||||
We are pleased to announce the release of Zephyr kernel version 1.7.0. This
|
||||
release continues refinement of the unified kernel introduced with the 1.6.0
|
||||
kernel release, simplifying the overall Zephyr architecture and programming
|
||||
interfaces. This is the last release that will support the deprecated legacy
|
||||
nano- and micro-kernel APIs found in the 1.5.0 release and earlier.
|
||||
|
||||
This release introduces a new native IP stack, replacing the legacy uIP stack,
|
||||
maintaining the legacy functionality, adding additional capabilities, and allowing
|
||||
future improvements.
|
||||
|
||||
We have introduced support for the RISC V and Xtensa architectures and now
|
||||
support 6 architectures in total.
|
||||
|
||||
Device tree support for ARM based boards added. The initial
|
||||
device tree support includes flash/sram base address and UART devices. Board
|
||||
support includes NXP Kinetis based SoCs, ARM Beetle, TI CC3200 LaunchXL, and
|
||||
STML32L476 based SoCs. Plan is to add support for other architectures and
|
||||
expand device support in upcoming Zephyr releases.
|
||||
|
||||
The following sections provide a detailed list of changes, by component, since
|
||||
kernel version 1.6.0.
|
||||
|
||||
Kernel
|
||||
======
|
||||
|
||||
* Introduction of k_poll API: k_poll() is similar to the POSIX poll() API in
|
||||
spirit in that it allows a single thread to monitor multiple events without
|
||||
actively polling them, but rather pending for one or more to become ready.
|
||||
* Optimized memory use of some thread fields
|
||||
* Remove usage of micro/nano kernel terminology from kernel code and introduced
|
||||
a legacy option to enable/disable legacy APIs. (using legacy.h)
|
||||
|
||||
|
||||
Architectures
|
||||
=============
|
||||
|
||||
* ARM: Added support for device tree
|
||||
* ARM: Fixed exception priority access on Cortex M0(+)
|
||||
* ARM: Refactored to use CMSIS
|
||||
|
||||
Boards
|
||||
======
|
||||
|
||||
* Added ARM MPS2_AN385 board
|
||||
* Added Atmel SAM E70 Xplained board
|
||||
* Added Nordic pca10056 PDK board
|
||||
* Added NXP FRDM-KW41Z board
|
||||
* Added ST Nucleo-F334R8, Nucleo-L476G, STM3210C-EVAL, and STM32373C-EVAL boards
|
||||
* Added Panther and tinyTILE boards, based on Quark SE C1000 and Intel Curie
|
||||
* Added support for Zedboard Pulpino, a RISC V based board
|
||||
* Added Qemu target for RISC V and a simulator target for the Xtensa architecture.
|
||||
|
||||
Drivers and Sensors
|
||||
===================
|
||||
|
||||
* Added Atmel SAM pmc, gpio, uart, and ethernet drivers
|
||||
* Added STM32F3x clock, flash, gpio, pinmux drivers
|
||||
* Added stm32cube pwm and clock drivers
|
||||
* Added cc3200 gpio driver
|
||||
* Added mcr20a ieee802154 driver
|
||||
* Added mcux pinmux, gpio, uart, and spi drivers
|
||||
* Added Beetle clock control and watchdog drivers
|
||||
|
||||
Networking
|
||||
==========
|
||||
|
||||
This version removes the legacy uIP stack and introduces a new native IP stack.
|
||||
Because of this there is lot of changes in the code base. The native IP stack
|
||||
will support the same functionality as the legacy IP stack found in 1.6, and
|
||||
add new networking features which are described below.
|
||||
|
||||
* IP stack code is moved to subsys/net/ip directory.
|
||||
* IP stack supports both IPv6 and IPv4, and they can be enabled simultaneously.
|
||||
* Multiple network technologies like Bluetooth IPSP and IEEE 802.15.4 can be
|
||||
enabled simultaneously. No routing functionality is provided by IP stack
|
||||
between enabled network technologies, applications need to decide where to
|
||||
send the network packets.
|
||||
* Network technologies are abstracted in IP layer 2 (L2) and presented to
|
||||
rest of the system as network interfaces. There exists L2 driver for
|
||||
Ethernet, Bluetooth and IEEE 802.15.4.
|
||||
* Created Bluetooth Internet Protocol Support Profile (IPSP) support. It will
|
||||
provide IPv6 connection over Bluetooth connection oriented channel (L2CAP).
|
||||
* Created DHCPv4 support.
|
||||
* Created CoAP implementation called ZoAP which replaces uIP based one.
|
||||
* Updated 6Lo implementation to support both Bluetooth and IEEE 802.15.4
|
||||
* Created application API (net_context) for creating connections and
|
||||
transferring data to external systems.
|
||||
* Added sample application (wpanusb) for exporting IEEE 802.15.4 radio over
|
||||
USB to external operating systems like Linux.
|
||||
* Added DNS client library.
|
||||
* Updated TCP implementation.
|
||||
* Created MQTT publisher support.
|
||||
* Created network test generator (zperf).
|
||||
* Created telnet console support.
|
||||
* Created IRC client sample application.
|
||||
* Created HTTP server and client sample applications.
|
||||
* Created net-shell module for interacting with network sub-system.
|
||||
* Created ieee15_4 shell module for dedicated interaction with
|
||||
IEEE 802.15.4 Soft MAC.
|
||||
* Created network management API for generic network settings request as well
|
||||
as a network event notification system (sender/listener).
|
||||
* Redesigned buffer & pool allocation API.
|
||||
|
||||
Bluetooth
|
||||
=========
|
||||
|
||||
* Redesigned buffer pools for smaller memory consumption
|
||||
* Redesigned thread model for smaller memory consumption
|
||||
* Utilized new k_poll API to consolidate all TX threads into a single one
|
||||
* Added more SDP functionality
|
||||
* Improved RFCOMM support
|
||||
* Reduced latencies in the Controller
|
||||
* Added SPI HCI driver
|
||||
|
||||
Libraries
|
||||
=========
|
||||
|
||||
* Updated mbedTLS library
|
||||
* Updated TinyCrypt to version 0.2.5
|
||||
|
||||
HALs
|
||||
====
|
||||
|
||||
* Updated FAT FS to rev 0.12b
|
||||
* Updated Nordic MDK header files
|
||||
* Updated QMSI to 1.4 RC3
|
||||
* Imported Atmel SDK (ASF) for SAM E70 and SAM3X
|
||||
* Imported Nordic SDK HAL and 802.15.4 radio driver
|
||||
* Renamed NXP KSDK to MCUX
|
||||
* Imported NXP MCUX for KW41Z
|
||||
* Imported Segger J-Link RTT library
|
||||
* Imported stm32cube for F4 and L4
|
||||
|
||||
Documentation
|
||||
=============
|
||||
|
||||
* General improvements and additions to kernel component docs
|
||||
* Moved supported board information back to the website site.
|
||||
* New website documentation theme to go with the new zephyrproject.org site.
|
||||
* New local-content generation theme (read-the-docs)
|
||||
* General spelling checks and organizational improvements.
|
||||
* Site-wide glossary added.
|
||||
* Porting guides added.
|
||||
* Sample README files converted to documents included in the website.
|
||||
* Improved consistency of :ref:`boards` and `samples documentation`_.
|
||||
|
||||
.. _samples documentation: https:/zephyrproject.org/doc/samples/samples.html
|
||||
|
||||
|
||||
JIRA Related Items
|
||||
==================
|
||||
|
||||
|
||||
.. comment List derived from https://jira.zephyrproject.org/issues/?filter=10345
|
||||
|
||||
* :jira:`ZEP-19` - IPSP node support
|
||||
* :jira:`ZEP-145` - no 'make flash' for Arduino Due
|
||||
* :jira:`ZEP-328` - HW Encryption Abstraction
|
||||
* :jira:`ZEP-359` - Move QEMU handling to a central location
|
||||
* :jira:`ZEP-365` - Zephyr's MQTT library
|
||||
* :jira:`ZEP-437` - TCP/IP API
|
||||
* :jira:`ZEP-513` - extern declarations of small microkernel objects in designated sections require __attribute__((section)) in gp-enabled systems
|
||||
* :jira:`ZEP-591` - MQTT Port to New IP Stack
|
||||
* :jira:`ZEP-604` - In coap_server sample app, CoAP resource separate is not able to send separate response
|
||||
* :jira:`ZEP-613` - TCP/UDP client and server mode functionality
|
||||
* :jira:`ZEP-641` - Bluetooth Eddystone sample does not correctly implement Eddystone beacon
|
||||
* :jira:`ZEP-648` - New CoAP Implementation
|
||||
* :jira:`ZEP-664` - Extend spi_qmsi_ss driver to support save/restore peripheral context
|
||||
* :jira:`ZEP-665` - Extend gpio_qmsi_ss driver to support save/restore peripheral context
|
||||
* :jira:`ZEP-666` - Extend i2c_qmsi_ss driver to support save/restore peripheral context
|
||||
* :jira:`ZEP-667` - Extend adc_qmsi_ss driver to support save/restore peripheral context
|
||||
* :jira:`ZEP-686` - docs: Info in Application Development Primer and Developing an Application and the Build System is largely duplicated
|
||||
* :jira:`ZEP-706` - cannot set debug breakpoints on ARC side of Arduino 101
|
||||
* :jira:`ZEP-719` - Add ksdk uart shim driver
|
||||
* :jira:`ZEP-734` - Port AES-CMAC-PRF-128 [RFC 4615] encryption library for Thread support
|
||||
* :jira:`ZEP-742` - nRF5x Series: System Clock driver using NRF_RTC
|
||||
* :jira:`ZEP-744` - USB WebUSB
|
||||
* :jira:`ZEP-748` - Enable mbedtls_sslclient sample to run on quark se board
|
||||
* :jira:`ZEP-759` - Add preliminary support for Atmel SAM E70 (Cortex-M7) chipset family and SAM E70 Xplained board
|
||||
* :jira:`ZEP-788` - UDP
|
||||
* :jira:`ZEP-789` - IPv4
|
||||
* :jira:`ZEP-790` - ICMPv4
|
||||
* :jira:`ZEP-791` - TCP
|
||||
* :jira:`ZEP-792` - ARP
|
||||
* :jira:`ZEP-793` - DNS Resolver
|
||||
* :jira:`ZEP-794` - Requirements for Internet Hosts - Communication Layers
|
||||
* :jira:`ZEP-796` - DHCPv4
|
||||
* :jira:`ZEP-798` - IPv6
|
||||
* :jira:`ZEP-799` - HTTP over TLS
|
||||
* :jira:`ZEP-801` - DNS Extensions to support IPv6
|
||||
* :jira:`ZEP-804` - IPv6 Addressing Architecture
|
||||
* :jira:`ZEP-805` - Internet Control Message Protocol (ICMP) v6
|
||||
* :jira:`ZEP-807` - Neighbor Discovery for IPv6
|
||||
* :jira:`ZEP-808` - IPv6 Stateless Autoconfiguration (SLAAC)
|
||||
* :jira:`ZEP-809` - IPv6 over 802.15.4
|
||||
* :jira:`ZEP-811` - The Trickle Algorithm
|
||||
* :jira:`ZEP-812` - Compression Format for IPv6 over 802.15.4
|
||||
* :jira:`ZEP-813` - RPL: IPv6 Routing Protocol
|
||||
* :jira:`ZEP-814` - Routing Metrics used in Path Selection
|
||||
* :jira:`ZEP-815` - Objective Function Zero for RPL
|
||||
* :jira:`ZEP-816` - Minimum Rank with Hysteresis (RPL)
|
||||
* :jira:`ZEP-818` - CoAP working over the new IP stack
|
||||
* :jira:`ZEP-820` - HTTP v1.1 Server Sample
|
||||
* :jira:`ZEP-823` - New IP Stack - Documentation
|
||||
* :jira:`ZEP-824` - Network Device Driver Porting Guide
|
||||
* :jira:`ZEP-825` - Porting guide for old-to-new IP Stack APIs
|
||||
* :jira:`ZEP-827` - HTTP Client sample application
|
||||
* :jira:`ZEP-830` - ICMPv6 Parameter Problem Support
|
||||
* :jira:`ZEP-832` - Hop-by-Hop option handling
|
||||
* :jira:`ZEP-847` - Network protocols must be moved to subsys/net/lib
|
||||
* :jira:`ZEP-854` - CoAP with DTLS sample
|
||||
* :jira:`ZEP-859` - Migrate ENC28J60 driver to YAIP IP stack
|
||||
* :jira:`ZEP-865` - convert filesystem sample to a runnable test
|
||||
* :jira:`ZEP-872` - Unable to flash Zephyr on Arduino 101 using Ubuntu and following wiki instructions
|
||||
* :jira:`ZEP-873` - DMA API Update
|
||||
* :jira:`ZEP-875` - 6LoWPAN - Context based compression support
|
||||
* :jira:`ZEP-876` - 6LoWPAN - Offset based Reassembly of 802.15.4 packets
|
||||
* :jira:`ZEP-879` - 6LoWPAN - Stateless Address Autoconfiguration
|
||||
* :jira:`ZEP-882` - 6LoWPAN - IPv6 Next Header Compression
|
||||
* :jira:`ZEP-883` - IP Stack L2 Interface Management API
|
||||
* :jira:`ZEP-884` - 802.15.4 - CSMA-CA Radio protocol support
|
||||
* :jira:`ZEP-885` - 802.15.4 - Beacon frame support
|
||||
* :jira:`ZEP-886` - 802.15.4 - MAC command frame support
|
||||
* :jira:`ZEP-887` - 802.15.4 - Management service: RFD level support
|
||||
* :jira:`ZEP-911` - Refine thread priorities & locking
|
||||
* :jira:`ZEP-919` - Purge obsolete microkernel & nanokernel code
|
||||
* :jira:`ZEP-929` - Verify the preempt-thread-only and coop-thread-only configurations
|
||||
* :jira:`ZEP-931` - Finalize kernel file naming & locations
|
||||
* :jira:`ZEP-936` - Adapt drivers to unified kernel
|
||||
* :jira:`ZEP-937` - Adapt networking to unified kernel
|
||||
* :jira:`ZEP-946` - Galileo Gen1 board support dropped?
|
||||
* :jira:`ZEP-951` - CONFIG_GDB_INFO build not working on ARM
|
||||
* :jira:`ZEP-953` - CONFIG_HPET_TIMER_DEBUG build warning
|
||||
* :jira:`ZEP-958` - simplify pinmux interface and merge the pinmux_dev into one single API
|
||||
* :jira:`ZEP-964` - Add a (hidden?) Kconfig option for disabling legacy API
|
||||
* :jira:`ZEP-975` - DNS client port to new IP stack
|
||||
* :jira:`ZEP-1012` - NATS client port to new IP stack
|
||||
* :jira:`ZEP-1038` - Hard real-time interrupt support
|
||||
* :jira:`ZEP-1060` - Contributor guide for documentation missing
|
||||
* :jira:`ZEP-1103` - Propose and implement synchronization flow for multicore power management
|
||||
* :jira:`ZEP-1165` - support enums as IRQ line argument in IRQ_CONNECT()
|
||||
* :jira:`ZEP-1172` - Update logger Api to allow using a hook for SYS_LOG_BACKEND_FN function
|
||||
* :jira:`ZEP-1177` - Reduce Zephyr's Dependency on Host Tools
|
||||
* :jira:`ZEP-1179` - Build issues when compiling with LLVM from ISSM (icx)
|
||||
* :jira:`ZEP-1189` - SoC I2C peripheral of the Quark SE cannot be used from the ARC core
|
||||
* :jira:`ZEP-1190` - SoC SPI peripheral of the Quark SE cannot be used from the ARC core
|
||||
* :jira:`ZEP-1222` - Add save/restore support to ARC core
|
||||
* :jira:`ZEP-1223` - Add save/restore support to arcv2_irq_unit
|
||||
* :jira:`ZEP-1224` - Add save/restore support to arcv2_timer_0/sys_clock
|
||||
* :jira:`ZEP-1230` - Optimize interrupt return code on ARC.
|
||||
* :jira:`ZEP-1233` - mbedDTLS DTLS client stability does not work on top of the tree for the net branch
|
||||
* :jira:`ZEP-1251` - Abstract driver re-entrancy code
|
||||
* :jira:`ZEP-1267` - Echo server crashes upon reception of router advertisement
|
||||
* :jira:`ZEP-1276` - Move disk_access_* out of file system subsystem
|
||||
* :jira:`ZEP-1283` - compile option to skip gpio toggle in samples/power/power_mgr
|
||||
* :jira:`ZEP-1284` - Remove arch/arm/core/gdb_stub.S and all the abstractions it introduced
|
||||
* :jira:`ZEP-1288` - Define _arc_v2_irq_unit device
|
||||
* :jira:`ZEP-1292` - Update external mbed TLS library to latest version (2.4.0)
|
||||
* :jira:`ZEP-1300` - ARM LTD V2M Beetle Support [Phase 2]
|
||||
* :jira:`ZEP-1304` - Define device tree bindings for NXP Kinetis K64F
|
||||
* :jira:`ZEP-1305` - Add DTS/DTB targets to build infrastructure
|
||||
* :jira:`ZEP-1306` - Create DTS/DTB parser
|
||||
* :jira:`ZEP-1307` - Plumbing the DTS configuration
|
||||
* :jira:`ZEP-1308` - zephyr thread function k_sleep doesn't work with nrf51822
|
||||
* :jira:`ZEP-1320` - Update Architecture Porting Guide
|
||||
* :jira:`ZEP-1321` - Glossary of Terms needs updating
|
||||
* :jira:`ZEP-1323` - Eliminate references to fiber, task, and nanokernel under ./include
|
||||
* :jira:`ZEP-1324` - Get rid of references to CONFIG_NANOKERNEL
|
||||
* :jira:`ZEP-1325` - Eliminate TICKLESS_IDLE_SUPPORTED option
|
||||
* :jira:`ZEP-1327` - Eliminate obsolete kernel directories
|
||||
* :jira:`ZEP-1329` - Rename kernel APIs that have nano\_ prefixes
|
||||
* :jira:`ZEP-1334` - Add make debug support for QEMU-based boards
|
||||
* :jira:`ZEP-1337` - Relocate event logger files
|
||||
* :jira:`ZEP-1338` - Update external fs with new FATFS revision 0.12b
|
||||
* :jira:`ZEP-1342` - legacy/kernel/test_early_sleep/ fails on EMSK
|
||||
* :jira:`ZEP-1347` - sys_bitfield_*() take unsigned long* vs memaddr_t
|
||||
* :jira:`ZEP-1351` - FDRM k64f SPI does not work
|
||||
* :jira:`ZEP-1355` - Connection Failed to be Established
|
||||
* :jira:`ZEP-1357` - iot/dns: Client is broken
|
||||
* :jira:`ZEP-1358` - BMI160 accelerometer gives 0 on all axes
|
||||
* :jira:`ZEP-1361` - IP stack is broken
|
||||
* :jira:`ZEP-1363` - Missing wiki board support page for arm/arduino_101_ble
|
||||
* :jira:`ZEP-1365` - Missing wiki board support page for arm/c3200_launchxl
|
||||
* :jira:`ZEP-1370` - There's a wiki page for arduino_due but no zephyr/boards support folder
|
||||
* :jira:`ZEP-1374` - Add ksdk spi shim driver
|
||||
* :jira:`ZEP-1387` - Add a driver for Atmel ataes132a HW Crypto module
|
||||
* :jira:`ZEP-1389` - Add support for KW41 SoC
|
||||
* :jira:`ZEP-1390` - Add support for FRDM-KW41Z
|
||||
* :jira:`ZEP-1393` - Add ksdk pinmux driver
|
||||
* :jira:`ZEP-1394` - Add ksdk gpio driver
|
||||
* :jira:`ZEP-1395` - Add data ready trigger to FXOS8700 driver
|
||||
* :jira:`ZEP-1401` - Enhance ready queue cache and interrupt exit code to reduce interrupt latency.
|
||||
* :jira:`ZEP-1403` - remove CONFIG_OMIT_FRAME_POINTER from ARC boards
|
||||
* :jira:`ZEP-1405` - function l2cap_br_conn_req in /subsys/bluetooth/host/l2cap_br.c references uninitialized pointer
|
||||
* :jira:`ZEP-1406` - Update sensor driver paths in wiki
|
||||
* :jira:`ZEP-1408` - quark_se_c1000_ss enter_arc_state() might need cc and memory clobber
|
||||
* :jira:`ZEP-1411` - Deprecate device_sync_call API and use semaphore directly
|
||||
* :jira:`ZEP-1413` - [ARC] test/legacy/kernel/test_tickless/microkernel fails to build
|
||||
* :jira:`ZEP-1415` - drivers/timer/* code comments still refer to micro/nano kernel
|
||||
* :jira:`ZEP-1418` - Add support for Nordic nRF52840 and its DK
|
||||
* :jira:`ZEP-1419` - SYS_LOG macros cause potentially bad behavior due to printk/printf selection
|
||||
* :jira:`ZEP-1420` - Make the time spent with interrupts disabled deterministic
|
||||
* :jira:`ZEP-1421` - BMI160 gyroscope driver stops reporting after 1-5 minutes
|
||||
* :jira:`ZEP-1422` - Arduino_101 doesn't response ipv6 ping request affer enable echo_client ipv6
|
||||
* :jira:`ZEP-1427` - wpanusb dongle / 15.4 communication instability
|
||||
* :jira:`ZEP-1429` - NXP MCR20A Driver
|
||||
* :jira:`ZEP-1432` - ksdk pinmux driver should expose the public pinmux API
|
||||
* :jira:`ZEP-1434` - menuconfig screen shots show nanokernel options
|
||||
* :jira:`ZEP-1437` - AIO: Fail to retrieve pending interrupt in ISR
|
||||
* :jira:`ZEP-1440` - Kconfig choice for MINIMAL_LIBC vs NEWLIB_LIBC is not selectable
|
||||
* :jira:`ZEP-1442` - Samples/net/dhcpv4_client: Build fail as No rule to make target prj\_.conf
|
||||
* :jira:`ZEP-1443` - Samples/net/zperf: Build fail as net_private.h can not be found
|
||||
* :jira:`ZEP-1448` - Samples/net/mbedtls_sslclient:Build fail as net/ip_buf.h can not be found
|
||||
* :jira:`ZEP-1449` - samples: logger_hook
|
||||
* :jira:`ZEP-1456` - Asserts on nrf51 running Bluetooth hci_uart sample
|
||||
* :jira:`ZEP-1457` - Add SPDX Tags to Zephyr licence boilerplate
|
||||
* :jira:`ZEP-1460` - Sanity check reports some qemu step failures as 'build_error'
|
||||
* :jira:`ZEP-1461` - Add zephyr support to openocd upstream
|
||||
* :jira:`ZEP-1467` - Cleanup misc/ and move features to subsystems in subsys/
|
||||
* :jira:`ZEP-1473` - ARP cache confused by use of gateway.
|
||||
* :jira:`ZEP-1474` - BLE Connection Parameter Request/Response Processing
|
||||
* :jira:`ZEP-1475` - k_free documentation should specify that NULL is valid
|
||||
* :jira:`ZEP-1476` - echo_client display port unreachable
|
||||
* :jira:`ZEP-1480` - Update supported distros in getting started guide
|
||||
* :jira:`ZEP-1481` - Bluetooth fails to init
|
||||
* :jira:`ZEP-1483` - H:4 HCI driver (h4.c) should rely on UART flow control to avoid dropping packets
|
||||
* :jira:`ZEP-1487` - I2C_SS: I2C doesn't set device busy before starting data transfer
|
||||
* :jira:`ZEP-1488` - SPI_SS: SPI doesn't set device busy before starting data transfer
|
||||
* :jira:`ZEP-1489` - [GATT] Nested Long Characteristic Value Reliable Writes
|
||||
* :jira:`ZEP-1490` - [PTS] TC_CONN_CPUP_BV_04_C test case is failing
|
||||
* :jira:`ZEP-1492` - Add Atmel SAM family GMAC Ethernet driver
|
||||
* :jira:`ZEP-1493` - Zephyr project documentation copyright
|
||||
* :jira:`ZEP-1495` - Networking API details documentation is missing
|
||||
* :jira:`ZEP-1496` - gpio_pin_enable_callback error
|
||||
* :jira:`ZEP-1497` - Cortex-M0 port exception and interrupt priority setting and getting is broken
|
||||
* :jira:`ZEP-1507` - fxos8700 broken gpio_callback implementation
|
||||
* :jira:`ZEP-1512` - doc-theme has its own conf.py
|
||||
* :jira:`ZEP-1514` - samples/bluetooth/ipsp build fail: net/ip_buf.h No such file or directory
|
||||
* :jira:`ZEP-1525` - driver: gpio: GPIO driver still uses nano_timer
|
||||
* :jira:`ZEP-1532` - Wrong accelerometer readings
|
||||
* :jira:`ZEP-1536` - Convert documentation of PWM samples to RST
|
||||
* :jira:`ZEP-1537` - Convert documentation of power management samples to RST
|
||||
* :jira:`ZEP-1538` - Convert documentation of zoap samples to RST
|
||||
* :jira:`ZEP-1539` - Create documentation in RST for all networking samples
|
||||
* :jira:`ZEP-1540` - Convert Bluetooth samples to RST
|
||||
* :jira:`ZEP-1542` - Multi Sessions HTTP Server sample
|
||||
* :jira:`ZEP-1543` - HTTP Server sample with basic authentication
|
||||
* :jira:`ZEP-1544` - Arduino_101 doesn't respond to ipv6 ping request after enable echo_server ipv6
|
||||
* :jira:`ZEP-1545` - AON Counter : ISR triggered twice on ARC
|
||||
* :jira:`ZEP-1546` - Bug in Zephyr OS high-precision timings sub-system (function sys_cycle_get_32())
|
||||
* :jira:`ZEP-1547` - Add support for H7 crypto function and CT2 SMP auth flag
|
||||
* :jira:`ZEP-1548` - Python script invocation is inconsistent
|
||||
* :jira:`ZEP-1549` - k_cpu_sleep_mode unaligned byte address
|
||||
* :jira:`ZEP-1554` - Xtensa integration
|
||||
* :jira:`ZEP-1557` - RISC V Port
|
||||
* :jira:`ZEP-1558` - Support of user private data pointer in Timer expiry function
|
||||
* :jira:`ZEP-1559` - Implement _tsc_read for ARC architecture
|
||||
* :jira:`ZEP-1562` - echo_server/echo_client examples hang randomly after some time of operation
|
||||
* :jira:`ZEP-1563` - move board documentation for NRF51/NRF52 back to git tree
|
||||
* :jira:`ZEP-1564` - 6lo uncompress_IPHC_header overwrites IPHC fields
|
||||
* :jira:`ZEP-1566` - WDT: Interrupt is triggered multiple times
|
||||
* :jira:`ZEP-1569` - net/tcp: TCP in server mode doesn't support multiple concurrent connections
|
||||
* :jira:`ZEP-1570` - net/tcp: TCP in server mode is unable to close client connections
|
||||
* :jira:`ZEP-1571` - Update "Changes from Version 1 Kernel" to include a "How-To Port Apps" section
|
||||
* :jira:`ZEP-1572` - Update QMSI to 1.4
|
||||
* :jira:`ZEP-1573` - net/tcp: User provided data in net_context_recv is not passed to callback
|
||||
* :jira:`ZEP-1574` - Samples/net/dhcpv4_client: Build fail as undefined reference to net_mgmt_add_event_callback
|
||||
* :jira:`ZEP-1579` - external links to zephyr technical docs are broken
|
||||
* :jira:`ZEP-1581` - [nRF52832] Blinky hangs after some minutes
|
||||
* :jira:`ZEP-1583` - ARC: warning: unmet direct dependencies (SOC_RISCV32_PULPINO || SOC_RISCV32_QEMU)
|
||||
* :jira:`ZEP-1585` - legacy.h should be disabled in kernel.h with CONFIG_LEGACY_KERNEL=n
|
||||
* :jira:`ZEP-1587` - sensor.h still uses legacy APIs and structs
|
||||
* :jira:`ZEP-1588` - I2C doesn't work on Arduino 101
|
||||
* :jira:`ZEP-1589` - Define yaml descriptions for UART devices
|
||||
* :jira:`ZEP-1590` - echo_server run on FRDM-K64F displays BUS FAULT
|
||||
* :jira:`ZEP-1591` - wiki: add Networking section and point https://wiki.zephyrproject.org/view/Network_Interfaces
|
||||
* :jira:`ZEP-1592` - echo-server does not build with newlib
|
||||
* :jira:`ZEP-1593` - /scripts/sysgen should create output using SPDX licensing tag
|
||||
* :jira:`ZEP-1598` - samples/philosophers build failed unexpectedly @quark_d2000 section noinit will not fit in region RAM
|
||||
* :jira:`ZEP-1601` - Console over Telnet
|
||||
* :jira:`ZEP-1602` - IPv6 ping fails using sample application echo_server on FRDM-K64F
|
||||
* :jira:`ZEP-1611` - Hardfault after a few echo requests (IPv6 over BLE)
|
||||
* :jira:`ZEP-1614` - Use correct i2c device driver name
|
||||
* :jira:`ZEP-1616` - Mix up between "network address" and "socket address" concepts in declaration of net_addr_pton()
|
||||
* :jira:`ZEP-1617` - mbedTLS server/client failing to run on qemu
|
||||
* :jira:`ZEP-1619` - Default value of NET_NBUF_RX_COUNT is too low, causes lock up on startup
|
||||
* :jira:`ZEP-1623` - (Parts) of Networking docs still refer to 1.5 world model (with fibers and tasks) and otherwise not up to date
|
||||
* :jira:`ZEP-1626` - SPI: spi cannot work in CPHA mode @ ARC
|
||||
* :jira:`ZEP-1632` - TCP ACK packet should not be forwarded to application recv cb.
|
||||
* :jira:`ZEP-1635` - MCR20A driver unstable
|
||||
* :jira:`ZEP-1638` - No (public) analog of inet_ntop()
|
||||
* :jira:`ZEP-1644` - Incoming connection handling for UDP is not exactly correct
|
||||
* :jira:`ZEP-1645` - API to wait on multiple kernel objects
|
||||
* :jira:`ZEP-1648` - Update links to wiki pages for board info back into the web docs
|
||||
* :jira:`ZEP-1650` - make clean (or pristine) is not removing all artifacts of document generation
|
||||
* :jira:`ZEP-1651` - i2c_dw malfunctioning due to various changes.
|
||||
* :jira:`ZEP-1653` - build issue when compiling with LLVM in ISSM (altmacro)
|
||||
* :jira:`ZEP-1654` - Build issues when compiling with LLVM(unknown attribute '_alloc_align_)
|
||||
* :jira:`ZEP-1655` - Build issues when compiling with LLVM(memory pool)
|
||||
* :jira:`ZEP-1656` - IPv6 over BLE no longer works after commit 2e9fd88
|
||||
* :jira:`ZEP-1657` - Zoap doxygen documentation needs to be perfected
|
||||
* :jira:`ZEP-1658` - IPv6 TCP low on buffers, stops responding after about 5 requests
|
||||
* :jira:`ZEP-1662` - zoap_packet_get_payload() should return the payload length
|
||||
* :jira:`ZEP-1663` - sanitycheck overrides user's environment for CCACHE
|
||||
* :jira:`ZEP-1665` - pinmux: missing default pinmux driver config for quark_se_ss
|
||||
* :jira:`ZEP-1669` - API documentation does not follow in-code documentation style
|
||||
* :jira:`ZEP-1672` - flash: Flash device binding failed on Arduino_101_sss
|
||||
* :jira:`ZEP-1674` - frdm_k64f: With Ethernet driver enabled, application can't start up without connected network cable
|
||||
* :jira:`ZEP-1677` - SDK: BLE cannot be initialized/advertised with CONFIG_ARC_INIT=y on Arduino 101
|
||||
* :jira:`ZEP-1681` - Save/restore debug registers during soc_sleep/soc_deep_sleep in c1000
|
||||
* :jira:`ZEP-1692` - [PTS] GATT/SR/GPA/BV-11-C fails
|
||||
* :jira:`ZEP-1701` - Provide an HTTP API
|
||||
* :jira:`ZEP-1704` - BMI160 samples fails to run
|
||||
* :jira:`ZEP-1706` - Barebone Panther board support
|
||||
* :jira:`ZEP-1707` - [PTS] 7 SM/MAS cases fail
|
||||
* :jira:`ZEP-1708` - [PTS] SM/MAS/PKE/BI-01-C fails
|
||||
* :jira:`ZEP-1709` - [PTS] SM/MAS/PKE/BI-02-C fails
|
||||
* :jira:`ZEP-1710` - Add TinyTILE board support
|
||||
* :jira:`ZEP-1713` - xtensa: correct all checkpatch issues
|
||||
* :jira:`ZEP-1716` - HTTP server sample that does not support up to 10 concurrent sessions.
|
||||
* :jira:`ZEP-1717` - GPIO: GPIO LEVEL interrupt cannot work well in deep sleep mode
|
||||
* :jira:`ZEP-1723` - Warnings in Network code/ MACROS, when built with ISSM's llvm/icx compiler
|
||||
* :jira:`ZEP-1732` - sample of zoap_server runs error.
|
||||
* :jira:`ZEP-1733` - Work on ZEP-686 led to regressions in docs on integration with 3rd-party code
|
||||
* :jira:`ZEP-1745` - Bluetooth samples build failure
|
||||
* :jira:`ZEP-1753` - sample of dhcpv4_client runs error on Arduino 101
|
||||
* :jira:`ZEP-1754` - sample of coaps_server was tested failed on qemu
|
||||
* :jira:`ZEP-1756` - net apps: [-Wpointer-sign] build warning raised when built with ISSM's llvm/icx compiler
|
||||
* :jira:`ZEP-1758` - PLL2 is not correctly enabled in STM32F10x connectivity line SoC
|
||||
* :jira:`ZEP-1763` - Nordic RTC timer driver not correct with tickless idle
|
||||
* :jira:`ZEP-1764` - samples: sample cases use hard code device name, such as "GPIOB" "I2C_0"
|
||||
* :jira:`ZEP-1768` - samples: cases miss testcase.ini
|
||||
* :jira:`ZEP-1774` - Malformed packet included with IPv6 over 802.15.4
|
||||
* :jira:`ZEP-1778` - tests/power: multicore case won't work as expected
|
||||
* :jira:`ZEP-1786` - TCP does not work on Arduino 101 board.
|
||||
* :jira:`ZEP-1787` - kernel event logger build failed with "CONFIG_LEGACY_KERNEL=n"
|
||||
* :jira:`ZEP-1789` - ARC: "samples/logger-hook" crashed __memory_error from sys_ring_buf_get
|
||||
* :jira:`ZEP-1799` - timeout_order_test _ASSERT_VALID_PRIO failed
|
||||
* :jira:`ZEP-1803` - Error occurs when exercising dma_transfer_stop
|
||||
* :jira:`ZEP-1806` - Build warnings with LLVM/icx (gdb_server)
|
||||
* :jira:`ZEP-1809` - Build error in net/ip with LLVM/icx
|
||||
* :jira:`ZEP-1810` - Build failure in net/lib/zoap with LLVM/icx
|
||||
* :jira:`ZEP-1811` - Build error in net/ip/net_mgmt.c with LLVM/icx
|
||||
* :jira:`ZEP-1839` - LL_ASSERT in event_common_prepareA
|
||||
* :jira:`ZEP-1851` - Build warnings with obj_tracing
|
||||
* :jira:`ZEP-1852` - LL_ASSERT in isr_radio_state_close()
|
||||
* :jira:`ZEP-1855` - IP stack buffer allocation fails over time
|
||||
* :jira:`ZEP-1858` - Zephyr NATS client fails to respond to server MSG
|
||||
* :jira:`ZEP-1864` - llvm icx build warning in tests/drivers/uart/*
|
||||
* :jira:`ZEP-1872` - samples/net: the HTTP client sample app must run on QEMU x86
|
||||
* :jira:`ZEP-1877` - samples/net: the coaps_server sample app runs failed on Arduino 101
|
||||
* :jira:`ZEP-1883` - Enabling Console on ARC Genuino 101
|
||||
* :jira:`ZEP-1890` - Bluetooth IPSP sample: Too small user data size
|
||||
|
||||
|
||||
.. _zephyr_1.6:
|
||||
|
||||
Zephyr Kernel 1.6.0
|
||||
********************
|
||||
|
||||
We are pleased to announce the release of Zephyr kernel version 1.6.0. This
|
||||
release introduces a the unified Kernel replacing the separate nano- and
|
||||
release introduces the unified Kernel replacing the separate nano- and
|
||||
micro-kernels and simplifying the overall Zephyr architecture and programming
|
||||
interfaces.
|
||||
Support for the ARM Cortex-M0/M0+ family was added and board support for
|
||||
@@ -64,7 +524,7 @@ Boards
|
||||
|
||||
* Renamed board Quark SE devboard to Quark SE C1000 devboard.
|
||||
* Renamed board Quark SE SSS devboard to Quark SE C1000 SS devboard.
|
||||
* Quark SE C1000: Disabled IPM and enabled UART0 on the Sensor SubSytem.
|
||||
* Quark SE C1000: Disabled IPM and enabled UART0 on the Sensor Subsystem.
|
||||
* Removed basic_cortex_m3 and basic_minuteia boards.
|
||||
* Arduino 101: Removed backup/restore scripts. To restore original bootloader
|
||||
use flashpack utility instead.
|
||||
@@ -235,7 +695,7 @@ JIRA Related Items
|
||||
* :jira:`ZEP-926` - API changes to memory pools
|
||||
* :jira:`ZEP-927` - API changes to memory maps
|
||||
* :jira:`ZEP-928` - API changes to event handling
|
||||
* :jira:`ZEP-930` - Cutover to unified kernel
|
||||
* :jira:`ZEP-930` - Cut over to unified kernel
|
||||
* :jira:`ZEP-933` - Unified kernel ARC port
|
||||
* :jira:`ZEP-934` - NIOS_II port
|
||||
* :jira:`ZEP-935` - Kernel logger support (validation)
|
||||
@@ -303,12 +763,12 @@ JIRA Related Items
|
||||
* :jira:`ZEP-940` - Fail to get ATT response
|
||||
* :jira:`ZEP-950` - USB: Device is not listed by USB20CV test suite
|
||||
* :jira:`ZEP-961` - samples: other cases cannot execute after run aon_counter case
|
||||
* :jira:`ZEP-967` - Sanity doesnt build 'samples/usb/dfu' with assertions (-R)
|
||||
* :jira:`ZEP-970` - Sanity doesnt build 'tests/kernel/test_build' with assertions (-R)
|
||||
* :jira:`ZEP-967` - Sanity doesn't build 'samples/usb/dfu' with assertions (-R)
|
||||
* :jira:`ZEP-970` - Sanity doesn't build 'tests/kernel/test_build' with assertions (-R)
|
||||
* :jira:`ZEP-982` - Minimal libc has EWOULDBLOCK != EAGAIN
|
||||
* :jira:`ZEP-1014` - [TCF] tests/bluetooth/init build fail
|
||||
* :jira:`ZEP-1025` - Unified kernel build sometimes breaks on a missing .d dependency file.
|
||||
* :jira:`ZEP-1027` - Doccumentation for GCC ARM is not accurate
|
||||
* :jira:`ZEP-1027` - Documentation for GCC ARM is not accurate
|
||||
* :jira:`ZEP-1031` - qmsi: dma: driver test fails with LLVM
|
||||
* :jira:`ZEP-1048` - grove_lcd sample: sample does not work if you disable serial
|
||||
* :jira:`ZEP-1051` - mpool allocation failed after defrag twice...
|
||||
@@ -323,7 +783,7 @@ JIRA Related Items
|
||||
* :jira:`ZEP-1101` - SYS_KERNEL_VER_PATCHLEVEL() and friends artificially limit version numbers to 4 bits
|
||||
* :jira:`ZEP-1124` - tests/kernel/test_sprintf/microkernel/testcase.ini#test failure on frdm_k64f
|
||||
* :jira:`ZEP-1130` - region 'RAM' overflowed occurs while building test_hmac_prng
|
||||
* :jira:`ZEP-1138` - Recived packets not being passed to upper layer from IP stack when using ENC28J60 driver
|
||||
* :jira:`ZEP-1138` - Received packets not being passed to upper layer from IP stack when using ENC28J60 driver
|
||||
* :jira:`ZEP-1139` - Fix build error when power management is built with unified kernel
|
||||
* :jira:`ZEP-1141` - Tinycrypt SHA256 test fails with system crash using unified kernel type
|
||||
* :jira:`ZEP-1144` - Tinycrypt AES128 fixed-key with variable-text test fails using unified kernel type
|
||||
|
||||
5
doc/static/zephyr-custom.css
vendored
5
doc/static/zephyr-custom.css
vendored
@@ -4,3 +4,8 @@
|
||||
table.hlist {
|
||||
width: 95% !important;
|
||||
}
|
||||
|
||||
/* override rtd theme white-space no-wrap in table heading and content */
|
||||
th,td {
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
Bluetooth
|
||||
#########
|
||||
|
||||
Zephyr comes integrated with a feature-rich and higly configurable
|
||||
Zephyr comes integrated with a feature-rich and highly configurable
|
||||
Bluetooth stack:
|
||||
|
||||
* Bluetooth 4.2 compliant
|
||||
|
||||
* Bluetooth Controller support (LE Link Layer)
|
||||
|
||||
* Currently supports Nordic Semconductor nRF51 and nRF52
|
||||
* Currently supports Nordic Semiconductor nRF51 and nRF52
|
||||
|
||||
* Generic Access Profile (GAP) with all possible roles
|
||||
|
||||
|
||||
@@ -462,9 +462,9 @@ TSPC_GAP_27_3 False (*) Peripheral Privacy Flag (C.1)
|
||||
TSPC_GAP_27_4 False (*) Reconnection Address (C.2)
|
||||
TSPC_GAP_27_5 False (*) Peripheral Preferred Connection Parameters
|
||||
(C.3)
|
||||
TSPC_GAP_27_6 True Writeable Device Name (C.3)
|
||||
TSPC_GAP_27_7 True Writeable Appearance (C.3)
|
||||
TSPC_GAP_27_8 False (*) Writeable Peripheral Privacy Flag (C.4)
|
||||
TSPC_GAP_27_6 True Writable Device Name (C.3)
|
||||
TSPC_GAP_27_7 True Writable Appearance (C.3)
|
||||
TSPC_GAP_27_8 False (*) Writable Peripheral Privacy Flag (C.4)
|
||||
============== ============== =======================================
|
||||
|
||||
|
||||
|
||||
@@ -217,8 +217,8 @@ TSPC_GATT_4B_38 True Server: Characteristic Format: struct (M)
|
||||
=============== =========== ============================================
|
||||
|
||||
|
||||
Generic Attribute Profile Service - SDP Inteoperability
|
||||
*******************************************************
|
||||
Generic Attribute Profile Service - SDP Interoperability
|
||||
********************************************************
|
||||
|
||||
============== =========== ============================================
|
||||
Parameter Name Selected Description
|
||||
|
||||
@@ -11,7 +11,7 @@ Applications that require a more extensive C library can either submit
|
||||
contributions that enhance the existing library or substitute with a replacement
|
||||
library.
|
||||
|
||||
The Zephyr SDK and other supported toolchains comes with a baremetal C library
|
||||
The Zephyr SDK and other supported toolchains comes with a bare-metal C library
|
||||
based on ``newlib`` that can be used with Zephyr by selecting the
|
||||
:option:`CONFIG_NEWLIB_LIBC` in the application configuration file. Part of the
|
||||
support for ``newlib`` is a set of hooks available under
|
||||
|
||||
@@ -24,7 +24,7 @@ The kernel event logger is capable of recording the following pre-defined
|
||||
event types:
|
||||
|
||||
* Interrupts.
|
||||
* Ccontext switching of threads.
|
||||
* Context switching of threads.
|
||||
* Kernel sleep events (i.e. entering and exiting a low power state).
|
||||
|
||||
The kernel event logger only records the pre-defined event types it has been
|
||||
|
||||
@@ -9,7 +9,7 @@ defined in a generic way.
|
||||
|
||||
This API can be deactivated through the Kconfig options, see
|
||||
:ref:`global_kconfig`.
|
||||
This aproach prevents impacting image size and execution time when the system
|
||||
This approach prevents impacting image size and execution time when the system
|
||||
log is not needed.
|
||||
|
||||
Each of the four ``SYS_LOG_X`` macros correspond to a different logging level,
|
||||
|
||||
@@ -28,7 +28,7 @@ buffers, rather this is done implicitly as :c:func:`net_buf_alloc` gets
|
||||
called.
|
||||
|
||||
If there is a need to reserve space in the buffer for protocol headers
|
||||
to be prependend later, it's possible to reserve this headroom with:
|
||||
to be prepended later, it's possible to reserve this headroom with:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
|
||||
@@ -26,15 +26,15 @@ migrate applications using the older v1.6 IP stack to the new v1.7 IP stack:
|
||||
at the same time. This means that applications can utilize concurrently e.g.,
|
||||
IEEE 802.15.4 and Bluetooth IP networking. The different network technologies
|
||||
are abstracted to network interfaces and there can be multiple network
|
||||
interaces in the system depending on configuration.
|
||||
interfaces in the system depending on configuration.
|
||||
|
||||
* **Network Kconfig options are changed.** Most of the networking configuration
|
||||
options are renamed. Please check the :ref:`networking` documentation for the
|
||||
new names.
|
||||
|
||||
* **All uIP based API's are gone.** Those API's were not public in v1.6 but
|
||||
applications could call them anyway. These uIP API's were mainly used to set
|
||||
IP address etc. management style operations. The new management API's can be
|
||||
* **All uIP based APIs are gone.** Those APIs were not public in v1.6 but
|
||||
applications could call them anyway. These uIP APIs were mainly used to set
|
||||
IP address etc. management style operations. The new management APIs can be
|
||||
found in net_if.h and net_mgmt.h in Zephyr v1.7.
|
||||
|
||||
* **Network buffer management is changed.** In earlier Zephyr versions, there
|
||||
|
||||
@@ -13,7 +13,7 @@ API is that the net_context API uses the fragmented network buffers (net_buf)
|
||||
defined in :file:`net/buf.h` and BSD socket API uses linear memory buffers.
|
||||
|
||||
This example creates a simple server that listens to incoming UDP connections
|
||||
and sends the received data back. You can downlow the example application
|
||||
and sends the received data back. You can download the example application
|
||||
source file here `connectivity-example-app.c <https://gerrit.zephyrproject.org/r/gitweb?p=zephyr.git;a=blob;f=doc/subsystems/networking/connectivity-example-app.c>`_
|
||||
|
||||
This example application begins with some initialization. (Use this as an
|
||||
|
||||
@@ -10,7 +10,7 @@ The networking stack supports the following features:
|
||||
|
||||
* IPv6
|
||||
|
||||
* IPv6 header compresson, which is part of the 6LoWPAN support
|
||||
* IPv6 header compression, which is part of the 6LoWPAN support
|
||||
|
||||
* UDP
|
||||
* IPv4
|
||||
|
||||
@@ -96,24 +96,24 @@ For example, using netcat ("nc") utility, connecting using UDP:
|
||||
$ echo foobar | nc -6 -u 2001:db8::1 4242
|
||||
foobar
|
||||
|
||||
.. note::
|
||||
|
||||
You will need to Ctrl+C manually.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ echo foobar | nc -u 192.0.2.1 4242
|
||||
foobar
|
||||
|
||||
If echo_server is compiled with TCP support (now enabled by default for
|
||||
echo_server sample, CONFIG_NETWORKING_WITH_TCP=y):
|
||||
echo_server sample, CONFIG_NET_TCP=y):
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ echo foobar | nc -6 -q2 2001:db8::1 4242
|
||||
foobar
|
||||
|
||||
You can also use the telnet comand to achieve the above.
|
||||
.. note::
|
||||
|
||||
You will need to Ctrl+C manually.
|
||||
|
||||
You can also use the telnet command to achieve the above.
|
||||
|
||||
Setting up NAT/masquerading to access Internet
|
||||
**********************************************
|
||||
|
||||
@@ -9,7 +9,7 @@ Overview
|
||||
The Shell enables multiple subsystem to use and expose their shell interface
|
||||
simultaneously.
|
||||
|
||||
Each subbsystem can support shell functionality dynamically by its Kconfig file,
|
||||
Each subsystem can support shell functionality dynamically by its Kconfig file,
|
||||
which enables or disables the shell usage for the subsystem.
|
||||
|
||||
Using shell commands
|
||||
@@ -92,7 +92,7 @@ In order to support shell in your subsystem, the application must do the followi
|
||||
callback functions in the shell database using :c:macro:`SHELL_REGISTER`.
|
||||
|
||||
Optionally, you can use one of the following API functions to override default
|
||||
behvior and settings:
|
||||
behavior and settings:
|
||||
|
||||
* :c:func:`shell_register_default_module`
|
||||
|
||||
|
||||
@@ -286,8 +286,8 @@ static int stm32f10x_clock_control_init(struct device *dev)
|
||||
pllmul(CONFIG_CLOCK_STM32F10X_CONN_LINE_PLL_MULTIPLIER);
|
||||
#endif /* CONFIG_CLOCK_STM32F10X_CONN_LINE_PLL_MULTIPLIER */
|
||||
#ifdef CONFIG_CLOCK_STM32F10X_CONN_LINE_PLL2_MULTIPLIER
|
||||
uint32_t pll2mul =
|
||||
pllmul(CLOCK_STM32F10X_CONN_LINE_PLL2_MULTIPLIER);
|
||||
uint32_t pll2_mul =
|
||||
pll2mul(CONFIG_CLOCK_STM32F10X_CONN_LINE_PLL2_MULTIPLIER);
|
||||
#endif /* CONFIG_CLOCK_STM32F10X_CONN_LINE_PLL2_MULTIPLIER */
|
||||
#ifdef CONFIG_CLOCK_STM32F10X_CONN_LINE_PREDIV1
|
||||
uint32_t prediv1 =
|
||||
@@ -341,7 +341,14 @@ static int stm32f10x_clock_control_init(struct device *dev)
|
||||
rcc->cfgr2.bit.prediv1src = STM32F10X_RCC_CFG2_PREDIV1_SRC_PLL2;
|
||||
|
||||
rcc->cfgr2.bit.prediv2 = prediv2;
|
||||
rcc->cfgr2.bit.pll2mul = pll2mul;
|
||||
rcc->cfgr2.bit.pll2mul = pll2_mul;
|
||||
|
||||
/* enable PLL2 */
|
||||
rcc->cr.bit.pll2on = 1;
|
||||
|
||||
/* wait for PLL to become ready */
|
||||
while (rcc->cr.bit.pll2rdy != 1) {
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CLOCK_STM32F10X_CONN_LINE_PREDIV1_SRC_HSE */
|
||||
#endif /* CONFIG_CLOCK_STM32F10X_CONN_LINE_PLL_SRC_PREDIV1 */
|
||||
|
||||
@@ -136,6 +136,16 @@ config IPM_CONSOLE_RECEIVER
|
||||
help
|
||||
Enable the receiving side of IPM console
|
||||
|
||||
config IPM_CONSOLE_STACK_SIZE
|
||||
int
|
||||
prompt "Stack size for IPM console receiver thread"
|
||||
depends on IPM_CONSOLE_RECEIVER
|
||||
default 512
|
||||
help
|
||||
Eack instance of the IPM console receiver driver creates a worker
|
||||
thread to print out incoming messages from the remote CPU. Specify the
|
||||
stack size for these threads here.
|
||||
|
||||
config IPM_CONSOLE_INIT_PRIORITY
|
||||
int
|
||||
prompt "IPM console init priority"
|
||||
|
||||
@@ -144,7 +144,7 @@ int ipm_console_receiver_init(struct device *d)
|
||||
|
||||
ipm_register_callback(ipm, ipm_console_receive_callback, d);
|
||||
|
||||
k_thread_spawn(config_info->thread_stack, IPM_CONSOLE_STACK_SIZE,
|
||||
k_thread_spawn(config_info->thread_stack, CONFIG_IPM_CONSOLE_STACK_SIZE,
|
||||
ipm_console_thread, d, NULL, NULL,
|
||||
K_PRIO_COOP(IPM_CONSOLE_PRI), 0, 0);
|
||||
ipm_set_enabled(ipm, 1);
|
||||
|
||||
@@ -17,6 +17,13 @@
|
||||
#include "qm_isr.h"
|
||||
#include "clk.h"
|
||||
|
||||
#define CYCLE_NOP \
|
||||
__asm__ __volatile__ ("nop"); \
|
||||
__asm__ __volatile__ ("nop"); \
|
||||
__asm__ __volatile__ ("nop"); \
|
||||
__asm__ __volatile__ ("nop")
|
||||
|
||||
|
||||
struct dma_qmsi_config_info {
|
||||
qm_dma_t instance; /* Controller instance. */
|
||||
};
|
||||
@@ -254,16 +261,26 @@ static int dma_qmsi_chan_config(struct device *dev, uint32_t channel,
|
||||
|
||||
static int dma_qmsi_transfer_start(struct device *dev, uint32_t channel)
|
||||
{
|
||||
int ret;
|
||||
const struct dma_qmsi_config_info *info = dev->config->config_info;
|
||||
|
||||
return qm_dma_transfer_start(info->instance, channel);
|
||||
ret = qm_dma_transfer_start(info->instance, channel);
|
||||
|
||||
CYCLE_NOP;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dma_qmsi_start(struct device *dev, uint32_t channel)
|
||||
{
|
||||
int ret;
|
||||
const struct dma_qmsi_config_info *info = dev->config->config_info;
|
||||
|
||||
return qm_dma_transfer_start(info->instance, channel);
|
||||
ret = qm_dma_transfer_start(info->instance, channel);
|
||||
|
||||
CYCLE_NOP;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dma_qmsi_transfer_stop(struct device *dev, uint32_t channel)
|
||||
|
||||
@@ -22,6 +22,13 @@ config ETH_MCUX_PHY_TICK_MS
|
||||
help
|
||||
Set the PHY status polling period.
|
||||
|
||||
config ETH_MCUX_PHY_EXTRA_DEBUG
|
||||
bool "Enable additional detailed PHY debug"
|
||||
default n
|
||||
help
|
||||
Enable additional PHY related debug information related to
|
||||
PHY status polling.
|
||||
|
||||
config ETH_MCUX_RX_BUFFERS
|
||||
int "Number of MCUX RX buffers"
|
||||
depends on ETH_MCUX
|
||||
|
||||
@@ -684,7 +684,8 @@ static void eth_enc28j60_iface_init_0(struct net_if *iface)
|
||||
|
||||
SYS_LOG_DBG("");
|
||||
|
||||
net_if_set_link_addr(iface, mac_address_0, sizeof(mac_address_0));
|
||||
net_if_set_link_addr(iface, mac_address_0, sizeof(mac_address_0),
|
||||
NET_LINK_ETHERNET);
|
||||
context->iface = iface;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,14 +34,36 @@ enum eth_mcux_phy_state {
|
||||
eth_mcux_phy_state_restart,
|
||||
eth_mcux_phy_state_read_status,
|
||||
eth_mcux_phy_state_read_duplex,
|
||||
eth_mcux_phy_state_wait
|
||||
eth_mcux_phy_state_wait,
|
||||
eth_mcux_phy_state_closing
|
||||
|
||||
};
|
||||
|
||||
static const char *
|
||||
phy_state_name(enum eth_mcux_phy_state state) __attribute__((unused));
|
||||
|
||||
static const char *phy_state_name(enum eth_mcux_phy_state state)
|
||||
{
|
||||
static const char * const name[] = {
|
||||
"initial",
|
||||
"reset",
|
||||
"autoneg",
|
||||
"restart",
|
||||
"read-status",
|
||||
"read-duplex",
|
||||
"wait",
|
||||
"closing"
|
||||
};
|
||||
|
||||
return name[state];
|
||||
}
|
||||
|
||||
struct eth_context {
|
||||
struct net_if *iface;
|
||||
enet_handle_t enet_handle;
|
||||
struct k_sem tx_buf_sem;
|
||||
enum eth_mcux_phy_state phy_state;
|
||||
bool enabled;
|
||||
bool link_up;
|
||||
phy_duplex_t phy_duplex;
|
||||
phy_speed_t phy_speed;
|
||||
@@ -107,6 +129,72 @@ static void eth_mcux_decode_duplex_and_speed(uint32_t status,
|
||||
}
|
||||
}
|
||||
|
||||
static void eth_mcux_phy_enter_reset(struct eth_context *context)
|
||||
{
|
||||
const uint32_t phy_addr = 0;
|
||||
|
||||
/* Reset the PHY. */
|
||||
ENET_StartSMIWrite(ENET, phy_addr, PHY_BASICCONTROL_REG,
|
||||
kENET_MiiWriteValidFrame,
|
||||
PHY_BCTL_RESET_MASK);
|
||||
context->phy_state = eth_mcux_phy_state_reset;
|
||||
}
|
||||
|
||||
static void eth_mcux_phy_start(struct eth_context *context)
|
||||
{
|
||||
#ifdef CONFIG_ETH_MCUX_PHY_DETAILED_DEBUG
|
||||
SYS_LOG_DBG("phy_state=%s", phy_state_name(context->phy_state));
|
||||
#endif
|
||||
|
||||
context->enabled = true;
|
||||
|
||||
switch (context->phy_state) {
|
||||
case eth_mcux_phy_state_initial:
|
||||
ENET_ActiveRead(ENET);
|
||||
eth_mcux_phy_enter_reset(context);
|
||||
break;
|
||||
case eth_mcux_phy_state_reset:
|
||||
case eth_mcux_phy_state_autoneg:
|
||||
case eth_mcux_phy_state_restart:
|
||||
case eth_mcux_phy_state_read_status:
|
||||
case eth_mcux_phy_state_read_duplex:
|
||||
case eth_mcux_phy_state_wait:
|
||||
case eth_mcux_phy_state_closing:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void eth_mcux_phy_stop(struct eth_context *context)
|
||||
{
|
||||
#ifdef CONFIG_ETH_MCUX_PHY_DETAILED_DEBUG
|
||||
SYS_LOG_DBG("phy_state=%s", phy_state_name(context->phy_state));
|
||||
#endif
|
||||
|
||||
context->enabled = false;
|
||||
|
||||
switch (context->phy_state) {
|
||||
case eth_mcux_phy_state_initial:
|
||||
case eth_mcux_phy_state_reset:
|
||||
case eth_mcux_phy_state_autoneg:
|
||||
case eth_mcux_phy_state_restart:
|
||||
case eth_mcux_phy_state_read_status:
|
||||
case eth_mcux_phy_state_read_duplex:
|
||||
/* Do nothing, let the current communication complete
|
||||
* then deal with shutdown.
|
||||
*/
|
||||
context->phy_state = eth_mcux_phy_state_closing;
|
||||
break;
|
||||
case eth_mcux_phy_state_wait:
|
||||
k_delayed_work_cancel(&context->delayed_phy_work);
|
||||
/* @todo, actually power downt he PHY ? */
|
||||
context->phy_state = eth_mcux_phy_state_initial;
|
||||
break;
|
||||
case eth_mcux_phy_state_closing:
|
||||
/* We are already going down. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void eth_mcux_phy_event(struct eth_context *context)
|
||||
{
|
||||
uint32_t status;
|
||||
@@ -115,15 +203,19 @@ static void eth_mcux_phy_event(struct eth_context *context)
|
||||
phy_speed_t phy_speed = kPHY_Speed100M;
|
||||
const uint32_t phy_addr = 0;
|
||||
|
||||
SYS_LOG_DBG("phy_state=%d", context->phy_state);
|
||||
|
||||
#ifdef CONFIG_ETH_MCUX_PHY_DETAILED_DEBUG
|
||||
SYS_LOG_DBG("phy_state=%s", phy_state_name(context->phy_state));
|
||||
#endif
|
||||
switch (context->phy_state) {
|
||||
case eth_mcux_phy_state_initial:
|
||||
/* Reset the PHY. */
|
||||
ENET_StartSMIWrite(ENET, phy_addr, PHY_BASICCONTROL_REG,
|
||||
kENET_MiiWriteValidFrame,
|
||||
PHY_BCTL_RESET_MASK);
|
||||
context->phy_state = eth_mcux_phy_state_reset;
|
||||
break;
|
||||
case eth_mcux_phy_state_closing:
|
||||
if (context->enabled) {
|
||||
eth_mcux_phy_enter_reset(context);
|
||||
} else {
|
||||
/* @todo, actually power down the PHY ? */
|
||||
context->phy_state = eth_mcux_phy_state_initial;
|
||||
}
|
||||
break;
|
||||
case eth_mcux_phy_state_reset:
|
||||
/* Setup PHY autonegotiation. */
|
||||
@@ -461,9 +553,8 @@ static int eth_0_init(struct device *dev)
|
||||
|
||||
ENET_SetCallback(&context->enet_handle, eth_callback, dev);
|
||||
eth_0_config_func();
|
||||
ENET_ActiveRead(ENET);
|
||||
|
||||
k_work_submit(&context->phy_work);
|
||||
eth_mcux_phy_start(context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -474,7 +565,8 @@ static void eth_0_iface_init(struct net_if *iface)
|
||||
struct eth_context *context = dev->driver_data;
|
||||
|
||||
net_if_set_link_addr(iface, context->mac_addr,
|
||||
sizeof(context->mac_addr));
|
||||
sizeof(context->mac_addr),
|
||||
NET_LINK_ETHERNET);
|
||||
context->iface = iface;
|
||||
}
|
||||
|
||||
|
||||
@@ -749,7 +749,8 @@ static void eth0_iface_init(struct net_if *iface)
|
||||
|
||||
/* Register Ethernet MAC Address with the upper layer */
|
||||
net_if_set_link_addr(iface, dev_data->mac_addr,
|
||||
sizeof(dev_data->mac_addr));
|
||||
sizeof(dev_data->mac_addr),
|
||||
NET_LINK_ETHERNET);
|
||||
|
||||
dev_data->iface = iface;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ config GPIO_MCUX_PORTA
|
||||
config GPIO_MCUX_PORTA_NAME
|
||||
string "Port A driver name"
|
||||
depends on GPIO_MCUX_PORTA
|
||||
default "gpio_porta"
|
||||
default "GPIO_0"
|
||||
|
||||
config GPIO_MCUX_PORTA_PRI
|
||||
int "Port A interrupt priority"
|
||||
@@ -42,7 +42,7 @@ config GPIO_MCUX_PORTB
|
||||
config GPIO_MCUX_PORTB_NAME
|
||||
string "Port B driver name"
|
||||
depends on GPIO_MCUX_PORTB
|
||||
default "gpio_portb"
|
||||
default "GPIO_1"
|
||||
|
||||
config GPIO_MCUX_PORTB_PRI
|
||||
int "Port B interrupt priority"
|
||||
@@ -59,7 +59,7 @@ config GPIO_MCUX_PORTC
|
||||
config GPIO_MCUX_PORTC_NAME
|
||||
string "Port C driver name"
|
||||
depends on GPIO_MCUX_PORTC
|
||||
default "gpio_portc"
|
||||
default "GPIO_2"
|
||||
|
||||
config GPIO_MCUX_PORTC_PRI
|
||||
int "Port C interrupt priority"
|
||||
@@ -76,7 +76,7 @@ config GPIO_MCUX_PORTD
|
||||
config GPIO_MCUX_PORTD_NAME
|
||||
string "Port D driver name"
|
||||
depends on GPIO_MCUX_PORTD
|
||||
default "gpio_portd"
|
||||
default "GPIO_3"
|
||||
|
||||
config GPIO_MCUX_PORTD_PRI
|
||||
int "Port D interrupt priority"
|
||||
@@ -93,7 +93,7 @@ config GPIO_MCUX_PORTE
|
||||
config GPIO_MCUX_PORTE_NAME
|
||||
string "Port E driver name"
|
||||
depends on GPIO_MCUX_PORTE
|
||||
default "gpio_porte"
|
||||
default "GPIO_4"
|
||||
|
||||
config GPIO_MCUX_PORTE_PRI
|
||||
int "Port E interrupt priority"
|
||||
|
||||
@@ -335,15 +335,42 @@ GPIO_DEVICE_INIT("GPIOE", e, GPIOE_BASE, STM32_PORTE,
|
||||
|
||||
#ifdef CONFIG_GPIO_STM32_PORTF
|
||||
GPIO_DEVICE_INIT("GPIOF", f, GPIOF_BASE, STM32_PORTF,
|
||||
STM32_PERIPH_GPIOF, STM32_CLOCK_BUS_GPIO);
|
||||
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
|
||||
STM32_PERIPH_GPIOF, STM32_CLOCK_BUS_GPIO
|
||||
#else
|
||||
#ifdef CONFIG_SOC_SERIES_STM32F1X
|
||||
STM32F10X_CLOCK_SUBSYS_IOPF
|
||||
| STM32F10X_CLOCK_SUBSYS_AFIO
|
||||
#elif CONFIG_SOC_SERIES_STM32F4X
|
||||
STM32F4X_CLOCK_ENABLE_GPIOF
|
||||
#endif
|
||||
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
|
||||
);
|
||||
#endif /* CONFIG_GPIO_STM32_PORTF */
|
||||
|
||||
#ifdef CONFIG_GPIO_STM32_PORTG
|
||||
GPIO_DEVICE_INIT("GPIOG", g, GPIOG_BASE, STM32_PORTG,
|
||||
STM32_PERIPH_GPIOG, STM32_CLOCK_BUS_GPIO);
|
||||
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
|
||||
STM32_PERIPH_GPIOG, STM32_CLOCK_BUS_GPIO
|
||||
#else
|
||||
#ifdef CONFIG_SOC_SERIES_STM32F1X
|
||||
STM32F10X_CLOCK_SUBSYS_IOPG
|
||||
| STM32F10X_CLOCK_SUBSYS_AFIO
|
||||
#elif CONFIG_SOC_SERIES_STM32F4X
|
||||
STM32F4X_CLOCK_ENABLE_GPIOG
|
||||
#endif
|
||||
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
|
||||
);
|
||||
#endif /* CONFIG_GPIO_STM32_PORTG */
|
||||
|
||||
#ifdef CONFIG_GPIO_STM32_PORTH
|
||||
GPIO_DEVICE_INIT("GPIOH", h, GPIOH_BASE, STM32_PORTH,
|
||||
STM32_PERIPH_GPIOH, STM32_CLOCK_BUS_GPIO);
|
||||
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
|
||||
STM32_PERIPH_GPIOH, STM32_CLOCK_BUS_GPIO
|
||||
#else
|
||||
#ifdef CONFIG_SOC_SERIES_STM32F4X
|
||||
STM32F4X_CLOCK_ENABLE_GPIOH
|
||||
#endif
|
||||
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
|
||||
);
|
||||
#endif /* CONFIG_GPIO_STM32_PORTH */
|
||||
|
||||
@@ -58,6 +58,8 @@ source "drivers/ieee802154/Kconfig.cc2520"
|
||||
|
||||
source "drivers/ieee802154/Kconfig.mcr20a"
|
||||
|
||||
source "drivers/ieee802154/Kconfig.nrf5"
|
||||
|
||||
menuconfig IEEE802154_UPIPE
|
||||
bool "UART PIPE fake radio driver support for QEMU"
|
||||
depends on BOARD_QEMU_X86
|
||||
|
||||
72
drivers/ieee802154/Kconfig.nrf5
Normal file
72
drivers/ieee802154/Kconfig.nrf5
Normal file
@@ -0,0 +1,72 @@
|
||||
# Kconfig.nrf5 - Nordic Semiconductor nRF5 802.15.4 configuration options
|
||||
#
|
||||
|
||||
menuconfig IEEE802154_NRF5
|
||||
bool "nRF52 series IEEE 802.15.4 Driver support"
|
||||
depends on NETWORKING && SOC_NRF52840
|
||||
select NET_L2_IEEE802154
|
||||
select HAS_NORDIC_DRIVERS
|
||||
default n
|
||||
|
||||
if IEEE802154_NRF5 || IEEE802154_NRF5_RAW
|
||||
|
||||
config IEEE802154_NRF5_DRV_NAME
|
||||
string "nRF52 IEEE 802.15.4 Driver's name"
|
||||
default "IEEE802154_nrf5"
|
||||
help
|
||||
This option sets the driver name
|
||||
|
||||
config IEEE802154_NRF5_RX_STACK_SIZE
|
||||
int "Driver's internal rx thread stack size"
|
||||
default 800
|
||||
help
|
||||
This option sets the driver's stack size for its internal rx thread.
|
||||
The default value should be sufficient, but in case it proves to be
|
||||
a too little one, this option makes it easy to play with the size.
|
||||
|
||||
config IEEE802154_NRF5_INIT_PRIO
|
||||
int "nRF52 IEEE 802.15.4 intialization priority"
|
||||
default 80
|
||||
help
|
||||
Set the initialization priority number. Do not mess with it unless
|
||||
you know what you are doing.
|
||||
|
||||
choice IEEE802154_NRF5_CCA_MODE
|
||||
prompt "nRF52 IEEE 802.15.4 CCA mode"
|
||||
default IEEE802154_NRF5_CCA_MODE_ED
|
||||
help
|
||||
CCA mode
|
||||
|
||||
config IEEE802154_NRF5_CCA_MODE_ED
|
||||
bool "Energy Above Threashold"
|
||||
|
||||
config IEEE802154_NRF5_CCA_MODE_CARRIER
|
||||
bool "Carrier Seen"
|
||||
|
||||
config IEEE802154_NRF5_CCA_MODE_CARRIER_AND_ED
|
||||
bool "Energy Above Threshold AND Carrier Seen"
|
||||
|
||||
config IEEE802154_NRF5_CCA_MODE_CARRIER_OR_ED
|
||||
bool "Energy Above Threshold OR Carrier Seen"
|
||||
|
||||
endchoice
|
||||
|
||||
config IEEE802154_NRF5_CCA_ED_THRESHOLD
|
||||
int "nRF52 IEEE 802.15.4 CCA Energy Detection threshold"
|
||||
default 45
|
||||
help
|
||||
If energy detected in a given channel is above the value then the channel
|
||||
is deemed busy. The unit is defined as per 802.15.4-2006 spec.
|
||||
|
||||
config IEEE802154_NRF5_CCA_CORR_THRESHOLD
|
||||
int "nRF52 IEEE 802.15.4 CCA Correlator threshold"
|
||||
default 45
|
||||
|
||||
config IEEE802154_NRF5_CCA_CORR_LIMIT
|
||||
int "nRF52 IEEE 802.15.4 CCA Correlator limit"
|
||||
default 2
|
||||
help
|
||||
Limit for occurrences above correlator threshold. When not equal to zero the
|
||||
corrolator based signal detect is enabled.
|
||||
|
||||
endif
|
||||
@@ -3,3 +3,4 @@ obj-$(CONFIG_IEEE802154_CC2520_RAW) += ieee802154_cc2520.o
|
||||
obj-$(CONFIG_IEEE802154_UPIPE) += ieee802154_uart_pipe.o
|
||||
obj-$(CONFIG_IEEE802154_MCR20A) += ieee802154_mcr20a.o
|
||||
obj-$(CONFIG_IEEE802154_MCR20A_RAW) += ieee802154_mcr20a.o
|
||||
obj-$(CONFIG_IEEE802154_NRF5) += ieee802154_nrf5.o
|
||||
|
||||
@@ -1056,7 +1056,7 @@ static void cc2520_iface_init(struct net_if *iface)
|
||||
|
||||
SYS_LOG_DBG("");
|
||||
|
||||
net_if_set_link_addr(iface, mac, 8);
|
||||
net_if_set_link_addr(iface, mac, 8, NET_LINK_IEEE802154);
|
||||
|
||||
cc2520->iface = iface;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -36,13 +36,13 @@ struct mcr20a_context {
|
||||
struct gpio_callback irqb_cb;
|
||||
struct mcr20a_spi spi;
|
||||
uint8_t mac_addr[8];
|
||||
struct k_mutex phy_mutex;
|
||||
struct k_sem isr_sem;
|
||||
/*********TX + CCA*********/
|
||||
struct k_sem seq_sync;
|
||||
atomic_t busy;
|
||||
atomic_t seq_retval;
|
||||
/************RX************/
|
||||
char __stack mcr20a_rx_stack[CONFIG_IEEE802154_MCR20A_RX_STACK_SIZE];
|
||||
struct k_sem trig_sem;
|
||||
uint8_t lqi;
|
||||
};
|
||||
|
||||
@@ -174,6 +174,8 @@ DEFINE_BURST_WRITE(t3cmp, MCR20A_T3CMP_LSB, 3, true)
|
||||
DEFINE_BURST_WRITE(t4cmp, MCR20A_T4CMP_LSB, 3, true)
|
||||
DEFINE_BURST_WRITE(t2primecmp, MCR20A_T2PRIMECMP_LSB, 2, true)
|
||||
DEFINE_BURST_WRITE(pll_int0, MCR20A_PLL_INT0, 3, true)
|
||||
DEFINE_BURST_WRITE(irqsts1_irqsts3, MCR20A_IRQSTS1, 3, true)
|
||||
DEFINE_BURST_WRITE(irqsts1_ctrl1, MCR20A_IRQSTS1, 4, true)
|
||||
|
||||
DEFINE_BURST_WRITE(pan_id, MCR20A_MACPANID0_LSB, 2, false)
|
||||
DEFINE_BURST_WRITE(short_addr, MCR20A_MACSHORTADDRS0_LSB, 2, false)
|
||||
|
||||
414
drivers/ieee802154/ieee802154_nrf5.c
Normal file
414
drivers/ieee802154/ieee802154_nrf5.c
Normal file
@@ -0,0 +1,414 @@
|
||||
/* ieee802154_nrf5.c - nRF5 802.15.4 driver */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define SYS_LOG_LEVEL CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL
|
||||
#define SYS_LOG_DOMAIN "dev/nrf5_802154"
|
||||
#include <logging/sys_log.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <kernel.h>
|
||||
#include <arch/cpu.h>
|
||||
|
||||
#include <board.h>
|
||||
#include <device.h>
|
||||
#include <init.h>
|
||||
#include <net/net_if.h>
|
||||
#include <net/nbuf.h>
|
||||
|
||||
#include <misc/byteorder.h>
|
||||
#include <string.h>
|
||||
#include <rand32.h>
|
||||
|
||||
#include <net/ieee802154_radio.h>
|
||||
#include <drivers/clock_control/nrf5_clock_control.h>
|
||||
#include <clock_control.h>
|
||||
|
||||
#include "nrf52840.h"
|
||||
#include "ieee802154_nrf5.h"
|
||||
#include "nrf_drv_radio802154.h"
|
||||
|
||||
struct nrf5_802154_config {
|
||||
void (*irq_config_func)(struct device *dev);
|
||||
};
|
||||
|
||||
static struct nrf5_802154_data nrf5_data;
|
||||
|
||||
/* Convenience defines for RADIO */
|
||||
#define NRF5_802154_DATA(dev) \
|
||||
((struct nrf5_802154_data * const)(dev)->driver_data)
|
||||
|
||||
#define NRF5_802154_CFG(dev) \
|
||||
((struct nrf5_802154_config * const)(dev)->config->config_info)
|
||||
|
||||
static void nrf5_get_eui64(uint8_t *mac)
|
||||
{
|
||||
memcpy(mac, (const uint32_t *)&NRF_FICR->DEVICEID, 8);
|
||||
}
|
||||
|
||||
static void nrf5_rx_thread(void *arg1, void *arg2, void *arg3)
|
||||
{
|
||||
struct device *dev = (struct device *)arg1;
|
||||
struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev);
|
||||
struct net_buf *pkt_buf = NULL;
|
||||
enum net_verdict ack_result;
|
||||
struct net_buf *buf;
|
||||
uint8_t pkt_len;
|
||||
|
||||
ARG_UNUSED(arg2);
|
||||
ARG_UNUSED(arg3);
|
||||
|
||||
while (1) {
|
||||
buf = NULL;
|
||||
|
||||
SYS_LOG_DBG("Waiting for frame");
|
||||
k_sem_take(&nrf5_radio->rx_wait, K_FOREVER);
|
||||
|
||||
SYS_LOG_DBG("Frame received");
|
||||
|
||||
buf = net_nbuf_get_reserve_rx(0, K_NO_WAIT);
|
||||
if (!buf) {
|
||||
SYS_LOG_ERR("No buf available");
|
||||
goto out;
|
||||
}
|
||||
|
||||
pkt_buf = net_nbuf_get_reserve_data(0, K_NO_WAIT);
|
||||
if (!pkt_buf) {
|
||||
SYS_LOG_ERR("No pkt_buf available");
|
||||
goto out;
|
||||
}
|
||||
|
||||
net_buf_frag_insert(buf, pkt_buf);
|
||||
|
||||
/* rx_mpdu contains length, psdu, [fcs], lqi
|
||||
* FCS filed (2 bytes) is not present if CRC is enabled
|
||||
*/
|
||||
pkt_len = nrf5_radio->rx_psdu[0] - NRF5_FCS_LENGTH;
|
||||
|
||||
/* Skip length (first byte) and copy the payload */
|
||||
memcpy(pkt_buf->data, nrf5_radio->rx_psdu + 1, pkt_len);
|
||||
net_buf_add(pkt_buf, pkt_len);
|
||||
|
||||
nrf_drv_radio802154_buffer_free(nrf5_radio->rx_psdu);
|
||||
|
||||
ack_result = ieee802154_radio_handle_ack(nrf5_radio->iface,
|
||||
buf);
|
||||
if (ack_result == NET_OK) {
|
||||
SYS_LOG_DBG("ACK packet handled");
|
||||
goto out;
|
||||
}
|
||||
|
||||
SYS_LOG_DBG("Caught a packet (%u) (LQI: %u)",
|
||||
pkt_len, nrf5_radio->lqi);
|
||||
|
||||
if (net_recv_data(nrf5_radio->iface, buf) < 0) {
|
||||
SYS_LOG_DBG("Packet dropped by NET stack");
|
||||
goto out;
|
||||
}
|
||||
|
||||
net_analyze_stack("nRF5 rx stack",
|
||||
(unsigned char *)nrf5_radio->rx_stack,
|
||||
CONFIG_IEEE802154_NRF5_RX_STACK_SIZE);
|
||||
continue;
|
||||
|
||||
out:
|
||||
if (buf) {
|
||||
net_buf_unref(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Radio device API */
|
||||
|
||||
static int nrf5_cca(struct device *dev)
|
||||
{
|
||||
struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev);
|
||||
|
||||
/* Current implementation of the NRF5 radio driver doesn't provide an
|
||||
* explicit API to perform CCA. However, Mode1 CCA (energy above
|
||||
* threshold), can be achieved using energy detection function.
|
||||
*/
|
||||
if (!nrf_drv_radio802154_energy_detection(nrf5_radio->channel, 128)) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* The nRF driver guarantees that a callback will be called once
|
||||
* the ED function is done, thus unlocking the semaphore.
|
||||
*/
|
||||
k_sem_take(&nrf5_radio->cca_wait, K_FOREVER);
|
||||
SYS_LOG_DBG("CCA: %d", nrf5_radio->channel_ed);
|
||||
|
||||
if (nrf5_radio->channel_ed > CONFIG_IEEE802154_NRF5_CCA_ED_THRESHOLD) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nrf5_set_channel(struct device *dev, uint16_t channel)
|
||||
{
|
||||
struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev);
|
||||
|
||||
SYS_LOG_DBG("%u", channel);
|
||||
|
||||
if (channel < 11 || channel > 26) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!nrf_drv_radio802154_receive(channel, false)) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
nrf5_radio->channel = channel;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nrf5_set_pan_id(struct device *dev, uint16_t pan_id)
|
||||
{
|
||||
uint8_t pan_id_le[2];
|
||||
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
sys_put_le16(pan_id, pan_id_le);
|
||||
nrf_drv_radio802154_pan_id_set(pan_id_le);
|
||||
|
||||
SYS_LOG_DBG("0x%x", pan_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nrf5_set_short_addr(struct device *dev, uint16_t short_addr)
|
||||
{
|
||||
uint8_t short_addr_le[2];
|
||||
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
sys_put_le16(short_addr, short_addr_le);
|
||||
nrf_drv_radio802154_short_address_set(short_addr_le);
|
||||
|
||||
SYS_LOG_DBG("0x%x", short_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nrf5_set_ieee_addr(struct device *dev, const uint8_t *ieee_addr)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
SYS_LOG_DBG("IEEE address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
ieee_addr[7], ieee_addr[6], ieee_addr[5], ieee_addr[4],
|
||||
ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]);
|
||||
|
||||
nrf_drv_radio802154_extended_address_set(ieee_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nrf5_set_txpower(struct device *dev, int16_t dbm)
|
||||
{
|
||||
struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev);
|
||||
|
||||
SYS_LOG_DBG("%d", dbm);
|
||||
nrf5_radio->txpower = dbm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nrf5_tx(struct device *dev,
|
||||
struct net_buf *buf,
|
||||
struct net_buf *frag)
|
||||
{
|
||||
struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev);
|
||||
uint8_t payload_len = net_nbuf_ll_reserve(buf) + frag->len;
|
||||
uint8_t *payload = frag->data - net_nbuf_ll_reserve(buf);
|
||||
|
||||
SYS_LOG_DBG("%p (%u)", payload, payload_len);
|
||||
|
||||
nrf5_radio->tx_success = false;
|
||||
nrf5_radio->tx_psdu[0] = payload_len + NRF5_FCS_LENGTH;
|
||||
|
||||
memcpy(nrf5_radio->tx_psdu + 1, payload, payload_len);
|
||||
|
||||
if (!nrf_drv_radio802154_transmit(nrf5_radio->tx_psdu,
|
||||
nrf5_radio->channel,
|
||||
nrf5_radio->txpower)) {
|
||||
SYS_LOG_ERR("Cannot send frame");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
SYS_LOG_DBG("Sending frame (ch:%d, txpower:%d)",
|
||||
nrf5_radio->channel,
|
||||
nrf5_radio->txpower);
|
||||
|
||||
/* The nRF driver guarantees that either
|
||||
* nrf_drv_radio802154_transmitted() or
|
||||
* nrf_drv_radio802154_energy_detected()
|
||||
* callback is called, thus unlocking the semaphore.
|
||||
*/
|
||||
k_sem_take(&nrf5_radio->tx_wait, K_FOREVER);
|
||||
|
||||
SYS_LOG_DBG("Result: %d", nrf5_data.tx_success);
|
||||
|
||||
return nrf5_radio->tx_success ? 0 : -EBUSY;
|
||||
}
|
||||
|
||||
static int nrf5_start(struct device *dev)
|
||||
{
|
||||
struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev);
|
||||
|
||||
nrf_drv_radio802154_receive(nrf5_radio->channel, false);
|
||||
SYS_LOG_DBG("nRF5 802154 radio started (channel: %d)",
|
||||
nrf5_radio->channel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nrf5_stop(struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
if (!nrf_drv_radio802154_sleep()) {
|
||||
SYS_LOG_ERR("Error while stopping radio");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
SYS_LOG_DBG("nRF5 802154 radio stopped");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t nrf5_get_lqi(struct device *dev)
|
||||
{
|
||||
struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev);
|
||||
|
||||
return nrf5_radio->lqi;
|
||||
}
|
||||
|
||||
static void nrf5_radio_irq(void *arg)
|
||||
{
|
||||
ARG_UNUSED(arg);
|
||||
|
||||
nrf_drv_radio802154_irq_handler();
|
||||
}
|
||||
|
||||
static void nrf5_config(struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
IRQ_CONNECT(NRF5_IRQ_RADIO_IRQn, 0, nrf5_radio_irq, NULL, 0);
|
||||
irq_enable(NRF5_IRQ_RADIO_IRQn);
|
||||
}
|
||||
|
||||
static int nrf5_init(struct device *dev)
|
||||
{
|
||||
const struct nrf5_802154_config *nrf5_radio_cfg = NRF5_802154_CFG(dev);
|
||||
struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev);
|
||||
struct device *clk_m16;
|
||||
|
||||
k_sem_init(&nrf5_radio->rx_wait, 0, 1);
|
||||
k_sem_init(&nrf5_radio->tx_wait, 0, 1);
|
||||
k_sem_init(&nrf5_radio->cca_wait, 0, 1);
|
||||
|
||||
clk_m16 = device_get_binding(CONFIG_CLOCK_CONTROL_NRF5_M16SRC_DRV_NAME);
|
||||
if (!clk_m16) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
clock_control_on(clk_m16, NULL);
|
||||
|
||||
nrf_drv_radio802154_init();
|
||||
|
||||
nrf5_radio_cfg->irq_config_func(dev);
|
||||
|
||||
k_thread_spawn(nrf5_radio->rx_stack,
|
||||
CONFIG_IEEE802154_NRF5_RX_STACK_SIZE,
|
||||
nrf5_rx_thread,
|
||||
dev, NULL, NULL,
|
||||
K_PRIO_COOP(2), 0, 0);
|
||||
|
||||
SYS_LOG_INF("nRF5 802154 radio initialized");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nrf5_iface_init(struct net_if *iface)
|
||||
{
|
||||
struct device *dev = net_if_get_device(iface);
|
||||
struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev);
|
||||
|
||||
SYS_LOG_DBG("");
|
||||
|
||||
nrf5_get_eui64(nrf5_radio->mac);
|
||||
net_if_set_link_addr(iface,
|
||||
nrf5_radio->mac,
|
||||
sizeof(nrf5_radio->mac),
|
||||
NET_LINK_IEEE802154);
|
||||
|
||||
nrf5_radio->iface = iface;
|
||||
ieee802154_init(iface);
|
||||
}
|
||||
|
||||
/* nRF5 radio driver callbacks */
|
||||
|
||||
void nrf_drv_radio802154_received(uint8_t *p_data, int8_t power, int8_t lqi)
|
||||
{
|
||||
nrf5_data.rx_psdu = p_data;
|
||||
nrf5_data.rssi = power;
|
||||
nrf5_data.lqi = lqi;
|
||||
|
||||
k_sem_give(&nrf5_data.rx_wait);
|
||||
}
|
||||
|
||||
void nrf_drv_radio802154_transmitted(bool pending_bit)
|
||||
{
|
||||
ARG_UNUSED(pending_bit);
|
||||
|
||||
nrf5_data.tx_success = true;
|
||||
k_sem_give(&nrf5_data.tx_wait);
|
||||
}
|
||||
|
||||
void nrf_drv_radio802154_busy_channel(void)
|
||||
{
|
||||
k_sem_give(&nrf5_data.tx_wait);
|
||||
}
|
||||
|
||||
void nrf_drv_radio802154_energy_detected(int8_t result)
|
||||
{
|
||||
nrf5_data.channel_ed = result;
|
||||
k_sem_give(&nrf5_data.cca_wait);
|
||||
}
|
||||
|
||||
static const struct nrf5_802154_config nrf5_radio_cfg = {
|
||||
.irq_config_func = nrf5_config,
|
||||
};
|
||||
|
||||
static struct ieee802154_radio_api nrf5_radio_api = {
|
||||
.iface_api.init = nrf5_iface_init,
|
||||
.iface_api.send = ieee802154_radio_send,
|
||||
|
||||
.cca = nrf5_cca,
|
||||
.set_channel = nrf5_set_channel,
|
||||
.set_pan_id = nrf5_set_pan_id,
|
||||
.set_short_addr = nrf5_set_short_addr,
|
||||
.set_ieee_addr = nrf5_set_ieee_addr,
|
||||
.set_txpower = nrf5_set_txpower,
|
||||
.start = nrf5_start,
|
||||
.stop = nrf5_stop,
|
||||
.tx = nrf5_tx,
|
||||
.get_lqi = nrf5_get_lqi,
|
||||
};
|
||||
|
||||
NET_DEVICE_INIT(nrf5_154_radio, CONFIG_IEEE802154_NRF5_DRV_NAME,
|
||||
nrf5_init, &nrf5_data, &nrf5_radio_cfg,
|
||||
CONFIG_IEEE802154_NRF5_INIT_PRIO,
|
||||
&nrf5_radio_api, IEEE802154_L2,
|
||||
NET_L2_GET_CTX_TYPE(IEEE802154_L2), 125);
|
||||
|
||||
NET_STACK_INFO_ADDR(RX, nrf5_154_radio,
|
||||
CONFIG_IEEE802154_NRF5_RX_STACK_SIZE,
|
||||
CONFIG_IEEE802154_NRF5_RX_STACK_SIZE,
|
||||
((struct nrf5_802154_data *)
|
||||
(&__device_nrf5_154_radio))->rx_stack, 0);
|
||||
59
drivers/ieee802154/ieee802154_nrf5.h
Normal file
59
drivers/ieee802154/ieee802154_nrf5.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* ieee802154_nrf5.h - nRF5 802.15.4 driver */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef __IEEE802154_NRF5_H__
|
||||
#define __IEEE802154_NRF5_H__
|
||||
|
||||
#include <sections.h>
|
||||
#include <atomic.h>
|
||||
|
||||
#define NRF5_FCS_LENGTH (2)
|
||||
#define NRF5_PSDU_LENGTH (125)
|
||||
#define NRF5_PHR_LENGTH (1)
|
||||
|
||||
struct nrf5_802154_data {
|
||||
/* Pointer to the network interface. */
|
||||
struct net_if *iface;
|
||||
/* Pointer to a received frame. */
|
||||
uint8_t *rx_psdu;
|
||||
/* TX buffer. First byte is PHR (length), remaining bytes are
|
||||
* MPDU data.
|
||||
*/
|
||||
uint8_t tx_psdu[NRF5_PHR_LENGTH + NRF5_PSDU_LENGTH];
|
||||
/* 802.15.4 HW address. */
|
||||
uint8_t mac[8];
|
||||
/* RX thread stack. */
|
||||
char __stack rx_stack[CONFIG_IEEE802154_NRF5_RX_STACK_SIZE];
|
||||
|
||||
/* CCA complete sempahore. Unlocked when CCA is complete. */
|
||||
struct k_sem cca_wait;
|
||||
/* RX synchronization semaphore. Unlocked when frame has been
|
||||
* received.
|
||||
*/
|
||||
struct k_sem rx_wait;
|
||||
/* TX synchronization semaphore. Unlocked when frame has been
|
||||
* sent or CCA failed.
|
||||
*/
|
||||
struct k_sem tx_wait;
|
||||
/* TX result. Set to 1 on success, 0 otherwise. */
|
||||
bool tx_success;
|
||||
|
||||
/* CCA channel energy. Unit as per 802.15.4-2006 specification. */
|
||||
int8_t channel_ed;
|
||||
|
||||
/* TX power, in dBm, to be used when sending a frame. */
|
||||
int8_t txpower;
|
||||
/* 802.15.4 channel to be used when sending a frame. */
|
||||
uint8_t channel;
|
||||
|
||||
/* Last received frame LQI value. */
|
||||
uint8_t lqi;
|
||||
/* Last received frame RSSI value. */
|
||||
int8_t rssi;
|
||||
};
|
||||
|
||||
#endif /* __IEEE802154_NRF5_H__ */
|
||||
@@ -84,7 +84,7 @@ static uint8_t *upipe_rx(uint8_t *buf, size_t *off)
|
||||
|
||||
goto flush;
|
||||
out:
|
||||
net_buf_unref(nbuf);
|
||||
net_nbuf_unref(nbuf);
|
||||
flush:
|
||||
upipe->rx = false;
|
||||
upipe->rx_len = 0;
|
||||
@@ -257,7 +257,7 @@ static void upipe_iface_init(struct net_if *iface)
|
||||
|
||||
SYS_LOG_DBG("");
|
||||
|
||||
net_if_set_link_addr(iface, mac, 8);
|
||||
net_if_set_link_addr(iface, mac, 8, NET_LINK_IEEE802154);
|
||||
|
||||
upipe_dev = dev;
|
||||
upipe->iface = iface;
|
||||
|
||||
@@ -41,6 +41,9 @@ enum slip_state {
|
||||
|
||||
struct slip_context {
|
||||
bool init_done;
|
||||
bool first; /* SLIP received it's byte or not after
|
||||
* driver initialization or SLIP_END byte.
|
||||
*/
|
||||
uint8_t buf[1]; /* SLIP data is read into this buf */
|
||||
struct net_buf *rx; /* and then placed into this net_buf */
|
||||
struct net_buf *last; /* Pointer to last fragment in the list */
|
||||
@@ -54,9 +57,6 @@ struct slip_context {
|
||||
#define SLIP_STATS(statement)
|
||||
#else
|
||||
uint16_t garbage;
|
||||
uint16_t multi_packets;
|
||||
uint16_t overflows;
|
||||
uint16_t ip_drop;
|
||||
#define SLIP_STATS(statement) statement
|
||||
#endif
|
||||
};
|
||||
@@ -173,15 +173,29 @@ static int slip_send(struct net_if *iface, struct net_buf *buf)
|
||||
|
||||
for (i = 0; i < frag->len; ++i) {
|
||||
c = *ptr++;
|
||||
if (c == SLIP_END) {
|
||||
slip_writeb(SLIP_ESC);
|
||||
c = SLIP_ESC_END;
|
||||
} else if (c == SLIP_ESC) {
|
||||
slip_writeb(SLIP_ESC);
|
||||
c = SLIP_ESC_ESC;
|
||||
}
|
||||
|
||||
slip_writeb(c);
|
||||
switch (c) {
|
||||
case SLIP_END:
|
||||
/* If it's the same code as an END character,
|
||||
* we send a special two character code so as
|
||||
* not to make the receiver think we sent
|
||||
* an END.
|
||||
*/
|
||||
slip_writeb(SLIP_ESC);
|
||||
slip_writeb(SLIP_ESC_END);
|
||||
break;
|
||||
case SLIP_ESC:
|
||||
/* If it's the same code as an ESC character,
|
||||
* we send a special two character code so as
|
||||
* not to make the receiver think we sent
|
||||
* an ESC.
|
||||
*/
|
||||
slip_writeb(SLIP_ESC);
|
||||
slip_writeb(SLIP_ESC_ESC);
|
||||
break;
|
||||
default:
|
||||
slip_writeb(c);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SLIP_DEBUG)
|
||||
@@ -258,31 +272,46 @@ static inline int slip_input_byte(struct slip_context *slip,
|
||||
if (c == SLIP_ESC) {
|
||||
slip->state = STATE_ESC;
|
||||
return 0;
|
||||
} else if (c == SLIP_END) {
|
||||
}
|
||||
|
||||
if (c == SLIP_END) {
|
||||
slip->state = STATE_OK;
|
||||
return 1;
|
||||
slip->first = false;
|
||||
|
||||
if (slip->rx) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (slip->first && !slip->rx) {
|
||||
/* Must have missed buffer allocation on first byte. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!slip->first) {
|
||||
slip->first = true;
|
||||
|
||||
slip->rx = net_nbuf_get_reserve_rx(0, K_NO_WAIT);
|
||||
if (!slip->rx) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
slip->last = net_nbuf_get_reserve_data(0, K_NO_WAIT);
|
||||
if (!slip->last) {
|
||||
net_nbuf_unref(slip->rx);
|
||||
slip->rx = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
net_buf_frag_add(slip->rx, slip->last);
|
||||
slip->ptr = net_nbuf_ip_data(slip->rx);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!slip->rx) {
|
||||
slip->rx = net_nbuf_get_reserve_rx(0, K_NO_WAIT);
|
||||
if (!slip->rx) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
slip->last = net_nbuf_get_reserve_data(0, K_NO_WAIT);
|
||||
if (!slip->last) {
|
||||
net_nbuf_unref(slip->rx);
|
||||
slip->rx = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
net_buf_frag_add(slip->rx, slip->last);
|
||||
slip->ptr = net_nbuf_ip_data(slip->rx);
|
||||
}
|
||||
|
||||
if (!net_buf_tailroom(slip->last)) {
|
||||
/* We need to allocate a new fragment */
|
||||
struct net_buf *frag;
|
||||
@@ -366,6 +395,7 @@ static int slip_init(struct device *dev)
|
||||
|
||||
slip->state = STATE_OK;
|
||||
slip->rx = NULL;
|
||||
slip->first = false;
|
||||
|
||||
#if defined(CONFIG_SLIP_TAP) && defined(CONFIG_NET_IPV4)
|
||||
SYS_LOG_DBG("ARP enabled");
|
||||
@@ -402,7 +432,8 @@ static void slip_iface_init(struct net_if *iface)
|
||||
|
||||
slip->init_done = true;
|
||||
|
||||
net_if_set_link_addr(iface, ll_addr->addr, ll_addr->len);
|
||||
net_if_set_link_addr(iface, ll_addr->addr, ll_addr->len,
|
||||
NET_LINK_ETHERNET);
|
||||
}
|
||||
|
||||
static struct net_if_api slip_if_api = {
|
||||
|
||||
@@ -106,6 +106,17 @@ config LOAPIC_TIMER_IRQ_PRIORITY
|
||||
help
|
||||
This options specifies the IRQ priority used by the LOAPIC timer.
|
||||
|
||||
config TSC_CYCLES_PER_SEC
|
||||
int
|
||||
prompt "Frequency of x86 CPU timestamp counter"
|
||||
default 0
|
||||
depends on LOAPIC_TIMER
|
||||
help
|
||||
The x86 implementation of LOAPIC k_cycle_get_32() relies on the x86 TSC.
|
||||
This runs at the CPU speed and not the bus speed. If set to 0, the
|
||||
value of CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC will be used instead;
|
||||
many MCUs these values are the same.
|
||||
|
||||
config ARCV2_TIMER
|
||||
bool "ARC Timer"
|
||||
default y
|
||||
|
||||
@@ -51,38 +51,6 @@
|
||||
|
||||
static uint32_t accumulated_cycle_count;
|
||||
|
||||
static uint32_t get_snapshot(void)
|
||||
{
|
||||
#if TIMER_0_SNAPSHOT
|
||||
uint32_t snap, s1, s2;
|
||||
int key;
|
||||
|
||||
key = irq_lock();
|
||||
|
||||
/* Writing any data to one of the snapshot registers populates all
|
||||
* of them with the value of the counter. The data written is ignored
|
||||
*/
|
||||
_nios2_reg_write((void *)TIMER_0_BASE, ALTERA_AVALON_TIMER_SNAPL_REG,
|
||||
1);
|
||||
|
||||
s1 = _nios2_reg_read((void *)TIMER_0_BASE,
|
||||
ALTERA_AVALON_TIMER_SNAPL_REG) &
|
||||
ALTERA_AVALON_TIMER_SNAPL_MSK;
|
||||
s2 = _nios2_reg_read((void *)TIMER_0_BASE,
|
||||
ALTERA_AVALON_TIMER_SNAPH_REG) &
|
||||
ALTERA_AVALON_TIMER_SNAPH_MSK;
|
||||
|
||||
irq_unlock(key);
|
||||
|
||||
snap = s1 | (s2 << 16);
|
||||
|
||||
return sys_clock_hw_cycles_per_tick - snap;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void timer_irq_handler(void *unused)
|
||||
{
|
||||
ARG_UNUSED(unused);
|
||||
@@ -128,8 +96,24 @@ int _sys_clock_driver_init(struct device *device)
|
||||
}
|
||||
|
||||
|
||||
uint32_t k_cycle_get_32(void)
|
||||
uint32_t _timer_cycle_get_32(void)
|
||||
{
|
||||
return accumulated_cycle_count + get_snapshot();
|
||||
/* XXX Per the Altera Embedded IP Peripherals guide, you cannot
|
||||
* use a timer instance for both the system clock and timestamps
|
||||
* at the same time.
|
||||
*
|
||||
* Having this function return accumulated_cycle_count + get_snapshot()
|
||||
* does not work reliably. It's possible for the current countdown
|
||||
* to reset to the next interval before the timer interrupt is
|
||||
* delivered (and accumulated cycle count gets updated). The result
|
||||
* is an unlucky call to this function will appear to jump backward
|
||||
* in time.
|
||||
*
|
||||
* To properly obtain timestamps, the CPU must be configured with
|
||||
* a second timer peripheral instance that is configured to
|
||||
* count down from some large initial 64-bit value. This
|
||||
* is currently unimplemented.
|
||||
*/
|
||||
return accumulated_cycle_count;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
/* running total of timer count */
|
||||
static uint32_t __noinit cycles_per_tick;
|
||||
static uint32_t accumulated_cycle_count;
|
||||
static volatile uint32_t accumulated_cycle_count;
|
||||
|
||||
#ifdef CONFIG_TICKLESS_IDLE
|
||||
static uint32_t __noinit max_system_ticks;
|
||||
@@ -413,9 +413,16 @@ int sys_clock_device_ctrl(struct device *port, uint32_t ctrl_command,
|
||||
}
|
||||
#endif /* CONFIG_DEVICE_POWER_MANAGEMENT */
|
||||
|
||||
uint32_t k_cycle_get_32(void)
|
||||
uint32_t _timer_cycle_get_32(void)
|
||||
{
|
||||
return (accumulated_cycle_count + timer0_count_register_get());
|
||||
uint32_t acc, count;
|
||||
|
||||
do {
|
||||
acc = accumulated_cycle_count;
|
||||
count = timer0_count_register_get();
|
||||
} while (acc != accumulated_cycle_count);
|
||||
|
||||
return acc + count;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SYSTEM_CLOCK_DISABLE)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <arch/arm/cortex_m/cmsis.h>
|
||||
|
||||
/* running total of timer count */
|
||||
static uint32_t clock_accumulated_count;
|
||||
static volatile uint32_t clock_accumulated_count;
|
||||
|
||||
/*
|
||||
* A board support package's board.h header must provide definitions for the
|
||||
@@ -557,9 +557,16 @@ int _sys_clock_driver_init(struct device *device)
|
||||
* systick counter is a 24-bit down counter which is reset to "reload" value
|
||||
* once it reaches 0.
|
||||
*/
|
||||
uint32_t k_cycle_get_32(void)
|
||||
uint32_t _timer_cycle_get_32(void)
|
||||
{
|
||||
return clock_accumulated_count + (SysTick->LOAD - SysTick->VAL);
|
||||
uint32_t cac, count;
|
||||
|
||||
do {
|
||||
cac = clock_accumulated_count;
|
||||
count = SysTick->LOAD - SysTick->VAL;
|
||||
} while (cac != clock_accumulated_count);
|
||||
|
||||
return cac + count;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYSTEM_CLOCK_DISABLE
|
||||
|
||||
@@ -593,7 +593,7 @@ int _sys_clock_driver_init(struct device *device)
|
||||
* it will need to call _hpetMainCounterAtomic().
|
||||
*/
|
||||
|
||||
uint32_t k_cycle_get_32(void)
|
||||
uint32_t _timer_cycle_get_32(void)
|
||||
{
|
||||
return (uint32_t) *_HPET_MAIN_COUNTER_VALUE;
|
||||
}
|
||||
|
||||
@@ -129,7 +129,6 @@ extern int32_t _sys_idle_elapsed_ticks;
|
||||
|
||||
/* computed counter 0 initial count value */
|
||||
static uint32_t __noinit cycles_per_tick;
|
||||
static uint32_t accumulated_cycle_count;
|
||||
|
||||
#if defined(CONFIG_TICKLESS_IDLE)
|
||||
static uint32_t programmed_cycles;
|
||||
@@ -277,13 +276,7 @@ void _timer_int_handler(void *unused /* parameter is not used */
|
||||
}
|
||||
|
||||
_sys_clock_final_tick_announce();
|
||||
|
||||
/* track the accumulated cycle count */
|
||||
accumulated_cycle_count += cycles_per_tick * _sys_idle_elapsed_ticks;
|
||||
#else
|
||||
/* track the accumulated cycle count */
|
||||
accumulated_cycle_count += cycles_per_tick;
|
||||
|
||||
_sys_clock_tick_announce();
|
||||
#endif /*CONFIG_TICKLESS_IDLE*/
|
||||
|
||||
@@ -503,7 +496,6 @@ int _sys_clock_driver_init(struct device *device)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
|
||||
static int sys_clock_suspend(struct device *dev)
|
||||
{
|
||||
@@ -584,32 +576,26 @@ int sys_clock_device_ctrl(struct device *port, uint32_t ctrl_command,
|
||||
* @brief Read the platform's timer hardware
|
||||
*
|
||||
* This routine returns the current time in terms of timer hardware clock
|
||||
* cycles.
|
||||
* cycles. We use the x86 TSC as the LOAPIC timer can't be used as a periodic
|
||||
* system clock and a timestamp source at the same time.
|
||||
*
|
||||
* @return up counter of elapsed clock cycles
|
||||
*/
|
||||
uint32_t k_cycle_get_32(void)
|
||||
uint32_t _timer_cycle_get_32(void)
|
||||
{
|
||||
uint32_t val; /* system clock value */
|
||||
#if CONFIG_TSC_CYCLES_PER_SEC != 0
|
||||
uint64_t tsc;
|
||||
|
||||
/*
|
||||
* The LOAPIC timer counter is a down counter. Thus to get the number
|
||||
* of elapsed cycles since 'accumlated_cycle_count' was last updated,
|
||||
* subtract the value in the Current Count Register (CCR) from the value
|
||||
* in the Initial Count Register (ICR).
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_TICKLESS_IDLE)
|
||||
/* The value in the ICR always matches cycles_per_tick. */
|
||||
val = accumulated_cycle_count - current_count_register_get() +
|
||||
cycles_per_tick;
|
||||
/* 64-bit math to avoid overflows */
|
||||
tsc = _tsc_read() * (uint64_t)sys_clock_hw_cycles_per_sec /
|
||||
(uint64_t) CONFIG_TSC_CYCLES_PER_SEC;
|
||||
return (uint32_t)tsc;
|
||||
#else
|
||||
/* The value in the ICR may vary. Read from the register. */
|
||||
val = accumulated_cycle_count - current_count_register_get() +
|
||||
initial_count_register_get();
|
||||
/* TSC runs same as the bus speed, nothing to do but return the TSC
|
||||
* value
|
||||
*/
|
||||
return _do_read_cpu_timestamp32();
|
||||
#endif
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SYSTEM_CLOCK_DISABLE)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Nordic Semiconductor ASA
|
||||
* Copyright (c) 2016-2017 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -10,130 +10,261 @@
|
||||
#include <drivers/clock_control/nrf5_clock_control.h>
|
||||
#include <arch/arm/cortex_m/cmsis.h>
|
||||
|
||||
#define RTC_TICKS ((uint32_t)(((((uint64_t)1000000UL / \
|
||||
/*
|
||||
* Convenience defines.
|
||||
*/
|
||||
#define SYS_CLOCK_RTC NRF_RTC1
|
||||
#define RTC_COUNTER SYS_CLOCK_RTC->COUNTER
|
||||
#define RTC_CC_VALUE SYS_CLOCK_RTC->CC[0]
|
||||
#define RTC_CC_EVENT SYS_CLOCK_RTC->EVENTS_COMPARE[0]
|
||||
|
||||
/* Minimum delta between current counter and CC register that the RTC is able
|
||||
* to handle
|
||||
*/
|
||||
#define RTC_MIN_DELTA 2
|
||||
#define RTC_MASK 0x00FFFFFF
|
||||
/* Maximum difference for RTC counter values used. Half the maximum value is
|
||||
* selected to be able to detect overflow (a negative value has the same
|
||||
* representation as a large positive value).
|
||||
*/
|
||||
#define RTC_HALF (RTC_MASK / 2)
|
||||
#define RTC_TICKS_PER_SYS_TICK ((uint32_t)((((uint64_t)1000000UL / \
|
||||
CONFIG_SYS_CLOCK_TICKS_PER_SEC) * \
|
||||
1000000000UL) / 30517578125UL)) & 0x00FFFFFF)
|
||||
1000000000UL) / 30517578125UL) & RTC_MASK)
|
||||
|
||||
extern int64_t _sys_clock_tick_count;
|
||||
extern int32_t _sys_idle_elapsed_ticks;
|
||||
static uint32_t rtc_clock_tick_count;
|
||||
|
||||
/*
|
||||
* rtc_past holds the value of RTC_COUNTER at the time the last sys tick was
|
||||
* announced, in RTC ticks. It is therefore always a multiple of
|
||||
* RTC_TICKS_PER_SYS_TICK.
|
||||
*/
|
||||
static uint32_t rtc_past;
|
||||
|
||||
#ifdef CONFIG_TICKLESS_IDLE
|
||||
static uint8_t volatile isr_req;
|
||||
static uint8_t isr_ack;
|
||||
/*
|
||||
* Holds the maximum sys ticks the kernel expects to see in the next
|
||||
* _sys_clock_tick_announce().
|
||||
*/
|
||||
static uint32_t expected_sys_ticks;
|
||||
#endif /* CONFIG_TICKLESS_IDLE */
|
||||
|
||||
static uint32_t rtc_compare_set(uint32_t rtc_ticks)
|
||||
/*
|
||||
* Set RTC Counter Compare (CC) register to a given value in RTC ticks.
|
||||
*/
|
||||
static void rtc_compare_set(uint32_t rtc_ticks)
|
||||
{
|
||||
uint32_t prev, cc, elapsed_ticks;
|
||||
uint8_t retry = 10;
|
||||
uint32_t rtc_now;
|
||||
|
||||
prev = NRF_RTC1->COUNTER;
|
||||
/* Try to set CC value. We assume the procedure is always successful. */
|
||||
RTC_CC_VALUE = rtc_ticks;
|
||||
rtc_now = RTC_COUNTER;
|
||||
|
||||
do {
|
||||
/* Assert if retries failed to set compare in the future */
|
||||
__ASSERT_NO_MSG(retry);
|
||||
retry--;
|
||||
|
||||
/* update with elapsed ticks from h/w */
|
||||
elapsed_ticks = (prev - rtc_clock_tick_count) & 0x00FFFFFF;
|
||||
|
||||
/* setup next RTC compare event by ticks */
|
||||
cc = (rtc_clock_tick_count + elapsed_ticks + rtc_ticks) &
|
||||
0x00FFFFFF;
|
||||
|
||||
NRF_RTC1->CC[0] = cc;
|
||||
|
||||
prev = NRF_RTC1->COUNTER;
|
||||
} while (((cc - prev) & 0x00FFFFFF) < 3);
|
||||
|
||||
#ifdef CONFIG_TICKLESS_IDLE
|
||||
/* If system clock ticks have elapsed, pend RTC IRQ which will
|
||||
* call announce
|
||||
/* The following checks if the CC register was set to a valid value.
|
||||
* The first test checks if the distance between the current RTC counter
|
||||
* and the value (in the future) set in the CC register is too small to
|
||||
* guarantee a compare event being triggered.
|
||||
* The second test checks if the current RTC counter is higher than the
|
||||
* value written to the CC register, i.e. the CC value is in the past,
|
||||
* by checking if the unsigned subtraction wraps around.
|
||||
* If either of the above are true then instead of waiting for the CC
|
||||
* event to trigger in the form of an interrupt, trigger it directly
|
||||
* using the NVIC.
|
||||
*/
|
||||
if (elapsed_ticks >= rtc_ticks) {
|
||||
uint8_t req;
|
||||
|
||||
/* pending the interrupt does not trigger the RTC event, hence
|
||||
* use a request/ack mechanism to let the ISR know that the
|
||||
* interrupt was requested
|
||||
*/
|
||||
req = isr_req + 1;
|
||||
if (req != isr_ack) {
|
||||
isr_req = req;
|
||||
}
|
||||
|
||||
if ((((rtc_ticks - rtc_now) & RTC_MASK) < RTC_MIN_DELTA) ||
|
||||
(((rtc_ticks - rtc_now) & RTC_MASK) > RTC_HALF)) {
|
||||
NVIC_SetPendingIRQ(NRF5_IRQ_RTC1_IRQn);
|
||||
}
|
||||
#endif /* CONFIG_TICKLESS_IDLE */
|
||||
|
||||
return elapsed_ticks;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TICKLESS_IDLE
|
||||
void _timer_idle_enter(int32_t ticks)
|
||||
/*
|
||||
* @brief Announces the number of sys ticks, if any, that have passed since the
|
||||
* last announcement, and programs the RTC to trigger the interrupt on the next
|
||||
* sys tick.
|
||||
*
|
||||
* This function is not reentrant. It is called from:
|
||||
*
|
||||
* * _timer_idle_exit(), which in turn is called with interrupts disabled when
|
||||
* an interrupt fires.
|
||||
* * rtc1_nrf5_isr(), which runs with interrupts enabled but at that time the
|
||||
* device cannot be idle and hence _timer_idle_exit() cannot be called.
|
||||
*
|
||||
* Since this function can be preempted, we need to take some provisions to
|
||||
* announce all expected sys ticks that have passed.
|
||||
*
|
||||
*/
|
||||
static void rtc_announce_set_next(void)
|
||||
{
|
||||
/* restrict ticks to max supported by RTC */
|
||||
if ((ticks < 0) || (ticks > (0x00FFFFFF / RTC_TICKS))) {
|
||||
ticks = 0x00FFFFFF / RTC_TICKS;
|
||||
}
|
||||
uint32_t rtc_now, rtc_elapsed, sys_elapsed;
|
||||
|
||||
/* Postpone RTC compare event by requested system clock ticks */
|
||||
rtc_compare_set(ticks * RTC_TICKS);
|
||||
}
|
||||
|
||||
void _timer_idle_exit(void)
|
||||
{
|
||||
/* Advance RTC compare event to next system clock tick */
|
||||
rtc_compare_set(RTC_TICKS);
|
||||
}
|
||||
#endif /* CONFIG_TICKLESS_IDLE */
|
||||
|
||||
static void rtc1_nrf5_isr(void *arg)
|
||||
{
|
||||
#ifdef CONFIG_TICKLESS_IDLE
|
||||
uint8_t req;
|
||||
|
||||
ARG_UNUSED(arg);
|
||||
|
||||
req = isr_req;
|
||||
/* iterate here since pending the interrupt can be done from higher
|
||||
* priority, and thus queuing multiple triggers
|
||||
/* Read the RTC counter one single time in the beginning, so that an
|
||||
* increase in the counter during this procedure leads to no race
|
||||
* conditions.
|
||||
*/
|
||||
while (NRF_RTC1->EVENTS_COMPARE[0] || (req != isr_ack)) {
|
||||
uint32_t elapsed_ticks;
|
||||
rtc_now = RTC_COUNTER;
|
||||
|
||||
NRF_RTC1->EVENTS_COMPARE[0] = 0;
|
||||
/* Calculate how many RTC ticks elapsed since the last sys tick. */
|
||||
rtc_elapsed = (rtc_now - rtc_past) & RTC_MASK;
|
||||
|
||||
if (req != isr_ack) {
|
||||
isr_ack = req;
|
||||
req = isr_req;
|
||||
/* If no sys ticks have elapsed, there is no point in incrementing the
|
||||
* counters or announcing it.
|
||||
*/
|
||||
if (rtc_elapsed >= RTC_TICKS_PER_SYS_TICK) {
|
||||
#ifdef CONFIG_TICKLESS_IDLE
|
||||
/* Calculate how many sys ticks elapsed since the last sys tick
|
||||
* and notify the kernel if necessary.
|
||||
*/
|
||||
sys_elapsed = rtc_elapsed / RTC_TICKS_PER_SYS_TICK;
|
||||
|
||||
elapsed_ticks = (NRF_RTC1->COUNTER -
|
||||
rtc_clock_tick_count)
|
||||
& 0x00FFFFFF;
|
||||
} else {
|
||||
elapsed_ticks = rtc_compare_set(RTC_TICKS);
|
||||
if (sys_elapsed > expected_sys_ticks) {
|
||||
/* Never announce more sys ticks than the kernel asked
|
||||
* to be idle for. The remainder will be announced when
|
||||
* the RTC ISR runs after rtc_compare_set() is called
|
||||
* after the first announcement.
|
||||
*/
|
||||
sys_elapsed = expected_sys_ticks;
|
||||
}
|
||||
#else
|
||||
ARG_UNUSED(arg);
|
||||
/* Never announce more than one sys tick if tickless idle is not
|
||||
* configured.
|
||||
*/
|
||||
sys_elapsed = 1;
|
||||
#endif /* CONFIG_TICKLESS_IDLE */
|
||||
|
||||
if (NRF_RTC1->EVENTS_COMPARE[0]) {
|
||||
uint32_t elapsed_ticks;
|
||||
|
||||
NRF_RTC1->EVENTS_COMPARE[0] = 0;
|
||||
|
||||
elapsed_ticks = rtc_compare_set(RTC_TICKS);
|
||||
#endif
|
||||
|
||||
rtc_clock_tick_count += elapsed_ticks;
|
||||
rtc_clock_tick_count &= 0x00FFFFFF;
|
||||
|
||||
/* update with elapsed ticks from the hardware */
|
||||
_sys_idle_elapsed_ticks = elapsed_ticks / RTC_TICKS;
|
||||
/* Store RTC_COUNTER floored to the last sys tick. This is
|
||||
* done, so that ISR can properly calculate that 1 sys tick
|
||||
* has passed.
|
||||
*/
|
||||
rtc_past = (rtc_past +
|
||||
(sys_elapsed * RTC_TICKS_PER_SYS_TICK)
|
||||
) & RTC_MASK;
|
||||
|
||||
_sys_idle_elapsed_ticks = sys_elapsed;
|
||||
_sys_clock_tick_announce();
|
||||
}
|
||||
|
||||
/* Set the RTC to the next sys tick */
|
||||
rtc_compare_set(rtc_past + RTC_TICKS_PER_SYS_TICK);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TICKLESS_IDLE
|
||||
/**
|
||||
* @brief Place system timer into idle state.
|
||||
*
|
||||
* Re-program the timer to enter into the idle state for the given number of
|
||||
* sys ticks, counted from the previous sys tick. The timer will fire in the
|
||||
* number of sys ticks supplied or the maximum number of sys ticks (converted
|
||||
* to RTC ticks) that can be programmed into the hardware.
|
||||
*
|
||||
* This will only be called from idle context, with IRQs disabled.
|
||||
*
|
||||
* A value of -1 will result in the maximum number of sys ticks.
|
||||
*
|
||||
* Example 1: Idle sleep is entered:
|
||||
*
|
||||
* sys tick timeline: (1) (2) (3) (4) (5) (6)
|
||||
* rtc tick timeline : 0----100----200----300----400----500----600
|
||||
* ******************
|
||||
* 150
|
||||
*
|
||||
* a) The last sys tick was announced at 100
|
||||
* b) The idle context enters sleep at 150, between sys tick 1 and 2, with
|
||||
* sys_ticks = 3.
|
||||
* c) The RTC is programmed to fire at sys tick 1 + 3 = 4 (RTC tick 400)
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
void _timer_idle_enter(int32_t sys_ticks)
|
||||
{
|
||||
/* Restrict ticks to max supported by RTC without risking overflow. */
|
||||
if ((sys_ticks < 0) ||
|
||||
(sys_ticks > (RTC_HALF / RTC_TICKS_PER_SYS_TICK))) {
|
||||
sys_ticks = RTC_HALF / RTC_TICKS_PER_SYS_TICK;
|
||||
}
|
||||
|
||||
expected_sys_ticks = sys_ticks;
|
||||
|
||||
/* If ticks is 0, the RTC interrupt handler will be set pending
|
||||
* immediately, meaning that we will not go to sleep.
|
||||
*/
|
||||
rtc_compare_set(rtc_past + (sys_ticks * RTC_TICKS_PER_SYS_TICK));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Handling of tickless idle when interrupted
|
||||
*
|
||||
* The function will be called by _sys_power_save_idle_exit(), called from
|
||||
* _arch_isr_direct_pm() for 'direct' interrupts, or from _isr_wrapper for
|
||||
* regular ones, which is called on every IRQ handler if the device was
|
||||
* idle, and optionally called when a 'direct' IRQ handler executes if the
|
||||
* device was idle.
|
||||
*
|
||||
* Example 1: Idle sleep is interrupted before time:
|
||||
*
|
||||
* sys tick timeline: (1) (2) (3) (4) (5) (6)
|
||||
* rtc tick timeline : 0----100----200----300----400----500----600
|
||||
* **************!***
|
||||
* 150 350
|
||||
*
|
||||
* Assume that _timer_idle_enter() is called at 150 (1) to sleep for 3
|
||||
* sys ticks. The last sys tick was announced at 100.
|
||||
*
|
||||
* On wakeup (non-RTC IRQ at 350):
|
||||
*
|
||||
* a) Notify how many sys ticks have passed, i.e., 350 - 150 / 100 = 2.
|
||||
* b) Schedule next sys tick at 400.
|
||||
*
|
||||
*/
|
||||
void _timer_idle_exit(void)
|
||||
{
|
||||
/* Clear the event flag and interrupt in case we woke up on the RTC
|
||||
* interrupt. No need to run the RTC ISR since everything that needs
|
||||
* to run in the ISR will be done in this call.
|
||||
*/
|
||||
RTC_CC_EVENT = 0;
|
||||
NVIC_ClearPendingIRQ(NRF5_IRQ_RTC1_IRQn);
|
||||
|
||||
rtc_announce_set_next();
|
||||
|
||||
/* After exiting idle, the kernel no longer expects more than one sys
|
||||
* ticks to have passed when _sys_clock_tick_announce() is called.
|
||||
*/
|
||||
expected_sys_ticks = 1;
|
||||
}
|
||||
#endif /* CONFIG_TICKLESS_IDLE */
|
||||
|
||||
/*
|
||||
* @brief Announces the number of sys ticks that have passed since the last
|
||||
* announcement, if any, and programs the RTC to trigger the interrupt on the
|
||||
* next sys tick.
|
||||
*
|
||||
* The ISR is set pending due to a regular sys tick and after exiting idle mode
|
||||
* as scheduled.
|
||||
*
|
||||
* Since this ISR can be preempted, we need to take some provisions to announce
|
||||
* all expected sys ticks that have passed.
|
||||
*
|
||||
* Consider the following example:
|
||||
*
|
||||
* sys tick timeline: (1) (2) (3) (4) (5) (6)
|
||||
* rtc tick timeline : 0----100----200----300----400----500----600
|
||||
* !**********
|
||||
* 450
|
||||
*
|
||||
* The last sys tick was anounced at 200, i.e, rtc_past = 200. The ISR is
|
||||
* executed at the next sys tick, i.e. 300. The following sys tick is due at
|
||||
* 400. However, the ISR is preempted for a number of sys ticks, until 450 in
|
||||
* this example. The ISR will then announce the number of sys ticks it was
|
||||
* delayed (2), and schedule the next sys tick (5) at 500.
|
||||
*/
|
||||
static void rtc1_nrf5_isr(void *arg)
|
||||
{
|
||||
ARG_UNUSED(arg);
|
||||
|
||||
RTC_CC_EVENT = 0;
|
||||
rtc_announce_set_next();
|
||||
}
|
||||
|
||||
int _sys_clock_driver_init(struct device *device)
|
||||
@@ -149,26 +280,38 @@ int _sys_clock_driver_init(struct device *device)
|
||||
|
||||
clock_control_on(clock, (void *)CLOCK_CONTROL_NRF5_K32SRC);
|
||||
|
||||
rtc_past = 0;
|
||||
|
||||
#ifdef CONFIG_TICKLESS_IDLE
|
||||
expected_sys_ticks = 1;
|
||||
#endif /* CONFIG_TICKLESS_IDLE */
|
||||
|
||||
/* TODO: replace with counter driver to access RTC */
|
||||
NRF_RTC1->PRESCALER = 0;
|
||||
NRF_RTC1->CC[0] = RTC_TICKS;
|
||||
NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE0_Msk;
|
||||
NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk;
|
||||
SYS_CLOCK_RTC->PRESCALER = 0;
|
||||
SYS_CLOCK_RTC->CC[0] = RTC_TICKS_PER_SYS_TICK;
|
||||
SYS_CLOCK_RTC->EVTENSET = RTC_EVTENSET_COMPARE0_Msk;
|
||||
SYS_CLOCK_RTC->INTENSET = RTC_INTENSET_COMPARE0_Msk;
|
||||
|
||||
/* Clear the event flag and possible pending interrupt */
|
||||
RTC_CC_EVENT = 0;
|
||||
NVIC_ClearPendingIRQ(NRF5_IRQ_RTC1_IRQn);
|
||||
|
||||
IRQ_CONNECT(NRF5_IRQ_RTC1_IRQn, 1, rtc1_nrf5_isr, 0, 0);
|
||||
irq_enable(NRF5_IRQ_RTC1_IRQn);
|
||||
|
||||
NRF_RTC1->TASKS_START = 1;
|
||||
SYS_CLOCK_RTC->TASKS_CLEAR = 1;
|
||||
SYS_CLOCK_RTC->TASKS_START = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t k_cycle_get_32(void)
|
||||
uint32_t _timer_cycle_get_32(void)
|
||||
{
|
||||
uint32_t elapsed_cycles;
|
||||
|
||||
elapsed_cycles = (NRF_RTC1->COUNTER -
|
||||
(_sys_clock_tick_count * RTC_TICKS)) & 0x00FFFFFF;
|
||||
elapsed_cycles = (RTC_COUNTER -
|
||||
(_sys_clock_tick_count * RTC_TICKS_PER_SYS_TICK))
|
||||
& RTC_MASK;
|
||||
|
||||
return (_sys_clock_tick_count * sys_clock_hw_cycles_per_tick) +
|
||||
elapsed_cycles;
|
||||
@@ -177,7 +320,7 @@ uint32_t k_cycle_get_32(void)
|
||||
#ifdef CONFIG_SYSTEM_CLOCK_DISABLE
|
||||
/**
|
||||
*
|
||||
* @brief Stop announcing ticks into the kernel
|
||||
* @brief Stop announcing sys ticks into the kernel
|
||||
*
|
||||
* This routine disables the RTC1 so that timer interrupts are no
|
||||
* longer delivered.
|
||||
@@ -186,9 +329,19 @@ uint32_t k_cycle_get_32(void)
|
||||
*/
|
||||
void sys_clock_disable(void)
|
||||
{
|
||||
unsigned int key;
|
||||
|
||||
key = irq_lock();
|
||||
|
||||
irq_disable(NRF5_IRQ_RTC1_IRQn);
|
||||
|
||||
NRF_RTC1->TASKS_STOP = 1;
|
||||
SYS_CLOCK_RTC->EVTENCLR = RTC_EVTENCLR_COMPARE0_Msk;
|
||||
SYS_CLOCK_RTC->INTENCLR = RTC_INTENCLR_COMPARE0_Msk;
|
||||
|
||||
SYS_CLOCK_RTC->TASKS_STOP = 1;
|
||||
SYS_CLOCK_RTC->TASKS_CLEAR = 1;
|
||||
|
||||
irq_unlock(key);
|
||||
|
||||
/* TODO: turn off (release) 32 KHz clock source.
|
||||
* Turning off of 32 KHz clock source is not implemented in clock
|
||||
|
||||
@@ -68,7 +68,7 @@ int _sys_clock_driver_init(struct device *device)
|
||||
*
|
||||
* @return up counter of elapsed clock cycles
|
||||
*/
|
||||
uint32_t k_cycle_get_32(void)
|
||||
uint32_t _timer_cycle_get_32(void)
|
||||
{
|
||||
return accumulated_cycle_count + timer->val;
|
||||
}
|
||||
|
||||
@@ -20,9 +20,6 @@ static volatile riscv_machine_timer_t *mtime =
|
||||
static volatile riscv_machine_timer_t *mtimecmp =
|
||||
(riscv_machine_timer_t *)RISCV_MTIMECMP_BASE;
|
||||
|
||||
static uint32_t accumulated_cycle_count;
|
||||
static uint64_t last_rtc_value;
|
||||
|
||||
/*
|
||||
* The RISCV machine-mode timer is a one shot timer that needs to be rearm upon
|
||||
* every interrupt. Timer clock is a 64-bits ART.
|
||||
@@ -44,7 +41,6 @@ static ALWAYS_INLINE void riscv_machine_rearm_timer(void)
|
||||
*/
|
||||
rtc = mtime->val_low;
|
||||
rtc |= ((uint64_t)mtime->val_high << 32);
|
||||
last_rtc_value = rtc;
|
||||
|
||||
/*
|
||||
* Rearm timer to generate an interrupt after
|
||||
@@ -59,8 +55,6 @@ static void riscv_machine_timer_irq_handler(void *unused)
|
||||
{
|
||||
ARG_UNUSED(unused);
|
||||
|
||||
accumulated_cycle_count += sys_clock_hw_cycles_per_tick;
|
||||
|
||||
_sys_clock_tick_announce();
|
||||
|
||||
/* Rearm timer */
|
||||
@@ -95,13 +89,10 @@ int _sys_clock_driver_init(struct device *device)
|
||||
*
|
||||
* @return up counter of elapsed clock cycles
|
||||
*/
|
||||
uint32_t k_cycle_get_32(void)
|
||||
uint32_t _timer_cycle_get_32(void)
|
||||
{
|
||||
uint64_t rtc;
|
||||
|
||||
rtc = mtime->val_low;
|
||||
rtc |= ((uint64_t)mtime->val_high << 32);
|
||||
|
||||
/* rtc - last_rtc_value is always <= sys_clock_hw_cycles_per_tick */
|
||||
return accumulated_cycle_count + (uint32_t)(rtc - last_rtc_value);
|
||||
/* We just want a cycle count so just post what's in the low 32
|
||||
* bits of the mtime real-time counter
|
||||
*/
|
||||
return mtime->val_low;
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ int _sys_clock_driver_init(struct device *device)
|
||||
*
|
||||
* @return up counter of elapsed clock cycles
|
||||
*/
|
||||
uint32_t k_cycle_get_32(void)
|
||||
uint32_t _timer_cycle_get_32(void)
|
||||
{
|
||||
return GET_TIMER_CURRENT_TIME();
|
||||
}
|
||||
|
||||
@@ -30,4 +30,10 @@
|
||||
|
||||
&uart0 {
|
||||
status = "ok";
|
||||
baud-rate = <115200>;
|
||||
};
|
||||
|
||||
&uart3 {
|
||||
status = "ok";
|
||||
baud-rate = <115200>;
|
||||
};
|
||||
|
||||
@@ -31,4 +31,10 @@
|
||||
|
||||
&uart0 {
|
||||
status = "ok";
|
||||
baud-rate = <115200>;
|
||||
};
|
||||
|
||||
&uart4 {
|
||||
status = "ok";
|
||||
baud-rate = <115200>;
|
||||
};
|
||||
|
||||
@@ -75,7 +75,6 @@
|
||||
interrupt-names = "status", "error";
|
||||
zephyr,irq-prio = <0>;
|
||||
|
||||
baud-rate = <115200>;
|
||||
pinctrl-0 = <&uart0_default>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
|
||||
@@ -3,3 +3,4 @@ obj-$(CONFIG_QMSI_BUILTIN) += qmsi/
|
||||
obj-$(CONFIG_HAS_STM32CUBE) += st/stm32cube/
|
||||
obj-$(CONFIG_HAS_CC3200SDK) += ti/cc3200sdk/
|
||||
obj-$(CONFIG_HAS_NORDIC_HAL) += nordic/
|
||||
obj-$(CONFIG_HAS_NORDIC_DRIVERS) += nordic/drivers/
|
||||
|
||||
@@ -8,4 +8,8 @@ config HAS_NORDIC_MDK
|
||||
bool
|
||||
|
||||
config HAS_NORDIC_HAL
|
||||
bool
|
||||
bool
|
||||
|
||||
config HAS_NORDIC_DRIVERS
|
||||
bool
|
||||
select HAS_NORDIC_HAL
|
||||
|
||||
@@ -5,3 +5,7 @@ endif
|
||||
ifdef CONFIG_HAS_NORDIC_HAL
|
||||
ZEPHYRINCLUDE += -I$(srctree)/ext/hal/nordic/hal
|
||||
endif
|
||||
|
||||
ifdef CONFIG_HAS_NORDIC_DRIVERS
|
||||
ZEPHYRINCLUDE += -I$(srctree)/ext/hal/nordic/drivers
|
||||
endif
|
||||
|
||||
33
ext/hal/nordic/drivers/Kbuild
Normal file
33
ext/hal/nordic/drivers/Kbuild
Normal file
@@ -0,0 +1,33 @@
|
||||
obj-$(CONFIG_IEEE802154_NRF5) += nrf_drv_radio802154.o
|
||||
|
||||
ifeq ($(CONFIG_IEEE802154_NRF5),y)
|
||||
# A common prefix used for placing radio buffer in a named
|
||||
# memory section.
|
||||
KBUILD_CFLAGS += -DRADIO_SECTION_PREFIX="\".top_of_image_ram\""
|
||||
|
||||
# Number of slots containing short addresses of nodes for which pending data is stored.
|
||||
KBUILD_CFLAGS += -DRADIO_PENDING_SHORT_ADDRESSES=1
|
||||
|
||||
# Number of slots containing extended addresses of nodes for which pending data is stored.
|
||||
KBUILD_CFLAGS += -DRADIO_PENDING_EXTENDED_ADDRESSES=1
|
||||
|
||||
# Number of buffers in receive queue.
|
||||
KBUILD_CFLAGS += -DRADIO_RX_BUFFERS=1
|
||||
|
||||
# CCA mode
|
||||
ifeq ($(CONFIG_IEEE802154_NRF5_CCA_MODE_ED),y)
|
||||
KBUILD_CFLAGS += -DRADIO_CCA_MODE=NRF_RADIO_CCA_MODE_ED
|
||||
else ifeq ($(CONFIG_IEEE802154_NRF5_CCA_MODE_CARRIER),y)
|
||||
KBUILD_CFLAGS += -DRADIO_CCA_MODE=NRF_RADIO_CCA_MODE_CARRIER
|
||||
else ifeq ($(IEEE802154_NRF5_CCA_MODE_CARRIER_AND_ED),y)
|
||||
KBUILD_CFLAGS += -DRADIO_CCA_MODE=NRF_RADIO_CCA_MODE_CARRIER_AND_ED
|
||||
else ifeq ($(IEEE802154_NRF5_CCA_MODE_CARRIER_OR_ED),y)
|
||||
KBUILD_CFLAGS += -DRADIO_CCA_MODE=NRF_RADIO_CCA_MODE_CARRIER_OR_ED
|
||||
endif
|
||||
|
||||
# CCA mode options
|
||||
KBUILD_CFLAGS += -DRADIO_CCA_CORR_LIMIT=$(CONFIG_IEEE802154_NRF5_CCA_CORR_LIMIT)
|
||||
KBUILD_CFLAGS += -DRADIO_CCA_CORR_THRESHOLD=$(CONFIG_IEEE802154_NRF5_CCA_CORR_THRESHOLD)
|
||||
KBUILD_CFLAGS += -DRADIO_CCA_ED_THRESHOLD=$(CONFIG_IEEE802154_NRF5_CCA_ED_THRESHOLD)
|
||||
|
||||
endif
|
||||
3
ext/hal/nordic/drivers/Makefile
Normal file
3
ext/hal/nordic/drivers/Makefile
Normal file
@@ -0,0 +1,3 @@
|
||||
ifeq ($(CONFIG_IEEE802154_NRF5),y)
|
||||
ZEPHYRINCLUDE += -I$(srctree)/ext/hal/nordic/drivers
|
||||
endif
|
||||
128
ext/hal/nordic/drivers/README.md
Normal file
128
ext/hal/nordic/drivers/README.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# nRF 802.15.4 radio driver.
|
||||
|
||||
This driver implements only __non-beacon mode__ of operation.
|
||||
It supports following __features__:
|
||||
* reception of unicast and broadcast frames (with filtering),
|
||||
* automatic sending ACK frames,
|
||||
* setting pending bit in ACK frame according to pending data for given
|
||||
destination,
|
||||
* transmission of unicast and broadcast frames,
|
||||
* automatic CCA procedure before transmission,
|
||||
* automatic receiving ACK frames,
|
||||
* low power mode (sleep),
|
||||
* energy detection,
|
||||
* promiscuous mode.
|
||||
|
||||
## Implementation details
|
||||
|
||||
The driver is a FSM. From API perspective it has 4 states. Most of those states
|
||||
contains sub-states in implementation.
|
||||
|
||||
### FSM description
|
||||
|
||||
```
|
||||
receive() transmit()
|
||||
--------> -------->
|
||||
Sleep Receive Transmit
|
||||
<-------- | /|\<--------
|
||||
sleep() | | receive() / transmitted() / busy_channel()
|
||||
| |
|
||||
energy_detection() | | energy_detected()
|
||||
\|/ |
|
||||
Energy detection
|
||||
```
|
||||
|
||||
#### Transitions
|
||||
|
||||
The driver is initialized in the Sleep state. The higher layer should call
|
||||
the receive() function to make the driver enter the Receive state and start
|
||||
radio operations.
|
||||
|
||||
In basic applications radio should be most time in a Receive state. In this
|
||||
state the radio receives incoming frames. Changing to any other state should be
|
||||
performed from Receive state.
|
||||
|
||||
When a frame is received in Receive state the driver notifies the higher layer
|
||||
by calling received() function. This function is called after reception of a
|
||||
broadcast frame or after sending an ACK to a unicast frame.
|
||||
In the promiscuous mode the higher layer is notified about all of the received
|
||||
frames. Even if the frame was not destined to the receiving node.
|
||||
|
||||
To transmit a frame the higher layer should call the transmit() function. If
|
||||
channel is busy the driver goes back to the Receive state and notifies the
|
||||
higher layer by calling the busy_channel() function. If a broadcast frame was
|
||||
transmitted the driver goes back to the Receive state and notifies the higher
|
||||
layer by calling the transmitted() function. If a unicast frame was transmitted
|
||||
and an ACK was received the driver goes back to the Receive state and notifies
|
||||
the higher layer by calling the transmitted() function. If a unicast frame was
|
||||
transmitted and there was no expected ACK received the higher layer shall call
|
||||
the receive() function after the ACK timeout to make the driver go back to the
|
||||
Receive state.
|
||||
|
||||
To perform an Energy Detection procedure the higher layer should call the
|
||||
energy_detection() function. When the procedure is completed the driver goes
|
||||
automatically back to the Receive state and notifies the higher layer with the
|
||||
energy_detected() function.
|
||||
|
||||
#### States
|
||||
|
||||
##### Sleep
|
||||
In this state the radio is in low power mode. It cannot transmit or receive any
|
||||
frame.
|
||||
|
||||
##### Receive
|
||||
In this state the radio receives 802.15.4 frames. It filters out frames with
|
||||
invalid CRC, length, type, destination address.
|
||||
If the driver receives unicast frame destined to the receiving node it
|
||||
automatically transmits an ACK frame. According to 802.15.4 standard, an ACK
|
||||
frame should be delayed aTurnaroundTime (192 uS) after reception of the ACKed
|
||||
frame. To perform this delay the driver uses the TIFS timer in the radio
|
||||
peripheral. This timer requires 3 shorts to work correctly:
|
||||
1. END -> DISABLE
|
||||
2. DISABLE -> TXEN
|
||||
3. READY -> START
|
||||
The driver has limited time after receiving of a frame to decide if an ACK
|
||||
should be transmitted. If ACK should not be transmitted the driver must abort
|
||||
sending ACK by disabling those shorts and triggering DISABLE task.
|
||||
To use this limited time most effective the driver uses the Bit Counter feature
|
||||
of the radio peripheral to get notification when the Frame Control field is
|
||||
received and when the destination address is received. Those fields are used to
|
||||
filter the frame before whole frame is received.
|
||||
If all 3 shorts used to send ACK automatically are enabled the radio peripheral
|
||||
sends ACK frames in loop. To prevent this during debugging process there are
|
||||
only 2 shorts enabled when waiting for frame (1. and 2.) and 2 other shorts are
|
||||
enabled in DISABLED event handler (1. and 3.). The first short is still enabled
|
||||
to automatically disable transmitter after transmission of the ACK frame.
|
||||
|
||||
##### Transmit
|
||||
In this state the radio performs the CCA procedure. If channel is free the radio
|
||||
transmits requested frame. If an ACK was requested in the transmitted frame
|
||||
the driver automatically receives the ACK frame in this state.
|
||||
To prevent the TXIDLE peripheral state the driver uses 2 shorts in Transmit
|
||||
state:
|
||||
1. READY -> START
|
||||
2. END -> DISABLE
|
||||
Those shorts automatically start transmission of the frame when transmitter is
|
||||
ready and disable transmitter when the frame was transmitted.
|
||||
|
||||
##### Energy detection
|
||||
In this state the radio performs the Energy Detection procedure. During this
|
||||
procedure the radio is busy and cannot change state to any other. The end of
|
||||
this procedure is notified to the higher layer by a function call.
|
||||
|
||||
### Mutex and critical sections.
|
||||
|
||||
State transitions in the FSM can be requested simultaneously by the higher layer
|
||||
and the IRQ handler. To prevent race conditions in the driver there is a mutex.
|
||||
The mutex is unlocked only in the *Receive* state (*WaitingRxFrame* substate).
|
||||
If there is requested state transition, the procedure shall lock the mutex
|
||||
before state is changed. If mutex cannot be locked, another procedure has locked
|
||||
it and is going to change the state.
|
||||
The mutex is unlocked when the driver enters *Receive* state.
|
||||
|
||||
A race condition could also occur during handle of a requests from the higher
|
||||
layer. Even if the receiver is stopped (TASK STOP) the END or DISABLED event can
|
||||
be raised for a few uS after triggering the task. To prevent interrupt of the
|
||||
higher layer request handler by IRQ handler, the higher layer request handlers
|
||||
are performend in critical sections. The critical sections are implemented as
|
||||
software interrupt requests with priority equal to the RADIO IRQ.
|
||||
1649
ext/hal/nordic/drivers/nrf_drv_radio802154.c
Normal file
1649
ext/hal/nordic/drivers/nrf_drv_radio802154.c
Normal file
File diff suppressed because it is too large
Load Diff
348
ext/hal/nordic/drivers/nrf_drv_radio802154.h
Normal file
348
ext/hal/nordic/drivers/nrf_drv_radio802154.h
Normal file
@@ -0,0 +1,348 @@
|
||||
/* Copyright (c) 2016, Nordic Semiconductor ASA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This module contains generic 802.15.4 radio driver for nRF SoC devices.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NRF_RADIO802154_H_
|
||||
#define NRF_RADIO802154_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize 802.15.4 driver.
|
||||
*
|
||||
* @note This function shall be called once, before any other function from this module.
|
||||
*
|
||||
* Initialize radio peripheral to Sleep state.
|
||||
*/
|
||||
void nrf_drv_radio802154_init(void);
|
||||
|
||||
/**
|
||||
* @brief Get channel on which the radio operates right now.
|
||||
*/
|
||||
uint8_t nrf_drv_radio802154_channel_get(void);
|
||||
|
||||
/**
|
||||
* @section Setting addresses and Pan Id of this device.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set PAN Id used by this device.
|
||||
*
|
||||
* @param[in] p_pan_id Pointer to PAN Id (2 bytes, little-endian).
|
||||
*
|
||||
* This function makes copy of the PAN Id.
|
||||
*/
|
||||
void nrf_drv_radio802154_pan_id_set(const uint8_t *p_pan_id);
|
||||
|
||||
/**
|
||||
* @brief Set Extended Address of this device.
|
||||
*
|
||||
* @param[in] p_extended_address Pointer to extended address (8 bytes, little-endian).
|
||||
*
|
||||
* This function makes copy of the address.
|
||||
*/
|
||||
void nrf_drv_radio802154_extended_address_set(const uint8_t *p_extended_address);
|
||||
|
||||
/**
|
||||
* @brief Set Short Address of this device.
|
||||
*
|
||||
* @param[in] p_short_address Pointer to short address (2 bytes, little-endian).
|
||||
*
|
||||
* This function makes copy of the address.
|
||||
*/
|
||||
void nrf_drv_radio802154_short_address_set(const uint8_t *p_short_address);
|
||||
|
||||
|
||||
/**
|
||||
* @section Functions to request FSM transitions.
|
||||
*
|
||||
* receive() transmit()
|
||||
* --------> -------->
|
||||
* Sleep Receive Transmit
|
||||
* <-------- | /|\<--------
|
||||
* sleep() | | receive() / transmitted() / busy_channel()
|
||||
* | |
|
||||
* energy_detection() | | energy_detected()
|
||||
* \|/ |
|
||||
* Energy detection
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Change radio state to Sleep.
|
||||
*
|
||||
* @note This function should be called only if radio is in Receive state.
|
||||
*
|
||||
* Sleep state is the lowest power state. In this state radio cannot transmit or receive frames.
|
||||
*
|
||||
* @return true If the radio changes it's state to low power mode.
|
||||
* @return false If the driver could not schedule changing state.
|
||||
*/
|
||||
bool nrf_drv_radio802154_sleep(void);
|
||||
|
||||
/**
|
||||
* @brief Change radio state to Receive.
|
||||
*
|
||||
* @note This function should be called in Sleep or Transmit state.
|
||||
*
|
||||
* In Receive state radio receives frames and automatically sends ACK frames when appropriate.
|
||||
* Received frame is reported to higher layer by nrf_radio802154_received() call.
|
||||
*
|
||||
* @param[in] channel Channel number on which radio will receive.
|
||||
* @param[in] force_rx If set to true then function is allowed to stop an ongoing
|
||||
* operation. If set to false then the function will succeed
|
||||
* only when radio is in RX or SLEEP state.
|
||||
*
|
||||
* @return true If the reception procedure was scheduled.
|
||||
* @return false If the driver could not schedule the reception procedure.
|
||||
*/
|
||||
bool nrf_drv_radio802154_receive(uint8_t channel, bool force_rx);
|
||||
|
||||
/**
|
||||
* @brief Change radio state to Transmit.
|
||||
*
|
||||
* @note This function should be called in Receive state. In other states transmission will be
|
||||
* scheduled.
|
||||
*
|
||||
* In Transmit state radio transmits given frame. If requested it waits for ACK frame.
|
||||
* Radio driver wait infinitely for ACK frame. Higher layer is responsible to call
|
||||
* nrf_radio802154_receive() after ACK timeout.
|
||||
* Transmission result is reported to higher layer by nrf_radio802154_transmitted() or
|
||||
* nrf_radio802154_busy_channel() calls.
|
||||
*
|
||||
* @param[in] p_data Pointer to array containing data to transmit. First byte should contain
|
||||
* frame length and following bytes should contain data. CRC is computed
|
||||
* automatically by radio hardware and can contain any bytes.
|
||||
* @param[in] channel Channel number on which radio will transmit given frame.
|
||||
* @param[in] power Transmission power [dBm]. Given value is rounded up to nearest permitted
|
||||
* value.
|
||||
*
|
||||
* @return true If the transmission procedure was scheduled.
|
||||
* @return false If the driver could not schedule the transmission procedure.
|
||||
*/
|
||||
bool nrf_drv_radio802154_transmit(const uint8_t *p_data, uint8_t channel, int8_t power);
|
||||
|
||||
/**
|
||||
* @brief Change radio state to Energy Detection.
|
||||
*
|
||||
* @note This function should be called in Receive state. In other states energy detection
|
||||
* procedure will be scheduled.
|
||||
*
|
||||
* In Energy Detection state radio detects maximum energy for given time. Result of the detection
|
||||
* is reported to the higher layer by nrf_radio802154_energy_detected() call.
|
||||
*
|
||||
* @param[in] channel Channel number on which radio will detect energy.
|
||||
* @param[in] time_us Duration of energy detection procedure. Given value is rounded up to
|
||||
* multiplication of 10s (128 us).
|
||||
*
|
||||
* @return true If the energy detection procedure was scheduled.
|
||||
* @return false If the driver could not schedule the energy detection procedure.
|
||||
*/
|
||||
bool nrf_drv_radio802154_energy_detection(uint8_t channel, uint32_t time_us);
|
||||
|
||||
|
||||
/**
|
||||
* @section Calls to higher layer.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Notify that frame was received.
|
||||
*
|
||||
* @note Buffer pointed by the p_data pointer is not modified by the radio driver (and can't
|
||||
* be used to receive a frame) until nrf_drv_radio802154_buffer_free() function is called.
|
||||
* @note Buffer pointed by the p_data pointer may be modified by the function handler (and other
|
||||
* modules) until nrf_drv_radio802154_buffer_free() function is called.
|
||||
*
|
||||
* @param[in] p_data Pointer to buffer containing received data. First byte in the buffer is
|
||||
* length of the frame and following bytes is the frame itself (after PHR).
|
||||
* @param[in] power RSSI of received frame.
|
||||
* @param[in] lqi LQI of received frame.
|
||||
*/
|
||||
void nrf_drv_radio802154_received(uint8_t * p_data, int8_t power, int8_t lqi);
|
||||
|
||||
/**
|
||||
* @brief Notify that frame was transmitted.
|
||||
*
|
||||
* @note If ACK was requested for transmitted frame this function is called after proper ACK is
|
||||
* received. If ACK was not requested this function is called just after transmission is
|
||||
* ended.
|
||||
*
|
||||
* @param[in] pending_bit Value of pending bit in received ACK or false if ACK was not requested.
|
||||
*/
|
||||
void nrf_drv_radio802154_transmitted(bool pending_bit);
|
||||
|
||||
/**
|
||||
* @brief Notify that frame was not transmitted due to busy channel.
|
||||
*
|
||||
* This function is called if CCA procedure (performed just before transmission) fails.
|
||||
*/
|
||||
void nrf_drv_radio802154_busy_channel(void);
|
||||
|
||||
/**
|
||||
* @brief Notify that Energy Detection procedure finished.
|
||||
*
|
||||
* @param[in] result Maximum energy detected during Energy Detection procedure.
|
||||
*/
|
||||
void nrf_drv_radio802154_energy_detected(int8_t result);
|
||||
|
||||
|
||||
/**
|
||||
* @section Driver memory management
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Notify driver that buffer containing received frame is not used anymore.
|
||||
*
|
||||
* @note The buffer pointed by the @p p_data pointer may be modified by this function.
|
||||
*
|
||||
* @param[in] p_data A pointer to the buffer containing received data that is no more needed by
|
||||
* the higher layer.
|
||||
*/
|
||||
void nrf_drv_radio802154_buffer_free(uint8_t * p_data);
|
||||
|
||||
|
||||
/**
|
||||
* @section RSSI measurement function.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Begin RSSI measurement.
|
||||
*
|
||||
* @note This function should be called in Receive state.
|
||||
*
|
||||
* Begin RSSI measurement. The result will be available in 8 uS. The result can be read by
|
||||
* nrf_radio802154_rssi_last_get() function.
|
||||
*/
|
||||
void nrf_drv_radio802154_rssi_measure(void);
|
||||
|
||||
/**
|
||||
* @brief Get result of last RSSI measurement.
|
||||
*
|
||||
* @returns RSSI measurement result [dBm].
|
||||
*/
|
||||
int8_t nrf_drv_radio802154_rssi_last_get(void);
|
||||
|
||||
|
||||
/**
|
||||
* @section Promiscuous mode.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Enable or disable promiscuous radio mode.
|
||||
*
|
||||
* In promiscuous mode driver notifies higher layer that it received any frame (regardless
|
||||
* frame type or destination address).
|
||||
* In normal mode (not promiscuous) higher layer is not notified about ACK frames and frames with
|
||||
* unknown type. Also frames with destination address not matching this device address are ignored.
|
||||
*
|
||||
* @param[in] enabled If promiscuous mode should be enabled.
|
||||
*/
|
||||
void nrf_drv_radio802154_promiscuous_set(bool enabled);
|
||||
|
||||
/**
|
||||
* @brief Check if radio is in promiscuous mode.
|
||||
*
|
||||
* @retval True Radio is in promiscuous mode.
|
||||
* @retval False Radio is not in promiscuous mode.
|
||||
*/
|
||||
bool nrf_drv_radio802154_promiscuous_get(void);
|
||||
|
||||
|
||||
/**
|
||||
* @section Setting pending bit in automatically transmitted ACK frames.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Enable or disable setting pending bit in automatically transmitted ACK frames.
|
||||
*
|
||||
* Radio driver automatically sends ACK frames in response to unicast frames destined to this node.
|
||||
* Pending bit in ACK frame can be set or cleared regarding data in pending buffer destined to ACK
|
||||
* destination.
|
||||
*
|
||||
* If setting pending bit in ACK frames is disabled, pending bit in every ACK frame is set.
|
||||
* If setting pending bit in ACK frames is enabled, radio driver checks if there is data
|
||||
* in pending buffer destined to ACK destination. If there is no such data, pending bit is cleared.
|
||||
*
|
||||
* @note It is possible that if there is a lot of supported peers radio driver cannot verify
|
||||
* if there is pending data before ACK is sent. In this case pending bit is set.
|
||||
*
|
||||
* @param[in] enabled If setting pending bit in ACK frames is enabled.
|
||||
*/
|
||||
void nrf_drv_radio802154_auto_pending_bit_set(bool enabled);
|
||||
|
||||
/**
|
||||
* @brief Add address of peer node for which there is pending data in the buffer.
|
||||
*
|
||||
* @note This function makes a copy of given address.
|
||||
*
|
||||
* @param[in] p_addr Array of bytes containing address of the node (little-endian).
|
||||
* @param[in] extended If given address is Extended MAC Address or Short MAC Address.
|
||||
*
|
||||
* @retval True Address successfully added to the list.
|
||||
* @retval False There is not enough memory to store this address in the list.
|
||||
*/
|
||||
bool nrf_drv_radio802154_pending_bit_for_addr_set(const uint8_t *p_addr, bool extended);
|
||||
|
||||
/**
|
||||
* @brief Remove address of peer node for which there is no more pending data in the buffer.
|
||||
*
|
||||
* @param[in] p_addr Array of bytes containing address of the node (little-endian).
|
||||
* @param[in] extended If given address is Extended MAC Address or Short MAC Address.
|
||||
*
|
||||
* @retval True Address successfully removed from the list.
|
||||
* @retval False There is no such address in the list.
|
||||
*/
|
||||
bool nrf_drv_radio802154_pending_bit_for_addr_clear(const uint8_t *p_addr, bool extended);
|
||||
|
||||
/**
|
||||
* @brief Remove all addresses of given type from pending bit list.
|
||||
*
|
||||
* @param[in] extended If function should remove all Exnteded MAC Adresses of all Short Addresses.
|
||||
*/
|
||||
void nrf_drv_radio802154_pending_bit_for_addr_reset(bool extended);
|
||||
|
||||
/**
|
||||
* @brief Radio IRQ handler.
|
||||
*/
|
||||
void nrf_drv_radio802154_irq_handler(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NRF_RADIO802154_H_ */
|
||||
@@ -8,7 +8,8 @@ Microcontroller products. It currently supports the following SoCs:
|
||||
- Intel® Quark™ D2000 Microcontroller
|
||||
- Intel® Quark™ SE Microcontroller
|
||||
|
||||
The current version supported in Zephyr is QMSI 1.4 RC2. See:
|
||||
The current version supported in Zephyr is QMSI 1.4 Release Candidate 4.
|
||||
See:
|
||||
|
||||
https://github.com/quark-mcu/qmsi/releases
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Intel Corporation
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Intel Corporation
|
||||
* Copyright (c) 2017, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user