Compare commits
123 Commits
v2.2.0-rc3
...
v2.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bd062c258 | ||
|
|
d2160cbf4a | ||
|
|
9a3aa3c9c3 | ||
|
|
137ebbc43f | ||
|
|
a520506076 | ||
|
|
2758c33e39 | ||
|
|
2fa7a7e977 | ||
|
|
dbfc2ebc6b | ||
|
|
82083a90cc | ||
|
|
341681f312 | ||
|
|
3f4221db6f | ||
|
|
4d949eebef | ||
|
|
8e8ba2396c | ||
|
|
0e51f8bd79 | ||
|
|
3e91120f2b | ||
|
|
fb244f7542 | ||
|
|
f7ac49efe6 | ||
|
|
fce4c9e317 | ||
|
|
385f88242e | ||
|
|
4e8e72bd4c | ||
|
|
eee10e9aff | ||
|
|
b7e7153b95 | ||
|
|
525500123a | ||
|
|
ff39065ed4 | ||
|
|
1b253c2dba | ||
|
|
37c46e3cf5 | ||
|
|
c5f9a2d2bc | ||
|
|
7e4bcff791 | ||
|
|
ee4006e42e | ||
|
|
bec2a497b9 | ||
|
|
2295af0f05 | ||
|
|
8e12b42af2 | ||
|
|
a3c2a72c6c | ||
|
|
c2e829ba8c | ||
|
|
b83d9a5eea | ||
|
|
a69cdb31ca | ||
|
|
d39cb42d09 | ||
|
|
9d83a7cd27 | ||
|
|
9518bd19b7 | ||
|
|
883f1aede0 | ||
|
|
ee4a28e127 | ||
|
|
497fe4267a | ||
|
|
dad082d170 | ||
|
|
4a45ceaf62 | ||
|
|
e35f86aae6 | ||
|
|
a997a803a3 | ||
|
|
dfc276f1be | ||
|
|
abd8ca94c2 | ||
|
|
cea65cb9cc | ||
|
|
2cfb11e050 | ||
|
|
4c6ee8b3d9 | ||
|
|
be56e36fe4 | ||
|
|
287f654e68 | ||
|
|
d4f39742ea | ||
|
|
5f0650b596 | ||
|
|
bf8caf3956 | ||
|
|
6ec317b2de | ||
|
|
4b2fc256cf | ||
|
|
8ed4b62dc0 | ||
|
|
38a2e2cf89 | ||
|
|
a3d413c51a | ||
|
|
d6d42bef97 | ||
|
|
f669b7cb9f | ||
|
|
61fc061fc4 | ||
|
|
502b67ceba | ||
|
|
fe6107f2b3 | ||
|
|
c3701f51d7 | ||
|
|
7f2996b061 | ||
|
|
9aed7fb040 | ||
|
|
80ea034f7d | ||
|
|
bb42abdd7c | ||
|
|
6f3f3c230c | ||
|
|
a2872c3a00 | ||
|
|
c97e1aafb1 | ||
|
|
2835da8194 | ||
|
|
46330f13ed | ||
|
|
759c41ea3f | ||
|
|
4759da8819 | ||
|
|
8d5bb88aa7 | ||
|
|
345d4f51c1 | ||
|
|
f7564323f5 | ||
|
|
51f7fc8fba | ||
|
|
04e6045505 | ||
|
|
dc277a8733 | ||
|
|
47ea3c4e2c | ||
|
|
d63651dd01 | ||
|
|
180cbf1a00 | ||
|
|
748c7757ea | ||
|
|
cf2d474adf | ||
|
|
f80164525f | ||
|
|
67d8f755e2 | ||
|
|
d3957fb1f9 | ||
|
|
6147bd3168 | ||
|
|
340ead4239 | ||
|
|
18a744861f | ||
|
|
7e0f31e3e7 | ||
|
|
e609ad0c43 | ||
|
|
23ace0e556 | ||
|
|
c88155fd2d | ||
|
|
219d9fc082 | ||
|
|
e0318ff3ee | ||
|
|
de3c5ae9ff | ||
|
|
a95298e54a | ||
|
|
cfd0f3e18d | ||
|
|
491367115d | ||
|
|
0cc209d5b2 | ||
|
|
ea331fd03f | ||
|
|
e81a3ee8c2 | ||
|
|
e5ddc31f74 | ||
|
|
f2469ce576 | ||
|
|
24ce05c841 | ||
|
|
8a5063924c | ||
|
|
fbeaa0a510 | ||
|
|
18dee338d8 | ||
|
|
53431884c3 | ||
|
|
50a396720d | ||
|
|
8d645b4a8e | ||
|
|
0280e0a471 | ||
|
|
ede8f165af | ||
|
|
b3bb324735 | ||
|
|
177e075bb5 | ||
|
|
f39f762054 | ||
|
|
105849cf38 |
4
.github/workflows/doc-build.yml
vendored
4
.github/workflows/doc-build.yml
vendored
@@ -30,8 +30,8 @@ jobs:
|
||||
- name: install-pip
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install 'breathe>=4.9.1' 'docutils>=0.14' \
|
||||
'sphinx>=1.7.5' sphinx_rtd_theme sphinx-tabs \
|
||||
pip3 install 'breathe>=4.9.1,<4.15.0' 'docutils>=0.14' \
|
||||
'sphinx>=1.7.5,<3.0' sphinx_rtd_theme sphinx-tabs \
|
||||
sphinxcontrib-svg2pdfconverter 'west>=0.6.2'
|
||||
pip3 install pyelftools
|
||||
|
||||
|
||||
4
.github/workflows/doc-publish.yml
vendored
4
.github/workflows/doc-publish.yml
vendored
@@ -61,8 +61,8 @@ jobs:
|
||||
- name: install-pip
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install 'breathe>=4.9.1' 'docutils>=0.14' \
|
||||
'sphinx>=1.7.5' sphinx_rtd_theme sphinx-tabs \
|
||||
pip3 install 'breathe>=4.9.1,<4.15.0' 'docutils>=0.14' \
|
||||
'sphinx>=1.7.5,<3.0' sphinx_rtd_theme sphinx-tabs \
|
||||
sphinxcontrib-svg2pdfconverter 'west>=0.6.2'
|
||||
pip3 install pyelftools
|
||||
|
||||
|
||||
@@ -347,7 +347,7 @@
|
||||
/samples/ @nashif
|
||||
/samples/basic/minimal/ @carlescufi
|
||||
/samples/basic/servo_motor/*microbit* @jhe
|
||||
/lib/updatehub/ @chtavares592 @otavio
|
||||
/lib/updatehub/ @nandojve @otavio
|
||||
/samples/bluetooth/ @jhedberg @Vudentz @joerchan
|
||||
/samples/boards/intel_s1000_crb/ @sathishkuttan @dcpleung @nashif
|
||||
/samples/display/ @vanwinkeljan
|
||||
@@ -361,7 +361,7 @@
|
||||
/samples/net/mqtt_publisher/ @jukkar @tbursztyka
|
||||
/samples/net/sockets/coap_*/ @rveerama1
|
||||
/samples/net/sockets/ @jukkar @tbursztyka @pfalcon
|
||||
/samples/net/updatehub/ @chtavares592 @otavio
|
||||
/samples/net/updatehub/ @nandojve @otavio
|
||||
/samples/sensor/ @MaureenHelm
|
||||
/samples/shields/ @avisconti
|
||||
/samples/subsys/logging/ @nordic-krch @jakub-uC
|
||||
|
||||
4
VERSION
4
VERSION
@@ -1,5 +1,5 @@
|
||||
VERSION_MAJOR = 2
|
||||
VERSION_MINOR = 2
|
||||
PATCHLEVEL = 0
|
||||
PATCHLEVEL = 1
|
||||
VERSION_TWEAK = 0
|
||||
EXTRAVERSION = rc3
|
||||
EXTRAVERSION =
|
||||
|
||||
@@ -206,7 +206,7 @@ SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_trap)
|
||||
/* do sys_call */
|
||||
mov_s ilink, K_SYSCALL_LIMIT
|
||||
cmp r6, ilink
|
||||
blt valid_syscall_id
|
||||
blo valid_syscall_id
|
||||
|
||||
mov_s r0, r6
|
||||
mov_s r6, K_SYSCALL_BAD
|
||||
|
||||
@@ -16,7 +16,7 @@ config ARM_MPU
|
||||
MCU implements Memory Protection Unit.
|
||||
|
||||
Notes:
|
||||
The ARMv6-M and ARMv8-M MPU architecture requires a power-of-two
|
||||
The ARMv6-M and ARMv7-M MPU architecture requires a power-of-two
|
||||
alignment of MPU region base address and size.
|
||||
|
||||
The NXP MPU as well as the ARMv8-M MPU do not require MPU regions
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#define ZEPHYR_ARCH_ARM_CORE_AARCH32_CORTEX_M_MPU_ARM_MPU_V7_INTERNAL_H_
|
||||
|
||||
|
||||
#include <sys/math_extras.h>
|
||||
|
||||
#define LOG_LEVEL CONFIG_MPU_LOG_LEVEL
|
||||
#include <logging/log.h>
|
||||
|
||||
@@ -200,6 +202,7 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size)
|
||||
u32_t r_addr_start;
|
||||
u32_t r_size_lshift;
|
||||
u32_t r_addr_end;
|
||||
u32_t end;
|
||||
|
||||
/* Lock IRQs to ensure RNR value is correct when reading RBAR, RASR. */
|
||||
unsigned int key;
|
||||
@@ -216,7 +219,12 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size)
|
||||
MPU_RASR_SIZE_Pos) + 1;
|
||||
r_addr_end = r_addr_start + (1UL << r_size_lshift) - 1;
|
||||
|
||||
if (start >= r_addr_start && (start + size - 1) <= r_addr_end) {
|
||||
size = size == 0 ? 0 : size - 1;
|
||||
if (u32_add_overflow(start, size, &end)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((start >= r_addr_start) && (end <= r_addr_end)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <soc.h>
|
||||
#include "arm_core_mpu_dev.h"
|
||||
#include <sys/__assert.h>
|
||||
#include <sys/math_extras.h>
|
||||
#include <linker/linker-defs.h>
|
||||
|
||||
#define LOG_LEVEL CONFIG_MPU_LOG_LEVEL
|
||||
@@ -428,11 +429,17 @@ static inline int is_in_region(u32_t r_index, u32_t start, u32_t size)
|
||||
{
|
||||
u32_t r_addr_start;
|
||||
u32_t r_addr_end;
|
||||
u32_t end;
|
||||
|
||||
r_addr_start = SYSMPU->WORD[r_index][0];
|
||||
r_addr_end = SYSMPU->WORD[r_index][1];
|
||||
|
||||
if (start >= r_addr_start && (start + size - 1) <= r_addr_end) {
|
||||
size = size == 0 ? 0 : size - 1;
|
||||
if (u32_add_overflow(start, size, &end)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((start >= r_addr_start) && (end <= r_addr_end)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -508,7 +508,10 @@ _do_syscall:
|
||||
ldr ip, =K_SYSCALL_LIMIT
|
||||
cmp r6, ip
|
||||
#endif
|
||||
blt valid_syscall_id
|
||||
/* The supplied syscall_id must be lower than the limit
|
||||
* (Requires unsigned integer comparison)
|
||||
*/
|
||||
blo valid_syscall_id
|
||||
|
||||
/* bad syscall id. Set arg1 to bad id and set call_id to SYSCALL_BAD */
|
||||
str r6, [r0]
|
||||
|
||||
@@ -11,3 +11,4 @@ CONFIG_SERIAL=y
|
||||
CONFIG_UART_SAM=y
|
||||
CONFIG_UART_SAM_PORT_0=y
|
||||
CONFIG_SOC_ATMEL_SAM3X_EXT_MAINCK=y
|
||||
CONFIG_WDT_DISABLE_AT_BOOT=y
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
compatible = "atmel,rf2xx";
|
||||
reg = <0x0>;
|
||||
label = "RF2XX_0";
|
||||
spi-max-frequency = <8000000>;
|
||||
spi-max-frequency = <6000000>;
|
||||
irq-gpios = <&portb 0 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>;
|
||||
reset-gpios = <&portb 15 GPIO_ACTIVE_LOW>;
|
||||
slptr-gpios = <&porta 20 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
board_runner_args(pyocd "--target=stm32g474retx")
|
||||
|
||||
# use target=stm32g474rbtx instead of stm32g474retx
|
||||
# to allow board re-flashing (see PR #23230)
|
||||
board_runner_args(pyocd "--target=stm32g474rbtx")
|
||||
|
||||
include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake)
|
||||
|
||||
@@ -6,8 +6,8 @@ toolchain:
|
||||
- zephyr
|
||||
- gnuarmemb
|
||||
- xtools
|
||||
ram: 32
|
||||
flash: 128
|
||||
ram: 128
|
||||
flash: 512
|
||||
supported:
|
||||
- arduino_gpio
|
||||
- arduino_i2c
|
||||
|
||||
@@ -12,3 +12,4 @@ CONFIG_BOARD_SAM4E_XPRO=y
|
||||
CONFIG_SOC_ATMEL_SAM4E_EXT_MAINCK=y
|
||||
CONFIG_GPIO_SAM=y
|
||||
CONFIG_GPIO=y
|
||||
CONFIG_WDT_DISABLE_AT_BOOT=y
|
||||
|
||||
@@ -11,3 +11,4 @@ CONFIG_UART_SAM_PORT_0=y
|
||||
CONFIG_BOARD_SAM4S_XPLAINED=y
|
||||
CONFIG_SOC_ATMEL_SAM4S_EXT_MAINCK=y
|
||||
CONFIG_GPIO=y
|
||||
CONFIG_WDT_DISABLE_AT_BOOT=y
|
||||
|
||||
@@ -13,4 +13,5 @@ CONFIG_SERIAL=y
|
||||
CONFIG_USART_SAM=y
|
||||
CONFIG_USART_SAM_PORT_1=y
|
||||
CONFIG_BOARD_SAM_E70_XPLAINED=y
|
||||
CONFIG_WDT_DISABLE_AT_BOOT=y
|
||||
CONFIG_BUILD_OUTPUT_HEX=y
|
||||
|
||||
@@ -12,3 +12,4 @@ CONFIG_UART_CONSOLE=y
|
||||
CONFIG_SERIAL=y
|
||||
CONFIG_USART_SAM=y
|
||||
CONFIG_USART_SAM_PORT_1=y
|
||||
CONFIG_WDT_DISABLE_AT_BOOT=y
|
||||
|
||||
@@ -527,12 +527,10 @@ html_context = {
|
||||
'theme_logo_only': False,
|
||||
'current_version': version,
|
||||
'versions': (("latest", "/"),
|
||||
("2.2.0", "/2.2.0/"),
|
||||
("2.1.0", "/2.1.0/"),
|
||||
("2.0.0", "/2.0.0/"),
|
||||
("1.14.1", "/1.14.1/"),
|
||||
("1.13.0", "/1.13.0/"),
|
||||
("1.12.0", "/1.12.0/"),
|
||||
("1.11.0", "/1.11.0/"),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -239,7 +239,9 @@ steps:
|
||||
|
||||
Tagging needs to be done via explicit git commands and not via GitHub's release
|
||||
interface. The GitHub release interface does not generate annotated tags (it
|
||||
generates 'lightweight' tags regardless of release or pre-release).
|
||||
generates 'lightweight' tags regardless of release or pre-release). You should
|
||||
also upload your gpg public key to your GitHub account, since the instructions
|
||||
below involve creating signed tags.
|
||||
|
||||
.. tabs::
|
||||
|
||||
@@ -263,8 +265,7 @@ steps:
|
||||
#. Tag and push the version, using an annotated tag::
|
||||
|
||||
$ git pull
|
||||
$ git tag -a v1.11.0-rc1
|
||||
<Use "Zephyr 1.11.0-rc1" as the tag annotation>
|
||||
$ git tag -m "Zephyr 1.11.0-rc1" -s v1.11.0-rc1
|
||||
$ git push git@github.com:zephyrproject-rtos/zephyr.git v1.11.0-rc1
|
||||
|
||||
#. Create a shortlog of changes between the previous release (use
|
||||
@@ -273,7 +274,7 @@ steps:
|
||||
$ git shortlog v1.10.0..v1.11.0-rc1
|
||||
|
||||
#. Find the new tag at the top of the releases page and edit the release
|
||||
with the ``Edit`` button with the following:
|
||||
with the ``Draft a new release`` button with the following:
|
||||
|
||||
* Name it ``Zephyr 1.11.0-rc1``
|
||||
* Copy the shortlog into the release notes textbox (*don't forget
|
||||
@@ -306,16 +307,14 @@ steps:
|
||||
#. Tag and push the version, using two annotated tags::
|
||||
|
||||
$ git pull
|
||||
$ git tag -a v1.11.0
|
||||
<Use "Zephyr 1.11.0" as the tag annotation>
|
||||
$ git tag -m "Zephyr 1.11.0" -s v1.11.0
|
||||
$ git push git@github.com:zephyrproject-rtos/zephyr.git v1.11.0
|
||||
|
||||
$ git tag -a zephyr-v1.11.0
|
||||
<Use "Zephyr 1.11.0" as the tag annotation>
|
||||
$ git tag -m "Zephyr 1.11.0" -s zephyr-v1.11.0
|
||||
$ git push git@github.com:zephyrproject-rtos/zephyr.git zephyr-v1.11.0
|
||||
|
||||
#. Find the new tag at the top of the releases page and edit the release
|
||||
with the ``Edit`` button with the following:
|
||||
with the ``Draft a new release`` button with the following:
|
||||
|
||||
* Name it ``Zephyr 1.11.0``
|
||||
* Copy the full content of ``docs/releases/release-notes-1.11.rst``
|
||||
|
||||
@@ -42,7 +42,7 @@ tools. First, make sure your development system OS is updated:
|
||||
|
||||
.. group-tab:: macOS
|
||||
|
||||
On macOS Mojave, you can manually check for updates by choosing
|
||||
On macOS Mojave or later, you can manually check for updates by choosing
|
||||
System Preferences from the Apple menu, then clicking Software Update (and
|
||||
click Update Now if there are). For other macOS versions, see the
|
||||
`Update macOS topic in Apple support
|
||||
@@ -306,15 +306,15 @@ including: compiler, assembler, linker, and their dependencies.
|
||||
.. code-block:: bash
|
||||
|
||||
cd ~
|
||||
wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.11.1/zephyr-sdk-0.11.1-setup.run
|
||||
wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.11.2/zephyr-sdk-0.11.2-setup.run
|
||||
|
||||
#. Run the installation binary, installing the SDK in your home
|
||||
folder :file:`~/zephyr-sdk-0.11.1`:
|
||||
folder :file:`~/zephyr-sdk-0.11.2`:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
chmod +x zephyr-sdk-0.11.1-setup.run
|
||||
./zephyr-sdk-0.11.1-setup.run -- -d ~/zephyr-sdk-0.11.1
|
||||
chmod +x zephyr-sdk-0.11.2-setup.run
|
||||
./zephyr-sdk-0.11.2-setup.run -- -d ~/zephyr-sdk-0.11.2
|
||||
|
||||
#. Set environment variables to let the build system know where to
|
||||
find the toolchain programs:
|
||||
@@ -322,7 +322,7 @@ including: compiler, assembler, linker, and their dependencies.
|
||||
.. code-block:: bash
|
||||
|
||||
export ZEPHYR_TOOLCHAIN_VARIANT=zephyr
|
||||
export ZEPHYR_SDK_INSTALL_DIR=~/zephyr-sdk-0.11.1
|
||||
export ZEPHYR_SDK_INSTALL_DIR=~/zephyr-sdk-0.11.2
|
||||
|
||||
The SDK contains a udev rules file that provides information
|
||||
needed to identify boards and grant hardware access permission to flash
|
||||
@@ -361,6 +361,12 @@ The sample :ref:`blinky-sample` blinks an LED on the target board. By
|
||||
building and running it, we can verify that the environment and tools
|
||||
are properly set up for Zephyr development.
|
||||
|
||||
.. note:: This sample is compatible with most boards supported by
|
||||
Zephyr, but not all of them. See the :ref:`blinky sample requirements
|
||||
<blinky-sample-requirements>` for more information. If this sample is not
|
||||
compatible with your board, a good alternative to try is the
|
||||
:ref:`Hello World sample <hello_world>`.
|
||||
|
||||
#. Set build environment variables:
|
||||
|
||||
.. tabs::
|
||||
|
||||
@@ -237,19 +237,19 @@ Follow these steps to install the Zephyr SDK:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.11.1/zephyr-sdk-0.11.1-setup.run
|
||||
wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.11.2/zephyr-sdk-0.11.2-setup.run
|
||||
|
||||
(You can change *0.11.1* to another version if needed; the `Zephyr
|
||||
(You can change *0.11.2* to another version if needed; the `Zephyr
|
||||
Downloads`_ page contains all available SDK releases.)
|
||||
|
||||
#. Run the installation binary, installing the SDK at
|
||||
:file:`~/zephyr-sdk-0.11.1`:
|
||||
:file:`~/zephyr-sdk-0.11.2`:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
cd <sdk download directory>
|
||||
chmod +x zephyr-sdk-0.11.1-setup.run
|
||||
./zephyr-sdk-0.11.1-setup.run -- -d ~/zephyr-sdk-0.11.1
|
||||
chmod +x zephyr-sdk-0.11.2-setup.run
|
||||
./zephyr-sdk-0.11.2-setup.run -- -d ~/zephyr-sdk-0.11.2
|
||||
|
||||
You can pick another directory if you want. If this fails, make sure
|
||||
Zephyr's dependencies were installed as described in `Install Requirements
|
||||
@@ -258,7 +258,7 @@ Follow these steps to install the Zephyr SDK:
|
||||
#. Set these :ref:`environment variables <env_vars>`:
|
||||
|
||||
- set :envvar:`ZEPHYR_TOOLCHAIN_VARIANT` to ``zephyr``
|
||||
- set :envvar:`ZEPHYR_SDK_INSTALL_DIR` to :file:`$HOME/zephyr-sdk-0.11.1`
|
||||
- set :envvar:`ZEPHYR_SDK_INSTALL_DIR` to :file:`$HOME/zephyr-sdk-0.11.2`
|
||||
(or wherever you chose to install the SDK)
|
||||
|
||||
If you ever want to uninstall the SDK, just remove the directory where you
|
||||
|
||||
@@ -1,54 +1,40 @@
|
||||
.. _installing_zephyr_mac:
|
||||
.. _mac-setup-alts:
|
||||
|
||||
Install macOS Host Dependencies
|
||||
###############################
|
||||
macOS alternative setup instructions
|
||||
####################################
|
||||
|
||||
This section describes how to set up a Zephyr development environment on macOS.
|
||||
.. _mac-gatekeeper:
|
||||
|
||||
These instructions have been tested on the following macOS versions:
|
||||
Important note about Gatekeeper
|
||||
*******************************
|
||||
|
||||
* Mac OS X 10.11 (El Capitan)
|
||||
* macOS Sierra 10.12
|
||||
Starting with macOS 10.15 Catalina, applications launched from the macOS
|
||||
Terminal application (or any other terminal emulator) are subject to the same
|
||||
system security policies that are applied to applications launched from the
|
||||
Dock. This means that if you download executable binaries using a web browser,
|
||||
macOS will not let you execute those from the Terminal by default. In order to
|
||||
get around this issue you can take two different approaches:
|
||||
|
||||
Update Your Operating System
|
||||
****************************
|
||||
* Run ``xattr -r -d com.apple.quarantine /path/to/folder`` where
|
||||
``path/to/folder`` is the path to the enclosing folder where the executables
|
||||
you want to run are located.
|
||||
|
||||
Before proceeding with the build, ensure your OS is up to date.
|
||||
* Open "System Preferences" -> "Security and Privacy" -> "Privacy" and then
|
||||
scroll down to "Developer Tools". Then unlock the lock to be able to make
|
||||
changes and check the checkbox corresponding to your terminal emulator of
|
||||
choice. This will apply to any executable being launched from such terminal
|
||||
program.
|
||||
|
||||
.. _mac_requirements:
|
||||
Note that this section does **not** apply to executables installed with
|
||||
Homebrew, since those are automatically un-quarantined by ``brew`` itself. This
|
||||
is however relevant for most :ref:`third_party_x_compilers`.
|
||||
|
||||
Install Requirements and Dependencies
|
||||
*************************************
|
||||
|
||||
.. NOTE FOR DOCS AUTHORS: DO NOT PUT DOCUMENTATION BUILD DEPENDENCIES HERE.
|
||||
|
||||
This section is for dependencies to build Zephyr binaries, *NOT* this
|
||||
documentation. If you need to add a dependency only required for building
|
||||
the docs, add it to doc/README.rst. (This change was made following the
|
||||
introduction of LaTeX->PDF support for the docs, as the texlive footprint is
|
||||
massive and not needed by users not building PDF documentation.)
|
||||
|
||||
Zephyr requires Python 3, while macOS only provides a Python 2
|
||||
installation. After following these instructions, the version of Python 2
|
||||
provided by macOS in ``/usr/bin/`` will sit alongside the Python 3 installation
|
||||
from Homebrew in ``/usr/local/bin``.
|
||||
|
||||
First, install :program:`Homebrew` by following instructions on the `Homebrew
|
||||
site`_. Homebrew is a free and open-source package management system that
|
||||
simplifies the installation of software on macOS. While installing Homebrew,
|
||||
you may be prompted to install additional missing dependencies; please follow
|
||||
any such instructions as well.
|
||||
|
||||
Now install these host dependencies with the ``brew`` command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
brew install cmake ninja gperf ccache dfu-util qemu dtc python3
|
||||
|
||||
.. _Homebrew site: https://brew.sh/
|
||||
.. _macOS Gatekeeper: https://en.wikipedia.org/wiki/Gatekeeper_(macOS)
|
||||
|
||||
Additional notes for MacPorts users
|
||||
***********************************
|
||||
|
||||
While MacPorts is not officially supported in this guide, it is possible to use MacPorts instead of Homebrew to get all the required dependencies on macOS.
|
||||
Note also that you may need to install ``rust`` and ``cargo`` for the Python dependencies to install correctly.
|
||||
While MacPorts is not officially supported in this guide, it is possible to use
|
||||
MacPorts instead of Homebrew to get all the required dependencies on macOS.
|
||||
Note also that you may need to install ``rust`` and ``cargo`` for the Python
|
||||
dependencies to install correctly.
|
||||
|
||||
@@ -1,106 +1,12 @@
|
||||
.. _installing_zephyr_win:
|
||||
.. _win-setup-alts:
|
||||
|
||||
Install Windows Host Dependencies
|
||||
#################################
|
||||
Windows alternative setup instructions
|
||||
######################################
|
||||
|
||||
This guide was tested on Windows versions 7, 8.1, and 10.
|
||||
.. _win-wsl:
|
||||
|
||||
Update Your Operating System
|
||||
****************************
|
||||
|
||||
Before proceeding with the build, ensure that you are running your
|
||||
Windows system with the latest updates installed.
|
||||
|
||||
.. _windows_requirements:
|
||||
|
||||
Install Requirements and Dependencies
|
||||
*************************************
|
||||
|
||||
.. NOTE FOR DOCS AUTHORS: DO NOT PUT DOCUMENTATION BUILD DEPENDENCIES HERE.
|
||||
|
||||
This section is for dependencies to build Zephyr binaries, *NOT* this
|
||||
documentation. If you need to add a dependency only required for building
|
||||
the docs, add it to doc/README.rst. (This change was made following the
|
||||
introduction of LaTeX->PDF support for the docs, as the texlive footprint is
|
||||
massive and not needed by users not building PDF documentation.)
|
||||
|
||||
There are 2 different ways of developing for Zephyr on Microsoft Windows:
|
||||
|
||||
#. :ref:`windows_install_native` (recommended)
|
||||
#. :ref:`windows_install_wsl`
|
||||
|
||||
The first option is fully Windows native; the other requires emulation layers
|
||||
that may result in slower build times.
|
||||
|
||||
.. _windows_install_native:
|
||||
|
||||
Option 1: Windows Command Prompt
|
||||
================================
|
||||
|
||||
These instructions assume you are using the ``cmd.exe`` command prompt. Some of
|
||||
the details, such as setting environment variables, may differ if you are using
|
||||
PowerShell.
|
||||
|
||||
The easiest way to install the native Windows dependencies is to first install
|
||||
`Chocolatey`_, a package manager for Windows. If you prefer to install
|
||||
dependencies manually, you can also download the required programs from their
|
||||
respective websites.
|
||||
|
||||
.. note::
|
||||
Chocolatey will properly set up your environment so tools can be
|
||||
found on your PATH. If you install programs manually, be sure to
|
||||
verify the programs can also be found on your PATH. For example,
|
||||
you may need to add ``C:\\Program Files\Git\bin`` after manually
|
||||
installing Git for Windows.
|
||||
|
||||
.. note::
|
||||
There are multiple ``set`` statements in this tutorial. You can avoid
|
||||
typing them every time by placing them inside a ``.cmd`` file and
|
||||
running that every time you open a command prompt.
|
||||
|
||||
#. If you're behind a corporate firewall, you'll likely need to specify a
|
||||
proxy to get access to internet resources:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
set HTTP_PROXY=http://user:password@proxy.mycompany.com:1234
|
||||
set HTTPS_PROXY=http://user:password@proxy.mycompany.com:1234
|
||||
|
||||
#. Install :program:`Chocolatey` by following the instructions on the
|
||||
`Chocolatey install`_ page.
|
||||
|
||||
#. Open a command prompt (``cmd.exe``) as an **Administrator** (press the
|
||||
Windows key, type "cmd.exe" in the prompt, then right-click the result and
|
||||
choose "Run as Administrator").
|
||||
|
||||
#. Optionally disable global confirmation to avoid having to confirm
|
||||
installation of individual programs:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
choco feature enable -n allowGlobalConfirmation
|
||||
|
||||
#. Install CMake:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System'
|
||||
|
||||
#. Install the rest of the tools:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
choco install git python ninja dtc-msys2 gperf
|
||||
|
||||
#. Close the Administrator command prompt window.
|
||||
|
||||
.. NOTE FOR DOCS AUTHORS: as a reminder, do *NOT* put dependencies for building
|
||||
the documentation itself here.
|
||||
|
||||
.. _windows_install_wsl:
|
||||
|
||||
Option 2: Windows 10 WSL (Windows Subsystem for Linux)
|
||||
======================================================
|
||||
Windows 10 WSL (Windows Subsystem for Linux)
|
||||
********************************************
|
||||
|
||||
If you are running a recent version of Windows 10 you can make use of the
|
||||
built-in functionality to natively run Ubuntu binaries directly on a standard
|
||||
@@ -126,7 +32,5 @@ command-prompt. This allows you to use software such as the :ref:`Zephyr SDK
|
||||
.. NOTE FOR DOCS AUTHORS: as a reminder, do *NOT* put dependencies for building
|
||||
the documentation itself here.
|
||||
|
||||
.. _Chocolatey: https://chocolatey.org/
|
||||
.. _Chocolatey install: https://chocolatey.org/install
|
||||
.. _Install the Windows Subsystem for Linux (WSL): https://msdn.microsoft.com/en-us/commandline/wsl/install_guide
|
||||
.. _Zephyr Issue 10420: https://github.com/zephyrproject-rtos/zephyr/issues/10420
|
||||
|
||||
@@ -22,9 +22,9 @@ GNU ARM Embedded
|
||||
|
||||
.. warning::
|
||||
|
||||
The GNU ARM Embedded Toolchain for Windows, version **8-2018-q4-major**
|
||||
has a `critical bug <https://github.com/zephyrproject-rtos/zephyr/issues/12257>`_
|
||||
and should not be used. Toolchain version **7-2018-q2-update** is known to work.
|
||||
On macOS Catalina or later you might need to :ref:`change a security
|
||||
policy <mac-gatekeeper>` for the toolchain to be able to run from the
|
||||
terminal.
|
||||
|
||||
#. :ref:`Set these environment variables <env_vars>`:
|
||||
|
||||
|
||||
@@ -65,6 +65,9 @@ Glossary of Terms
|
||||
The set of Zephyr-supplied files that implement the Zephyr kernel,
|
||||
including its core services, device drivers, network stack, and so on.
|
||||
|
||||
SoC
|
||||
`System on a chip`_
|
||||
|
||||
west
|
||||
A multi-repo meta-tool developed for the Zephyr project. See :ref:`west`.
|
||||
|
||||
@@ -92,3 +95,5 @@ Glossary of Terms
|
||||
(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.
|
||||
|
||||
.. _System on a chip: https://en.wikipedia.org/wiki/System_on_a_chip
|
||||
|
||||
@@ -271,6 +271,8 @@ reg
|
||||
``reg = <0x40003000 0x1000>;`` means the register map occupies 0x1000 bytes
|
||||
in the memory map.
|
||||
|
||||
.. _devicetree-in-out-files:
|
||||
|
||||
Input and output files
|
||||
**********************
|
||||
|
||||
|
||||
@@ -3,40 +3,26 @@
|
||||
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.
|
||||
To add Zephyr support for a new :term:`board`, you at least need a *board
|
||||
directory* with various files in it. Files in the board directory inherit
|
||||
support for at least one SoC and all of its features. Therefore, Zephyr must
|
||||
support your :term:`SoC` as well.
|
||||
|
||||
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.
|
||||
Boards, SoCs, etc.
|
||||
******************
|
||||
|
||||
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.
|
||||
Zephyr's hardware support hierarchy has these layers, from most to least
|
||||
specific:
|
||||
|
||||
Hardware Configuration Hierarchy
|
||||
********************************
|
||||
- Board: a particular CPU instance and its peripherals in a concrete hardware
|
||||
specification
|
||||
- SoC: the exact system on a chip the board's CPU is part of
|
||||
- SoC series: a smaller group of tightly related SoCs
|
||||
- SoC family: a wider group of SoCs with similar characteristics
|
||||
- CPU core: a particular CPU in an architecture
|
||||
- Architecture: an instruction set architecture
|
||||
|
||||
Hardware definitions in Zephyr follow a well-defined hierarchy of configurations
|
||||
and layers, below are the layers 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:
|
||||
You can visualize the hierarchy like this:
|
||||
|
||||
.. figure:: board/hierarchy.png
|
||||
:width: 500px
|
||||
@@ -45,131 +31,429 @@ available in the source tree:
|
||||
|
||||
Configuration Hierarchy
|
||||
|
||||
Here are some examples. Notice how the SoC series and family levels are
|
||||
not always used.
|
||||
|
||||
Hierarchy Example
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
+------------+-----------+--------------+------------+--------------+---------+
|
||||
|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 |Lakemont |Lakemont |
|
||||
+------------+-----------+--------------+------------+--------------+---------+
|
||||
|Architecture|ARM |ARM |ARM |x86 |x86 |
|
||||
+------------+-----------+--------------+------------+--------------+---------+
|
||||
* - Board
|
||||
- SoC
|
||||
- SoC series
|
||||
- SoC family
|
||||
- CPU core
|
||||
- Architecture
|
||||
* - :ref:`nrf52_pca10040 <nrf52_pca10040>`
|
||||
- nRF52832
|
||||
- nRF52
|
||||
- Nordic nRF5
|
||||
- Arm Cortex-M4
|
||||
- Arm
|
||||
* - :ref:`frdm_k64f <frdm_k64f>`
|
||||
- MK64F12
|
||||
- Kinetis K6x
|
||||
- NXP Kinetis
|
||||
- Arm Cortex-M4
|
||||
- Arm
|
||||
* - :ref:`stm32h474i_disco <stm32h747i_disco_board>`
|
||||
- STM32H747XI
|
||||
- STM32H7
|
||||
- STMicro STM32
|
||||
- Arm Cortex-M7
|
||||
- Arm
|
||||
* - :ref:`rv32m1_vega_ri5cy <rv32m1_vega>`
|
||||
- RV32M1
|
||||
- (Not used)
|
||||
- (Not used)
|
||||
- RI5CY
|
||||
- RISC-V
|
||||
|
||||
Make sure your SoC is supported
|
||||
*******************************
|
||||
|
||||
Start by making sure your SoC is supported by Zephyr. If it is, it's time to
|
||||
:ref:`create-your-board-directory`. If you don't know, try:
|
||||
|
||||
- checking :ref:`boards` for names that look relevant, and reading individual
|
||||
board documentation to find out for sure.
|
||||
- asking your SoC vendor
|
||||
|
||||
If you need to add SoC, CPU core, or even architecture support, this is the
|
||||
wrong page, but here is some general advice.
|
||||
|
||||
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`.
|
||||
|
||||
See :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.
|
||||
CPU core support files go in ``core`` subdirectories under :zephyr_file:`arch`,
|
||||
e.g. :zephyr_file:`arch/x86/core`.
|
||||
|
||||
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 feature set that serves the purpose of distinguishing different
|
||||
SoCs belonging to the same family.
|
||||
See :ref:`gs_toolchain` for information about toolchains (compiler, linker,
|
||||
etc.) supported by Zephyr. If you need to support a new toolchain,
|
||||
:ref:`build_overview` is a good place to start learning about the build system.
|
||||
Please reach out to the community if you are looking for advice or want to
|
||||
collaborate on toolchain support.
|
||||
|
||||
SoC
|
||||
---
|
||||
===
|
||||
|
||||
Finally, an SoC is actual hardware component that is physically available on a
|
||||
board.
|
||||
Zephyr SoC support files are in architecture-specific subdirectories of
|
||||
:zephyr_file:`soc`. They are generally grouped by SoC family.
|
||||
|
||||
Board
|
||||
=====
|
||||
When adding a new SoC family or series for a vendor that already has SoC
|
||||
support within Zephyr, please try to extract common functionality into shared
|
||||
files to avoid duplication. If there is no support for your vendor yet, you can
|
||||
add it in a new directory ``zephyr/soc/<YOUR-ARCH>/<YOUR-SOC>``; please use
|
||||
self-explanatory directory names.
|
||||
|
||||
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.
|
||||
.. _create-your-board-directory:
|
||||
|
||||
A board port on Zephyr typically consists of two parts:
|
||||
Create your board directory
|
||||
***************************
|
||||
|
||||
- A hardware description (usually done by device tree), which specifies embedded
|
||||
SoC reference, connectors and any other hardware components such as LEDs,
|
||||
buttons, sensors or communication peripherals (USB, BLE controller, ...).
|
||||
Once you've found an existing board that uses your SoC, you can usually start
|
||||
by copy/pasting its board directory and changing its contents for your
|
||||
hardware.
|
||||
|
||||
- A software configuration (done using Kconfig) of features and peripheral
|
||||
drivers. This default board configuration is subordinated to features
|
||||
activation which is application responsibility. Though, it should also enable
|
||||
a minimal set of features common to many applications and to applicable
|
||||
project-provided :ref:`samples-and-demos`.
|
||||
You need to give your board a unique name. Run ``west boards`` for a list of
|
||||
names that are already taken, and pick something new. Let's say your board is
|
||||
called ``plank`` (please don't actually use that name).
|
||||
|
||||
Start by creating the board directory ``zephyr/boards/<ARCH>/plank``, where
|
||||
``<ARCH>`` is your SoC's architecture subdirectory. (You don't have to put your
|
||||
board directory in the zephyr repository, but it's the easiest way to get
|
||||
started. See :ref:`custom_board_definition` for documentation on moving your
|
||||
board directory to a separate repository once it's working.)
|
||||
|
||||
Your board directory should look like this:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
boards/<ARCH>/plank
|
||||
├── board.cmake
|
||||
├── CMakeLists.txt
|
||||
├── doc
|
||||
│ ├── plank.png
|
||||
│ └── index.rst
|
||||
├── Kconfig.board
|
||||
├── Kconfig.defconfig
|
||||
├── plank_defconfig
|
||||
├── plank.dts
|
||||
└── plank.yaml
|
||||
|
||||
Replace ``plank`` with your board's name, of course.
|
||||
|
||||
The mandatory files are:
|
||||
|
||||
#. :file:`plank.dts`: a hardware description in :ref:`devicetree` format. This
|
||||
declares your SoC, connectors, and any other hardware components such as
|
||||
LEDs, buttons, sensors, or communication peripherals (USB, BLE controller,
|
||||
etc).
|
||||
|
||||
#. :file:`Kconfig.board`, :file:`Kconfig.defconfig`, :file:`plank_defconfig`:
|
||||
software configuration in :ref:`kconfig` formats. This provides default
|
||||
settings for software features and peripheral drivers.
|
||||
|
||||
The optional files are:
|
||||
|
||||
- :file:`board.cmake`: used for :ref:`flash-and-debug-support`
|
||||
- :file:`CMakeLists.txt`: if you need to add additional source files to
|
||||
your build.
|
||||
|
||||
One common use for this file is to add a :file:`pinmux.c` file in your board
|
||||
directory to the build, which configures pin controllers at boot time. In
|
||||
that case, :file:`CMakeLists.txt` usually looks like this:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
if(CONFIG_PINMUX)
|
||||
zephyr_library()
|
||||
zephyr_library_sources(pinmux.c)
|
||||
zephyr_library_include_directories(${ZEPHYR_BASE}/drivers)
|
||||
endif()
|
||||
|
||||
- :file:`doc/index.rst`, :file:`doc/plank.png`: documentation for and a picture
|
||||
of your board. You only need this if you're :ref:`contributing-your-board` to
|
||||
Zephyr.
|
||||
- :file:`plank.yaml`: a YAML file with miscellaneous metadata used by the
|
||||
:ref:`sanitycheck_script`.
|
||||
|
||||
.. _default_board_configuration:
|
||||
|
||||
Default board configuration
|
||||
***************************
|
||||
Write your devicetree
|
||||
*********************
|
||||
|
||||
When porting Zephyr to a board, you must provide the board's default
|
||||
Kconfig configuration, which is used in application builds unless explicitly
|
||||
overridden.
|
||||
The devicetree file :file:`boards/<ARCH>/plank/plank.dts` describes your board
|
||||
hardware in the Devicetree Source (DTS) format (as usual, change ``plank`` to
|
||||
your board's name). If you're new to devicetree, see :ref:`devicetree-intro`.
|
||||
|
||||
In general, :file:`plank.dts` should look like this:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
/dts-v1/;
|
||||
#include <your_soc_vendor/your_soc.dtsi>
|
||||
|
||||
/ {
|
||||
model = "A human readable name";
|
||||
compatible = "yourcompany,plank";
|
||||
|
||||
chosen {
|
||||
zephyr,console = &your_uart_console;
|
||||
zephyr,sram = &your_memory_node;
|
||||
/* other chosen settings for your hardware */
|
||||
};
|
||||
|
||||
/*
|
||||
* Your board-specific hardware: buttons, LEDs, sensors, etc.
|
||||
*/
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
led0: led_0 {
|
||||
gpios = < /* GPIO your LED is hooked up to */ >;
|
||||
label = "LED 0";
|
||||
};
|
||||
/* ... other LEDs ... */
|
||||
};
|
||||
|
||||
buttons {
|
||||
compatible = "gpio-keys";
|
||||
/* ... your button definitions ... */
|
||||
};
|
||||
|
||||
/* These aliases are provided for compatibility with samples */
|
||||
aliases {
|
||||
led0 = &led0; /* now you support the blinky sample! */
|
||||
/* other aliases go here */
|
||||
};
|
||||
};
|
||||
|
||||
&some_peripheral_you_want_to_enable { /* like a GPIO or SPI controller */
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&another_peripheral_you_want {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
If you're in a hurry, simple hardware can usually be supported by copy/paste
|
||||
followed by trial and error. If you want to understand details, you will need
|
||||
to read the rest of the devicetree documentation and the devicetree
|
||||
specification.
|
||||
|
||||
Write Kconfig files
|
||||
*******************
|
||||
|
||||
Zephyr uses the Kconfig language to configure software features. Your board
|
||||
needs to provide some Kconfig settings before you can compile a Zephyr
|
||||
application for it.
|
||||
|
||||
Setting Kconfig configuration values is documented in detail in
|
||||
:ref:`setting_configuration_values`, which you should go through. Note that the
|
||||
default board configuration might involve both :file:`<BOARD>_defconfig` and
|
||||
:file:`Kconfig.defconfig` files. The rest of this section contains some
|
||||
board-specific guidelines.
|
||||
:ref:`setting_configuration_values`.
|
||||
|
||||
In order to provide consistency across the various boards and ease the work of
|
||||
users providing applications that are not board specific, the following
|
||||
guidelines should be followed when porting a board. Unless explicitly stated,
|
||||
peripherals should be disabled by default.
|
||||
There are three mandatory Kconfig files in the board directory for a board
|
||||
named ``plank``:
|
||||
|
||||
- Configure and enable a working clock configuration, along with a tick source.
|
||||
.. code-block:: none
|
||||
|
||||
boards/<ARCH>/plank
|
||||
├── Kconfig.board
|
||||
├── Kconfig.defconfig
|
||||
└── plank_defconfig
|
||||
|
||||
:file:`Kconfig.board`
|
||||
Included by :zephyr_file:`boards/Kconfig` to include your board
|
||||
in the list of options.
|
||||
|
||||
This should at least contain a definition for a ``BOARD_PLANK`` option,
|
||||
which looks something like this:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
config BOARD_PLANK
|
||||
bool "Plank board"
|
||||
depends on SOC_SERIES_YOUR_SOC_SERIES_HERE
|
||||
select SOC_PART_NUMBER_ABCDEFGH
|
||||
|
||||
:file:`Kconfig.defconfig`
|
||||
Board-specific default values for Kconfig options.
|
||||
|
||||
The entire file should be inside an ``if BOARD_PLANK`` / ``endif`` pair of
|
||||
lines, like this:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
if BOARD_PLANK
|
||||
|
||||
# Always set CONFIG_BOARD here. This isn't meant to be customized,
|
||||
# but is set as a "default" due to Kconfig language restrictions.
|
||||
config BOARD
|
||||
default "plank"
|
||||
|
||||
# Other options you want enabled by default go next. Examples:
|
||||
|
||||
config FOO
|
||||
default y
|
||||
|
||||
if NETWORKING
|
||||
config SOC_ETHERNET_DRIVER
|
||||
default y
|
||||
endif # NETWORKING
|
||||
|
||||
endif # BOARD_PLANK
|
||||
|
||||
:file:`plank_defconfig`
|
||||
A Kconfig fragment that is merged as-is into the final build directory
|
||||
:file:`.config` whenever an application is compiled for your board.
|
||||
|
||||
You should at least select your board's SOC and do any mandatory settings for
|
||||
your system clock, console, etc. The results are architecture-specific, but
|
||||
typically look something like this:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
CONFIG_SOC_${VENDOR_XYZ3000}=y /* select your SoC */
|
||||
CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=120000000 /* set up your clock, etc */
|
||||
CONFIG_SERIAL=y
|
||||
|
||||
Build, test, and fix
|
||||
********************
|
||||
|
||||
Now it's time to build and test the application(s) you want to run on your
|
||||
board until you're satisfied.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
west build -b plank samples/hello_world
|
||||
west flash
|
||||
|
||||
For ``west flash`` to work, see :ref:`flash-and-debug-support` below. You can
|
||||
also just flash :file:`build/zephyr/zephyr.elf`, :file:`zephyr.hex`, or
|
||||
:file:`zephyr.bin` with any other tools you prefer.
|
||||
|
||||
.. _porting-general-recommendations:
|
||||
|
||||
General recommendations
|
||||
***********************
|
||||
|
||||
For consistency and to make it easier for users to build generic applications
|
||||
that are not board specific for your board, please follow these guidelines
|
||||
while porting.
|
||||
|
||||
- Unless explicitly recommended otherwise by this section, leave peripherals
|
||||
and their drivers disabled by default.
|
||||
|
||||
- Configure and enable a system clock, along with a tick source.
|
||||
|
||||
- Provide pin and driver configuration that matches the board's valuable
|
||||
components such as sensors, buttons or LEDs, and communication interfaces
|
||||
such as USB, Ethernet connector, or Bluetooth/Wi-Fi chip.
|
||||
|
||||
- When a well-known connector is present (such as used on an Arduino or
|
||||
96board), configure pins to fit this connector.
|
||||
- If your board uses a well-known connector standard (like Arduino, Mikrobus,
|
||||
Grove, or 96Boards connectors), add connector nodes to your DTS and configure
|
||||
pin muxes accordingly.
|
||||
|
||||
- Configure components that enable the use of these pins, such as
|
||||
configuring an SPI instance for Arduino SPI.
|
||||
configuring an SPI instance to use the usual Arduino SPI pins.
|
||||
|
||||
- If available, configure and enable a serial output for the console.
|
||||
- If available, configure and enable a serial output for the console
|
||||
using the ``zephyr,console`` chosen node in the devicetree.
|
||||
|
||||
- Propose and configure a default network interface.
|
||||
- If your board supports networking, configure a default interface.
|
||||
|
||||
- Enable all GPIO ports.
|
||||
- Enable all GPIO ports connected to peripherals or expansion connectors.
|
||||
|
||||
- If available, enable pinmux and interrupt controller drivers.
|
||||
|
||||
.. _flash-and-debug-support:
|
||||
|
||||
Flash and debug support
|
||||
***********************
|
||||
|
||||
Zephyr supports :ref:`west-build-flash-debug` via west extension commands.
|
||||
|
||||
To add ``west flash`` and ``west debug`` support for your board, you need to
|
||||
create a :file:`board.cmake` file in your board directory. This file's job is
|
||||
to configure a "runner" for your board. (There's nothing special you need to
|
||||
do to get ``west build`` support for your board.)
|
||||
|
||||
"Runners" are Zephyr-specific Python classes that wrap :ref:`flash and debug
|
||||
host tools <debug-host-tools>` and integrate with west and the zephyr build
|
||||
system to support ``west flash`` and related commands. Each runner supports
|
||||
flashing, debugging, or both. You need to configure the arguments to these
|
||||
Python scripts in your :file:`board.cmake` to support those commands like this
|
||||
example :file:`board.cmake`:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
board_runner_args(nrfjprog "--nrf-family=NRF52")
|
||||
board_runner_args(jlink "--device=nrf52" "--speed=4000")
|
||||
board_runner_args(pyocd "--target=nrf52" "--frequency=4000000")
|
||||
|
||||
include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake)
|
||||
include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake)
|
||||
include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake)
|
||||
|
||||
This example configures the ``nrfjprog``, ``jlink``, and ``pyocd`` runners.
|
||||
|
||||
.. warning::
|
||||
|
||||
Runners usually have names which match the tools they wrap, so the ``jlink``
|
||||
runner wraps Segger's J-Link tools, and so on. But the runner command line
|
||||
options like ``--speed`` etc. are specific to the Python scripts.
|
||||
|
||||
For more details:
|
||||
|
||||
- Run ``west flash --context`` to see a list of available runners which support
|
||||
flashing, and ``west flash --context -r <RUNNER>`` to view the specific options
|
||||
available for an individual runner.
|
||||
- Run ``west debug --context`` and ``west debug --context <RUNNER>`` to get
|
||||
the same output for runners which support debugging.
|
||||
- Run ``west flash --help`` and ``west debug --help`` for top-level options
|
||||
for flashing and debugging.
|
||||
- See :ref:`west-runner` for Python APIs.
|
||||
- Look for :file:`board.cmake` files for other boards similar to your own for
|
||||
more examples.
|
||||
|
||||
To see what a ``west flash`` or ``west debug`` command is doing exactly, run it
|
||||
in verbose mode:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
west --verbose flash
|
||||
west --verbose debug
|
||||
|
||||
Verbose mode prints any host tool commands the runner uses.
|
||||
|
||||
The order of the ``include()`` calls in your :file:`board.cmake` matters. The
|
||||
first ``include`` sets the default runner if it's not already set. For example,
|
||||
including ``nrfjprog.board.cmake`` first means that ``nrjfprog`` is the default
|
||||
flash runner for this board. Since ``nrfjprog`` does not support debugging,
|
||||
``jlink`` is the default debug runner.
|
||||
|
||||
.. _contributing-your-board:
|
||||
|
||||
Contributing your board
|
||||
***********************
|
||||
|
||||
If you want to contribute your board to Zephyr, first -- thanks!
|
||||
|
||||
There are some extra things you'll need to do:
|
||||
|
||||
#. Make sure you've followed all the :ref:`porting-general-recommendations`.
|
||||
They are requirements for boards included with Zephyr.
|
||||
|
||||
#. Add documentation for your board using the template file
|
||||
:zephyr_file:`doc/templates/board.tmpl`. See :ref:`zephyr_doc` for
|
||||
information on how to build your documentation before submitting
|
||||
your pull request.
|
||||
|
||||
#. Prepare a pull request adding your board which follows the
|
||||
:ref:`contribute_guidelines`.
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
Porting
|
||||
#######
|
||||
|
||||
This section contains details regarding porting the Zephyr kernel to new
|
||||
architectures, SoCs and boards. This section also describes the standard
|
||||
API interfaces supported by Zephyr.
|
||||
These pages document how to port Zephyr to new hardware.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
@@ -532,8 +532,8 @@ For example, to print usage information about the ``jlink`` runner::
|
||||
|
||||
.. _west-runner:
|
||||
|
||||
Implementation Details
|
||||
**********************
|
||||
runners package API
|
||||
*******************
|
||||
|
||||
The flash and debug commands are implemented as west *extension
|
||||
commands*: that is, they are west commands whose source code lives
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,3 +14,4 @@ for ensuring security is addressed within the Zephyr project.
|
||||
secure-coding.rst
|
||||
sensor-threat.rst
|
||||
hardening-tool.rst
|
||||
vulnerabilities.rst
|
||||
|
||||
25
doc/security/vulnerabilities.rst
Normal file
25
doc/security/vulnerabilities.rst
Normal file
@@ -0,0 +1,25 @@
|
||||
.. _vulnerabilities:
|
||||
|
||||
Vulnerabilities
|
||||
###############
|
||||
|
||||
This page collects all of the vulnerabilities that are discovered and
|
||||
fixed in each release. It will also often have more details than is
|
||||
available in the releases. Some vulnerabilities are deemed to be
|
||||
sensitive, and will not be publically discussed until there is
|
||||
sufficient time to fix them. Because the release notes are locked to
|
||||
a version, the information here can be updated after the embargo is
|
||||
lifted.
|
||||
|
||||
Release 1.14.0 and 2.0.0
|
||||
------------------------
|
||||
|
||||
The following security vulnerability (CVE) was addressed in this
|
||||
release:
|
||||
|
||||
* Fixes CVE-2019-9506: The Bluetooth BR/EDR specification up to and
|
||||
including version 5.1 permits sufficiently low encryption key length
|
||||
and does not prevent an attacker from influencing the key length
|
||||
negotiation. This allows practical brute-force attacks (aka "KNOB")
|
||||
that can decrypt traffic and inject arbitrary ciphertext without the
|
||||
victim noticing.
|
||||
@@ -168,12 +168,14 @@ static int adc_xec_start_read(struct device *dev,
|
||||
|
||||
/* Setup ADC resolution */
|
||||
reg = adc_regs->sar_control_reg;
|
||||
reg &= ~MCHP_ADC_SAR_CTRL_RES_MASK;
|
||||
reg &= ~(MCHP_ADC_SAR_CTRL_RES_MASK |
|
||||
(1 << MCHP_ADC_SAR_CTRL_SHIFTD_POS));
|
||||
|
||||
if (sequence->resolution == 12) {
|
||||
reg |= MCHP_ADC_SAR_CTRL_RES_12_BITS;
|
||||
} else if (sequence->resolution == 10) {
|
||||
reg |= MCHP_ADC_SAR_CTRL_RES_10_BITS;
|
||||
reg |= MCHP_ADC_SAR_CTRL_SHIFTD_EN;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -20,9 +20,14 @@ config ETH_SAM_GMAC_NAME
|
||||
required by all driver API functions. Device name has to be unique.
|
||||
|
||||
config ETH_SAM_GMAC_QUEUES
|
||||
int "Number of hardware TX and RX queues"
|
||||
int "Number of active hardware TX and RX queues"
|
||||
default 1
|
||||
range 1 3
|
||||
range 1 1 if SOC_SERIES_SAM4E
|
||||
range 1 3 if !SOC_SERIES_SAM4E && \
|
||||
!SOC_ATMEL_SAME70_REVB && \
|
||||
!SOC_ATMEL_SAMV71_REVB
|
||||
range 1 6 if SOC_ATMEL_SAME70_REVB || \
|
||||
SOC_ATMEL_SAMV71_REVB
|
||||
help
|
||||
Select the number of hardware queues used by the driver. Packets will be
|
||||
routed to appropriate queues based on their priority.
|
||||
@@ -44,6 +49,9 @@ config ETH_SAM_GMAC_FORCED_QUEUE
|
||||
default 0
|
||||
range 0 1 if ETH_SAM_GMAC_QUEUES = 2
|
||||
range 0 2 if ETH_SAM_GMAC_QUEUES = 3
|
||||
range 0 3 if ETH_SAM_GMAC_QUEUES = 4
|
||||
range 0 4 if ETH_SAM_GMAC_QUEUES = 5
|
||||
range 0 5 if ETH_SAM_GMAC_QUEUES = 6
|
||||
help
|
||||
Which queue to force the routing to. This affects both the TX and RX queues
|
||||
setup.
|
||||
|
||||
@@ -399,18 +399,29 @@ static void eth_mcux_phy_setup(void)
|
||||
{
|
||||
#ifdef CONFIG_SOC_SERIES_IMX_RT
|
||||
const u32_t phy_addr = 0U;
|
||||
u32_t status;
|
||||
status_t res;
|
||||
u32_t oms_override;
|
||||
|
||||
/* Prevent PHY entering NAND Tree mode override*/
|
||||
ENET_StartSMIRead(ENET, phy_addr, PHY_OMS_STATUS_REG,
|
||||
kENET_MiiReadValidFrame);
|
||||
status = ENET_ReadSMIData(ENET);
|
||||
/* Disable MII interrupts to prevent triggering PHY events. */
|
||||
ENET_DisableInterrupts(ENET, ENET_EIR_MII_MASK);
|
||||
|
||||
if (status & PHY_OMS_NANDTREE_MASK) {
|
||||
status &= ~PHY_OMS_NANDTREE_MASK;
|
||||
ENET_StartSMIWrite(ENET, phy_addr, PHY_OMS_OVERRIDE_REG,
|
||||
kENET_MiiWriteValidFrame, status);
|
||||
/* Prevent PHY entering NAND Tree mode override. */
|
||||
res = PHY_Read(ENET, phy_addr, PHY_OMS_OVERRIDE_REG, &oms_override);
|
||||
if (res != kStatus_Success) {
|
||||
LOG_WRN("Reading PHY reg failed (status 0x%x)", res);
|
||||
} else {
|
||||
if (oms_override & PHY_OMS_NANDTREE_MASK) {
|
||||
oms_override &= ~PHY_OMS_NANDTREE_MASK;
|
||||
res = PHY_Write(ENET, phy_addr, PHY_OMS_OVERRIDE_REG,
|
||||
oms_override);
|
||||
if (res != kStatus_Success) {
|
||||
LOG_WRN("Writing PHY reg failed (status 0x%x)",
|
||||
res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ENET_EnableInterrupts(ENET, ENET_EIR_MII_MASK);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||
"due to the granularity of RX DMA"
|
||||
#endif
|
||||
|
||||
#if (CONFIG_ETH_SAM_GMAC_BUF_RX_COUNT + 1) * CONFIG_ETH_SAM_GMAC_QUEUES \
|
||||
#if (CONFIG_ETH_SAM_GMAC_BUF_RX_COUNT + 1) * GMAC_ACTIVE_QUEUE_NUM \
|
||||
> CONFIG_NET_BUF_RX_COUNT
|
||||
#error Not enough RX buffers to allocate descriptors for each HW queue
|
||||
#endif
|
||||
@@ -75,49 +75,269 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||
/* RX descriptors list */
|
||||
static struct gmac_desc rx_desc_que0[MAIN_QUEUE_RX_DESC_COUNT]
|
||||
__nocache __aligned(GMAC_DESC_ALIGNMENT);
|
||||
#if GMAC_PRIORITY_QUEUE_NUM >= 1
|
||||
static struct gmac_desc rx_desc_que1[PRIORITY_QUEUE1_RX_DESC_COUNT]
|
||||
__nocache __aligned(GMAC_DESC_ALIGNMENT);
|
||||
#endif
|
||||
#if GMAC_PRIORITY_QUEUE_NUM >= 2
|
||||
static struct gmac_desc rx_desc_que2[PRIORITY_QUEUE2_RX_DESC_COUNT]
|
||||
__nocache __aligned(GMAC_DESC_ALIGNMENT);
|
||||
#endif
|
||||
#if GMAC_PRIORITY_QUEUE_NUM >= 3
|
||||
static struct gmac_desc rx_desc_que3[PRIORITY_QUEUE3_RX_DESC_COUNT]
|
||||
__nocache __aligned(GMAC_DESC_ALIGNMENT);
|
||||
#endif
|
||||
#if GMAC_PRIORITY_QUEUE_NUM >= 4
|
||||
static struct gmac_desc rx_desc_que4[PRIORITY_QUEUE4_RX_DESC_COUNT]
|
||||
__nocache __aligned(GMAC_DESC_ALIGNMENT);
|
||||
#endif
|
||||
#if GMAC_PRIORITY_QUEUE_NUM >= 5
|
||||
static struct gmac_desc rx_desc_que5[PRIORITY_QUEUE5_RX_DESC_COUNT]
|
||||
__nocache __aligned(GMAC_DESC_ALIGNMENT);
|
||||
#endif
|
||||
|
||||
/* TX descriptors list */
|
||||
static struct gmac_desc tx_desc_que0[MAIN_QUEUE_TX_DESC_COUNT]
|
||||
__nocache __aligned(GMAC_DESC_ALIGNMENT);
|
||||
#if GMAC_PRIORITY_QUEUE_NUM >= 1
|
||||
static struct gmac_desc tx_desc_que1[PRIORITY_QUEUE1_TX_DESC_COUNT]
|
||||
__nocache __aligned(GMAC_DESC_ALIGNMENT);
|
||||
#endif
|
||||
#if GMAC_PRIORITY_QUEUE_NUM >= 2
|
||||
static struct gmac_desc tx_desc_que2[PRIORITY_QUEUE2_TX_DESC_COUNT]
|
||||
__nocache __aligned(GMAC_DESC_ALIGNMENT);
|
||||
#endif
|
||||
#if GMAC_PRIORITY_QUEUE_NUM >= 3
|
||||
static struct gmac_desc tx_desc_que3[PRIORITY_QUEUE3_TX_DESC_COUNT]
|
||||
__nocache __aligned(GMAC_DESC_ALIGNMENT);
|
||||
#endif
|
||||
#if GMAC_PRIORITY_QUEUE_NUM >= 4
|
||||
static struct gmac_desc tx_desc_que4[PRIORITY_QUEUE4_TX_DESC_COUNT]
|
||||
__nocache __aligned(GMAC_DESC_ALIGNMENT);
|
||||
#endif
|
||||
#if GMAC_PRIORITY_QUEUE_NUM >= 5
|
||||
static struct gmac_desc tx_desc_que5[PRIORITY_QUEUE5_TX_DESC_COUNT]
|
||||
__nocache __aligned(GMAC_DESC_ALIGNMENT);
|
||||
#endif
|
||||
|
||||
/* RX buffer accounting list */
|
||||
static struct net_buf *rx_frag_list_que0[MAIN_QUEUE_RX_DESC_COUNT];
|
||||
#if GMAC_PRIORITY_QUEUE_NO >= 1
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 1
|
||||
static struct net_buf *rx_frag_list_que1[PRIORITY_QUEUE1_RX_DESC_COUNT];
|
||||
#endif
|
||||
#if GMAC_PRIORITY_QUEUE_NO == 2
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 2
|
||||
static struct net_buf *rx_frag_list_que2[PRIORITY_QUEUE2_RX_DESC_COUNT];
|
||||
#endif
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 3
|
||||
static struct net_buf *rx_frag_list_que3[PRIORITY_QUEUE3_RX_DESC_COUNT];
|
||||
#endif
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 4
|
||||
static struct net_buf *rx_frag_list_que4[PRIORITY_QUEUE4_RX_DESC_COUNT];
|
||||
#endif
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 5
|
||||
static struct net_buf *rx_frag_list_que5[PRIORITY_QUEUE5_RX_DESC_COUNT];
|
||||
#endif
|
||||
|
||||
#if GMAC_MULTIPLE_TX_PACKETS == 1
|
||||
/* TX buffer accounting list */
|
||||
static struct net_buf *tx_frag_list_que0[MAIN_QUEUE_TX_DESC_COUNT];
|
||||
#if GMAC_PRIORITY_QUEUE_NO >= 1
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 1
|
||||
static struct net_buf *tx_frag_list_que1[PRIORITY_QUEUE1_TX_DESC_COUNT];
|
||||
#endif
|
||||
#if GMAC_PRIORITY_QUEUE_NO == 2
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 2
|
||||
static struct net_buf *tx_frag_list_que2[PRIORITY_QUEUE2_TX_DESC_COUNT];
|
||||
#endif
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 3
|
||||
static struct net_buf *tx_frag_list_que3[PRIORITY_QUEUE3_TX_DESC_COUNT];
|
||||
#endif
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 4
|
||||
static struct net_buf *tx_frag_list_que4[PRIORITY_QUEUE4_TX_DESC_COUNT];
|
||||
#endif
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 5
|
||||
static struct net_buf *tx_frag_list_que5[PRIORITY_QUEUE5_TX_DESC_COUNT];
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PTP_CLOCK_SAM_GMAC)
|
||||
/* TX frames accounting list */
|
||||
static struct net_pkt *tx_frame_list_que0[CONFIG_NET_PKT_TX_COUNT + 1];
|
||||
#if GMAC_PRIORITY_QUEUE_NO >= 1
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 1
|
||||
static struct net_pkt *tx_frame_list_que1[CONFIG_NET_PKT_TX_COUNT + 1];
|
||||
#endif
|
||||
#if GMAC_PRIORITY_QUEUE_NO == 2
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 2
|
||||
static struct net_pkt *tx_frame_list_que2[CONFIG_NET_PKT_TX_COUNT + 1];
|
||||
#endif
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 3
|
||||
static struct net_pkt *tx_frame_list_que3[CONFIG_NET_PKT_TX_COUNT + 1];
|
||||
#endif
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 4
|
||||
static struct net_pkt *tx_frame_list_que4[CONFIG_NET_PKT_TX_COUNT + 1];
|
||||
#endif
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 5
|
||||
static struct net_pkt *tx_frame_list_que5[CONFIG_NET_PKT_TX_COUNT + 1];
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MODULO_INC(val, max) {val = (++val < max) ? val : 0; }
|
||||
|
||||
static int rx_descriptors_init(Gmac *gmac, struct gmac_queue *queue);
|
||||
static void tx_descriptors_init(Gmac *gmac, struct gmac_queue *queue);
|
||||
static int nonpriority_queue_init(Gmac *gmac, struct gmac_queue *queue);
|
||||
|
||||
#if GMAC_PRIORITY_QUEUE_NUM >= 1
|
||||
static inline void set_receive_buf_queue_pointer(
|
||||
Gmac *gmac,
|
||||
struct gmac_queue *queue)
|
||||
{
|
||||
/* Set Receive Buffer Queue Pointer Register */
|
||||
if (queue->que_idx == GMAC_QUE_0) {
|
||||
gmac->GMAC_RBQB = (u32_t)queue->rx_desc_list.buf;
|
||||
} else {
|
||||
gmac->GMAC_RBQBAPQ[queue->que_idx - 1] =
|
||||
(u32_t)queue->rx_desc_list.buf;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void disable_all_priority_queue_interrupt(Gmac *gmac)
|
||||
{
|
||||
u32_t idx;
|
||||
|
||||
for (idx = 0; idx < GMAC_PRIORITY_QUEUE_NUM; idx++) {
|
||||
gmac->GMAC_IDRPQ[idx] = UINT32_MAX;
|
||||
(void)gmac->GMAC_ISRPQ[idx];
|
||||
}
|
||||
}
|
||||
|
||||
static int priority_queue_init(Gmac *gmac, struct gmac_queue *queue)
|
||||
{
|
||||
int result;
|
||||
int queue_index;
|
||||
|
||||
__ASSERT_NO_MSG(queue->rx_desc_list.len > 0);
|
||||
__ASSERT_NO_MSG(queue->tx_desc_list.len > 0);
|
||||
__ASSERT(!((u32_t)queue->rx_desc_list.buf & ~GMAC_RBQB_ADDR_Msk),
|
||||
"RX descriptors have to be word aligned");
|
||||
__ASSERT(!((u32_t)queue->tx_desc_list.buf & ~GMAC_TBQB_ADDR_Msk),
|
||||
"TX descriptors have to be word aligned");
|
||||
|
||||
/* Extract queue index for easier referencing */
|
||||
queue_index = queue->que_idx - 1;
|
||||
|
||||
/* Setup descriptor lists */
|
||||
result = rx_descriptors_init(gmac, queue);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
tx_descriptors_init(gmac, queue);
|
||||
|
||||
#if GMAC_MULTIPLE_TX_PACKETS == 0
|
||||
k_sem_init(&queue->tx_sem, 0, 1);
|
||||
#else
|
||||
k_sem_init(&queue->tx_desc_sem, queue->tx_desc_list.len - 1,
|
||||
queue->tx_desc_list.len - 1);
|
||||
#endif
|
||||
|
||||
/* Setup RX buffer size for DMA */
|
||||
gmac->GMAC_RBSRPQ[queue_index] =
|
||||
GMAC_RBSRPQ_RBS(CONFIG_NET_BUF_DATA_SIZE >> 6);
|
||||
|
||||
/* Set Receive Buffer Queue Pointer Register */
|
||||
gmac->GMAC_RBQBAPQ[queue_index] = (u32_t)queue->rx_desc_list.buf;
|
||||
/* Set Transmit Buffer Queue Pointer Register */
|
||||
gmac->GMAC_TBQBAPQ[queue_index] = (u32_t)queue->tx_desc_list.buf;
|
||||
|
||||
/* Enable RX/TX completion and error interrupts */
|
||||
gmac->GMAC_IERPQ[queue_index] = GMAC_INTPQ_EN_FLAGS;
|
||||
|
||||
queue->err_rx_frames_dropped = 0U;
|
||||
queue->err_rx_flushed_count = 0U;
|
||||
queue->err_tx_flushed_count = 0U;
|
||||
|
||||
LOG_INF("Queue %d activated", queue->que_idx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int priority_queue_init_as_idle(Gmac *gmac, struct gmac_queue *queue)
|
||||
{
|
||||
struct gmac_desc_list *rx_desc_list = &queue->rx_desc_list;
|
||||
struct gmac_desc_list *tx_desc_list = &queue->tx_desc_list;
|
||||
|
||||
__ASSERT(!((u32_t)rx_desc_list->buf & ~GMAC_RBQB_ADDR_Msk),
|
||||
"RX descriptors have to be word aligned");
|
||||
__ASSERT(!((u32_t)tx_desc_list->buf & ~GMAC_TBQB_ADDR_Msk),
|
||||
"TX descriptors have to be word aligned");
|
||||
__ASSERT((rx_desc_list->len == 1U) && (tx_desc_list->len == 1U),
|
||||
"Priority queues are currently not supported, descriptor "
|
||||
"list has to have a single entry");
|
||||
|
||||
/* Setup RX descriptor lists */
|
||||
/* Take ownership from GMAC and set the wrap bit */
|
||||
rx_desc_list->buf[0].w0 = GMAC_RXW0_WRAP;
|
||||
rx_desc_list->buf[0].w1 = 0U;
|
||||
/* Setup TX descriptor lists */
|
||||
tx_desc_list->buf[0].w0 = 0U;
|
||||
/* Take ownership from GMAC and set the wrap bit */
|
||||
tx_desc_list->buf[0].w1 = GMAC_TXW1_USED | GMAC_TXW1_WRAP;
|
||||
|
||||
/* Set Receive Buffer Queue Pointer Register */
|
||||
gmac->GMAC_RBQBAPQ[queue->que_idx - 1] = (u32_t)rx_desc_list->buf;
|
||||
/* Set Transmit Buffer Queue Pointer Register */
|
||||
gmac->GMAC_TBQBAPQ[queue->que_idx - 1] = (u32_t)tx_desc_list->buf;
|
||||
|
||||
LOG_INF("Queue %d set to idle", queue->que_idx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int queue_init(Gmac *gmac, struct gmac_queue *queue)
|
||||
{
|
||||
if (queue->que_idx == GMAC_QUE_0) {
|
||||
return nonpriority_queue_init(gmac, queue);
|
||||
} else if (queue->que_idx <= GMAC_ACTIVE_PRIORITY_QUEUE_NUM) {
|
||||
return priority_queue_init(gmac, queue);
|
||||
} else {
|
||||
return priority_queue_init_as_idle(gmac, queue);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline void set_receive_buf_queue_pointer(
|
||||
Gmac *gmac,
|
||||
struct gmac_queue *queue)
|
||||
{
|
||||
gmac->GMAC_RBQB = (u32_t)queue->rx_desc_list.buf;
|
||||
}
|
||||
|
||||
static int queue_init(Gmac *gmac, struct gmac_queue *queue)
|
||||
{
|
||||
return nonpriority_queue_init(gmac, queue);
|
||||
}
|
||||
|
||||
#define disable_all_queue_interrupt(gmac)
|
||||
|
||||
#endif
|
||||
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 1
|
||||
static int eth_sam_gmac_setup_qav(Gmac *gmac, int queue_id, bool enable);
|
||||
|
||||
static inline void eth_sam_gmac_init_qav(Gmac *gmac)
|
||||
{
|
||||
u32_t idx;
|
||||
|
||||
for (idx = GMAC_QUE_1; idx <= GMAC_ACTIVE_PRIORITY_QUEUE_NUM; idx++) {
|
||||
eth_sam_gmac_setup_qav(gmac, idx, true);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define eth_sam_gmac_init_qav(gmac)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Cache helpers
|
||||
*/
|
||||
@@ -611,13 +831,7 @@ static void rx_error_handler(Gmac *gmac, struct gmac_queue *queue)
|
||||
queue->rx_desc_list.buf[i].w0 &= ~GMAC_RXW0_OWNERSHIP;
|
||||
}
|
||||
|
||||
/* Set Receive Buffer Queue Pointer Register */
|
||||
if (queue->que_idx == 0) {
|
||||
gmac->GMAC_RBQB = (u32_t)queue->rx_desc_list.buf;
|
||||
} else {
|
||||
gmac->GMAC_RBQBAPQ[queue->que_idx - 1] =
|
||||
(u32_t)queue->rx_desc_list.buf;
|
||||
}
|
||||
set_receive_buf_queue_pointer(gmac, queue);
|
||||
|
||||
/* Restart reception */
|
||||
gmac->GMAC_NCR |= GMAC_NCR_RXEN;
|
||||
@@ -652,11 +866,11 @@ static int get_mck_clock_divisor(u32_t mck)
|
||||
return mck_divisor;
|
||||
}
|
||||
|
||||
#if GMAC_PRIORITY_QUEUE_NO >= 1
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 1
|
||||
static int eth_sam_gmac_setup_qav(Gmac *gmac, int queue_id, bool enable)
|
||||
{
|
||||
/* Verify queue id */
|
||||
if (queue_id < 1 || queue_id > GMAC_PRIORITY_QUEUE_NO) {
|
||||
if (queue_id < GMAC_QUE_1 || queue_id > GMAC_ACTIVE_PRIORITY_QUEUE_NUM) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -680,7 +894,7 @@ static int eth_sam_gmac_setup_qav(Gmac *gmac, int queue_id, bool enable)
|
||||
static int eth_sam_gmac_get_qav_status(Gmac *gmac, int queue_id, bool *enabled)
|
||||
{
|
||||
/* Verify queue id */
|
||||
if (queue_id < 1 || queue_id > GMAC_PRIORITY_QUEUE_NO) {
|
||||
if (queue_id < GMAC_QUE_1 || queue_id > GMAC_ACTIVE_PRIORITY_QUEUE_NUM) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -699,7 +913,7 @@ static int eth_sam_gmac_setup_qav_idle_slope(Gmac *gmac, int queue_id,
|
||||
u32_t cbscr_val;
|
||||
|
||||
/* Verify queue id */
|
||||
if (queue_id < 1 || queue_id > GMAC_PRIORITY_QUEUE_NO) {
|
||||
if (queue_id < GMAC_QUE_1 || queue_id > GMAC_ACTIVE_PRIORITY_QUEUE_NUM) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -742,7 +956,7 @@ static int eth_sam_gmac_get_qav_idle_slope(Gmac *gmac, int queue_id,
|
||||
unsigned int *idle_slope)
|
||||
{
|
||||
/* Verify queue id */
|
||||
if (queue_id < 1 || queue_id > GMAC_PRIORITY_QUEUE_NO) {
|
||||
if (queue_id < GMAC_QUE_1 || queue_id > GMAC_ACTIVE_PRIORITY_QUEUE_NUM) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -792,7 +1006,7 @@ static int eth_sam_gmac_setup_qav_delta_bandwidth(Gmac *gmac, int queue_id,
|
||||
u32_t idle_slope;
|
||||
|
||||
/* Verify queue id */
|
||||
if (queue_id < 1 || queue_id > GMAC_PRIORITY_QUEUE_NO) {
|
||||
if (queue_id < GMAC_QUE_1 || queue_id > GMAC_ACTIVE_PRIORITY_QUEUE_NUM) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -857,12 +1071,10 @@ static int gmac_init(Gmac *gmac, u32_t gmac_ncfgr_val)
|
||||
|
||||
/* Disable all interrupts */
|
||||
gmac->GMAC_IDR = UINT32_MAX;
|
||||
gmac->GMAC_IDRPQ[GMAC_QUE_1 - 1] = UINT32_MAX;
|
||||
gmac->GMAC_IDRPQ[GMAC_QUE_2 - 1] = UINT32_MAX;
|
||||
/* Clear all interrupts */
|
||||
(void)gmac->GMAC_ISR;
|
||||
(void)gmac->GMAC_ISRPQ[GMAC_QUE_1 - 1];
|
||||
(void)gmac->GMAC_ISRPQ[GMAC_QUE_2 - 1];
|
||||
disable_all_priority_queue_interrupt(gmac);
|
||||
|
||||
/* Setup Hash Registers - enable reception of all multicast frames when
|
||||
* GMAC_NCFGR_MTIHEN is set.
|
||||
*/
|
||||
@@ -888,10 +1100,9 @@ static int gmac_init(Gmac *gmac, u32_t gmac_ncfgr_val)
|
||||
/* Enable Qav if priority queues are used, and setup the default delta
|
||||
* bandwidth according to IEEE802.1Qav (34.3.1)
|
||||
*/
|
||||
#if GMAC_PRIORITY_QUEUE_NO == 1
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM == 1
|
||||
eth_sam_gmac_setup_qav_delta_bandwidth(gmac, 1, 75);
|
||||
eth_sam_gmac_setup_qav(gmac, 1, true);
|
||||
#elif GMAC_PRIORITY_QUEUE_NO == 2
|
||||
#elif GMAC_ACTIVE_PRIORITY_QUEUE_NUM == 2
|
||||
/* For multiple priority queues, 802.1Qav suggests using 75% for the
|
||||
* highest priority queue, and 0% for the lower priority queues.
|
||||
* This is because the lower priority queues are supposed to be using
|
||||
@@ -904,10 +1115,25 @@ static int gmac_init(Gmac *gmac, u32_t gmac_ncfgr_val)
|
||||
*/
|
||||
eth_sam_gmac_setup_qav_delta_bandwidth(gmac, 1, 25);
|
||||
eth_sam_gmac_setup_qav_delta_bandwidth(gmac, 2, 50);
|
||||
eth_sam_gmac_setup_qav(gmac, 1, true);
|
||||
eth_sam_gmac_setup_qav(gmac, 2, true);
|
||||
#elif GMAC_ACTIVE_PRIORITY_QUEUE_NUM == 3
|
||||
eth_sam_gmac_setup_qav_delta_bandwidth(gmac, 1, 25);
|
||||
eth_sam_gmac_setup_qav_delta_bandwidth(gmac, 2, 25);
|
||||
eth_sam_gmac_setup_qav_delta_bandwidth(gmac, 3, 25);
|
||||
#elif GMAC_ACTIVE_PRIORITY_QUEUE_NUM == 4
|
||||
eth_sam_gmac_setup_qav_delta_bandwidth(gmac, 1, 21);
|
||||
eth_sam_gmac_setup_qav_delta_bandwidth(gmac, 2, 18);
|
||||
eth_sam_gmac_setup_qav_delta_bandwidth(gmac, 3, 18);
|
||||
eth_sam_gmac_setup_qav_delta_bandwidth(gmac, 4, 18);
|
||||
#elif GMAC_ACTIVE_PRIORITY_QUEUE_NUM == 5
|
||||
eth_sam_gmac_setup_qav_delta_bandwidth(gmac, 1, 15);
|
||||
eth_sam_gmac_setup_qav_delta_bandwidth(gmac, 2, 15);
|
||||
eth_sam_gmac_setup_qav_delta_bandwidth(gmac, 3, 15);
|
||||
eth_sam_gmac_setup_qav_delta_bandwidth(gmac, 4, 15);
|
||||
eth_sam_gmac_setup_qav_delta_bandwidth(gmac, 5, 15);
|
||||
#endif
|
||||
|
||||
eth_sam_gmac_init_qav(gmac);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -991,100 +1217,6 @@ static int nonpriority_queue_init(Gmac *gmac, struct gmac_queue *queue)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int priority_queue_init(Gmac *gmac, struct gmac_queue *queue)
|
||||
{
|
||||
int result;
|
||||
int queue_index;
|
||||
|
||||
__ASSERT_NO_MSG(queue->rx_desc_list.len > 0);
|
||||
__ASSERT_NO_MSG(queue->tx_desc_list.len > 0);
|
||||
__ASSERT(!((u32_t)queue->rx_desc_list.buf & ~GMAC_RBQB_ADDR_Msk),
|
||||
"RX descriptors have to be word aligned");
|
||||
__ASSERT(!((u32_t)queue->tx_desc_list.buf & ~GMAC_TBQB_ADDR_Msk),
|
||||
"TX descriptors have to be word aligned");
|
||||
|
||||
/* Extract queue index for easier referencing */
|
||||
queue_index = queue->que_idx - 1;
|
||||
|
||||
/* Setup descriptor lists */
|
||||
result = rx_descriptors_init(gmac, queue);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
tx_descriptors_init(gmac, queue);
|
||||
|
||||
#if GMAC_MULTIPLE_TX_PACKETS == 0
|
||||
k_sem_init(&queue->tx_sem, 0, 1);
|
||||
#else
|
||||
k_sem_init(&queue->tx_desc_sem, queue->tx_desc_list.len - 1,
|
||||
queue->tx_desc_list.len - 1);
|
||||
#endif
|
||||
|
||||
/* Setup RX buffer size for DMA */
|
||||
gmac->GMAC_RBSRPQ[queue_index] =
|
||||
GMAC_RBSRPQ_RBS(CONFIG_NET_BUF_DATA_SIZE >> 6);
|
||||
|
||||
/* Set Receive Buffer Queue Pointer Register */
|
||||
gmac->GMAC_RBQBAPQ[queue_index] = (u32_t)queue->rx_desc_list.buf;
|
||||
/* Set Transmit Buffer Queue Pointer Register */
|
||||
gmac->GMAC_TBQBAPQ[queue_index] = (u32_t)queue->tx_desc_list.buf;
|
||||
|
||||
/* Enable RX/TX completion and error interrupts */
|
||||
gmac->GMAC_IERPQ[queue_index] = GMAC_INTPQ_EN_FLAGS;
|
||||
|
||||
queue->err_rx_frames_dropped = 0U;
|
||||
queue->err_rx_flushed_count = 0U;
|
||||
queue->err_tx_flushed_count = 0U;
|
||||
|
||||
LOG_INF("Queue %d activated", queue->que_idx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int priority_queue_init_as_idle(Gmac *gmac, struct gmac_queue *queue)
|
||||
{
|
||||
struct gmac_desc_list *rx_desc_list = &queue->rx_desc_list;
|
||||
struct gmac_desc_list *tx_desc_list = &queue->tx_desc_list;
|
||||
|
||||
__ASSERT(!((u32_t)rx_desc_list->buf & ~GMAC_RBQB_ADDR_Msk),
|
||||
"RX descriptors have to be word aligned");
|
||||
__ASSERT(!((u32_t)tx_desc_list->buf & ~GMAC_TBQB_ADDR_Msk),
|
||||
"TX descriptors have to be word aligned");
|
||||
__ASSERT((rx_desc_list->len == 1U) && (tx_desc_list->len == 1U),
|
||||
"Priority queues are currently not supported, descriptor "
|
||||
"list has to have a single entry");
|
||||
|
||||
/* Setup RX descriptor lists */
|
||||
/* Take ownership from GMAC and set the wrap bit */
|
||||
rx_desc_list->buf[0].w0 = GMAC_RXW0_WRAP;
|
||||
rx_desc_list->buf[0].w1 = 0U;
|
||||
/* Setup TX descriptor lists */
|
||||
tx_desc_list->buf[0].w0 = 0U;
|
||||
/* Take ownership from GMAC and set the wrap bit */
|
||||
tx_desc_list->buf[0].w1 = GMAC_TXW1_USED | GMAC_TXW1_WRAP;
|
||||
|
||||
/* Set Receive Buffer Queue Pointer Register */
|
||||
gmac->GMAC_RBQBAPQ[queue->que_idx - 1] = (u32_t)rx_desc_list->buf;
|
||||
/* Set Transmit Buffer Queue Pointer Register */
|
||||
gmac->GMAC_TBQBAPQ[queue->que_idx - 1] = (u32_t)tx_desc_list->buf;
|
||||
|
||||
LOG_INF("Queue %d set to idle", queue->que_idx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int queue_init(Gmac *gmac, struct gmac_queue *queue)
|
||||
{
|
||||
if (queue->que_idx == 0) {
|
||||
return nonpriority_queue_init(gmac, queue);
|
||||
} else if (queue->que_idx <= GMAC_PRIORITY_QUEUE_NO) {
|
||||
return priority_queue_init(gmac, queue);
|
||||
} else {
|
||||
return priority_queue_init_as_idle(gmac, queue);
|
||||
}
|
||||
}
|
||||
|
||||
static struct net_pkt *frame_get(struct gmac_queue *queue)
|
||||
{
|
||||
struct gmac_desc_list *rx_desc_list = &queue->rx_desc_list;
|
||||
@@ -1270,19 +1402,28 @@ static void eth_rx(struct gmac_queue *queue)
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_ETH_SAM_GMAC_FORCE_QUEUE) && \
|
||||
((CONFIG_ETH_SAM_GMAC_QUEUES != NET_TC_TX_COUNT) || \
|
||||
((GMAC_ACTIVE_QUEUE_NUM != NET_TC_TX_COUNT) || \
|
||||
((NET_TC_TX_COUNT != NET_TC_RX_COUNT) && defined(CONFIG_NET_VLAN)))
|
||||
static int priority2queue(enum net_priority priority)
|
||||
{
|
||||
static const u8_t queue_priority_map[] = {
|
||||
#if CONFIG_ETH_SAM_GMAC_QUEUES == 1
|
||||
#if GMAC_ACTIVE_QUEUE_NUM == 1
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
#endif
|
||||
#if CONFIG_ETH_SAM_GMAC_QUEUES == 2
|
||||
#if GMAC_ACTIVE_QUEUE_NUM == 2
|
||||
0, 0, 0, 0, 1, 1, 1, 1
|
||||
#endif
|
||||
#if CONFIG_ETH_SAM_GMAC_QUEUES == 3
|
||||
#if GMAC_ACTIVE_QUEUE_NUM == 3
|
||||
0, 0, 0, 0, 1, 1, 2, 2
|
||||
#endif
|
||||
#if GMAC_ACTIVE_QUEUE_NUM == 4
|
||||
0, 0, 0, 0, 1, 1, 2, 3
|
||||
#endif
|
||||
#if GMAC_ACTIVE_QUEUE_NUM == 5
|
||||
0, 0, 0, 0, 1, 2, 3, 4
|
||||
#endif
|
||||
#if GMAC_ACTIVE_QUEUE_NUM == 6
|
||||
0, 0, 0, 1, 2, 3, 4, 5
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1328,7 +1469,7 @@ static int eth_tx(struct device *dev, struct net_pkt *pkt)
|
||||
#if defined(CONFIG_ETH_SAM_GMAC_FORCE_QUEUE)
|
||||
/* Route eveything to the forced queue */
|
||||
queue = &dev_data->queue_list[CONFIG_ETH_SAM_GMAC_FORCED_QUEUE];
|
||||
#elif CONFIG_ETH_SAM_GMAC_QUEUES == CONFIG_NET_TC_TX_COUNT
|
||||
#elif GMAC_ACTIVE_QUEUE_NUM == CONFIG_NET_TC_TX_COUNT
|
||||
/* Prefer to chose queue based on its traffic class */
|
||||
queue = &dev_data->queue_list[net_tx_priority2tc(pkt_prio)];
|
||||
#else
|
||||
@@ -1521,7 +1662,7 @@ static void queue0_isr(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
#if GMAC_PRIORITY_QUEUE_NO >= 1
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 1
|
||||
static inline void priority_queue_isr(void *arg, unsigned int queue_idx)
|
||||
{
|
||||
struct device *const dev = (struct device *const)arg;
|
||||
@@ -1572,20 +1713,41 @@ static inline void priority_queue_isr(void *arg, unsigned int queue_idx)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GMAC_PRIORITY_QUEUE_NO >= 1
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 1
|
||||
static void queue1_isr(void *arg)
|
||||
{
|
||||
priority_queue_isr(arg, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GMAC_PRIORITY_QUEUE_NO == 2
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 2
|
||||
static void queue2_isr(void *arg)
|
||||
{
|
||||
priority_queue_isr(arg, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 3
|
||||
static void queue3_isr(void *arg)
|
||||
{
|
||||
priority_queue_isr(arg, 3);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 4
|
||||
static void queue4_isr(void *arg)
|
||||
{
|
||||
priority_queue_isr(arg, 4);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 5
|
||||
static void queue5_isr(void *arg)
|
||||
{
|
||||
priority_queue_isr(arg, 5);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int eth_initialize(struct device *dev)
|
||||
{
|
||||
const struct eth_sam_dev_cfg *const cfg = DEV_CFG(dev);
|
||||
@@ -1702,7 +1864,7 @@ static void eth0_iface_init(struct net_if *iface)
|
||||
NET_LINK_ETHERNET);
|
||||
|
||||
/* Initialize GMAC queues */
|
||||
for (i = 0; i < GMAC_QUEUE_NO; i++) {
|
||||
for (i = GMAC_QUE_0; i < GMAC_QUEUE_NUM; i++) {
|
||||
result = queue_init(cfg->regs, &dev_data->queue_list[i]);
|
||||
if (result < 0) {
|
||||
LOG_ERR("Unable to initialize ETH queue%d", i);
|
||||
@@ -1710,14 +1872,14 @@ static void eth0_iface_init(struct net_if *iface)
|
||||
}
|
||||
}
|
||||
|
||||
#if GMAC_PRIORITY_QUEUE_NO >= 1
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 1
|
||||
#if defined(CONFIG_ETH_SAM_GMAC_FORCE_QUEUE)
|
||||
for (i = 0; i < CONFIG_NET_TC_RX_COUNT; ++i) {
|
||||
cfg->regs->GMAC_ST1RPQ[i] =
|
||||
GMAC_ST1RPQ_DSTCM(i) |
|
||||
GMAC_ST1RPQ_QNB(CONFIG_ETH_SAM_GMAC_FORCED_QUEUE);
|
||||
}
|
||||
#elif CONFIG_ETH_SAM_GMAC_QUEUES == NET_TC_RX_COUNT
|
||||
#elif GMAC_ACTIVE_QUEUE_NUM == NET_TC_RX_COUNT
|
||||
/* If TC configuration is compatible with HW configuration, setup the
|
||||
* screening registers based on the DS/TC values.
|
||||
* Map them 1:1 - TC 0 -> Queue 0, TC 1 -> Queue 1 etc.
|
||||
@@ -1779,13 +1941,13 @@ static enum ethernet_hw_caps eth_sam_gmac_get_capabilities(struct device *dev)
|
||||
ETHERNET_PTP |
|
||||
#endif
|
||||
ETHERNET_PRIORITY_QUEUES |
|
||||
#if GMAC_PRIORITY_QUEUE_NO >= 1
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 1
|
||||
ETHERNET_QAV |
|
||||
#endif
|
||||
ETHERNET_LINK_100BASE_T;
|
||||
}
|
||||
|
||||
#if GMAC_PRIORITY_QUEUE_NO >= 1
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 1
|
||||
static int eth_sam_gmac_set_qav_param(struct device *dev,
|
||||
enum ethernet_config_type type,
|
||||
const struct ethernet_config *config)
|
||||
@@ -1833,7 +1995,7 @@ static int eth_sam_gmac_set_config(struct device *dev,
|
||||
const struct ethernet_config *config)
|
||||
{
|
||||
switch (type) {
|
||||
#if GMAC_PRIORITY_QUEUE_NO >= 1
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 1
|
||||
case ETHERNET_CONFIG_TYPE_QAV_PARAM:
|
||||
return eth_sam_gmac_set_qav_param(dev, type, config);
|
||||
#endif
|
||||
@@ -1844,7 +2006,7 @@ static int eth_sam_gmac_set_config(struct device *dev,
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
#if GMAC_PRIORITY_QUEUE_NO >= 1
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 1
|
||||
static int eth_sam_gmac_get_qav_param(struct device *dev,
|
||||
enum ethernet_config_type type,
|
||||
struct ethernet_config *config)
|
||||
@@ -1879,7 +2041,7 @@ static int eth_sam_gmac_get_qav_param(struct device *dev,
|
||||
return eth_sam_gmac_get_qav_delta_bandwidth(gmac, queue_id,
|
||||
delta_bandwidth);
|
||||
case ETHERNET_QAV_PARAM_TYPE_TRAFFIC_CLASS:
|
||||
#if CONFIG_ETH_SAM_GMAC_QUEUES == NET_TC_TX_COUNT
|
||||
#if GMAC_ACTIVE_QUEUE_NUM == NET_TC_TX_COUNT
|
||||
config->qav_param.traffic_class = queue_id;
|
||||
return 0;
|
||||
#else
|
||||
@@ -1900,9 +2062,9 @@ static int eth_sam_gmac_get_config(struct device *dev,
|
||||
{
|
||||
switch (type) {
|
||||
case ETHERNET_CONFIG_TYPE_PRIORITY_QUEUES_NUM:
|
||||
config->priority_queues_num = GMAC_PRIORITY_QUEUE_NO;
|
||||
config->priority_queues_num = GMAC_ACTIVE_PRIORITY_QUEUE_NUM;
|
||||
return 0;
|
||||
#if GMAC_PRIORITY_QUEUE_NO >= 1
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 1
|
||||
case ETHERNET_CONFIG_TYPE_QAV_PARAM:
|
||||
return eth_sam_gmac_get_qav_param(dev, type, config);
|
||||
#endif
|
||||
@@ -1943,17 +2105,35 @@ static void eth0_irq_config(void)
|
||||
DEVICE_GET(eth0_sam_gmac), 0);
|
||||
irq_enable(GMAC_IRQn);
|
||||
|
||||
#if GMAC_PRIORITY_QUEUE_NO >= 1
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 1
|
||||
IRQ_CONNECT(GMAC_Q1_IRQn, CONFIG_ETH_SAM_GMAC_IRQ_PRI, queue1_isr,
|
||||
DEVICE_GET(eth0_sam_gmac), 0);
|
||||
irq_enable(GMAC_Q1_IRQn);
|
||||
#endif
|
||||
|
||||
#if GMAC_PRIORITY_QUEUE_NO == 2
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 2
|
||||
IRQ_CONNECT(GMAC_Q2_IRQn, CONFIG_ETH_SAM_GMAC_IRQ_PRI, queue2_isr,
|
||||
DEVICE_GET(eth0_sam_gmac), 0);
|
||||
irq_enable(GMAC_Q2_IRQn);
|
||||
#endif
|
||||
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 3
|
||||
IRQ_CONNECT(GMAC_Q3_IRQn, CONFIG_ETH_SAM_GMAC_IRQ_PRI, queue3_isr,
|
||||
DEVICE_GET(eth0_sam_gmac), 0);
|
||||
irq_enable(GMAC_Q3_IRQn);
|
||||
#endif
|
||||
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 4
|
||||
IRQ_CONNECT(GMAC_Q4_IRQn, CONFIG_ETH_SAM_GMAC_IRQ_PRI, queue4_isr,
|
||||
DEVICE_GET(eth0_sam_gmac), 0);
|
||||
irq_enable(GMAC_Q4_IRQn);
|
||||
#endif
|
||||
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 5
|
||||
IRQ_CONNECT(GMAC_Q5_IRQn, CONFIG_ETH_SAM_GMAC_IRQ_PRI, queue5_isr,
|
||||
DEVICE_GET(eth0_sam_gmac), 0);
|
||||
irq_enable(GMAC_Q5_IRQn);
|
||||
#endif
|
||||
}
|
||||
|
||||
static const struct soc_gpio_pin pins_eth0[] = PINS_GMAC0;
|
||||
@@ -1978,7 +2158,8 @@ static struct eth_sam_dev_data eth0_data = {
|
||||
CONFIG_ETH_SAM_GMAC_MAC5,
|
||||
},
|
||||
#endif
|
||||
.queue_list = {{
|
||||
.queue_list = {
|
||||
{
|
||||
.que_idx = GMAC_QUE_0,
|
||||
.rx_desc_list = {
|
||||
.buf = rx_desc_que0,
|
||||
@@ -2001,6 +2182,7 @@ static struct eth_sam_dev_data eth0_data = {
|
||||
},
|
||||
#endif
|
||||
#endif
|
||||
#if GMAC_PRIORITY_QUEUE_NUM >= 1
|
||||
}, {
|
||||
.que_idx = GMAC_QUE_1,
|
||||
.rx_desc_list = {
|
||||
@@ -2011,7 +2193,7 @@ static struct eth_sam_dev_data eth0_data = {
|
||||
.buf = tx_desc_que1,
|
||||
.len = ARRAY_SIZE(tx_desc_que1),
|
||||
},
|
||||
#if GMAC_PRIORITY_QUEUE_NO >= 1
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 1
|
||||
.rx_frag_list = rx_frag_list_que1,
|
||||
#if GMAC_MULTIPLE_TX_PACKETS == 1
|
||||
.tx_frag_list = {
|
||||
@@ -2026,6 +2208,8 @@ static struct eth_sam_dev_data eth0_data = {
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if GMAC_PRIORITY_QUEUE_NUM >= 2
|
||||
}, {
|
||||
.que_idx = GMAC_QUE_2,
|
||||
.rx_desc_list = {
|
||||
@@ -2036,7 +2220,7 @@ static struct eth_sam_dev_data eth0_data = {
|
||||
.buf = tx_desc_que2,
|
||||
.len = ARRAY_SIZE(tx_desc_que2),
|
||||
},
|
||||
#if GMAC_PRIORITY_QUEUE_NO == 2
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 2
|
||||
.rx_frag_list = rx_frag_list_que2,
|
||||
#if GMAC_MULTIPLE_TX_PACKETS == 1
|
||||
.tx_frag_list = {
|
||||
@@ -2050,6 +2234,88 @@ static struct eth_sam_dev_data eth0_data = {
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if GMAC_PRIORITY_QUEUE_NUM >= 3
|
||||
}, {
|
||||
.que_idx = GMAC_QUE_3,
|
||||
.rx_desc_list = {
|
||||
.buf = rx_desc_que3,
|
||||
.len = ARRAY_SIZE(rx_desc_que3),
|
||||
},
|
||||
.tx_desc_list = {
|
||||
.buf = tx_desc_que3,
|
||||
.len = ARRAY_SIZE(tx_desc_que3),
|
||||
},
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 3
|
||||
.rx_frag_list = rx_frag_list_que3,
|
||||
#if GMAC_MULTIPLE_TX_PACKETS == 1
|
||||
.tx_frag_list = {
|
||||
.buf = (u32_t *)tx_frag_list_que3,
|
||||
.len = ARRAY_SIZE(tx_frag_list_que3),
|
||||
},
|
||||
#if defined(CONFIG_PTP_CLOCK_SAM_GMAC)
|
||||
.tx_frames = {
|
||||
.buf = (u32_t *)tx_frame_list_que3,
|
||||
.len = ARRAY_SIZE(tx_frame_list_que3),
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if GMAC_PRIORITY_QUEUE_NUM >= 4
|
||||
}, {
|
||||
.que_idx = GMAC_QUE_4,
|
||||
.rx_desc_list = {
|
||||
.buf = rx_desc_que4,
|
||||
.len = ARRAY_SIZE(rx_desc_que4),
|
||||
},
|
||||
.tx_desc_list = {
|
||||
.buf = tx_desc_que4,
|
||||
.len = ARRAY_SIZE(tx_desc_que4),
|
||||
},
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 4
|
||||
.rx_frag_list = rx_frag_list_que4,
|
||||
#if GMAC_MULTIPLE_TX_PACKETS == 1
|
||||
.tx_frag_list = {
|
||||
.buf = (u32_t *)tx_frag_list_que4,
|
||||
.len = ARRAY_SIZE(tx_frag_list_que4),
|
||||
},
|
||||
#if defined(CONFIG_PTP_CLOCK_SAM_GMAC)
|
||||
.tx_frames = {
|
||||
.buf = (u32_t *)tx_frame_list_que4,
|
||||
.len = ARRAY_SIZE(tx_frame_list_que4),
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if GMAC_PRIORITY_QUEUE_NUM >= 5
|
||||
}, {
|
||||
.que_idx = GMAC_QUE_5,
|
||||
.rx_desc_list = {
|
||||
.buf = rx_desc_que5,
|
||||
.len = ARRAY_SIZE(rx_desc_que5),
|
||||
},
|
||||
.tx_desc_list = {
|
||||
.buf = tx_desc_que5,
|
||||
.len = ARRAY_SIZE(tx_desc_que5),
|
||||
},
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 5
|
||||
.rx_frag_list = rx_frag_list_que5,
|
||||
#if GMAC_MULTIPLE_TX_PACKETS == 1
|
||||
.tx_frag_list = {
|
||||
.buf = (u32_t *)tx_frag_list_que5,
|
||||
.len = ARRAY_SIZE(tx_frag_list_que5),
|
||||
},
|
||||
#if defined(CONFIG_PTP_CLOCK_SAM_GMAC)
|
||||
.tx_frames = {
|
||||
.buf = (u32_t *)tx_frame_list_que5,
|
||||
.len = ARRAY_SIZE(tx_frame_list_que5),
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
},
|
||||
|
||||
@@ -27,34 +27,71 @@
|
||||
#define GMAC_FRAME_SIZE_MAX (GMAC_MTU + 18)
|
||||
|
||||
/** Cache alignment */
|
||||
#define GMAC_DCACHE_ALIGNMENT 32
|
||||
#define GMAC_DCACHE_ALIGNMENT 32
|
||||
/** Memory alignment of the RX/TX Buffer Descriptor List */
|
||||
#define GMAC_DESC_ALIGNMENT 4
|
||||
#define GMAC_DESC_ALIGNMENT 4
|
||||
/** Total number of queues supported by GMAC hardware module */
|
||||
#define GMAC_QUEUE_NO 3
|
||||
#if defined(CONFIG_SOC_ATMEL_SAME70_REVB) || \
|
||||
defined(CONFIG_SOC_ATMEL_SAMV71_REVB)
|
||||
#define GMAC_QUEUE_NUM 6
|
||||
#elif !defined(CONFIG_SOC_SERIES_SAM4E)
|
||||
#define GMAC_QUEUE_NUM 3
|
||||
#else
|
||||
#define GMAC_QUEUE_NUM 1
|
||||
#endif
|
||||
#define GMAC_PRIORITY_QUEUE_NUM (GMAC_QUEUE_NUM - 1)
|
||||
#if (GMAC_PRIORITY_QUEUE_NUM >= 1)
|
||||
BUILD_ASSERT_MSG(ARRAY_SIZE(GMAC->GMAC_TBQBAPQ) + 1 == GMAC_QUEUE_NUM,
|
||||
"GMAC_QUEUE_NUM doesn't match soc header");
|
||||
#endif
|
||||
/** Number of priority queues used */
|
||||
#define GMAC_PRIORITY_QUEUE_NO (CONFIG_ETH_SAM_GMAC_QUEUES - 1)
|
||||
#define GMAC_ACTIVE_QUEUE_NUM (CONFIG_ETH_SAM_GMAC_QUEUES)
|
||||
#define GMAC_ACTIVE_PRIORITY_QUEUE_NUM (GMAC_ACTIVE_QUEUE_NUM - 1)
|
||||
|
||||
/** RX descriptors count for main queue */
|
||||
#define MAIN_QUEUE_RX_DESC_COUNT CONFIG_ETH_SAM_GMAC_BUF_RX_COUNT
|
||||
#define MAIN_QUEUE_RX_DESC_COUNT CONFIG_ETH_SAM_GMAC_BUF_RX_COUNT
|
||||
/** TX descriptors count for main queue */
|
||||
#define MAIN_QUEUE_TX_DESC_COUNT (CONFIG_NET_BUF_TX_COUNT + 1)
|
||||
#define MAIN_QUEUE_TX_DESC_COUNT (CONFIG_NET_BUF_TX_COUNT + 1)
|
||||
|
||||
/** RX/TX descriptors count for priority queues */
|
||||
#if GMAC_PRIORITY_QUEUE_NO == 2
|
||||
#define PRIORITY_QUEUE2_RX_DESC_COUNT MAIN_QUEUE_RX_DESC_COUNT
|
||||
#define PRIORITY_QUEUE2_TX_DESC_COUNT MAIN_QUEUE_TX_DESC_COUNT
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 1
|
||||
#define PRIORITY_QUEUE1_RX_DESC_COUNT MAIN_QUEUE_RX_DESC_COUNT
|
||||
#define PRIORITY_QUEUE1_TX_DESC_COUNT MAIN_QUEUE_TX_DESC_COUNT
|
||||
#else
|
||||
#define PRIORITY_QUEUE2_RX_DESC_COUNT 1
|
||||
#define PRIORITY_QUEUE2_TX_DESC_COUNT 1
|
||||
#define PRIORITY_QUEUE1_RX_DESC_COUNT 1
|
||||
#define PRIORITY_QUEUE1_TX_DESC_COUNT 1
|
||||
#endif
|
||||
|
||||
#if GMAC_PRIORITY_QUEUE_NO >= 1
|
||||
#define PRIORITY_QUEUE1_RX_DESC_COUNT MAIN_QUEUE_RX_DESC_COUNT
|
||||
#define PRIORITY_QUEUE1_TX_DESC_COUNT MAIN_QUEUE_TX_DESC_COUNT
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 2
|
||||
#define PRIORITY_QUEUE2_RX_DESC_COUNT MAIN_QUEUE_RX_DESC_COUNT
|
||||
#define PRIORITY_QUEUE2_TX_DESC_COUNT MAIN_QUEUE_TX_DESC_COUNT
|
||||
#else
|
||||
#define PRIORITY_QUEUE1_RX_DESC_COUNT 1
|
||||
#define PRIORITY_QUEUE1_TX_DESC_COUNT 1
|
||||
#define PRIORITY_QUEUE2_RX_DESC_COUNT 1
|
||||
#define PRIORITY_QUEUE2_TX_DESC_COUNT 1
|
||||
#endif
|
||||
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 3
|
||||
#define PRIORITY_QUEUE3_RX_DESC_COUNT MAIN_QUEUE_RX_DESC_COUNT
|
||||
#define PRIORITY_QUEUE3_TX_DESC_COUNT MAIN_QUEUE_TX_DESC_COUNT
|
||||
#else
|
||||
#define PRIORITY_QUEUE3_RX_DESC_COUNT 1
|
||||
#define PRIORITY_QUEUE3_TX_DESC_COUNT 1
|
||||
#endif
|
||||
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 4
|
||||
#define PRIORITY_QUEUE4_RX_DESC_COUNT MAIN_QUEUE_RX_DESC_COUNT
|
||||
#define PRIORITY_QUEUE4_TX_DESC_COUNT MAIN_QUEUE_TX_DESC_COUNT
|
||||
#else
|
||||
#define PRIORITY_QUEUE4_RX_DESC_COUNT 1
|
||||
#define PRIORITY_QUEUE4_TX_DESC_COUNT 1
|
||||
#endif
|
||||
|
||||
#if GMAC_ACTIVE_PRIORITY_QUEUE_NUM >= 5
|
||||
#define PRIORITY_QUEUE5_RX_DESC_COUNT MAIN_QUEUE_RX_DESC_COUNT
|
||||
#define PRIORITY_QUEUE5_TX_DESC_COUNT MAIN_QUEUE_TX_DESC_COUNT
|
||||
#else
|
||||
#define PRIORITY_QUEUE5_RX_DESC_COUNT 1
|
||||
#define PRIORITY_QUEUE5_TX_DESC_COUNT 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -147,6 +184,9 @@ enum queue_idx {
|
||||
GMAC_QUE_0, /** Main queue */
|
||||
GMAC_QUE_1, /** Priority queue 1 */
|
||||
GMAC_QUE_2, /** Priority queue 2 */
|
||||
GMAC_QUE_3, /** Priority queue 3 */
|
||||
GMAC_QUE_4, /** Priority queue 4 */
|
||||
GMAC_QUE_5, /** Priority queue 5 */
|
||||
};
|
||||
|
||||
/** Minimal ring buffer implementation */
|
||||
@@ -217,7 +257,7 @@ struct eth_sam_dev_data {
|
||||
struct device *ptp_clock;
|
||||
#endif
|
||||
u8_t mac_addr[6];
|
||||
struct gmac_queue queue_list[GMAC_QUEUE_NO];
|
||||
struct gmac_queue queue_list[GMAC_QUEUE_NUM];
|
||||
};
|
||||
|
||||
#define DEV_CFG(dev) \
|
||||
|
||||
@@ -71,6 +71,8 @@ static inline int z_vrfy_gpio_pin_interrupt_configure(struct device *port,
|
||||
static inline int z_vrfy_gpio_enable_callback(struct device *port,
|
||||
gpio_pin_t pin)
|
||||
{
|
||||
Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, enable_callback));
|
||||
|
||||
return z_impl_gpio_enable_callback((struct device *)port, pin);
|
||||
}
|
||||
#include <syscalls/gpio_enable_callback_mrsh.c>
|
||||
@@ -78,12 +80,16 @@ static inline int z_vrfy_gpio_enable_callback(struct device *port,
|
||||
static inline int z_vrfy_gpio_disable_callback(struct device *port,
|
||||
gpio_pin_t pin)
|
||||
{
|
||||
Z_OOPS(Z_SYSCALL_DRIVER_GPIO(port, disable_callback));
|
||||
|
||||
return z_impl_gpio_disable_callback((struct device *)port, pin);
|
||||
}
|
||||
#include <syscalls/gpio_disable_callback_mrsh.c>
|
||||
|
||||
static inline int z_vrfy_gpio_get_pending_int(struct device *dev)
|
||||
{
|
||||
Z_OOPS(Z_SYSCALL_DRIVER_GPIO(dev, get_pending_int));
|
||||
|
||||
return z_impl_gpio_get_pending_int((struct device *)dev);
|
||||
}
|
||||
#include <syscalls/gpio_get_pending_int_mrsh.c>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* ieee802154_rf2xx.c - ATMEL RF2XX IEEE 802.15.4 Driver */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Gerson Fernando Budke
|
||||
* Copyright (c) 2019-2020 Gerson Fernando Budke
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -77,16 +77,6 @@ static inline void trx_isr_handler(struct device *port,
|
||||
k_sem_give(&ctx->trx_isr_lock);
|
||||
}
|
||||
|
||||
static void trx_isr_timeout(struct k_timer *timer_id)
|
||||
{
|
||||
struct rf2xx_context *ctx = (struct rf2xx_context *)
|
||||
k_timer_user_data_get(timer_id);
|
||||
|
||||
k_mutex_lock(&ctx->phy_mutex, K_FOREVER);
|
||||
ctx->trx_state = RF2XX_TRX_PHY_STATE_IDLE;
|
||||
k_mutex_unlock(&ctx->phy_mutex);
|
||||
}
|
||||
|
||||
static void rf2xx_trx_set_state(struct device *dev,
|
||||
enum rf2xx_trx_state_cmd_t state)
|
||||
{
|
||||
@@ -104,6 +94,30 @@ static void rf2xx_trx_set_state(struct device *dev,
|
||||
RF2XX_TRX_PHY_STATUS_MASK));
|
||||
}
|
||||
|
||||
static void rf2xx_trx_set_tx_state(struct device *dev)
|
||||
{
|
||||
u8_t status;
|
||||
|
||||
/**
|
||||
* Ensures that RX automatically ACK will be sent when requested.
|
||||
* Datasheet: Chapter 7.2.3 RX_AACK_ON – Receive with Automatic ACK
|
||||
* Datasheet: Figure 7-13. Timing Example of an RX_AACK Transaction
|
||||
* for Slotted Operation.
|
||||
*
|
||||
* This will create a spin lock that wait transceiver be free from
|
||||
* current receive frame process
|
||||
*/
|
||||
do {
|
||||
status = (rf2xx_iface_reg_read(dev, RF2XX_TRX_STATUS_REG) &
|
||||
RF2XX_TRX_PHY_STATUS_MASK);
|
||||
} while (status == RF2XX_TRX_PHY_STATUS_BUSY_RX_AACK ||
|
||||
status == RF2XX_TRX_PHY_STATUS_STATE_TRANSITION);
|
||||
|
||||
rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_TRX_OFF);
|
||||
rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG);
|
||||
rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_TX_ARET_ON);
|
||||
}
|
||||
|
||||
static void rf2xx_trx_set_rx_state(struct device *dev)
|
||||
{
|
||||
rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_TRX_OFF);
|
||||
@@ -131,8 +145,12 @@ static void rf2xx_trx_rx(struct device *dev)
|
||||
* This obligate the driver to have rx_buf statically allocated with
|
||||
* RX2XX_MAX_FRAME_SIZE.
|
||||
*/
|
||||
rf2xx_iface_frame_read(dev, rx_buf, RX2XX_FRAME_HEADER_SIZE);
|
||||
pkt_len = rx_buf[RX2XX_FRAME_PHR_INDEX];
|
||||
if (ctx->trx_model != RF2XX_TRX_MODEL_231) {
|
||||
pkt_len = ctx->rx_phr;
|
||||
} else {
|
||||
rf2xx_iface_frame_read(dev, rx_buf, RX2XX_FRAME_HEADER_SIZE);
|
||||
pkt_len = rx_buf[RX2XX_FRAME_PHR_INDEX];
|
||||
}
|
||||
|
||||
if (pkt_len < RX2XX_FRAME_MIN_PHR_SIZE) {
|
||||
LOG_ERR("invalid RX frame length");
|
||||
@@ -190,6 +208,53 @@ static void rf2xx_trx_rx(struct device *dev)
|
||||
K_THREAD_STACK_SIZEOF(ctx->trx_stack));
|
||||
}
|
||||
}
|
||||
|
||||
static void rf2xx_process_rx_frame(struct device *dev)
|
||||
{
|
||||
struct rf2xx_context *ctx = dev->driver_data;
|
||||
|
||||
if (ctx->trx_model != RF2XX_TRX_MODEL_231) {
|
||||
rf2xx_trx_rx(dev);
|
||||
} else {
|
||||
/* Ensures that automatically ACK will be sent
|
||||
* when requested
|
||||
*/
|
||||
while (rf2xx_iface_reg_read(dev, RF2XX_TRX_STATUS_REG) ==
|
||||
RF2XX_TRX_PHY_STATUS_BUSY_RX_AACK) {
|
||||
;
|
||||
};
|
||||
|
||||
/* Set PLL_ON to avoid transceiver receive
|
||||
* new data until finish reading process
|
||||
*/
|
||||
rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_PLL_ON);
|
||||
rf2xx_trx_rx(dev);
|
||||
rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_RX_AACK_ON);
|
||||
}
|
||||
}
|
||||
|
||||
static void rf2xx_process_tx_frame(struct device *dev)
|
||||
{
|
||||
struct rf2xx_context *ctx = dev->driver_data;
|
||||
|
||||
ctx->trx_trac = (rf2xx_iface_reg_read(dev, RF2XX_TRX_STATE_REG) >>
|
||||
RF2XX_TRAC_STATUS) & 7;
|
||||
k_sem_give(&ctx->trx_tx_sync);
|
||||
rf2xx_trx_set_rx_state(dev);
|
||||
}
|
||||
|
||||
static void rf2xx_process_trx_end(struct device *dev)
|
||||
{
|
||||
u8_t trx_status = (rf2xx_iface_reg_read(dev, RF2XX_TRX_STATUS_REG) &
|
||||
RF2XX_TRX_PHY_STATUS_MASK);
|
||||
|
||||
if (trx_status == RF2XX_TRX_PHY_STATUS_TX_ARET_ON) {
|
||||
rf2xx_process_tx_frame(dev);
|
||||
} else {
|
||||
rf2xx_process_rx_frame(dev);
|
||||
}
|
||||
}
|
||||
|
||||
static void rf2xx_thread_main(void *arg)
|
||||
{
|
||||
struct device *dev = INT_TO_POINTER(arg);
|
||||
@@ -198,9 +263,9 @@ static void rf2xx_thread_main(void *arg)
|
||||
|
||||
while (true) {
|
||||
k_sem_take(&ctx->trx_isr_lock, K_FOREVER);
|
||||
k_mutex_lock(&ctx->phy_mutex, K_FOREVER);
|
||||
|
||||
isr_status = rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG);
|
||||
|
||||
/*
|
||||
* IRQ_7 (BAT_LOW) Indicates a supply voltage below the
|
||||
* programmed threshold. 9.5.4
|
||||
@@ -228,39 +293,12 @@ static void rf2xx_thread_main(void *arg)
|
||||
* IRQ_0 (PLL_LOCK) Indicates PLL lock.
|
||||
*/
|
||||
if (isr_status & (1 << RF2XX_RX_START)) {
|
||||
ctx->trx_state = RF2XX_TRX_PHY_BUSY_RX;
|
||||
k_timer_start(&ctx->trx_isr_timeout, K_MSEC(10), 0);
|
||||
} else if (isr_status & (1 << RF2XX_TRX_END)) {
|
||||
if (ctx->trx_state == RF2XX_TRX_PHY_BUSY_RX) {
|
||||
/* Ensures that automatically ACK will be sent
|
||||
* when requested
|
||||
*/
|
||||
while (rf2xx_iface_reg_read(dev,
|
||||
RF2XX_TRX_STATUS_REG) ==
|
||||
RF2XX_TRX_PHY_STATUS_BUSY_RX_AACK) {
|
||||
};
|
||||
|
||||
/* Set PLL_ON to avoid transceiver receive
|
||||
* new data until finish reading process
|
||||
*/
|
||||
rf2xx_trx_set_state(dev,
|
||||
RF2XX_TRX_PHY_STATE_CMD_PLL_ON);
|
||||
k_timer_stop(&ctx->trx_isr_timeout);
|
||||
rf2xx_trx_rx(dev);
|
||||
rf2xx_trx_set_state(dev,
|
||||
RF2XX_TRX_PHY_STATE_CMD_RX_AACK_ON);
|
||||
/*if (ctx->trx_state == RF2XX_TRX_PHY_BUSY_TX)*/
|
||||
} else {
|
||||
ctx->trx_trac =
|
||||
(rf2xx_iface_reg_read(dev,
|
||||
RF2XX_TRX_STATE_REG) >>
|
||||
RF2XX_TRAC_STATUS) & 7;
|
||||
k_sem_give(&ctx->trx_tx_sync);
|
||||
rf2xx_trx_set_rx_state(dev);
|
||||
if (ctx->trx_model != RF2XX_TRX_MODEL_231) {
|
||||
rf2xx_iface_sram_read(dev, 0, &ctx->rx_phr, 1);
|
||||
}
|
||||
ctx->trx_state = RF2XX_TRX_PHY_STATE_IDLE;
|
||||
} else if (isr_status & (1 << RF2XX_TRX_END)) {
|
||||
rf2xx_process_trx_end(dev);
|
||||
}
|
||||
k_mutex_unlock(&ctx->phy_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,37 +472,14 @@ static int rf2xx_tx(struct device *dev,
|
||||
ARG_UNUSED(pkt);
|
||||
|
||||
struct rf2xx_context *ctx = dev->driver_data;
|
||||
bool abort = true;
|
||||
int response = 0;
|
||||
|
||||
k_mutex_lock(&ctx->phy_mutex, K_FOREVER);
|
||||
/* Reset semaphore in case ACK was received after timeout */
|
||||
rf2xx_trx_set_tx_state(dev);
|
||||
rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG);
|
||||
|
||||
k_sem_reset(&ctx->trx_tx_sync);
|
||||
|
||||
if (ctx->trx_state == RF2XX_TRX_PHY_STATE_IDLE) {
|
||||
ctx->trx_state = RF2XX_TRX_PHY_BUSY_TX;
|
||||
abort = false;
|
||||
|
||||
/**
|
||||
* Set extended TX mode
|
||||
* Datasheet: chapter 7.2 Extended Operating Mode
|
||||
*/
|
||||
rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_TX_ARET_ON);
|
||||
rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG);
|
||||
rf2xx_iface_frame_write(dev, frag->data, frag->len);
|
||||
rf2xx_iface_phy_tx_start(dev);
|
||||
}
|
||||
|
||||
k_mutex_unlock(&ctx->phy_mutex);
|
||||
|
||||
if (abort) {
|
||||
LOG_DBG("TX Abort, TRX isn't idle!");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait transceiver...
|
||||
*/
|
||||
rf2xx_iface_frame_write(dev, frag->data, frag->len);
|
||||
rf2xx_iface_phy_tx_start(dev);
|
||||
k_sem_take(&ctx->trx_tx_sync, K_FOREVER);
|
||||
|
||||
switch (ctx->trx_trac) {
|
||||
@@ -506,11 +521,11 @@ static int rf2xx_start(struct device *dev)
|
||||
const struct rf2xx_config *conf = dev->config->config_info;
|
||||
struct rf2xx_context *ctx = dev->driver_data;
|
||||
|
||||
k_mutex_lock(&ctx->phy_mutex, K_FOREVER);
|
||||
rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_TRX_OFF);
|
||||
rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG);
|
||||
gpio_pin_interrupt_configure(ctx->irq_gpio, conf->irq.pin,
|
||||
GPIO_INT_EDGE_TO_ACTIVE);
|
||||
rf2xx_trx_set_rx_state(dev);
|
||||
k_mutex_unlock(&ctx->phy_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -520,11 +535,10 @@ static int rf2xx_stop(struct device *dev)
|
||||
const struct rf2xx_config *conf = dev->config->config_info;
|
||||
struct rf2xx_context *ctx = dev->driver_data;
|
||||
|
||||
k_mutex_lock(&ctx->phy_mutex, K_FOREVER);
|
||||
gpio_pin_interrupt_configure(ctx->irq_gpio, conf->irq.pin,
|
||||
GPIO_INT_DISABLE);
|
||||
rf2xx_trx_set_state(dev, RF2XX_TRX_PHY_STATE_CMD_TRX_OFF);
|
||||
k_mutex_unlock(&ctx->phy_mutex);
|
||||
rf2xx_iface_reg_read(dev, RF2XX_IRQ_STATUS_REG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -545,8 +559,6 @@ static int power_on_and_setup(struct device *dev)
|
||||
struct rf2xx_context *ctx = dev->driver_data;
|
||||
u8_t config;
|
||||
|
||||
ctx->trx_state = RF2XX_TRX_PHY_STATE_IDLE;
|
||||
|
||||
rf2xx_iface_phy_rst(dev);
|
||||
|
||||
/* Sync transceiver state */
|
||||
@@ -721,11 +733,8 @@ static int rf2xx_init(struct device *dev)
|
||||
|
||||
LOG_DBG("\nInitialize RF2XX Transceiver\n");
|
||||
|
||||
k_mutex_init(&ctx->phy_mutex);
|
||||
k_sem_init(&ctx->trx_tx_sync, 0, 1);
|
||||
k_sem_init(&ctx->trx_isr_lock, 0, 1);
|
||||
k_timer_init(&ctx->trx_isr_timeout, trx_isr_timeout, NULL);
|
||||
k_timer_user_data_set(&ctx->trx_isr_timeout, ctx);
|
||||
|
||||
if (configure_gpios(dev) != 0) {
|
||||
LOG_ERR("Configuring GPIOS failed");
|
||||
@@ -860,12 +869,10 @@ static struct ieee802154_radio_api rf2xx_radio_api = {
|
||||
.spi.cs.devname = DT_INST_##n##_ATMEL_RF2XX_CS_GPIOS_CONTROLLER, \
|
||||
.spi.cs.pin = DT_INST_##n##_ATMEL_RF2XX_CS_GPIOS_PIN, \
|
||||
.spi.cs.flags = DT_INST_##n##_ATMEL_RF2XX_CS_GPIOS_FLAGS, \
|
||||
}
|
||||
};
|
||||
|
||||
#define IEEE802154_RF2XX_DEVICE_DATA(n) \
|
||||
static struct rf2xx_context rf2xx_ctx_data_##n = { \
|
||||
.trx_state = RF2XX_TRX_PHY_STATE_INITIAL, \
|
||||
}
|
||||
static struct rf2xx_context rf2xx_ctx_data_##n;
|
||||
|
||||
#define IEEE802154_RF2XX_RAW_DEVICE_INIT(n) \
|
||||
DEVICE_AND_API_INIT( \
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* ieee802154_rf2xx.h - IEEE 802.15.4 Driver definition for ATMEL RF2XX */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Gerson Fernando Budke
|
||||
* Copyright (c) 2019-2020 Gerson Fernando Budke
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -65,14 +65,6 @@ enum rf2xx_trx_state_trac_t {
|
||||
RF2XX_TRX_PHY_STATE_TRAC_INVALID = 0x07,
|
||||
};
|
||||
|
||||
enum rf2xx_trx_state_t {
|
||||
RF2XX_TRX_PHY_STATE_INITIAL,
|
||||
RF2XX_TRX_PHY_STATE_IDLE,
|
||||
RF2XX_TRX_PHY_STATE_SLEEP,
|
||||
RF2XX_TRX_PHY_BUSY_RX,
|
||||
RF2XX_TRX_PHY_BUSY_TX,
|
||||
};
|
||||
|
||||
enum rf2xx_trx_model_t {
|
||||
RF2XX_TRX_MODEL_INV = 0x00,
|
||||
RF2XX_TRX_MODEL_230 = 0x02,
|
||||
@@ -127,11 +119,8 @@ struct rf2xx_context {
|
||||
CONFIG_IEEE802154_RF2XX_RX_STACK_SIZE);
|
||||
struct k_sem trx_isr_lock;
|
||||
struct k_sem trx_tx_sync;
|
||||
struct k_timer trx_isr_timeout;
|
||||
struct k_mutex phy_mutex;
|
||||
|
||||
enum rf2xx_trx_model_t trx_model;
|
||||
enum rf2xx_trx_state_t trx_state;
|
||||
enum rf2xx_trx_state_trac_t trx_trac;
|
||||
|
||||
u8_t mac_addr[8];
|
||||
@@ -139,6 +128,7 @@ struct rf2xx_context {
|
||||
u8_t pkt_ed;
|
||||
s8_t trx_rssi_base;
|
||||
u8_t trx_version;
|
||||
u8_t rx_phr;
|
||||
};
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_RF2XX_H_ */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* ieee802154_rf2xx_iface.c - ATMEL RF2XX IEEE 802.15.4 Interface */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Gerson Fernando Budke
|
||||
* Copyright (c) 2019-2020 Gerson Fernando Budke
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -248,3 +248,49 @@ void rf2xx_iface_frame_write(struct device *dev,
|
||||
LOG_DBG("Frame W: PhyStatus: %02X. length: %02X", status, length);
|
||||
LOG_HEXDUMP_DBG(data, length, "payload");
|
||||
}
|
||||
|
||||
void rf2xx_iface_sram_read(struct device *dev,
|
||||
u8_t address,
|
||||
u8_t *data,
|
||||
u8_t length)
|
||||
{
|
||||
const struct rf2xx_context *ctx = dev->driver_data;
|
||||
u8_t cmd = RF2XX_RF_CMD_SRAM_R;
|
||||
u8_t status[2];
|
||||
|
||||
const struct spi_buf tx_buf[2] = {
|
||||
{
|
||||
.buf = &cmd,
|
||||
.len = 1
|
||||
},
|
||||
{
|
||||
.buf = &address,
|
||||
.len = 1
|
||||
},
|
||||
};
|
||||
const struct spi_buf_set tx = {
|
||||
.buffers = tx_buf,
|
||||
.count = 2
|
||||
};
|
||||
const struct spi_buf rx_buf[2] = {
|
||||
{
|
||||
.buf = status,
|
||||
.len = 2
|
||||
},
|
||||
{
|
||||
.buf = data,
|
||||
.len = length
|
||||
},
|
||||
};
|
||||
const struct spi_buf_set rx = {
|
||||
.buffers = rx_buf,
|
||||
.count = 2
|
||||
};
|
||||
|
||||
if (spi_transceive(ctx->spi, &ctx->spi_cfg, &tx, &rx) != 0) {
|
||||
LOG_ERR("Failed to exec rf2xx_sram_read");
|
||||
}
|
||||
|
||||
LOG_DBG("SRAM R: length: %02X, status: %02X", length, status[0]);
|
||||
LOG_HEXDUMP_DBG(data, length, "content");
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* ieee802154_rf2xx_iface.h - ATMEL RF2XX transceiver interface */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Gerson Fernando Budke
|
||||
* Copyright (c) 2019-2020 Gerson Fernando Budke
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -107,4 +107,19 @@ void rf2xx_iface_frame_write(struct device *dev,
|
||||
u8_t *data,
|
||||
u8_t length);
|
||||
|
||||
/**
|
||||
* @brief Reads sram data from the transceiver
|
||||
*
|
||||
* This function reads the sram data of the transceiver.
|
||||
*
|
||||
* @param[in] dev Transceiver device instance
|
||||
* @param[in] address Start address to be read
|
||||
* @param[out] data Pointer to the location to store data
|
||||
* @param[in] length Number of bytes to be read from the sram space
|
||||
*/
|
||||
void rf2xx_iface_sram_read(struct device *dev,
|
||||
u8_t address,
|
||||
u8_t *data,
|
||||
u8_t length);
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_RF2XX_IFACE_H_ */
|
||||
|
||||
@@ -19,12 +19,16 @@ static inline int z_vrfy_kscan_config(struct device *dev,
|
||||
|
||||
static inline int z_vrfy_kscan_disable_callback(struct device *dev);
|
||||
{
|
||||
Z_OOPS(Z_SYSCALL_DRIVER_KSCAN(dev, disable_callback));
|
||||
|
||||
return z_impl_kscan_disable_callback((struct device *)dev);
|
||||
}
|
||||
#include <syscalls/kscan_disable_callback_mrsh.c>
|
||||
|
||||
static int z_vrfy_kscan_enable_callback(struct device *dev);
|
||||
{
|
||||
Z_OOPS(Z_SYSCALL_DRIVER_KSCAN(dev, enable_callback));
|
||||
|
||||
return z_impl_kscan_enable_callback((struct device *)dev);
|
||||
}
|
||||
#include <syscalls/kscan_enable_callback_mrsh.c>
|
||||
|
||||
@@ -940,7 +940,7 @@ static const struct uart_driver_api uart_sam0_driver_api = {
|
||||
#define UART_SAM0_IRQ_HANDLER_FUNC(n) \
|
||||
.irq_config_func = uart_sam0_irq_config_##n,
|
||||
|
||||
#ifdef DT_ATMEL_SAM0_UART_0_IRQ_3
|
||||
#ifdef DT_INST_0_ATMEL_SAM0_UART_IRQ_3
|
||||
#define UART_SAM0_IRQ_HANDLER(n) \
|
||||
static void uart_sam0_irq_config_##n(struct device *dev) \
|
||||
{ \
|
||||
|
||||
@@ -83,7 +83,8 @@ static void timer_isr(void *arg)
|
||||
int z_clock_driver_init(struct device *device)
|
||||
{
|
||||
IRQ_CONNECT(RISCV_MACHINE_TIMER_IRQ, 0, timer_isr, NULL, 0);
|
||||
set_mtimecmp(mtime() + CYC_PER_TICK);
|
||||
last_count = mtime();
|
||||
set_mtimecmp(last_count + CYC_PER_TICK);
|
||||
irq_enable(RISCV_MACHINE_TIMER_IRQ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -14,13 +14,8 @@ if WATCHDOG
|
||||
|
||||
config WDT_DISABLE_AT_BOOT
|
||||
bool "Disable at boot"
|
||||
default y
|
||||
help
|
||||
Disable watchdog at Zephyr system startup for the SoCs that enable
|
||||
the watchdog by default after reset.
|
||||
|
||||
Note that disabling this configuration option does not enable the
|
||||
watchdog for the SoCs that boot with the watchdog disabled.
|
||||
Disable watchdog at Zephyr system startup.
|
||||
|
||||
module = WDT
|
||||
module-str = watchdog
|
||||
|
||||
@@ -322,6 +322,7 @@ struct bt_le_adv_param {
|
||||
*/
|
||||
#define BT_LE_ADV_PARAM(_options, _int_min, _int_max) \
|
||||
((struct bt_le_adv_param[]) { { \
|
||||
.id = BT_ID_DEFAULT, \
|
||||
.options = (_options), \
|
||||
.interval_min = (_int_min), \
|
||||
.interval_max = (_int_max), \
|
||||
|
||||
@@ -817,10 +817,11 @@ ssize_t bt_gatt_attr_read_cpf(struct bt_conn *conn,
|
||||
#define BT_GATT_ATTRIBUTE(_uuid, _perm, _read, _write, _value) \
|
||||
{ \
|
||||
.uuid = _uuid, \
|
||||
.perm = _perm, \
|
||||
.read = _read, \
|
||||
.write = _write, \
|
||||
.user_data = _value, \
|
||||
.handle = 0, \
|
||||
.perm = _perm, \
|
||||
}
|
||||
|
||||
/** @brief Notification complete result callback.
|
||||
|
||||
@@ -578,6 +578,8 @@ void arch_mem_domain_destroy(struct k_mem_domain *domain);
|
||||
* if the supplied memory buffer spans multiple enabled memory management
|
||||
* regions (even if all such regions permit user access).
|
||||
*
|
||||
* @warning 0 size buffer has undefined behavior.
|
||||
*
|
||||
* @param addr start address of the buffer
|
||||
* @param size the size of the buffer
|
||||
* @param write If nonzero, additionally check if the area is writable.
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
* true if the operation overflowed.
|
||||
*/
|
||||
/**@{*/
|
||||
static bool u16_add_overflow(u16_t a, u16_t b, u16_t *result);
|
||||
static bool u32_add_overflow(u32_t a, u32_t b, u32_t *result);
|
||||
static bool u64_add_overflow(u64_t a, u64_t b, u64_t *result);
|
||||
static bool size_add_overflow(size_t a, size_t b, size_t *result);
|
||||
@@ -40,6 +41,7 @@ static bool size_add_overflow(size_t a, size_t b, size_t *result);
|
||||
* true if the operation overflowed.
|
||||
*/
|
||||
/**@{*/
|
||||
static bool u16_mul_overflow(u16_t a, u16_t b, u16_t *result);
|
||||
static bool u32_mul_overflow(u32_t a, u32_t b, u32_t *result);
|
||||
static bool u64_mul_overflow(u64_t a, u64_t b, u64_t *result);
|
||||
static bool size_mul_overflow(size_t a, size_t b, size_t *result);
|
||||
|
||||
@@ -29,6 +29,11 @@
|
||||
#endif
|
||||
|
||||
#if use_builtin(__builtin_add_overflow)
|
||||
static inline bool u16_add_overflow(u16_t a, u16_t b, u16_t *result)
|
||||
{
|
||||
return __builtin_add_overflow(a, b, result);
|
||||
}
|
||||
|
||||
static inline bool u32_add_overflow(u32_t a, u32_t b, u32_t *result)
|
||||
{
|
||||
return __builtin_add_overflow(a, b, result);
|
||||
@@ -44,6 +49,15 @@ static inline bool size_add_overflow(size_t a, size_t b, size_t *result)
|
||||
return __builtin_add_overflow(a, b, result);
|
||||
}
|
||||
#else /* !use_builtin(__builtin_add_overflow) */
|
||||
static inline bool u16_add_overflow(u16_t a, u16_t b, u16_t *result)
|
||||
{
|
||||
u16_t c = a + b;
|
||||
|
||||
*result = c;
|
||||
|
||||
return c < a;
|
||||
}
|
||||
|
||||
static inline bool u32_add_overflow(u32_t a, u32_t b, u32_t *result)
|
||||
{
|
||||
u32_t c = a + b;
|
||||
@@ -73,6 +87,11 @@ static inline bool size_add_overflow(size_t a, size_t b, size_t *result)
|
||||
#endif /* use_builtin(__builtin_add_overflow) */
|
||||
|
||||
#if use_builtin(__builtin_mul_overflow)
|
||||
static inline bool u16_mul_overflow(u16_t a, u16_t b, u16_t *result)
|
||||
{
|
||||
return __builtin_mul_overflow(a, b, result);
|
||||
}
|
||||
|
||||
static inline bool u32_mul_overflow(u32_t a, u32_t b, u32_t *result)
|
||||
{
|
||||
return __builtin_mul_overflow(a, b, result);
|
||||
@@ -88,6 +107,15 @@ static inline bool size_mul_overflow(size_t a, size_t b, size_t *result)
|
||||
return __builtin_mul_overflow(a, b, result);
|
||||
}
|
||||
#else /* !use_builtin(__builtin_mul_overflow) */
|
||||
static inline bool u16_mul_overflow(u16_t a, u16_t b, u16_t *result)
|
||||
{
|
||||
u16_t c = a * b;
|
||||
|
||||
*result = c;
|
||||
|
||||
return a != 0 && (c / a) != b;
|
||||
}
|
||||
|
||||
static inline bool u32_mul_overflow(u32_t a, u32_t b, u32_t *result)
|
||||
{
|
||||
u32_t c = a * b;
|
||||
|
||||
@@ -648,6 +648,7 @@ config EXECUTE_XOR_WRITE
|
||||
config STACK_POINTER_RANDOM
|
||||
int "Initial stack pointer randomization bounds"
|
||||
depends on !STACK_GROWS_UP
|
||||
depends on MULTITHREADING
|
||||
depends on TEST_RANDOM_GENERATOR || ENTROPY_HAS_DRIVER
|
||||
default 0
|
||||
help
|
||||
|
||||
@@ -55,11 +55,11 @@ static int cmd_info(const struct shell *shell, size_t argc, char **argv)
|
||||
ARG_UNUSED(argc);
|
||||
ARG_UNUSED(argv);
|
||||
|
||||
char *device_id = k_malloc(DEVICE_ID_MAX_SIZE);
|
||||
char *device_id = k_malloc(DEVICE_ID_HEX_MAX_SIZE);
|
||||
char *firmware_version = k_malloc(BOOT_IMG_VER_STRLEN_MAX);
|
||||
|
||||
updatehub_get_device_identity(device_id, DEVICE_ID_HEX_MAX_SIZE);
|
||||
updatehub_get_firmware_version(firmware_version, BOOT_IMG_VER_STRLEN_MAX);
|
||||
updatehub_get_device_identity(device_id, DEVICE_ID_MAX_SIZE);
|
||||
|
||||
shell_fprintf(shell, SHELL_NORMAL, "Unique device id: %s\n",
|
||||
device_id);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2019 O.S.Systems
|
||||
* Copyright (c) 2018-2020 O.S.Systems
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -35,11 +35,18 @@ LOG_MODULE_REGISTER(updatehub);
|
||||
#define NETWORK_TIMEOUT K_SECONDS(2)
|
||||
#define UPDATEHUB_POLL_INTERVAL K_MINUTES(CONFIG_UPDATEHUB_POLL_INTERVAL)
|
||||
#define MAX_PATH_SIZE 255
|
||||
#define MAX_PAYLOAD_SIZE 500
|
||||
#define MAX_DOWNLOAD_DATA 1100
|
||||
/* MAX_PAYLOAD_SIZE must reflect size COAP_BLOCK_x option */
|
||||
#define MAX_PAYLOAD_SIZE 1024
|
||||
/* MAX_DOWNLOAD_DATA must be equal or bigger than:
|
||||
* MAX_PAYLOAD_SIZE + (len + header + options)
|
||||
* otherwise download size will be less than real size.
|
||||
*/
|
||||
#define MAX_DOWNLOAD_DATA (MAX_PAYLOAD_SIZE + 32)
|
||||
#define COAP_MAX_RETRY 3
|
||||
#define MAX_IP_SIZE 30
|
||||
|
||||
#define SHA256_HEX_DIGEST_SIZE ((TC_SHA256_DIGEST_SIZE * 2) + 1)
|
||||
|
||||
#if defined(CONFIG_UPDATEHUB_CE)
|
||||
#define UPDATEHUB_SERVER CONFIG_UPDATEHUB_SERVER
|
||||
#else
|
||||
@@ -61,11 +68,31 @@ static struct updatehub_context {
|
||||
} ctx;
|
||||
|
||||
static struct update_info {
|
||||
char package_uid[TC_SHA256_BLOCK_SIZE + 1];
|
||||
char sha256sum_image[TC_SHA256_BLOCK_SIZE + 1];
|
||||
char package_uid[SHA256_HEX_DIGEST_SIZE];
|
||||
char sha256sum_image[SHA256_HEX_DIGEST_SIZE];
|
||||
int image_size;
|
||||
} update_info;
|
||||
|
||||
static struct k_delayed_work updatehub_work_handle;
|
||||
|
||||
static int bin2hex_str(u8_t *bin, size_t bin_len, char *str, size_t str_buf_len)
|
||||
{
|
||||
if (bin == NULL || str == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ensures at least an empty string */
|
||||
if (str_buf_len < 1) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
memset(str, 0, str_buf_len);
|
||||
/* str_buf_len - 1 ensure space for \0 */
|
||||
bin2hex(bin, bin_len, str, str_buf_len - 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wait_fds(void)
|
||||
{
|
||||
if (poll(ctx.fds, ctx.nfds, NETWORK_TIMEOUT) < 0) {
|
||||
@@ -76,7 +103,7 @@ static void wait_fds(void)
|
||||
static void prepare_fds(void)
|
||||
{
|
||||
ctx.fds[ctx.nfds].fd = ctx.sock;
|
||||
ctx.fds[ctx.nfds].events = 1;
|
||||
ctx.fds[ctx.nfds].events = POLLIN;
|
||||
ctx.nfds++;
|
||||
}
|
||||
|
||||
@@ -84,8 +111,6 @@ static int metadata_hash_get(char *metadata)
|
||||
{
|
||||
struct tc_sha256_state_struct sha256sum;
|
||||
unsigned char hash[TC_SHA256_DIGEST_SIZE];
|
||||
char buffer[3];
|
||||
int buffer_len = 0;
|
||||
|
||||
if (tc_sha256_init(&sha256sum) == 0) {
|
||||
return -1;
|
||||
@@ -99,13 +124,9 @@ static int metadata_hash_get(char *metadata)
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(update_info.package_uid, 0, TC_SHA256_BLOCK_SIZE + 1);
|
||||
for (int i = 0; i < TC_SHA256_DIGEST_SIZE; i++) {
|
||||
snprintk(buffer, sizeof(buffer), "%02x",
|
||||
hash[i]);
|
||||
buffer_len = buffer_len + strlen(buffer);
|
||||
strncat(&update_info.package_uid[i], buffer,
|
||||
MIN(TC_SHA256_BLOCK_SIZE, buffer_len));
|
||||
if (bin2hex_str(hash, TC_SHA256_DIGEST_SIZE,
|
||||
update_info.package_uid, SHA256_HEX_DIGEST_SIZE)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -141,7 +162,7 @@ static bool start_coap_client(void)
|
||||
}
|
||||
|
||||
#if defined(CONFIG_UPDATEHUB_DTLS)
|
||||
int verify = TLS_PEER_VERIFY_NONE;
|
||||
int verify = TLS_PEER_VERIFY_REQUIRED;
|
||||
sec_tag_t sec_list[] = { CA_CERTIFICATE_TAG };
|
||||
int protocol = IPPROTO_DTLS_1_2;
|
||||
char port[] = "5684";
|
||||
@@ -288,7 +309,7 @@ static int send_request(enum coap_msgtype msgtype, enum coap_method method,
|
||||
}
|
||||
|
||||
ret = coap_packet_append_payload(&request_packet,
|
||||
&ctx.payload,
|
||||
ctx.payload,
|
||||
strlen(ctx.payload));
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Not able to append payload");
|
||||
@@ -315,12 +336,36 @@ error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool install_update_cb_sha256(void)
|
||||
{
|
||||
u8_t hash[TC_SHA256_DIGEST_SIZE];
|
||||
char sha256[SHA256_HEX_DIGEST_SIZE];
|
||||
|
||||
if (tc_sha256_final(hash, &ctx.sha256sum) < 1) {
|
||||
LOG_ERR("Could not finish sha256sum");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bin2hex_str(hash, TC_SHA256_DIGEST_SIZE,
|
||||
sha256, SHA256_HEX_DIGEST_SIZE)) {
|
||||
LOG_ERR("Could not create sha256sum hex representation");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strncmp(sha256, update_info.sha256sum_image,
|
||||
SHA256_HEX_DIGEST_SIZE) != 0) {
|
||||
LOG_ERR("SHA256SUM of image are not the same");
|
||||
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void install_update_cb(void)
|
||||
{
|
||||
struct coap_packet response_packet;
|
||||
char buffer[3], sha256_image_dowloaded[TC_SHA256_BLOCK_SIZE + 1];
|
||||
u8_t *data = k_malloc(MAX_DOWNLOAD_DATA);
|
||||
int i, buffer_len = 0;
|
||||
int rcvd = -1;
|
||||
|
||||
if (data == NULL) {
|
||||
@@ -370,32 +415,15 @@ static void install_update_cb(void)
|
||||
}
|
||||
|
||||
if (coap_next_block(&response_packet, &ctx.block) == 0) {
|
||||
LOG_ERR("Could not get the next");
|
||||
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (ctx.downloaded_size == ctx.block.total_size) {
|
||||
u8_t image_hash[TC_SHA256_DIGEST_SIZE];
|
||||
|
||||
if (tc_sha256_final(image_hash, &ctx.sha256sum) < 1) {
|
||||
LOG_ERR("Could not finish sha256sum");
|
||||
if (ctx.downloaded_size != ctx.block.total_size) {
|
||||
LOG_ERR("Could not get the next coap block");
|
||||
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
memset(&sha256_image_dowloaded, 0, TC_SHA256_BLOCK_SIZE + 1);
|
||||
for (i = 0; i < TC_SHA256_DIGEST_SIZE; i++) {
|
||||
snprintk(buffer, sizeof(buffer), "%02x", image_hash[i]);
|
||||
buffer_len = buffer_len + strlen(buffer);
|
||||
strncat(&sha256_image_dowloaded[i], buffer,
|
||||
MIN(TC_SHA256_BLOCK_SIZE, buffer_len));
|
||||
}
|
||||
|
||||
if (strncmp(sha256_image_dowloaded,
|
||||
update_info.sha256sum_image,
|
||||
strlen(update_info.sha256sum_image)) != 0) {
|
||||
LOG_ERR("SHA256SUM of image are not the same");
|
||||
LOG_INF("Firmware downloaded successfully");
|
||||
if (!install_update_cb_sha256()) {
|
||||
LOG_ERR("Firmware validation has failed");
|
||||
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -479,7 +507,7 @@ static int report(enum updatehub_state state)
|
||||
struct report report;
|
||||
int ret = -1;
|
||||
const char *exec = state_name(state);
|
||||
char *device_id = k_malloc(DEVICE_ID_MAX_SIZE);
|
||||
char *device_id = k_malloc(DEVICE_ID_HEX_MAX_SIZE);
|
||||
char *firmware_version = k_malloc(BOOT_IMG_VER_STRLEN_MAX);
|
||||
|
||||
if (device_id == NULL || firmware_version == NULL) {
|
||||
@@ -487,7 +515,7 @@ static int report(enum updatehub_state state)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!updatehub_get_device_identity(device_id, DEVICE_ID_MAX_SIZE)) {
|
||||
if (!updatehub_get_device_identity(device_id, DEVICE_ID_HEX_MAX_SIZE)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -559,22 +587,23 @@ error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void probe_cb(char *metadata)
|
||||
static void probe_cb(char *metadata, size_t metadata_size)
|
||||
{
|
||||
struct coap_packet reply;
|
||||
char tmp[MAX_PAYLOAD_SIZE];
|
||||
char tmp[MAX_DOWNLOAD_DATA];
|
||||
size_t tmp_len;
|
||||
int rcvd = -1;
|
||||
|
||||
wait_fds();
|
||||
|
||||
rcvd = recv(ctx.sock, metadata, MAX_PAYLOAD_SIZE, MSG_DONTWAIT);
|
||||
rcvd = recv(ctx.sock, tmp, MAX_DOWNLOAD_DATA, MSG_DONTWAIT);
|
||||
if (rcvd <= 0) {
|
||||
LOG_ERR("Could not receive data");
|
||||
ctx.code_status = UPDATEHUB_NETWORKING_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (coap_packet_parse(&reply, metadata, rcvd, NULL, 0) < 0) {
|
||||
if (coap_packet_parse(&reply, tmp, rcvd, NULL, 0) < 0) {
|
||||
LOG_ERR("Invalid data received");
|
||||
ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR;
|
||||
return;
|
||||
@@ -586,10 +615,25 @@ static void probe_cb(char *metadata)
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&tmp, 0, MAX_PAYLOAD_SIZE);
|
||||
memcpy(tmp, reply.data + reply.offset, reply.max_len - reply.offset);
|
||||
memset(metadata, 0, MAX_PAYLOAD_SIZE);
|
||||
memcpy(metadata, tmp, strlen(tmp));
|
||||
/* check if we have buffer space to receive payload */
|
||||
if (metadata_size < (reply.max_len - reply.offset)) {
|
||||
LOG_ERR("There is no buffer available");
|
||||
ctx.code_status = UPDATEHUB_METADATA_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(metadata, reply.data + reply.offset,
|
||||
reply.max_len - reply.offset);
|
||||
|
||||
/* ensures payload have a valid string with size lower
|
||||
* than metadata_size
|
||||
*/
|
||||
tmp_len = strlen(metadata);
|
||||
if (tmp_len >= metadata_size) {
|
||||
LOG_ERR("Invalid metadata data received");
|
||||
ctx.code_status = UPDATEHUB_METADATA_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.code_status = UPDATEHUB_OK;
|
||||
|
||||
@@ -602,11 +646,13 @@ enum updatehub_response updatehub_probe(void)
|
||||
struct resp_probe_some_boards metadata_some_boards;
|
||||
struct resp_probe_any_boards metadata_any_boards;
|
||||
|
||||
char *metadata = k_malloc(MAX_PAYLOAD_SIZE);
|
||||
char *metadata_copy = k_malloc(MAX_PAYLOAD_SIZE);
|
||||
char *device_id = k_malloc(DEVICE_ID_MAX_SIZE);
|
||||
char *metadata = k_malloc(MAX_DOWNLOAD_DATA);
|
||||
char *metadata_copy = k_malloc(MAX_DOWNLOAD_DATA);
|
||||
char *device_id = k_malloc(DEVICE_ID_HEX_MAX_SIZE);
|
||||
char *firmware_version = k_malloc(BOOT_IMG_VER_STRLEN_MAX);
|
||||
|
||||
size_t sha256size;
|
||||
|
||||
if (device_id == NULL || firmware_version == NULL ||
|
||||
metadata == NULL || metadata_copy == NULL) {
|
||||
LOG_ERR("Could not alloc probe memory");
|
||||
@@ -614,8 +660,6 @@ enum updatehub_response updatehub_probe(void)
|
||||
goto error;
|
||||
}
|
||||
|
||||
k_sem_init(&ctx.semaphore, 0, 1);
|
||||
|
||||
if (!boot_is_img_confirmed()) {
|
||||
LOG_ERR("The current image is not confirmed");
|
||||
ctx.code_status = UPDATEHUB_UNCONFIRMED_IMAGE;
|
||||
@@ -627,7 +671,7 @@ enum updatehub_response updatehub_probe(void)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!updatehub_get_device_identity(device_id, DEVICE_ID_MAX_SIZE)) {
|
||||
if (!updatehub_get_device_identity(device_id, DEVICE_ID_HEX_MAX_SIZE)) {
|
||||
ctx.code_status = UPDATEHUB_METADATA_ERROR;
|
||||
goto error;
|
||||
}
|
||||
@@ -658,8 +702,7 @@ enum updatehub_response updatehub_probe(void)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
memset(metadata, 0, MAX_PAYLOAD_SIZE);
|
||||
probe_cb(metadata);
|
||||
probe_cb(metadata, MAX_DOWNLOAD_DATA);
|
||||
|
||||
if (ctx.code_status != UPDATEHUB_OK) {
|
||||
goto cleanup;
|
||||
@@ -687,9 +730,18 @@ enum updatehub_response updatehub_probe(void)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
sha256size = strlen(
|
||||
metadata_any_boards.objects[1].objects.sha256sum) + 1;
|
||||
|
||||
if (sha256size != SHA256_HEX_DIGEST_SIZE) {
|
||||
LOG_ERR("SHA256 size is invalid");
|
||||
ctx.code_status = UPDATEHUB_METADATA_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
memcpy(update_info.sha256sum_image,
|
||||
metadata_any_boards.objects[1].objects.sha256sum,
|
||||
strlen(metadata_any_boards.objects[1].objects.sha256sum));
|
||||
SHA256_HEX_DIGEST_SIZE);
|
||||
update_info.image_size = metadata_any_boards.objects[1].objects.size;
|
||||
} else {
|
||||
if (!is_compatible_hardware(&metadata_some_boards)) {
|
||||
@@ -698,10 +750,19 @@ enum updatehub_response updatehub_probe(void)
|
||||
UPDATEHUB_INCOMPATIBLE_HARDWARE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
sha256size = strlen(
|
||||
metadata_any_boards.objects[1].objects.sha256sum) + 1;
|
||||
|
||||
if (sha256size != SHA256_HEX_DIGEST_SIZE) {
|
||||
LOG_ERR("SHA256 size is invalid");
|
||||
ctx.code_status = UPDATEHUB_METADATA_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
memcpy(update_info.sha256sum_image,
|
||||
metadata_some_boards.objects[1].objects.sha256sum,
|
||||
strlen(metadata_some_boards.objects[1]
|
||||
.objects.sha256sum));
|
||||
SHA256_HEX_DIGEST_SIZE);
|
||||
update_info.image_size =
|
||||
metadata_some_boards.objects[1].objects.size;
|
||||
}
|
||||
@@ -741,6 +802,12 @@ enum updatehub_response updatehub_update(void)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (boot_request_upgrade(BOOT_UPGRADE_TEST)) {
|
||||
LOG_ERR("Could not reporting downloaded state");
|
||||
ctx.code_status = UPDATEHUB_INSTALL_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (report(UPDATEHUB_STATE_INSTALLED) < 0) {
|
||||
LOG_ERR("Could not reporting installed state");
|
||||
goto error;
|
||||
@@ -765,7 +832,7 @@ error:
|
||||
return ctx.code_status;
|
||||
}
|
||||
|
||||
static void autohandler(struct k_delayed_work *work)
|
||||
static void autohandler(struct k_work *work)
|
||||
{
|
||||
switch (updatehub_probe()) {
|
||||
case UPDATEHUB_UNCONFIRMED_IMAGE:
|
||||
@@ -794,13 +861,11 @@ static void autohandler(struct k_delayed_work *work)
|
||||
break;
|
||||
}
|
||||
|
||||
k_delayed_work_submit(work, UPDATEHUB_POLL_INTERVAL);
|
||||
k_delayed_work_submit(&updatehub_work_handle, UPDATEHUB_POLL_INTERVAL);
|
||||
}
|
||||
|
||||
void updatehub_autohandler(void)
|
||||
{
|
||||
static struct k_delayed_work work;
|
||||
|
||||
k_delayed_work_init(&work, autohandler);
|
||||
k_delayed_work_submit(&work, K_NO_WAIT);
|
||||
k_delayed_work_init(&updatehub_work_handle, autohandler);
|
||||
k_delayed_work_submit(&updatehub_work_handle, K_NO_WAIT);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018 O.S.Systems
|
||||
* Copyright (c) 2018-2020 O.S.Systems
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -7,23 +7,16 @@
|
||||
|
||||
bool updatehub_get_device_identity(char *id, int id_max_len)
|
||||
{
|
||||
int i, id_len = 0, buf_len = 0;
|
||||
char buf[3];
|
||||
u8_t hwinfo_id[id_max_len];
|
||||
u8_t hwinfo_id[DEVICE_ID_BIN_MAX_SIZE];
|
||||
size_t length;
|
||||
|
||||
length = hwinfo_get_device_id(hwinfo_id, sizeof(hwinfo_id) - 1);
|
||||
length = hwinfo_get_device_id(hwinfo_id, DEVICE_ID_BIN_MAX_SIZE);
|
||||
if (length <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(id, 0, id_max_len);
|
||||
length = bin2hex(hwinfo_id, length, id, id_max_len - 1);
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
snprintk(buf, sizeof(buf), "%02x", hwinfo_id[i]);
|
||||
id_len = strlen(id);
|
||||
strncat(id, buf, id_max_len - id_len);
|
||||
}
|
||||
|
||||
return true;
|
||||
return length > 0;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
#include <zephyr.h>
|
||||
#include <drivers/hwinfo.h>
|
||||
|
||||
#define DEVICE_ID_MAX_SIZE 65
|
||||
#define DEVICE_ID_BIN_MAX_SIZE 64
|
||||
#define DEVICE_ID_HEX_MAX_SIZE ((DEVICE_ID_BIN_MAX_SIZE * 2) + 1)
|
||||
|
||||
bool updatehub_get_device_identity(char *id, int id_max_len);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.. _blinky-sample:
|
||||
|
||||
Blinky Application
|
||||
##################
|
||||
Blinky sample
|
||||
#############
|
||||
|
||||
Overview
|
||||
********
|
||||
@@ -10,22 +10,24 @@ The Blinky example shows how to configure GPIO pins as outputs which can also be
|
||||
used to drive LEDs on the hardware usually delivered as "User LEDs" on many of
|
||||
the supported boards in Zephyr.
|
||||
|
||||
.. _blinky-sample-requirements:
|
||||
|
||||
Requirements
|
||||
************
|
||||
|
||||
The demo assumes that an LED is connected to one of GPIO lines. The
|
||||
sample code is configured to work on boards that have defined the led0
|
||||
alias in their board devicetree description file. Doing so will generate
|
||||
these variables:
|
||||
|
||||
- DT_ALIAS_LED0_GPIOS_CONTROLLER
|
||||
- DT_ALIAS_LED0_GPIOS_PIN
|
||||
sample code is configured to work on boards that have defined the ``led0``
|
||||
alias in their :ref:`board's devicetree description file
|
||||
<devicetree-in-out-files>`, :file:`<board>.dts`.
|
||||
Doing so will generate these variables:
|
||||
|
||||
- ``DT_ALIAS_LED0_GPIOS_CONTROLLER``
|
||||
- ``DT_ALIAS_LED0_GPIOS_PIN``
|
||||
|
||||
Building and Running
|
||||
********************
|
||||
|
||||
This samples does not output anything to the console. It can be built and
|
||||
This sample does not output anything to the console. It can be built and
|
||||
flashed to a board as follows:
|
||||
|
||||
.. zephyr-app-commands::
|
||||
|
||||
@@ -12,7 +12,19 @@
|
||||
#define SLEEP_TIME_MS 1000
|
||||
|
||||
#ifndef DT_ALIAS_LED0_GPIOS_FLAGS
|
||||
#define DT_ALIAS_LED0_GPIOS_FLAGS 0
|
||||
#define FLAGS 0
|
||||
#else
|
||||
#define FLAGS DT_ALIAS_LED0_GPIOS_FLAGS
|
||||
#endif
|
||||
|
||||
/* Make sure the board's devicetree declares led0 in its /aliases. */
|
||||
#ifdef DT_ALIAS_LED0_GPIOS_CONTROLLER
|
||||
#define LED0 DT_ALIAS_LED0_GPIOS_CONTROLLER
|
||||
#define PIN DT_ALIAS_LED0_GPIOS_PIN
|
||||
#else
|
||||
#error "Unsupported board: led0 devicetree alias is not defined"
|
||||
#define LED0 ""
|
||||
#define PIN 0
|
||||
#endif
|
||||
|
||||
void main(void)
|
||||
@@ -21,20 +33,18 @@ void main(void)
|
||||
bool led_is_on = true;
|
||||
int ret;
|
||||
|
||||
dev = device_get_binding(DT_ALIAS_LED0_GPIOS_CONTROLLER);
|
||||
dev = device_get_binding(LED0);
|
||||
if (dev == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ret = gpio_pin_configure(dev, DT_ALIAS_LED0_GPIOS_PIN,
|
||||
GPIO_OUTPUT_ACTIVE
|
||||
| DT_ALIAS_LED0_GPIOS_FLAGS);
|
||||
ret = gpio_pin_configure(dev, PIN, GPIO_OUTPUT_ACTIVE | FLAGS);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
gpio_pin_set(dev, DT_ALIAS_LED0_GPIOS_PIN, (int)led_is_on);
|
||||
gpio_pin_set(dev, PIN, (int)led_is_on);
|
||||
led_is_on = !led_is_on;
|
||||
k_sleep(SLEEP_TIME_MS);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
CONFIG_LOG=y
|
||||
CONFIG_WDT_LOG_LEVEL_DBG=y
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_WDT_DISABLE_AT_BOOT=n
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
CONFIG_UPDATEHUB=y
|
||||
|
||||
#Minimal Heap mem pool size for the updatehub working
|
||||
CONFIG_HEAP_MEM_POOL_SIZE=2048
|
||||
CONFIG_HEAP_MEM_POOL_SIZE=8192
|
||||
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
|
||||
|
||||
CONFIG_NET_IPV4=y
|
||||
|
||||
13
samples/sensor/bme280/nrf52840_pca10056.overlay
Normal file
13
samples/sensor/bme280/nrf52840_pca10056.overlay
Normal file
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
&i2c0 {
|
||||
bme280@76 {
|
||||
compatible = "bosch,bme280";
|
||||
reg = <0x76>;
|
||||
label = "BME280";
|
||||
};
|
||||
};
|
||||
@@ -4,7 +4,7 @@ tests:
|
||||
sample.sensor.bme280:
|
||||
harness: console
|
||||
tags: sensors
|
||||
depends_on: i2c bme280
|
||||
platform_whitelist: nrf52840_pca10056
|
||||
harness_config:
|
||||
type: one_line
|
||||
regex:
|
||||
|
||||
@@ -30,12 +30,12 @@ Building and Running
|
||||
This project outputs sensor data to the console. It requires a BME680
|
||||
sensor. It should work with any platform featuring a I2C peripheral interface.
|
||||
It does not work on QEMU.
|
||||
In this example below the :ref:`nrf52_pca10040` board is used.
|
||||
In this example below the :ref:`nrf52840_pca10056` board is used.
|
||||
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/sensor/bme680
|
||||
:board: nrf52_pca10040
|
||||
:board: nrf52840_pca10056
|
||||
:goals: build flash
|
||||
|
||||
Sample Output
|
||||
|
||||
13
samples/sensor/bme680/nrf52840_pca10056.overlay
Normal file
13
samples/sensor/bme680/nrf52840_pca10056.overlay
Normal file
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
&i2c0 {
|
||||
bme680@76 {
|
||||
compatible = "bosch,bme680";
|
||||
reg = <0x76>;
|
||||
label = "BME680";
|
||||
};
|
||||
};
|
||||
@@ -4,4 +4,4 @@ tests:
|
||||
sample.sensor.bme680:
|
||||
harness: sensor
|
||||
tags: samples sensor
|
||||
depends_on: i2c bme680
|
||||
platform_whitelist: nrf52840_pca10056
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Pillow
|
||||
PyYAML>=5.1
|
||||
anytree
|
||||
breathe>=4.9.1
|
||||
breathe>=4.9.1,<4.15.0
|
||||
colorama
|
||||
docutils>=0.14
|
||||
gcovr>=4.2
|
||||
@@ -15,7 +15,7 @@ pykwalify
|
||||
pyocd>=0.24.0
|
||||
pyserial
|
||||
pytest
|
||||
sphinx>=1.7.5
|
||||
sphinx>=1.7.5,<3.0.0
|
||||
sphinx_rtd_theme
|
||||
sphinx-tabs
|
||||
sphinxcontrib-svg2pdfconverter
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -56,13 +56,20 @@ class DfuUtilBinaryRunner(ZephyrBinaryRunner):
|
||||
parser.add_argument("--img",
|
||||
help="binary to flash, default is --bin-file")
|
||||
parser.add_argument("--dfuse", default=False, action='store_true',
|
||||
help='''set if target is a DfuSe device;
|
||||
implies --dt-flash.''')
|
||||
help='''use the DfuSe protocol extensions
|
||||
supported by STMicroelectronics
|
||||
devices (if given, the image flash
|
||||
address respects
|
||||
CONFIG_FLASH_BASE_ADDRESS and
|
||||
CONFIG_FLASH_LOAD_OFFSET)''')
|
||||
parser.add_argument("--dfuse-modifiers", default='leave',
|
||||
help='''colon-separated list of DfuSe modifiers
|
||||
(default is "leave", which starts execution
|
||||
immediately); --dfuse must also be given for this
|
||||
option to take effect.''')
|
||||
help='''colon-separated list of additional
|
||||
DfuSe modifiers for dfu-util's -s
|
||||
option (default is
|
||||
"-s <flash-address>:leave", which starts
|
||||
execution immediately); requires
|
||||
--dfuse
|
||||
''')
|
||||
parser.add_argument('--dfu-util', default='dfu-util',
|
||||
help='dfu-util executable; defaults to "dfu-util"')
|
||||
|
||||
|
||||
@@ -15,13 +15,13 @@ from runners.core import ZephyrBinaryRunner, RunnerCaps
|
||||
class MiscFlasher(ZephyrBinaryRunner):
|
||||
'''Runner for handling special purpose flashing commands.'''
|
||||
|
||||
def __init__(self, cfg, command, args):
|
||||
def __init__(self, cfg, cmd, args):
|
||||
super().__init__(cfg)
|
||||
if not command:
|
||||
if not cmd:
|
||||
# This is a board definition error, not a user error,
|
||||
# so we can do it now and not in do_run().
|
||||
raise ValueError('no command was given')
|
||||
self.command = command
|
||||
self.cmd = cmd
|
||||
self.args = args
|
||||
|
||||
@classmethod
|
||||
@@ -34,7 +34,7 @@ class MiscFlasher(ZephyrBinaryRunner):
|
||||
|
||||
@classmethod
|
||||
def do_add_parser(cls, parser):
|
||||
parser.add_argument('command',
|
||||
parser.add_argument('cmd',
|
||||
help='''command to run; it will be passed the
|
||||
build directory as its first argument''')
|
||||
parser.add_argument('args', nargs='*',
|
||||
@@ -43,8 +43,8 @@ class MiscFlasher(ZephyrBinaryRunner):
|
||||
|
||||
@classmethod
|
||||
def create(cls, cfg, args):
|
||||
return MiscFlasher(cfg, args.command, args.args)
|
||||
return MiscFlasher(cfg, args.cmd, args.args)
|
||||
|
||||
def do_run(self, *args, **kwargs):
|
||||
self.require(self.command)
|
||||
self.check_call([self.command, self.cfg.build_dir] + self.args)
|
||||
self.require(self.cmd)
|
||||
self.check_call([self.cmd, self.cfg.build_dir] + self.args)
|
||||
|
||||
@@ -6,11 +6,9 @@
|
||||
if SOC_STM32G474XX
|
||||
|
||||
config SOC
|
||||
string
|
||||
default "stm32g474xx"
|
||||
|
||||
config NUM_IRQS
|
||||
int
|
||||
default 102
|
||||
|
||||
endif # SOC_STM32G474XX
|
||||
|
||||
@@ -117,7 +117,6 @@ config BT_LLL_VENDOR_NORDIC
|
||||
select BT_HAS_HCI_VS
|
||||
select ENTROPY_NRF5_RNG
|
||||
select ENTROPY_NRF5_BIAS_CORRECTION
|
||||
|
||||
select BT_CTLR_LE_ENC_SUPPORT if !BT_CTLR_DATA_LENGTH_CLEAR && \
|
||||
!BT_CTLR_PHY_2M_NRF
|
||||
select BT_CTLR_CONN_PARAM_REQ_SUPPORT
|
||||
@@ -137,11 +136,6 @@ config BT_LLL_VENDOR_NORDIC
|
||||
select BT_CTLR_XTAL_ADVANCED_SUPPORT
|
||||
select BT_CTLR_SCHED_ADVANCED_SUPPORT
|
||||
select BT_CTLR_TIFS_HW_SUPPORT
|
||||
|
||||
# Until ticker resolve collision is fixed for skipped ticker catch-up
|
||||
# issue, use the old compatibility mode
|
||||
select BT_TICKER_COMPATIBILITY_MODE
|
||||
|
||||
default y
|
||||
help
|
||||
Use Nordic Lower Link Layer implementation.
|
||||
@@ -876,6 +870,15 @@ config BT_CTLR_USER_EVT_RANGE
|
||||
Number of event types reserved for proprietary use. The range
|
||||
is typically used when BT_CTLR_USER_EXT is in use.
|
||||
|
||||
config BT_CTLR_USER_TICKER_ID_RANGE
|
||||
int "Range of ticker id constants reserved for proprietary ticker nodes"
|
||||
depends on BT_CTLR_USER_EXT
|
||||
default 0
|
||||
range 0 10
|
||||
help
|
||||
Number of ticker ids reserved for proprietary use. The range
|
||||
is typically used when BT_CTLR_USER_EXT is in use.
|
||||
|
||||
config BT_RX_USER_PDU_LEN
|
||||
int "Maximum supported proprietary PDU buffer length"
|
||||
depends on BT_CTLR_USER_EXT
|
||||
|
||||
@@ -103,6 +103,7 @@
|
||||
|
||||
#define LL_FEAT_BIT_MASK 0x1FFFF
|
||||
#define LL_FEAT_BIT_MASK_VALID 0x1CF2F
|
||||
#define LL_FEAT_FILTER_OCTET0 0x1FF00
|
||||
#define LL_FEAT (LL_FEAT_BIT_ENC | \
|
||||
LL_FEAT_BIT_CONN_PARAM_REQ | \
|
||||
LL_FEAT_BIT_EXT_REJ_IND | \
|
||||
|
||||
@@ -66,10 +66,11 @@
|
||||
#define RADIO_PKT_TIME(octets, phy) \
|
||||
(((phy) & BIT(2)) ? \
|
||||
(80 + 256 + 16 + 24 + ((((2 + (octets) + 4) * 8) + 24 + 3) * 8)) : \
|
||||
(((octets) + 14) * 8 / BIT(((phy) & 0x03) >> 1)))
|
||||
(((octets) + 13 + PREAMBLE_SIZE(phy)) * 8 / \
|
||||
BIT(((phy) & 0x03) >> 1)))
|
||||
#else /* !CONFIG_BT_CTLR_PHY_CODED */
|
||||
#define RADIO_PKT_TIME(octets, phy) \
|
||||
(((octets) + 14) * 8 / BIT(((phy) & 0x03) >> 1))
|
||||
(((octets) + 13 + PREAMBLE_SIZE(phy)) * 8 / BIT(((phy) & 0x03) >> 1))
|
||||
#endif /* !CONFIG_BT_CTLR_PHY_CODED */
|
||||
|
||||
/* Inter Frame Space */
|
||||
@@ -641,7 +642,8 @@ static void common_init(void)
|
||||
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
|
||||
/* Initialize the DLE defaults */
|
||||
_radio.default_tx_octets = PDU_DC_PAYLOAD_SIZE_MIN;
|
||||
_radio.default_tx_time = RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0);
|
||||
_radio.default_tx_time =
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0));
|
||||
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
@@ -2245,8 +2247,8 @@ isr_rx_conn_pkt_ctrl_rej_dle(struct radio_pdu_node_rx *node_rx,
|
||||
lr->max_rx_octets = conn->max_rx_octets;
|
||||
lr->max_tx_octets = conn->max_tx_octets;
|
||||
#if !defined(CONFIG_BT_CTLR_PHY)
|
||||
lr->max_rx_time = RADIO_PKT_TIME(conn->max_rx_octets, 0);
|
||||
lr->max_tx_time = RADIO_PKT_TIME(conn->max_tx_octets, 0);
|
||||
lr->max_rx_time = RADIO_PKT_TIME(conn->max_rx_octets, BIT(0));
|
||||
lr->max_tx_time = RADIO_PKT_TIME(conn->max_tx_octets, BIT(0));
|
||||
#else /* CONFIG_BT_CTLR_PHY */
|
||||
lr->max_rx_time = conn->max_rx_time;
|
||||
lr->max_tx_time = conn->max_tx_time;
|
||||
@@ -2464,7 +2466,7 @@ static inline u8_t isr_rx_conn_pkt_ctrl_dle(struct pdu_data *pdu_data_rx,
|
||||
* peer max_rx_time
|
||||
*/
|
||||
if (lr->max_rx_time >=
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0)) {
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0))) {
|
||||
eff_tx_time =
|
||||
MIN(lr->max_rx_time,
|
||||
_radio.conn_curr->default_tx_time);
|
||||
@@ -2480,7 +2482,7 @@ static inline u8_t isr_rx_conn_pkt_ctrl_dle(struct pdu_data *pdu_data_rx,
|
||||
* peer max_tx_time
|
||||
*/
|
||||
if (lr->max_tx_time >=
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0)) {
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0))) {
|
||||
eff_rx_time =
|
||||
MIN(lr->max_tx_time,
|
||||
RADIO_PKT_TIME(LL_LENGTH_OCTETS_RX_MAX,
|
||||
@@ -2610,8 +2612,8 @@ static inline u8_t isr_rx_conn_pkt_ctrl_dle(struct pdu_data *pdu_data_rx,
|
||||
lr->max_tx_octets = eff_tx_octets;
|
||||
|
||||
#if !defined(CONFIG_BT_CTLR_PHY)
|
||||
lr->max_rx_time = RADIO_PKT_TIME(eff_rx_octets, 0);
|
||||
lr->max_tx_time = RADIO_PKT_TIME(eff_tx_octets, 0);
|
||||
lr->max_rx_time = RADIO_PKT_TIME(eff_rx_octets, BIT(0));
|
||||
lr->max_tx_time = RADIO_PKT_TIME(eff_tx_octets, BIT(0));
|
||||
#else /* CONFIG_BT_CTLR_PHY */
|
||||
lr->max_rx_time = eff_rx_time;
|
||||
lr->max_tx_time = eff_tx_time;
|
||||
@@ -4849,10 +4851,10 @@ static inline void isr_close_conn(void)
|
||||
rx_time = conn->max_rx_time;
|
||||
}
|
||||
#else /* !CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
tx_time = MAX(RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0),
|
||||
tx_time = MAX(RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0)),
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN,
|
||||
conn->phy_tx));
|
||||
rx_time = MAX(RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0),
|
||||
rx_time = MAX(RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0)),
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN,
|
||||
conn->phy_rx));
|
||||
#endif /* !CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
@@ -4860,12 +4862,13 @@ static inline void isr_close_conn(void)
|
||||
ready_delay = (conn->role) ?
|
||||
radio_rx_ready_delay_get(0, 0) :
|
||||
radio_tx_ready_delay_get(0, 0);
|
||||
tx_time = RADIO_PKT_TIME(conn->max_tx_octets, 0);
|
||||
tx_time = RADIO_PKT_TIME(conn->max_tx_octets, BIT(0));
|
||||
if (conn->evt_len_adv) {
|
||||
rx_time = RADIO_PKT_TIME(conn->llcp_length.rx_octets,
|
||||
0);
|
||||
BIT(0));
|
||||
} else {
|
||||
rx_time = RADIO_PKT_TIME(conn->max_rx_octets, 0);
|
||||
rx_time = RADIO_PKT_TIME(conn->max_rx_octets,
|
||||
BIT(0));
|
||||
}
|
||||
#endif /* !CONFIG_BT_CTLR_PHY */
|
||||
|
||||
@@ -8428,12 +8431,12 @@ static inline int event_len_prep(struct connection *conn)
|
||||
#endif /* !CONFIG_BT_CTLR_PHY */
|
||||
) {
|
||||
lr->max_rx_time =
|
||||
RADIO_PKT_TIME(LL_LENGTH_OCTETS_RX_MAX, 0);
|
||||
RADIO_PKT_TIME(LL_LENGTH_OCTETS_RX_MAX, BIT(0));
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
lr->max_tx_time = conn->default_tx_time;
|
||||
#else /* !CONFIG_BT_CTLR_PHY */
|
||||
lr->max_tx_time =
|
||||
RADIO_PKT_TIME(conn->default_tx_octets, 0);
|
||||
RADIO_PKT_TIME(conn->default_tx_octets, BIT(0));
|
||||
#endif /* !CONFIG_BT_CTLR_PHY */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
@@ -8637,8 +8640,8 @@ static inline int event_len_prep(struct connection *conn)
|
||||
lr->max_rx_octets = conn->max_rx_octets;
|
||||
lr->max_tx_octets = tx_octets;
|
||||
#if !defined(CONFIG_BT_CTLR_PHY)
|
||||
lr->max_rx_time = RADIO_PKT_TIME(conn->max_rx_octets, 0);
|
||||
lr->max_tx_time = RADIO_PKT_TIME(tx_octets, 0);
|
||||
lr->max_rx_time = RADIO_PKT_TIME(conn->max_rx_octets, BIT(0));
|
||||
lr->max_tx_time = RADIO_PKT_TIME(tx_octets, BIT(0));
|
||||
#else /* CONFIG_BT_CTLR_PHY */
|
||||
lr->max_rx_time = conn->max_rx_time;
|
||||
lr->max_tx_time = tx_time;
|
||||
@@ -8862,7 +8865,7 @@ static inline void event_phy_upd_ind_prep(struct connection *conn,
|
||||
u16_t tx_time = RADIO_PKT_TIME(conn->max_tx_octets,
|
||||
conn->phy_tx);
|
||||
if (tx_time >=
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0)) {
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0))) {
|
||||
eff_tx_time = MIN(tx_time,
|
||||
conn->default_tx_time);
|
||||
#if defined(CONFIG_BT_CTLR_PHY_CODED)
|
||||
@@ -8873,7 +8876,7 @@ static inline void event_phy_upd_ind_prep(struct connection *conn,
|
||||
} else {
|
||||
eff_tx_time =
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN,
|
||||
0);
|
||||
BIT(0));
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
}
|
||||
@@ -8885,7 +8888,7 @@ static inline void event_phy_upd_ind_prep(struct connection *conn,
|
||||
u16_t rx_time = RADIO_PKT_TIME(conn->max_rx_octets,
|
||||
conn->phy_rx);
|
||||
if (rx_time >=
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0)) {
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0))) {
|
||||
eff_rx_time = MIN(rx_time,
|
||||
RADIO_PKT_TIME(LL_LENGTH_OCTETS_RX_MAX,
|
||||
BIT(2)));
|
||||
@@ -8897,7 +8900,7 @@ static inline void event_phy_upd_ind_prep(struct connection *conn,
|
||||
} else {
|
||||
eff_rx_time =
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN,
|
||||
0);
|
||||
BIT(0));
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
}
|
||||
@@ -11043,9 +11046,9 @@ static void length_resp_send(struct connection *conn,
|
||||
|
||||
#if !defined(CONFIG_BT_CTLR_PHY)
|
||||
pdu_ctrl_tx->llctrl.length_rsp.max_rx_time =
|
||||
RADIO_PKT_TIME(eff_rx_octets, 0);
|
||||
RADIO_PKT_TIME(eff_rx_octets, BIT(0));
|
||||
pdu_ctrl_tx->llctrl.length_rsp.max_tx_time =
|
||||
RADIO_PKT_TIME(eff_tx_octets, 0);
|
||||
RADIO_PKT_TIME(eff_tx_octets, BIT(0));
|
||||
#else /* CONFIG_BT_CTLR_PHY */
|
||||
pdu_ctrl_tx->llctrl.length_rsp.max_rx_time = eff_rx_time;
|
||||
pdu_ctrl_tx->llctrl.length_rsp.max_tx_time = eff_tx_time;
|
||||
@@ -11536,9 +11539,9 @@ u32_t radio_adv_enable(u16_t interval, u8_t chan_map, u8_t filter_policy,
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
conn->default_tx_time = _radio.default_tx_time;
|
||||
conn->max_tx_time =
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0);
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0));
|
||||
conn->max_rx_time =
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0);
|
||||
RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0));
|
||||
#endif /* CONFIG_BT_CTLR_PHY */
|
||||
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
|
||||
@@ -12075,8 +12078,8 @@ u32_t radio_connect_enable(u8_t adv_addr_type, u8_t *adv_addr, u16_t interval,
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
conn->default_tx_time = _radio.default_tx_time;
|
||||
conn->max_tx_time = RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0);
|
||||
conn->max_rx_time = RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, 0);
|
||||
conn->max_tx_time = RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0));
|
||||
conn->max_rx_time = RADIO_PKT_TIME(PDU_DC_PAYLOAD_SIZE_MIN, BIT(0));
|
||||
#endif /* CONFIG_BT_CTLR_PHY */
|
||||
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
|
||||
|
||||
@@ -54,6 +54,13 @@ enum {
|
||||
1),
|
||||
#endif /* CONFIG_BT_CONN */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_USER_EXT) && \
|
||||
(CONFIG_BT_CTLR_USER_TICKER_ID_RANGE > 0)
|
||||
TICKER_ID_USER_BASE,
|
||||
TICKER_ID_USER_LAST = (TICKER_ID_USER_BASE +
|
||||
CONFIG_BT_CTLR_USER_TICKER_ID_RANGE - 1),
|
||||
#endif /* CONFIG_BT_CTLR_USER_EXT */
|
||||
|
||||
TICKER_ID_MAX,
|
||||
};
|
||||
|
||||
|
||||
@@ -688,6 +688,7 @@ static int isr_rx_pdu(struct lll_conn *lll, struct pdu_data *pdu_data_rx,
|
||||
if (link) {
|
||||
struct pdu_data *pdu_data_tx;
|
||||
u8_t pdu_data_tx_len;
|
||||
u8_t offset;
|
||||
|
||||
pdu_data_tx = (void *)(tx->pdu +
|
||||
lll->packet_tx_head_offset);
|
||||
@@ -702,9 +703,10 @@ static int isr_rx_pdu(struct lll_conn *lll, struct pdu_data *pdu_data_rx,
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_LE_ENC */
|
||||
|
||||
lll->packet_tx_head_offset += pdu_data_tx_len;
|
||||
if (lll->packet_tx_head_offset ==
|
||||
lll->packet_tx_head_len) {
|
||||
offset = lll->packet_tx_head_offset + pdu_data_tx_len;
|
||||
if (offset < lll->packet_tx_head_len) {
|
||||
lll->packet_tx_head_offset = offset;
|
||||
} else if (offset == lll->packet_tx_head_len) {
|
||||
lll->packet_tx_head_len = 0;
|
||||
lll->packet_tx_head_offset = 0;
|
||||
|
||||
|
||||
@@ -98,11 +98,18 @@
|
||||
#define FLASH_TICKER_USER_APP_OPS 0
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_USER_EXT)
|
||||
#define USER_TICKER_NODES CONFIG_BT_CTLR_USER_TICKER_ID_RANGE
|
||||
#else
|
||||
#define USER_TICKER_NODES 0
|
||||
#endif
|
||||
|
||||
#define TICKER_NODES (TICKER_ID_ULL_BASE + \
|
||||
BT_ADV_TICKER_NODES + \
|
||||
BT_SCAN_TICKER_NODES + \
|
||||
BT_CONN_TICKER_NODES + \
|
||||
FLASH_TICKER_NODES)
|
||||
FLASH_TICKER_NODES + \
|
||||
USER_TICKER_NODES)
|
||||
#define TICKER_USER_APP_OPS (TICKER_USER_THREAD_OPS + \
|
||||
FLASH_TICKER_USER_APP_OPS)
|
||||
#define TICKER_USER_OPS (TICKER_USER_LLL_OPS + \
|
||||
|
||||
@@ -600,8 +600,8 @@ u8_t ll_adv_enable(u8_t enable)
|
||||
/* Use the default 1M packet max time. Value of 0 is
|
||||
* equivalent to using BIT(0).
|
||||
*/
|
||||
conn_lll->max_tx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0);
|
||||
conn_lll->max_rx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0);
|
||||
conn_lll->max_tx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M);
|
||||
conn_lll->max_rx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M);
|
||||
#endif /* CONFIG_BT_CTLR_PHY */
|
||||
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
|
||||
@@ -650,7 +650,8 @@ u8_t ll_adv_enable(u8_t enable)
|
||||
conn->llcp_rx = NULL;
|
||||
conn->llcp_cu.req = conn->llcp_cu.ack = 0;
|
||||
conn->llcp_feature.req = conn->llcp_feature.ack = 0;
|
||||
conn->llcp_feature.features = LL_FEAT;
|
||||
conn->llcp_feature.features_conn = LL_FEAT;
|
||||
conn->llcp_feature.features_peer = 0;
|
||||
conn->llcp_version.req = conn->llcp_version.ack = 0;
|
||||
conn->llcp_version.tx = conn->llcp_version.rx = 0;
|
||||
conn->llcp_terminate.reason_peer = 0;
|
||||
|
||||
@@ -275,7 +275,7 @@ u8_t ll_conn_update(u16_t handle, u8_t cmd, u8_t status, u16_t interval_min,
|
||||
#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
|
||||
if (!conn->llcp_conn_param.disabled &&
|
||||
(!conn->common.fex_valid ||
|
||||
(conn->llcp_feature.features &
|
||||
(conn->llcp_feature.features_conn &
|
||||
BIT(BT_LE_FEAT_BIT_CONN_PARAM_REQ)))) {
|
||||
cmd++;
|
||||
} else if (conn->lll.role) {
|
||||
@@ -480,12 +480,12 @@ void ll_length_max_get(u16_t *max_tx_octets, u16_t *max_tx_time,
|
||||
*max_tx_octets = LL_LENGTH_OCTETS_RX_MAX;
|
||||
*max_rx_octets = LL_LENGTH_OCTETS_RX_MAX;
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
*max_tx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, BIT(2));
|
||||
*max_rx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, BIT(2));
|
||||
*max_tx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_CODED);
|
||||
*max_rx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_CODED);
|
||||
#else /* !CONFIG_BT_CTLR_PHY */
|
||||
/* Default is 1M packet timing */
|
||||
*max_tx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, 0);
|
||||
*max_rx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, 0);
|
||||
*max_tx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_1M);
|
||||
*max_rx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_1M);
|
||||
#endif /* !CONFIG_BT_CTLR_PHY */
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
@@ -1045,6 +1045,10 @@ void ull_conn_done(struct node_rx_event_done *done)
|
||||
ull_slave_done(done, &ticks_drift_plus,
|
||||
&ticks_drift_minus);
|
||||
|
||||
if (!conn->tx_head) {
|
||||
ull_conn_tx_demux(UINT8_MAX);
|
||||
}
|
||||
|
||||
if (conn->tx_head || memq_peek(lll->memq_tx.head,
|
||||
lll->memq_tx.tail,
|
||||
NULL)) {
|
||||
@@ -1209,9 +1213,10 @@ void ull_conn_done(struct node_rx_event_done *done)
|
||||
#endif /* CONFIG_BT_CTLR_CONN_RSSI */
|
||||
|
||||
/* break latency based on ctrl procedure pending */
|
||||
if ((((conn->llcp_req - conn->llcp_ack) & 0x03) == 0x02) &&
|
||||
((conn->llcp_type == LLCP_CONN_UPD) ||
|
||||
(conn->llcp_type == LLCP_CHAN_MAP))) {
|
||||
if (((((conn->llcp_req - conn->llcp_ack) & 0x03) == 0x02) &&
|
||||
((conn->llcp_type == LLCP_CONN_UPD) ||
|
||||
(conn->llcp_type == LLCP_CHAN_MAP))) ||
|
||||
(conn->llcp_cu.req != conn->llcp_cu.ack)) {
|
||||
lll->latency_event = 0;
|
||||
}
|
||||
|
||||
@@ -1583,7 +1588,7 @@ static int init_reset(void)
|
||||
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
|
||||
/* Initialize the DLE defaults */
|
||||
default_tx_octets = PDU_DC_PAYLOAD_SIZE_MIN;
|
||||
default_tx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0);
|
||||
default_tx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M);
|
||||
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
@@ -2494,7 +2499,8 @@ static inline void event_enc_reject_prep(struct ll_conn *conn,
|
||||
pdu->ll_id = PDU_DATA_LLID_CTRL;
|
||||
|
||||
if (conn->common.fex_valid &&
|
||||
(conn->llcp_feature.features & BIT(BT_LE_FEAT_BIT_EXT_REJ_IND))) {
|
||||
(conn->llcp_feature.features_conn &
|
||||
BIT(BT_LE_FEAT_BIT_EXT_REJ_IND))) {
|
||||
struct pdu_data_llctrl_reject_ext_ind *p;
|
||||
|
||||
pdu->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND;
|
||||
@@ -2722,7 +2728,7 @@ static inline void event_fex_prep(struct ll_conn *conn)
|
||||
pdu->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_FEATURE_RSP;
|
||||
(void)memset(&pdu->llctrl.feature_rsp.features[0], 0x00,
|
||||
sizeof(pdu->llctrl.feature_rsp.features));
|
||||
sys_put_le24(conn->llcp_feature.features,
|
||||
sys_put_le24(conn->llcp_feature.features_peer,
|
||||
pdu->llctrl.feature_req.features);
|
||||
|
||||
/* enqueue feature rsp structure into rx queue */
|
||||
@@ -2740,7 +2746,7 @@ static inline void event_fex_prep(struct ll_conn *conn)
|
||||
conn->llcp_feature.ack--;
|
||||
|
||||
/* use initial feature bitmap */
|
||||
conn->llcp_feature.features = LL_FEAT;
|
||||
conn->llcp_feature.features_conn = LL_FEAT;
|
||||
|
||||
/* place the feature exchange req packet as next in tx queue */
|
||||
pdu->ll_id = PDU_DATA_LLID_CTRL;
|
||||
@@ -2752,7 +2758,7 @@ static inline void event_fex_prep(struct ll_conn *conn)
|
||||
(void)memset(&pdu->llctrl.feature_req.features[0],
|
||||
0x00,
|
||||
sizeof(pdu->llctrl.feature_req.features));
|
||||
sys_put_le24(conn->llcp_feature.features,
|
||||
sys_put_le24(conn->llcp_feature.features_conn,
|
||||
pdu->llctrl.feature_req.features);
|
||||
|
||||
ctrl_tx_enqueue(conn, tx);
|
||||
@@ -3157,14 +3163,14 @@ static inline void dle_max_time_get(const struct ll_conn *conn,
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
#if defined(CONFIG_BT_CTLR_PHY_CODED)
|
||||
feature_coded_phy = (conn->llcp_feature.features &
|
||||
feature_coded_phy = (conn->llcp_feature.features_conn &
|
||||
BIT(BT_LE_FEAT_BIT_PHY_CODED));
|
||||
#else
|
||||
feature_coded_phy = 0;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PHY_2M)
|
||||
feature_phy_2m = (conn->llcp_feature.features &
|
||||
feature_phy_2m = (conn->llcp_feature.features_conn &
|
||||
BIT(BT_LE_FEAT_BIT_PHY_2M));
|
||||
#else
|
||||
feature_phy_2m = 0;
|
||||
@@ -3176,31 +3182,31 @@ static inline void dle_max_time_get(const struct ll_conn *conn,
|
||||
|
||||
if (!conn->common.fex_valid ||
|
||||
(!feature_coded_phy && !feature_phy_2m)) {
|
||||
rx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, 0);
|
||||
rx_time = PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_1M);
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
tx_time = MAX(MIN(PKT_US(LL_LENGTH_OCTETS_RX_MAX, 0),
|
||||
tx_time = MAX(MIN(PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_1M),
|
||||
conn->default_tx_time),
|
||||
PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0));
|
||||
PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M));
|
||||
#else /* !CONFIG_BT_CTLR_PHY */
|
||||
tx_time = PKT_US(conn->default_tx_octets, 0);
|
||||
tx_time = PKT_US(conn->default_tx_octets, PHY_1M);
|
||||
#endif /* !CONFIG_BT_CTLR_PHY */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
#if defined(CONFIG_BT_CTLR_PHY_CODED)
|
||||
} else if (feature_coded_phy) {
|
||||
rx_time = MAX(PKT_US(LL_LENGTH_OCTETS_RX_MAX, BIT(2)),
|
||||
PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, BIT(2)));
|
||||
tx_time = MIN(PKT_US(LL_LENGTH_OCTETS_RX_MAX, BIT(2)),
|
||||
rx_time = MAX(PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_CODED),
|
||||
PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_CODED));
|
||||
tx_time = MIN(PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_CODED),
|
||||
conn->default_tx_time);
|
||||
tx_time = MAX(PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0), tx_time);
|
||||
tx_time = MAX(PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M), tx_time);
|
||||
#endif /* CONFIG_BT_CTLR_PHY_CODED */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PHY_2M)
|
||||
} else if (feature_phy_2m) {
|
||||
rx_time = MAX(PKT_US(LL_LENGTH_OCTETS_RX_MAX, BIT(1)),
|
||||
PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, BIT(1)));
|
||||
tx_time = MAX(PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0),
|
||||
MIN(PKT_US(LL_LENGTH_OCTETS_RX_MAX, BIT(1)),
|
||||
rx_time = MAX(PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_2M),
|
||||
PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_2M));
|
||||
tx_time = MAX(PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M),
|
||||
MIN(PKT_US(LL_LENGTH_OCTETS_RX_MAX, PHY_2M),
|
||||
conn->default_tx_time));
|
||||
#endif /* CONFIG_BT_CTLR_PHY_2M */
|
||||
#endif /* CONFIG_BT_CTLR_PHY */
|
||||
@@ -3342,8 +3348,8 @@ static inline void event_len_prep(struct ll_conn *conn)
|
||||
lr->max_tx_octets = sys_cpu_to_le16(tx_octets);
|
||||
#if !defined(CONFIG_BT_CTLR_PHY)
|
||||
lr->max_rx_time =
|
||||
sys_cpu_to_le16(PKT_US(lll->max_rx_octets, 0));
|
||||
lr->max_tx_time = sys_cpu_to_le16(PKT_US(tx_octets, 0));
|
||||
sys_cpu_to_le16(PKT_US(lll->max_rx_octets, PHY_1M));
|
||||
lr->max_tx_time = sys_cpu_to_le16(PKT_US(tx_octets, PHY_1M));
|
||||
#else /* CONFIG_BT_CTLR_PHY */
|
||||
lr->max_rx_time = sys_cpu_to_le16(lll->max_rx_time);
|
||||
lr->max_tx_time = sys_cpu_to_le16(tx_time);
|
||||
@@ -4002,12 +4008,28 @@ static inline u32_t feat_get(u8_t *features)
|
||||
return feat;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a logical and on octet0 and keep the remaining bits of the
|
||||
* first input parameter
|
||||
*/
|
||||
static inline u32_t feat_land_octet0(u32_t feat_to_keep, u32_t feat_octet0)
|
||||
{
|
||||
u32_t feat_result;
|
||||
|
||||
feat_result = feat_to_keep & feat_octet0;
|
||||
feat_result &= 0xFF;
|
||||
feat_result |= feat_to_keep & LL_FEAT_FILTER_OCTET0;
|
||||
|
||||
return feat_result;
|
||||
}
|
||||
|
||||
static int feature_rsp_send(struct ll_conn *conn, struct node_rx_pdu *rx,
|
||||
struct pdu_data *pdu_rx)
|
||||
{
|
||||
struct pdu_data_llctrl_feature_req *req;
|
||||
struct node_tx *tx;
|
||||
struct pdu_data *pdu_tx;
|
||||
u32_t feat;
|
||||
|
||||
/* acquire tx mem */
|
||||
tx = mem_acquire(&mem_conn_tx_ctrl.free);
|
||||
@@ -4017,7 +4039,14 @@ static int feature_rsp_send(struct ll_conn *conn, struct node_rx_pdu *rx,
|
||||
|
||||
/* AND the feature set to get Feature USED */
|
||||
req = &pdu_rx->llctrl.feature_req;
|
||||
conn->llcp_feature.features &= feat_get(&req->features[0]);
|
||||
conn->llcp_feature.features_conn &= feat_get(&req->features[0]);
|
||||
/*
|
||||
* Get all the features of peer, except octet 0.
|
||||
* Octet 0 is the actual features used on the link
|
||||
* See BTCore V5.2, Vol. 6, Part B, chapter 5.1.4
|
||||
*/
|
||||
conn->llcp_feature.features_peer =
|
||||
feat_land_octet0(feat_get(&req->features[0]), LL_FEAT);
|
||||
|
||||
/* features exchanged */
|
||||
conn->common.fex_valid = 1U;
|
||||
@@ -4026,12 +4055,16 @@ static int feature_rsp_send(struct ll_conn *conn, struct node_rx_pdu *rx,
|
||||
pdu_tx = (void *)tx->pdu;
|
||||
pdu_tx->ll_id = PDU_DATA_LLID_CTRL;
|
||||
pdu_tx->len = offsetof(struct pdu_data_llctrl, feature_rsp) +
|
||||
sizeof(struct pdu_data_llctrl_feature_rsp);
|
||||
sizeof(struct pdu_data_llctrl_feature_rsp);
|
||||
pdu_tx->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_FEATURE_RSP;
|
||||
(void)memset(&pdu_tx->llctrl.feature_rsp.features[0], 0x00,
|
||||
sizeof(pdu_tx->llctrl.feature_rsp.features));
|
||||
sys_put_le24(conn->llcp_feature.features,
|
||||
pdu_tx->llctrl.feature_req.features);
|
||||
/*
|
||||
* On feature response we send the local supported features.
|
||||
* See BTCore V5.2 VOl 6 Part B, chapter 5.1.4
|
||||
*/
|
||||
feat = feat_land_octet0(LL_FEAT, conn->llcp_feature.features_conn);
|
||||
sys_put_le24(feat, pdu_tx->llctrl.feature_rsp.features);
|
||||
|
||||
ctrl_tx_sec_enqueue(conn, tx);
|
||||
|
||||
@@ -4048,7 +4081,14 @@ static void feature_rsp_recv(struct ll_conn *conn, struct pdu_data *pdu_rx)
|
||||
rsp = &pdu_rx->llctrl.feature_rsp;
|
||||
|
||||
/* AND the feature set to get Feature USED */
|
||||
conn->llcp_feature.features &= feat_get(&rsp->features[0]);
|
||||
conn->llcp_feature.features_conn &= feat_get(&rsp->features[0]);
|
||||
/*
|
||||
* Get all the features of peer, except octet 0.
|
||||
* Octet 0 is the actual features used on the link
|
||||
* See BTCore V5.2, Vol. 6, Part B, chapter 5.1.4
|
||||
*/
|
||||
conn->llcp_feature.features_peer =
|
||||
feat_land_octet0(feat_get(&rsp->features[0]), LL_FEAT);
|
||||
|
||||
/* features exchanged */
|
||||
conn->common.fex_valid = 1U;
|
||||
@@ -4290,9 +4330,9 @@ static inline int reject_ind_dle_recv(struct ll_conn *conn,
|
||||
lr->max_tx_octets = sys_cpu_to_le16(conn->lll.max_tx_octets);
|
||||
#if !defined(CONFIG_BT_CTLR_PHY)
|
||||
lr->max_rx_time =
|
||||
sys_cpu_to_le16(PKT_US(conn->lll.max_rx_octets, 0));
|
||||
sys_cpu_to_le16(PKT_US(conn->lll.max_rx_octets, PHY_1M));
|
||||
lr->max_tx_time =
|
||||
sys_cpu_to_le16(PKT_US(conn->lll.max_tx_octets, 0));
|
||||
sys_cpu_to_le16(PKT_US(conn->lll.max_tx_octets, PHY_1M));
|
||||
#else /* CONFIG_BT_CTLR_PHY */
|
||||
lr->max_rx_time = sys_cpu_to_le16(conn->lll.max_rx_time);
|
||||
lr->max_tx_time = sys_cpu_to_le16(conn->lll.max_tx_time);
|
||||
@@ -4446,9 +4486,9 @@ static void length_resp_send(struct ll_conn *conn, struct node_tx *tx,
|
||||
|
||||
#if !defined(CONFIG_BT_CTLR_PHY)
|
||||
pdu_tx->llctrl.length_rsp.max_rx_time =
|
||||
sys_cpu_to_le16(PKT_US(eff_rx_octets, 0));
|
||||
sys_cpu_to_le16(PKT_US(eff_rx_octets, PHY_1M));
|
||||
pdu_tx->llctrl.length_rsp.max_tx_time =
|
||||
sys_cpu_to_le16(PKT_US(eff_tx_octets, 0));
|
||||
sys_cpu_to_le16(PKT_US(eff_tx_octets, PHY_1M));
|
||||
#else /* CONFIG_BT_CTLR_PHY */
|
||||
pdu_tx->llctrl.length_rsp.max_rx_time = sys_cpu_to_le16(eff_rx_time);
|
||||
pdu_tx->llctrl.length_rsp.max_tx_time = sys_cpu_to_le16(eff_tx_time);
|
||||
@@ -4488,8 +4528,7 @@ static inline int length_req_rsp_recv(struct ll_conn *conn, memq_link_t *link,
|
||||
if (/* Local idle, and Peer request then complete the Peer procedure
|
||||
* with response.
|
||||
*/
|
||||
((conn->llcp_length.req == conn->llcp_length.ack) &&
|
||||
(pdu_rx->llctrl.opcode == PDU_DATA_LLCTRL_TYPE_LENGTH_REQ)) ||
|
||||
((conn->llcp_length.req == conn->llcp_length.ack) && tx) ||
|
||||
/* or Local has active... */
|
||||
((conn->llcp_length.req != conn->llcp_length.ack) &&
|
||||
/* with Local requested and Peer request then complete the
|
||||
@@ -4497,17 +4536,12 @@ static inline int length_req_rsp_recv(struct ll_conn *conn, memq_link_t *link,
|
||||
*/
|
||||
((((conn->llcp_length.state == LLCP_LENGTH_STATE_REQ) ||
|
||||
(conn->llcp_length.state == LLCP_LENGTH_STATE_REQ_ACK_WAIT)) &&
|
||||
(pdu_rx->llctrl.opcode ==
|
||||
PDU_DATA_LLCTRL_TYPE_LENGTH_REQ)) ||
|
||||
tx) ||
|
||||
/* with Local waiting for response, and Peer response then
|
||||
* complete the Local procedure or Peer request then complete the
|
||||
* Peer procedure with response.
|
||||
*/
|
||||
((conn->llcp_length.state == LLCP_LENGTH_STATE_RSP_WAIT) &&
|
||||
((pdu_rx->llctrl.opcode ==
|
||||
PDU_DATA_LLCTRL_TYPE_LENGTH_RSP) ||
|
||||
(pdu_rx->llctrl.opcode ==
|
||||
PDU_DATA_LLCTRL_TYPE_LENGTH_REQ)))))) {
|
||||
(conn->llcp_length.state == LLCP_LENGTH_STATE_RSP_WAIT)))) {
|
||||
struct pdu_data_llctrl_length_req *lr;
|
||||
u16_t max_rx_octets;
|
||||
u16_t max_tx_octets;
|
||||
@@ -4546,7 +4580,7 @@ static inline int length_req_rsp_recv(struct ll_conn *conn, memq_link_t *link,
|
||||
lr_rx_time = sys_le16_to_cpu(lr->max_rx_time);
|
||||
lr_tx_time = sys_le16_to_cpu(lr->max_tx_time);
|
||||
|
||||
if (lr_rx_time >= PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0)) {
|
||||
if (lr_rx_time >= PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M)) {
|
||||
eff_tx_time = MIN(lr_rx_time, max_tx_time);
|
||||
#if defined(CONFIG_BT_CTLR_PHY_CODED)
|
||||
eff_tx_time = MAX(eff_tx_time,
|
||||
@@ -4558,7 +4592,7 @@ static inline int length_req_rsp_recv(struct ll_conn *conn, memq_link_t *link,
|
||||
/* use the minimal of our max supported and
|
||||
* peer max_tx_time
|
||||
*/
|
||||
if (lr_tx_time >= PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0)) {
|
||||
if (lr_tx_time >= PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M)) {
|
||||
eff_rx_time = MIN(lr_tx_time, max_rx_time);
|
||||
#if defined(CONFIG_BT_CTLR_PHY_CODED)
|
||||
eff_rx_time = MAX(eff_rx_time,
|
||||
@@ -4662,18 +4696,29 @@ static inline int length_req_rsp_recv(struct ll_conn *conn, memq_link_t *link,
|
||||
|
||||
#if !defined(CONFIG_BT_CTLR_PHY)
|
||||
lr->max_rx_time =
|
||||
sys_cpu_to_le16(PKT_US(eff_rx_octets, 0));
|
||||
sys_cpu_to_le16(PKT_US(eff_rx_octets, PHY_1M));
|
||||
lr->max_tx_time =
|
||||
sys_cpu_to_le16(PKT_US(eff_tx_octets, 0));
|
||||
sys_cpu_to_le16(PKT_US(eff_tx_octets, PHY_1M));
|
||||
#else /* CONFIG_BT_CTLR_PHY */
|
||||
lr->max_rx_time = sys_cpu_to_le16(eff_rx_time);
|
||||
lr->max_tx_time = sys_cpu_to_le16(eff_tx_time);
|
||||
#endif /* CONFIG_BT_CTLR_PHY */
|
||||
}
|
||||
} else {
|
||||
/* Drop response with no Local initiated request. */
|
||||
LL_ASSERT(pdu_rx->llctrl.opcode ==
|
||||
PDU_DATA_LLCTRL_TYPE_LENGTH_RSP);
|
||||
/* Drop response with no Local initiated request and duplicate
|
||||
* requests.
|
||||
*/
|
||||
if (pdu_rx->llctrl.opcode != PDU_DATA_LLCTRL_TYPE_LENGTH_RSP) {
|
||||
mem_release(tx, &mem_conn_tx_ctrl.free);
|
||||
|
||||
/* Defer new request if previous in resize state */
|
||||
if (conn->llcp_length.state ==
|
||||
LLCP_LENGTH_STATE_RESIZE) {
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
send_length_resp:
|
||||
@@ -5394,7 +5439,9 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
|
||||
#endif /* CONFIG_BT_CTLR_SLAVE_FEAT_REQ */
|
||||
|
||||
case PDU_DATA_LLCTRL_TYPE_FEATURE_RSP:
|
||||
if (!pdu_len_cmp(PDU_DATA_LLCTRL_TYPE_FEATURE_RSP,
|
||||
if ((!IS_ENABLED(CONFIG_BT_CTLR_SLAVE_FEAT_REQ) &&
|
||||
conn->lll.role) ||
|
||||
!pdu_len_cmp(PDU_DATA_LLCTRL_TYPE_FEATURE_RSP,
|
||||
pdu_rx->len)) {
|
||||
goto ull_conn_rx_unknown_rsp_send;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
*/
|
||||
#define PAYLOAD_OVERHEAD_SIZE (2 + 4)
|
||||
|
||||
#define PHY_1M BIT(0)
|
||||
#define PHY_2M BIT(1)
|
||||
#define PHY_CODED BIT(2)
|
||||
#if defined(CONFIG_BT_CTLR_PHY_CODED)
|
||||
#define CODED_PHY_PREAMBLE_TIME_US (80)
|
||||
#define CODED_PHY_ACCESS_ADDRESS_TIME_US (256)
|
||||
@@ -33,23 +36,23 @@
|
||||
CODED_PHY_CRC_SIZE + \
|
||||
CODED_PHY_TERM2_SIZE) * 8)
|
||||
|
||||
#define PKT_US(octets, phy) (((phy) & BIT(2)) ? \
|
||||
#define PKT_US(octets, phy) (((phy) & PHY_CODED) ? \
|
||||
(CODED_PHY_PREAMBLE_TIME_US + \
|
||||
FEC_BLOCK1_TIME_US + \
|
||||
FEC_BLOCK2_TIME_US(octets)) : \
|
||||
(((PREAMBLE_SIZE(1) + \
|
||||
(((PREAMBLE_SIZE(phy) + \
|
||||
ACCESS_ADDR_SIZE + \
|
||||
PAYLOAD_OVERHEAD_SIZE + \
|
||||
(octets) + \
|
||||
CRC_SIZE) * 8) / \
|
||||
BIT(((phy) & 0x03) >> 1)))
|
||||
#else /* !CONFIG_BT_CTLR_PHY_CODED */
|
||||
#define PKT_US(octets, phy) (((PREAMBLE_SIZE(1) + \
|
||||
#define PKT_US(octets, phy) ((((PREAMBLE_SIZE(phy)) + \
|
||||
ACCESS_ADDR_SIZE + \
|
||||
PAYLOAD_OVERHEAD_SIZE + \
|
||||
(octets) + \
|
||||
CRC_SIZE) * 8) / \
|
||||
BIT(((phy) & 0x03) >> 1))
|
||||
BIT(((phy) & 0x03) >> 1))
|
||||
#endif /* !CONFIG_BT_CTLR_PHY_CODED */
|
||||
|
||||
struct ll_conn *ll_conn_acquire(void);
|
||||
|
||||
@@ -140,7 +140,8 @@ struct ll_conn {
|
||||
struct {
|
||||
u8_t req;
|
||||
u8_t ack;
|
||||
u32_t features;
|
||||
u32_t features_conn;
|
||||
u32_t features_peer;
|
||||
} llcp_feature;
|
||||
|
||||
struct {
|
||||
|
||||
@@ -127,8 +127,8 @@ u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
|
||||
conn_lll->max_rx_octets = PDU_DC_PAYLOAD_SIZE_MIN;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
conn_lll->max_tx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0);
|
||||
conn_lll->max_rx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, 0);
|
||||
conn_lll->max_tx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M);
|
||||
conn_lll->max_rx_time = PKT_US(PDU_DC_PAYLOAD_SIZE_MIN, PHY_1M);
|
||||
#endif /* CONFIG_BT_CTLR_PHY */
|
||||
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
|
||||
|
||||
@@ -197,7 +197,8 @@ u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
|
||||
conn->llcp_rx = NULL;
|
||||
conn->llcp_cu.req = conn->llcp_cu.ack = 0;
|
||||
conn->llcp_feature.req = conn->llcp_feature.ack = 0;
|
||||
conn->llcp_feature.features = LL_FEAT;
|
||||
conn->llcp_feature.features_conn = LL_FEAT;
|
||||
conn->llcp_feature.features_peer = 0;
|
||||
conn->llcp_version.req = conn->llcp_version.ack = 0;
|
||||
conn->llcp_version.tx = conn->llcp_version.rx = 0U;
|
||||
conn->llcp_terminate.reason_peer = 0U;
|
||||
|
||||
@@ -79,7 +79,13 @@ void ull_slave_setup(memq_link_t *link, struct node_rx_hdr *rx,
|
||||
sizeof(lll->data_chan_map));
|
||||
lll->data_chan_count = util_ones_count_get(&lll->data_chan_map[0],
|
||||
sizeof(lll->data_chan_map));
|
||||
if (lll->data_chan_count < 2) {
|
||||
return;
|
||||
}
|
||||
lll->data_chan_hop = pdu_adv->connect_ind.hop;
|
||||
if ((lll->data_chan_hop < 5) || (lll->data_chan_hop > 16)) {
|
||||
return;
|
||||
}
|
||||
interval = sys_le16_to_cpu(pdu_adv->connect_ind.interval);
|
||||
lll->interval = interval;
|
||||
lll->latency = sys_le16_to_cpu(pdu_adv->connect_ind.latency);
|
||||
|
||||
@@ -629,15 +629,10 @@ static u32_t ticker_dequeue(struct ticker_instance *instance, u8_t id)
|
||||
static u8_t ticker_resolve_collision(struct ticker_node *nodes,
|
||||
struct ticker_node *ticker)
|
||||
{
|
||||
u8_t skipped = 0;
|
||||
s32_t lazy_current = ticker->lazy_current;
|
||||
if ((ticker->priority != TICKER_PRIORITY_CRITICAL) &&
|
||||
(ticker->next != TICKER_NULL)) {
|
||||
s32_t lazy_current = ticker->lazy_current;
|
||||
|
||||
if (ticker->lazy_periodic > lazy_current) {
|
||||
/* Programmed latency must be respected */
|
||||
skipped = 1;
|
||||
|
||||
} else if ((ticker->priority != TICKER_PRIORITY_CRITICAL) &&
|
||||
(ticker->next != TICKER_NULL)) {
|
||||
/* Check if this ticker node will starve next node which has
|
||||
* latency or higher priority
|
||||
*/
|
||||
@@ -645,7 +640,7 @@ static u8_t ticker_resolve_collision(struct ticker_node *nodes,
|
||||
lazy_current -= ticker->lazy_periodic;
|
||||
}
|
||||
u8_t id_head = ticker->next;
|
||||
u32_t acc_ticks_to_expire = 0;
|
||||
u32_t acc_ticks_to_expire = 0U;
|
||||
|
||||
/* Age is time since last expiry */
|
||||
u32_t current_age = ticker->ticks_periodic +
|
||||
@@ -661,7 +656,7 @@ static u8_t ticker_resolve_collision(struct ticker_node *nodes,
|
||||
}
|
||||
|
||||
/* We only care about nodes with slot reservation */
|
||||
if (ticker_next->ticks_slot == 0) {
|
||||
if (ticker_next->ticks_slot == 0U) {
|
||||
id_head = ticker_next->next;
|
||||
continue;
|
||||
}
|
||||
@@ -716,13 +711,13 @@ static u8_t ticker_resolve_collision(struct ticker_node *nodes,
|
||||
(next_has_priority && !current_is_older) ||
|
||||
(equal_priority && next_is_older))) {
|
||||
/* This node must be skipped - check window */
|
||||
skipped = 1;
|
||||
break;
|
||||
return 1U;
|
||||
}
|
||||
id_head = ticker_next->next;
|
||||
}
|
||||
}
|
||||
return skipped;
|
||||
|
||||
return 0U;
|
||||
}
|
||||
#endif /* !CONFIG_BT_TICKER_COMPATIBILITY_MODE */
|
||||
|
||||
@@ -998,7 +993,6 @@ static u8_t ticker_remainder_inc(struct ticker_node *ticker)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_TICKER_COMPATIBILITY_MODE)
|
||||
/**
|
||||
* @brief Decrement remainder
|
||||
*
|
||||
@@ -1028,7 +1022,6 @@ static u8_t ticker_remainder_dec(struct ticker_node *ticker)
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_BT_TICKER_COMPATIBILITY_MODE */
|
||||
|
||||
/**
|
||||
* @brief Invoke user operation callback
|
||||
@@ -1084,7 +1077,6 @@ static inline void ticker_job_node_update(struct ticker_node *ticker,
|
||||
if ((ticker->ticks_periodic != 0U) &&
|
||||
(user_op->params.update.lazy != 0U)) {
|
||||
user_op->params.update.lazy--;
|
||||
#if defined(CONFIG_BT_TICKER_COMPATIBILITY_MODE)
|
||||
while ((ticks_to_expire > ticker->ticks_periodic) &&
|
||||
(ticker->lazy_current > user_op->params.update.lazy)) {
|
||||
ticks_to_expire -= ticker->ticks_periodic +
|
||||
@@ -1097,7 +1089,6 @@ static inline void ticker_job_node_update(struct ticker_node *ticker,
|
||||
ticker_remainder_inc(ticker);
|
||||
ticker->lazy_current++;
|
||||
}
|
||||
#endif /* CONFIG_BT_TICKER_COMPATIBILITY_MODE */
|
||||
ticker->lazy_periodic = user_op->params.update.lazy;
|
||||
}
|
||||
|
||||
@@ -1331,9 +1322,18 @@ static inline void ticker_job_worker_bh(struct ticker_instance *instance,
|
||||
struct ticker_node *node;
|
||||
u32_t ticks_expired;
|
||||
|
||||
#if !defined(CONFIG_BT_TICKER_COMPATIBILITY_MODE)
|
||||
u32_t ticks_latency;
|
||||
u32_t ticks_now;
|
||||
|
||||
ticks_now = cntr_cnt_get();
|
||||
ticks_latency = ticker_ticks_diff_get(ticks_now, ticks_previous);
|
||||
#endif /* !CONFIG_BT_TICKER_COMPATIBILITY_MODE */
|
||||
|
||||
node = &instance->nodes[0];
|
||||
ticks_expired = 0U;
|
||||
while (instance->ticker_id_head != TICKER_NULL) {
|
||||
u8_t is_must_expire_skip = 0U;
|
||||
struct ticker_node *ticker;
|
||||
u32_t ticks_to_expire;
|
||||
u8_t id_expired;
|
||||
@@ -1354,32 +1354,29 @@ static inline void ticker_job_worker_bh(struct ticker_instance *instance,
|
||||
ticks_expired += ticks_to_expire;
|
||||
|
||||
#if !defined(CONFIG_BT_TICKER_COMPATIBILITY_MODE)
|
||||
if (ticker->lazy_current != 0U &&
|
||||
!TICKER_RESCHEDULE_PENDING(ticker)) {
|
||||
ticks_latency -= ticks_to_expire;
|
||||
|
||||
is_must_expire_skip = (ticker->must_expire &&
|
||||
(ticker->lazy_current != 0U));
|
||||
#endif /* !CONFIG_BT_TICKER_COMPATIBILITY_MODE */
|
||||
|
||||
/* decrement ticks_slot_previous */
|
||||
if (instance->ticks_slot_previous > ticks_to_expire) {
|
||||
instance->ticks_slot_previous -= ticks_to_expire;
|
||||
} else {
|
||||
instance->ticker_id_slot_previous = TICKER_NULL;
|
||||
instance->ticks_slot_previous = 0U;
|
||||
} else
|
||||
#endif /* !CONFIG_BT_TICKER_COMPATIBILITY_MODE */
|
||||
{
|
||||
/* decrement ticks_slot_previous */
|
||||
if (instance->ticks_slot_previous > ticks_to_expire) {
|
||||
instance->ticks_slot_previous -=
|
||||
ticks_to_expire;
|
||||
} else {
|
||||
instance->ticker_id_slot_previous = TICKER_NULL;
|
||||
instance->ticks_slot_previous = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
/* If a reschedule is set pending, we will need to keep
|
||||
* the slot_previous information
|
||||
*/
|
||||
if (!TICKER_RESCHEDULE_PENDING(ticker) &&
|
||||
ticker->ticks_slot != 0U) {
|
||||
instance->ticker_id_slot_previous =
|
||||
id_expired;
|
||||
instance->ticks_slot_previous =
|
||||
ticker->ticks_slot;
|
||||
}
|
||||
/* If a reschedule is set pending, we will need to keep
|
||||
* the slot_previous information
|
||||
*/
|
||||
if ((ticker->ticks_slot != 0U) &&
|
||||
(((ticker->req - ticker->ack) & 0xff) == 2U) &&
|
||||
!is_must_expire_skip &&
|
||||
!TICKER_RESCHEDULE_PENDING(ticker)) {
|
||||
instance->ticker_id_slot_previous = id_expired;
|
||||
instance->ticks_slot_previous = ticker->ticks_slot;
|
||||
}
|
||||
|
||||
/* ticker expired, set ticks_to_expire zero */
|
||||
@@ -1398,12 +1395,62 @@ static inline void ticker_job_worker_bh(struct ticker_instance *instance,
|
||||
* restarted
|
||||
*/
|
||||
ticker->ticks_to_expire = ticks_elapsed;
|
||||
|
||||
/* Reset ticker state, so that its put
|
||||
* back in requested state later down
|
||||
* in the code.
|
||||
*/
|
||||
ticker->req = ticker->ack;
|
||||
} else {
|
||||
/* Reload ticks_to_expire with one period */
|
||||
ticker->ticks_to_expire =
|
||||
ticker->ticks_periodic;
|
||||
ticker->ticks_to_expire +=
|
||||
ticker_remainder_inc(ticker);
|
||||
u16_t lazy_periodic;
|
||||
u32_t count;
|
||||
u16_t lazy;
|
||||
|
||||
/* If not skipped, apply lazy_periodic */
|
||||
if (!ticker->lazy_current) {
|
||||
lazy_periodic = ticker->lazy_periodic;
|
||||
} else {
|
||||
lazy_periodic = 0U;
|
||||
|
||||
/* Reset ticker state, so that its put
|
||||
* back in requested state later down
|
||||
* in the code.
|
||||
*/
|
||||
ticker->req = ticker->ack;
|
||||
}
|
||||
|
||||
/* Reload ticks_to_expire with atleast one
|
||||
* period.
|
||||
*/
|
||||
ticks_to_expire = 0U;
|
||||
count = 1 + lazy_periodic;
|
||||
while (count--) {
|
||||
ticks_to_expire +=
|
||||
ticker->ticks_periodic;
|
||||
ticks_to_expire +=
|
||||
ticker_remainder_inc(ticker);
|
||||
}
|
||||
|
||||
/* Skip intervals that have elapsed w.r.t.
|
||||
* current ticks.
|
||||
*/
|
||||
lazy = 0U;
|
||||
if (!ticker->must_expire) {
|
||||
while (ticks_to_expire <
|
||||
ticks_latency) {
|
||||
ticks_to_expire +=
|
||||
ticker->ticks_periodic;
|
||||
ticks_to_expire +=
|
||||
ticker_remainder_inc(ticker);
|
||||
lazy++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use the calculated ticks to expire and
|
||||
* laziness.
|
||||
*/
|
||||
ticker->ticks_to_expire = ticks_to_expire;
|
||||
ticker->lazy_current += (lazy_periodic + lazy);
|
||||
}
|
||||
|
||||
ticks_to_expire_prep(ticker, instance->ticks_current,
|
||||
@@ -2049,6 +2096,7 @@ static inline void ticker_job_compare_update(struct ticker_instance *instance,
|
||||
if (instance->ticker_id_head == TICKER_NULL) {
|
||||
if (cntr_stop() == 0) {
|
||||
instance->ticks_slot_previous = 0U;
|
||||
instance->ticks_current = cntr_cnt_get();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4303,8 +4303,11 @@ static int cf_set(const char *name, size_t len_rd, settings_read_cb read_cb,
|
||||
cfg = find_cf_cfg(NULL);
|
||||
if (!cfg) {
|
||||
BT_ERR("Unable to restore CF: no cfg left");
|
||||
return 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cfg->id = id;
|
||||
bt_addr_le_copy(&cfg->peer, &addr);
|
||||
}
|
||||
|
||||
if (len_rd) {
|
||||
@@ -4358,6 +4361,7 @@ static int db_hash_commit(void)
|
||||
if (!memcmp(stored_hash, db_hash, sizeof(stored_hash))) {
|
||||
BT_DBG("Database Hash matches");
|
||||
k_delayed_work_cancel(&gatt_sc.work);
|
||||
atomic_clear_bit(gatt_sc.flags, SC_RANGE_CHANGED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -573,7 +573,7 @@ static void le_update_private_addr(void)
|
||||
/* If both advertiser and scanner is running then the advertiser ID must
|
||||
* be BT_ID_DEFAULT, this will update the RPA address for both roles.
|
||||
*/
|
||||
err = le_set_private_addr(bt_dev.adv_id);
|
||||
err = le_set_private_addr(adv_enabled ? bt_dev.adv_id : BT_ID_DEFAULT);
|
||||
if (err) {
|
||||
BT_WARN("Failed to update RPA address (%d)", err);
|
||||
return;
|
||||
@@ -875,6 +875,17 @@ static void hci_num_completed_packets(struct net_buf *buf)
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool rpa_timeout_valid_check(void)
|
||||
{
|
||||
#if defined(CONFIG_BT_PRIVACY)
|
||||
/* Check if create conn timeout will happen before RPA timeout. */
|
||||
return k_delayed_work_remaining_get(&bt_dev.rpa_update) >
|
||||
K_SECONDS(CONFIG_BT_CREATE_CONN_TIMEOUT);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_CENTRAL)
|
||||
int bt_le_create_conn(const struct bt_conn *conn)
|
||||
{
|
||||
@@ -890,8 +901,8 @@ int bt_le_create_conn(const struct bt_conn *conn)
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
|
||||
if (use_filter) {
|
||||
err = le_set_private_addr(bt_dev.adv_id);
|
||||
if (use_filter || rpa_timeout_valid_check()) {
|
||||
err = le_set_private_addr(BT_ID_DEFAULT);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -4086,8 +4097,7 @@ static void send_cmd(void)
|
||||
if (err) {
|
||||
BT_ERR("Unable to send to driver (err %d)", err);
|
||||
k_sem_give(&bt_dev.ncmd_sem);
|
||||
hci_cmd_done(cmd(buf)->opcode, BT_HCI_ERR_UNSPECIFIED,
|
||||
NULL);
|
||||
hci_cmd_done(cmd(buf)->opcode, BT_HCI_ERR_UNSPECIFIED, buf);
|
||||
net_buf_unref(bt_dev.sent_cmd);
|
||||
bt_dev.sent_cmd = NULL;
|
||||
net_buf_unref(buf);
|
||||
|
||||
@@ -1793,10 +1793,13 @@ static void smp_pairing_complete(struct bt_smp *smp, u8_t status)
|
||||
} else {
|
||||
u8_t auth_err = auth_err_get(status);
|
||||
|
||||
/*
|
||||
* Clear the key pool entry in case of pairing failure.
|
||||
/* Clear the key pool entry in case of pairing failure if the
|
||||
* keys already existed before the pairing procedure or the
|
||||
* pairing failed during key distribution.
|
||||
*/
|
||||
if (smp->chan.chan.conn->le.keys) {
|
||||
if (smp->chan.chan.conn->le.keys &&
|
||||
(!smp->chan.chan.conn->le.keys->enc_size ||
|
||||
atomic_test_bit(smp->flags, SMP_FLAG_KEYS_DISTR))) {
|
||||
bt_keys_clear(smp->chan.chan.conn->le.keys);
|
||||
smp->chan.chan.conn->le.keys = NULL;
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ static void net_key_status(struct bt_mesh_model *model,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
struct net_key_param *param;
|
||||
u16_t net_idx, app_idx;
|
||||
u16_t net_idx;
|
||||
u8_t status;
|
||||
|
||||
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
|
||||
@@ -165,7 +165,7 @@ static void net_key_status(struct bt_mesh_model *model,
|
||||
}
|
||||
|
||||
status = net_buf_simple_pull_u8(buf);
|
||||
key_idx_unpack(buf, &net_idx, &app_idx);
|
||||
net_idx = net_buf_simple_pull_le16(buf) & 0xfff;
|
||||
|
||||
param = cli->op_param;
|
||||
if (param->net_idx != net_idx) {
|
||||
|
||||
@@ -3416,7 +3416,8 @@ u8_t bt_mesh_relay_get(void)
|
||||
|
||||
u8_t bt_mesh_friend_get(void)
|
||||
{
|
||||
BT_DBG("conf %p conf->frnd 0x%02x", conf, conf->frnd);
|
||||
BT_DBG("conf %p conf->frnd 0x%02x", conf,
|
||||
conf ? conf->frnd : BT_MESH_FRIEND_NOT_SUPPORTED);
|
||||
|
||||
if (conf) {
|
||||
return conf->frnd;
|
||||
|
||||
@@ -2299,7 +2299,7 @@ static struct key_update *cdb_key_update_find(bool app_key, u16_t key_idx,
|
||||
match = NULL;
|
||||
*free_slot = NULL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(key_updates); i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(cdb_key_updates); i++) {
|
||||
struct key_update *update = &cdb_key_updates[i];
|
||||
|
||||
if (!update->valid) {
|
||||
|
||||
@@ -167,7 +167,7 @@ int net_ipv4_parse_hdr_options(struct net_pkt *pkt,
|
||||
/* Options length should be zero, when cursor reachs to
|
||||
* End of options.
|
||||
*/
|
||||
if (opts_len) {
|
||||
if (total_opts_len) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ LOG_MODULE_REGISTER(net_coap, CONFIG_COAP_LOG_LEVEL);
|
||||
|
||||
#include <zephyr/types.h>
|
||||
#include <sys/byteorder.h>
|
||||
#include <sys/math_extras.h>
|
||||
|
||||
#include <net/net_ip.h>
|
||||
#include <net/net_core.h>
|
||||
@@ -469,7 +470,9 @@ static int parse_option(u8_t *data, u16_t offset, u16_t *pos,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*opt_len += hdr_len;
|
||||
if (u16_add_overflow(*opt_len, hdr_len, opt_len)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (len > COAP_OPTION_NO_EXT) {
|
||||
@@ -480,11 +483,15 @@ static int parse_option(u8_t *data, u16_t offset, u16_t *pos,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*opt_len += hdr_len;
|
||||
if (u16_add_overflow(*opt_len, hdr_len, opt_len)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
*opt_delta += delta;
|
||||
*opt_len += len;
|
||||
if (u16_add_overflow(*opt_delta, delta, opt_delta) ||
|
||||
u16_add_overflow(*opt_len, len, opt_len)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (r == 0) {
|
||||
if (len == 0U) {
|
||||
@@ -519,7 +526,10 @@ static int parse_option(u8_t *data, u16_t offset, u16_t *pos,
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
*pos += len;
|
||||
if (u16_add_overflow(*pos, len, pos)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = max_len - *pos;
|
||||
}
|
||||
|
||||
|
||||
@@ -413,7 +413,7 @@ void shell_spaces_trim(char *str)
|
||||
/* +1 for EOS */
|
||||
memmove(&str[i + 1],
|
||||
&str[j],
|
||||
len - shift + 1);
|
||||
len - j + 1);
|
||||
len -= shift;
|
||||
shift = 0U;
|
||||
}
|
||||
|
||||
@@ -109,7 +109,12 @@ static struct k_thread mass_thread_data;
|
||||
static struct k_sem disk_wait_sem;
|
||||
static volatile u32_t defered_wr_sz;
|
||||
|
||||
static u8_t page[BLOCK_SIZE];
|
||||
/*
|
||||
* Keep block buffer larger than BLOCK_SIZE for the case
|
||||
* the dCBWDataTransferLength is multiple of the BLOCK_SIZE and
|
||||
* the length of the transferred data is not aligned to the BLOCK_SIZE.
|
||||
*/
|
||||
static u8_t page[BLOCK_SIZE + CONFIG_MASS_STORAGE_BULK_EP_MPS];
|
||||
|
||||
/* Initialized during mass_storage_init() */
|
||||
static u32_t memory_size;
|
||||
@@ -433,6 +438,13 @@ static bool infoTransfer(void)
|
||||
(cbw.CB[5] << 0);
|
||||
|
||||
LOG_DBG("LBA (block) : 0x%x ", n);
|
||||
if ((n * BLOCK_SIZE) >= memory_size) {
|
||||
LOG_ERR("LBA out of range");
|
||||
csw.Status = CSW_FAILED;
|
||||
sendCSW();
|
||||
return false;
|
||||
}
|
||||
|
||||
addr = n * BLOCK_SIZE;
|
||||
|
||||
/* Number of Blocks to transfer */
|
||||
@@ -648,7 +660,7 @@ static void memoryWrite(u8_t *buf, u16_t size)
|
||||
}
|
||||
|
||||
/* if the array is filled, write it in memory */
|
||||
if (!((addr + size) % BLOCK_SIZE)) {
|
||||
if ((addr % BLOCK_SIZE) + size >= BLOCK_SIZE) {
|
||||
if (!(disk_access_status(disk_pdrv) &
|
||||
DISK_STATUS_WR_PROTECT)) {
|
||||
LOG_DBG("Disk WRITE Qd %d", (addr/BLOCK_SIZE));
|
||||
@@ -726,6 +738,11 @@ static void mass_storage_bulk_out(u8_t ep,
|
||||
static void thread_memory_write_done(void)
|
||||
{
|
||||
u32_t size = defered_wr_sz;
|
||||
size_t overflowed_len = (addr + size) % CONFIG_MASS_STORAGE_BULK_EP_MPS;
|
||||
|
||||
if (overflowed_len) {
|
||||
memcpy(page, &page[BLOCK_SIZE], overflowed_len);
|
||||
}
|
||||
|
||||
addr += size;
|
||||
length -= size;
|
||||
|
||||
@@ -509,6 +509,15 @@ static int dfu_class_handle_req(struct usb_setup_packet *pSetup,
|
||||
len = pSetup->wLength;
|
||||
}
|
||||
|
||||
if (len > USB_DFU_MAX_XFER_SIZE) {
|
||||
/*
|
||||
* The host could requests more data as stated
|
||||
* in wTransferSize. Limit upload length to the
|
||||
* size of the request-buffer.
|
||||
*/
|
||||
len = USB_DFU_MAX_XFER_SIZE;
|
||||
}
|
||||
|
||||
if (len) {
|
||||
const struct flash_area *fa;
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_WDT_DISABLE_AT_BOOT=n
|
||||
CONFIG_ZTEST=y
|
||||
CONFIG_BOOT_BANNER=n
|
||||
|
||||
@@ -1112,6 +1112,10 @@ void test_bad_syscall(void)
|
||||
|
||||
arch_syscall_invoke0(INT_MAX);
|
||||
|
||||
expect_fault = true;
|
||||
expected_reason = K_ERR_KERNEL_OOPS;
|
||||
|
||||
arch_syscall_invoke0(UINT_MAX);
|
||||
}
|
||||
|
||||
static struct k_sem recycle_sem;
|
||||
|
||||
@@ -13,3 +13,4 @@ CONFIG_ENTROPY_GENERATOR=y
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_ZTEST=y
|
||||
CONFIG_MAIN_STACK_SIZE=1280
|
||||
CONFIG_NET_IPV4_HDR_OPTIONS=y
|
||||
|
||||
2
west.yml
2
west.yml
@@ -53,7 +53,7 @@ manifest:
|
||||
revision: 3b54187649cc9b37161d49918f1ad28ff7c7f830
|
||||
path: modules/hal/openisa
|
||||
- name: hal_microchip
|
||||
revision: 85302959c0c659311cf90ac51d133e5ce19c9288
|
||||
revision: 03c8819ac3105cc2aee295a8d330de0e665b705f
|
||||
path: modules/hal/microchip
|
||||
- name: hal_silabs
|
||||
revision: 9a3fe1af3a14bf88c86b9cda3bf2a0921d5a97a1
|
||||
|
||||
Reference in New Issue
Block a user