Date   

Re: Using IC manufacturer header files

Carles Cufi
 

Hi Anas,

-----Original Message-----
From: Nashif, Anas [mailto:anas.nashif(a)intel.com]
Sent: Tuesday, April 19, 2016 17:46
To: Maciek Borzecki <maciek.borzecki(a)gmail.com>
Cc: Cufi, Carles <Carles.Cufi(a)nordicsemi.no>;
devel(a)lists.zephyrproject.org
Subject: Re: [devel] Re: Re: Using IC manufacturer header files

Hi,
Preference is to keep the most essential parts for building a basic
Zephyr application on a specific board self-contained without external
dependencies.
Sounds good. However please bear in mind that those are SoC include headers, not board ones. They define registers and memory maps for the different Nordic System-on-Chip.

Given the current feedback, we'll proceed to use the original header files directly and without modification by simply including them in the Zephyr codebase.

Thanks,

Carles


Re: Using IC manufacturer header files

Carles Cufi
 

Hi Maciek,

-----Original Message-----
From: Maciek Borzecki [mailto:maciek.borzecki(a)gmail.com]
Sent: Tuesday, April 19, 2016 17:27
To: Nashif, Anas <anas.nashif(a)intel.com>
Cc: Cufi, Carles <Carles.Cufi(a)nordicsemi.no>;
devel(a)lists.zephyrproject.org
Subject: Re: [devel] Re: Using IC manufacturer header files

On Tue, Apr 19, 2016 at 5:04 PM, Nashif, Anas <anas.nashif(a)intel.com>
wrote:
Hi,
Any files or headers included from an external project that need to be
kept in sync with upstream can keep their style and formatting to allow
updates in the future. This was the approach taken when we imported the
IP stack from contiki AFAIK.

How about keeping the library/headers external and passing their
location in Kconfig? Similar to what buildroot does with external
kernel/toolchains. Is that acceptable too?

Not sure if you mean pulling the source code from another repository at build time, since I don't know what buildroot does with kernel/toolchains.
However the MDK is not currently available in a repository, instead it is released as a .zip file by Nordic every time it gets updated. We could of course mirror it in a repo, but that would anyway require us to update it manually every time a new version is available.

Thanks,

Carles


Re: Using IC manufacturer header files

Carles Cufi
 

Hi there,

-----Original Message-----
From: Nashif, Anas [mailto:anas.nashif(a)intel.com]
Sent: Tuesday, April 19, 2016 17:04
To: Cufi, Carles <Carles.Cufi(a)nordicsemi.no>;
devel(a)lists.zephyrproject.org
Subject: Re: [devel] Using IC manufacturer header files

Hi,
Any files or headers included from an external project that need to be
kept in sync with upstream can keep their style and formatting to allow
updates in the future. This was the approach taken when we imported the
IP stack from contiki AFAIK.
Sounds like a good idea. Since those files are part of the Nordic MDK, which sees frequent releases, I also think it would not make sense to try and convert them to a different coding style.

Thanks,

Carles


Re: Setting correct ZEPHYR_GCC_VARIANT

Eric Zaluzec <Eric.Zaluzec@...>
 

Thanks Anas. This documentation was what I was missing.

As regards to building with Yocto, it was not necessary use case. The use case was just a quick way to build & rebuild the zephyr kernel with multiple machine types. This is not required.


Re: Setting correct ZEPHYR_GCC_VARIANT

Eric Zaluzec <Eric.Zaluzec@...>
 

Thank you. This resolved my problem. I was using a zephyr source github repository without the SDK. Documentation here https://www.zephyrproject.org/doc/dev/getting_started/installation_linux.html was the missing piece.


Re: Setting correct ZEPHYR_GCC_VARIANT

Nashif, Anas
 

On 19/04/2016, 11:46, "Eric Zaluzec" <Eric.Zaluzec(a)gmail.com> wrote:

I apologize if this forum is the wrong place to post this question, I was not sure where else to post.
I am attempting to build the zephyr nanokernel with the Galileo board. I am following the steps here:
https://www.zephyrproject.org/doc/board/galileo.html

I am preparing the boot device, and under the zephyr/samples/hello_world/nanokernel directory, I am running 'make BOARD=galileo', but I get back an error saying ZEPHYR_GCC_VARIANT is not set. I am looking for any help or sources with documentation, which address how to correctly set up a GCC VARIANT for the zephyr kernel.

I am very familiar and actively use the Yocto project for many different build environments. The Linux Foundation class (LFD405) was excellent. I tried to create a package recipe for Yocto to build, but the grub source files had too many variables set to the build's host machine.

Are there any Yocto builds yet that support building the zephyr kernel?
No, bot sure why you want to use Yocto to build zephyr. What is the use case here?


Any input or good sources to read how to set the correct GCC VARIANT for zephyr would greatly be appreciated. I could not find any useful information on the Galileo Gen1/Gen2 page on the zephyrproject.org. https://www.zephyrproject.org/doc/board/galileo.html

see https://www.zephyrproject.org/doc/dev/getting_started/installation_linux.html


Anas



Cheers.


Re: Setting correct ZEPHYR_GCC_VARIANT

Vlad Dogaru <vlad.dogaru@...>
 

Hi Eric,

Assuming you've installed the SDK, you need to set ZEPHYR_GCC_VARIANT.
You can do this in ~/.zephyrrc, which is sourced by zephyr-env.sh:

$ cat .zephyrrc
export ZEPHYR_GCC_VARIANT=zephyr
export ZEPHYR_SDK_INSTALL_DIR=/opt/zephyr-sdk

Hope this helps,
Vlad

On Tue, Apr 19, 2016 at 03:46:10PM +0000, Eric Zaluzec wrote:
I apologize if this forum is the wrong place to post this question, I was not sure where else to post.
I am attempting to build the zephyr nanokernel with the Galileo board. I am following the steps here:
https://www.zephyrproject.org/doc/board/galileo.html

I am preparing the boot device, and under the zephyr/samples/hello_world/nanokernel directory, I am running 'make BOARD=galileo', but I get back an error saying ZEPHYR_GCC_VARIANT is not set. I am looking for any help or sources with documentation, which address how to correctly set up a GCC VARIANT for the zephyr kernel.

I am very familiar and actively use the Yocto project for many different build environments. The Linux Foundation class (LFD405) was excellent. I tried to create a package recipe for Yocto to build, but the grub source files had too many variables set to the build's host machine.

Are there any Yocto builds yet that support building the zephyr kernel?

Any input or good sources to read how to set the correct GCC VARIANT for zephyr would greatly be appreciated. I could not find any useful information on the Galileo Gen1/Gen2 page on the zephyrproject.org. https://www.zephyrproject.org/doc/board/galileo.html

Cheers.


Setting correct ZEPHYR_GCC_VARIANT

Eric Zaluzec <Eric.Zaluzec@...>
 

I apologize if this forum is the wrong place to post this question, I was not sure where else to post.
I am attempting to build the zephyr nanokernel with the Galileo board. I am following the steps here:
https://www.zephyrproject.org/doc/board/galileo.html

I am preparing the boot device, and under the zephyr/samples/hello_world/nanokernel directory, I am running 'make BOARD=galileo', but I get back an error saying ZEPHYR_GCC_VARIANT is not set. I am looking for any help or sources with documentation, which address how to correctly set up a GCC VARIANT for the zephyr kernel.

I am very familiar and actively use the Yocto project for many different build environments. The Linux Foundation class (LFD405) was excellent. I tried to create a package recipe for Yocto to build, but the grub source files had too many variables set to the build's host machine.

Are there any Yocto builds yet that support building the zephyr kernel?

Any input or good sources to read how to set the correct GCC VARIANT for zephyr would greatly be appreciated. I could not find any useful information on the Galileo Gen1/Gen2 page on the zephyrproject.org. https://www.zephyrproject.org/doc/board/galileo.html

Cheers.


Re: Using IC manufacturer header files

Nashif, Anas
 

Hi,
Preference is to keep the most essential parts for building a basic Zephyr application on a specific board self-contained without external dependencies.

Anas

On 19/04/2016, 11:26, "Maciek Borzecki" <maciek.borzecki(a)gmail.com> wrote:

On Tue, Apr 19, 2016 at 5:04 PM, Nashif, Anas <anas.nashif(a)intel.com> wrote:
Hi,
Any files or headers included from an external project that need to be kept in sync with upstream can keep their style and formatting to allow updates in the future. This was the approach taken when we imported the IP stack from contiki AFAIK.
How about keeping the library/headers external and passing their
location in Kconfig? Similar to what buildroot does with external
kernel/toolchains. Is that acceptable too?

Cheers,
--
Maciek Borzecki


Daily JIRA Digest

donotreply@...
 

NEW JIRA items within last 24 hours: 3
[ZEP-205] Fail to enable udp loopback for ipv4
https://jira.zephyrproject.org/browse/ZEP-205
[ZEP-207] Fail to have both ipv6 and ipv4 capability in zephyr
https://jira.zephyrproject.org/browse/ZEP-207
[ZEP-206] ipv4 udp multicast is not supported
https://jira.zephyrproject.org/browse/ZEP-206

UPDATED JIRA items within last 24 hours: 1
[ZEP-186] ISSM - ARC support
https://jira.zephyrproject.org/browse/ZEP-186

CLOSED JIRA items within last 24 hours: 0

RESOLVED JIRA items within last 24 hours: 0


Re: Using IC manufacturer header files

Maciek Borzecki <maciek.borzecki@...>
 

On Tue, Apr 19, 2016 at 5:04 PM, Nashif, Anas <anas.nashif(a)intel.com> wrote:
Hi,
Any files or headers included from an external project that need to be kept in sync with upstream can keep their style and formatting to allow updates in the future. This was the approach taken when we imported the IP stack from contiki AFAIK.
How about keeping the library/headers external and passing their
location in Kconfig? Similar to what buildroot does with external
kernel/toolchains. Is that acceptable too?

Cheers,
--
Maciek Borzecki


Daily Gerrit Digest

donotreply@...
 

NEW within last 24 hours:
- https://gerrit.zephyrproject.org/r/1521 : qmsi: use QMSI_LIBRARY instead of QMSI_DRIVERS
- https://gerrit.zephyrproject.org/r/1523 : spi: revert changes to API
- https://gerrit.zephyrproject.org/r/1525 : sensors: bma280: compute accel scales based on data width
- https://gerrit.zephyrproject.org/r/1527 : sensors: bma280: add support for BMC150 accelerometer
- https://gerrit.zephyrproject.org/r/1526 : sensors: bma280: fix accel data sample calculation
- https://gerrit.zephyrproject.org/r/1522 : doc: add architecture porting guide
- https://gerrit.zephyrproject.org/r/1520 : ipm console: Implement flow control between sender and receiver
- https://gerrit.zephyrproject.org/r/1519 : doc: add step for windows build configuration
- https://gerrit.zephyrproject.org/r/1518 : build: fixes issue in windows Kconfig support
- https://gerrit.zephyrproject.org/r/1516 : x86: make GDT setup optional

UPDATED within last 24 hours:
- https://gerrit.zephyrproject.org/r/1496 : qmsi: gpio: use built-in qmsi driver
- https://gerrit.zephyrproject.org/r/1489 : pwm: unify driver names
- https://gerrit.zephyrproject.org/r/1483 : qmsi: watchdog: use built-in qmsi driver
- https://gerrit.zephyrproject.org/r/1506 : qmsi: flash: use built-in qmsi driver
- https://gerrit.zephyrproject.org/r/1493 : qmsi: aio: use built-in qmsi driver
- https://gerrit.zephyrproject.org/r/1488 : qmsi: i2c: use built-in qmsi driver
- https://gerrit.zephyrproject.org/r/1499 : qmsi: adc: use built-in qmsi driver
- https://gerrit.zephyrproject.org/r/1098 : drivers: add qmsi files for Quark MCUs
- https://gerrit.zephyrproject.org/r/1497 : samples: power: use string for driver name
- https://gerrit.zephyrproject.org/r/1482 : qmsi: rtc: use built-in qmsi driver
- https://gerrit.zephyrproject.org/r/1500 : qmsi: uart: use built-in qmsi driver
- https://gerrit.zephyrproject.org/r/1498 : nble: Use string name for GPIO driver
- https://gerrit.zephyrproject.org/r/1491 : spi: use global init priority
- https://gerrit.zephyrproject.org/r/1492 : qmsi: spi: use built-in qmsi driver
- https://gerrit.zephyrproject.org/r/1490 : qmsi: pwm: use built-in qmsi driver
- https://gerrit.zephyrproject.org/r/1495 : qmsi: aon_counters: use built-in qmsi driver
- https://gerrit.zephyrproject.org/r/1494 : aio: rename sample name and make it generic
- https://gerrit.zephyrproject.org/r/1201 : Bluetooth: tester: Add support for seqence gatt database
- https://gerrit.zephyrproject.org/r/1202 : Bluetooth: tester: Return pre defined db offset on start server
- https://gerrit.zephyrproject.org/r/914 : gpio: Improve the public API to handle multi callbacks
- https://gerrit.zephyrproject.org/r/1387 : Bluetooth: gatt: include service api definition proposal
- https://gerrit.zephyrproject.org/r/1271 : sensors: Using new GPIO API callbacks
- https://gerrit.zephyrproject.org/r/1515 : sensor: bmi160: switch to the new logging API
- https://gerrit.zephyrproject.org/r/1353 : samples: Using new GPIO API callbacks
- https://gerrit.zephyrproject.org/r/1452 : sensor: bmi160: add x86 app for receiving BMI160 interrupts
- https://gerrit.zephyrproject.org/r/1455 : sensor: bmi160: fix bmi160_reg_field_update function
- https://gerrit.zephyrproject.org/r/1454 : sensor: bmi160: create two wrappers for bmi160_reg_val_to_range
- https://gerrit.zephyrproject.org/r/1354 : cc2520: Using new GPIO API callbacks
- https://gerrit.zephyrproject.org/r/1451 : sensor: sensor.h: fix typo
- https://gerrit.zephyrproject.org/r/1450 : sensor: bmi160: move sample app to arc subdirectory
- https://gerrit.zephyrproject.org/r/1453 : sensor: bmi160: move the printing macro to the header
- https://gerrit.zephyrproject.org/r/1457 : sensor: bmi160: add support for triggers
- https://gerrit.zephyrproject.org/r/1362 : doc/board: Add documentation file for olimexino_stm32
- https://gerrit.zephyrproject.org/r/1361 : boards/olimexino_stm32: add new board
- https://gerrit.zephyrproject.org/r/1456 : sensor: bmi160: make some read/write functions global
- https://gerrit.zephyrproject.org/r/1458 : sensor: bmi160: add trigger tests to the application
- https://gerrit.zephyrproject.org/r/1445 : gpio: Deprecate API 1.0 callback type and related function
- https://gerrit.zephyrproject.org/r/1363 : sanitycheck: Add olimexino_stm32 board to sanitycheck
- https://gerrit.zephyrproject.org/r/1325 : power_mgmt: Provide APIs for devices to signal busy to PM policy mgr
- https://gerrit.zephyrproject.org/r/1326 : power_mgmt: Sample usage of device_xxx__busy() APIs
- https://gerrit.zephyrproject.org/r/1132 : zephyr-env: prepend SDK tools to PATH
- https://gerrit.zephyrproject.org/r/1508 : microkernel: use _thread_essential_set()
- https://gerrit.zephyrproject.org/r/1514 : nanokernel: tighten _is_thread_essential()
- https://gerrit.zephyrproject.org/r/1369 : samples: adding ADC pulse sensor sample
- https://gerrit.zephyrproject.org/r/202 : doc: Add Arduino 101 Blinky application tutorial.
- https://gerrit.zephyrproject.org/r/1379 : microkernel: [un]block tasks on nanokernel objects infrastructure

MERGED within last 24 hours:
- https://gerrit.zephyrproject.org/r/1524 : Bluetooth: Add missing debug log to HCI driver send()
- https://gerrit.zephyrproject.org/r/1517 : i2c/quark_se_ss: fix RX request pause conditions
- https://gerrit.zephyrproject.org/r/999 : Bluetooth: BR/EDR: Initiate encryption on link
- https://gerrit.zephyrproject.org/r/1034 : Bluetooth: BR/EDR: Notify about pairing while JustWorks
- https://gerrit.zephyrproject.org/r/998 : Bluetooth: BR/EDR: Initiate authentication
- https://gerrit.zephyrproject.org/r/1512 : Bluetooth: samples: Add sample Kconfig for nimble based controllers
- https://gerrit.zephyrproject.org/r/1502 : Bluetooth: tester: Update tester application README
- https://gerrit.zephyrproject.org/r/1501 : fixed inclusion of limits.h when building with newlib
- https://gerrit.zephyrproject.org/r/1484 : checkpatch: warn on COMPLEX_MACRO and MULTISTATEMENT_MACRO_USE_DO_WHILE
- https://gerrit.zephyrproject.org/r/1215 : stm32: rename SOC_STM32F1X -> SOC_SERIES_STM32F1X
- https://gerrit.zephyrproject.org/r/1219 : soc: introduce SoC families and series
- https://gerrit.zephyrproject.org/r/1217 : stm32: reorganise soc directory and use family/series
- https://gerrit.zephyrproject.org/r/1216 : kinetis: reorganise soc directory using soc family
- https://gerrit.zephyrproject.org/r/1221 : new SoC naming convention
- https://gerrit.zephyrproject.org/r/1214 : stm32: rename CONFIG_SOC_STM32 -> CONFIG_SOC_FAMILY_STM32
- https://gerrit.zephyrproject.org/r/1479 : make_zephyr_sdk: Install Nios2 toolchain
- https://gerrit.zephyrproject.org/r/1478 : newlib: Add support for Nios2
- https://gerrit.zephyrproject.org/r/1477 : zephyr-sdk.conf: Bumped DISTRO_VERSION
- https://gerrit.zephyrproject.org/r/1475 : BOSSA: Add BOSSA tool for Arduino Due
- https://gerrit.zephyrproject.org/r/1474 : hosttools-tarbal.bb: Integrate PLY library into SDK
- https://gerrit.zephyrproject.org/r/1476 : make_zephyr_sdk.sh: Bumped SDK version to 0.8.0
- https://gerrit.zephyrproject.org/r/1507 : arduino_101: speed up loading of firmware
- https://gerrit.zephyrproject.org/r/1460 : doc: collaboration: code: gerrit commit message JIRA key
- https://gerrit.zephyrproject.org/r/1481 : doc: remove collaboration guides
- https://gerrit.zephyrproject.org/r/1480 : doc: process tinycrypt headers with doxygen


Re: Using IC manufacturer header files

Nashif, Anas
 

Hi,
Any files or headers included from an external project that need to be kept in sync with upstream can keep their style and formatting to allow updates in the future. This was the approach taken when we imported the IP stack from contiki AFAIK.

Anas

On 19/04/2016, 04:55, "Cufi, Carles" <Carles.Cufi(a)nordicsemi.no> wrote:

Hi there,

We are working on a port to a new ARM SoC family (Nordic nRF5X) and are wondering about a couple of things.
There has been some discussion lately on whether to use the ARM CMSIS header files directly. After a short discussion with Ben, we decided to integrate them in our branch (include/arch/arm/cortex_m/cmsis-core) so as to use a standard API to interface with the Cortex-M cores.
But a new question arose when adding SoC-specific headers to the Zephyr codebase: Nordic provides an MDK with all the relevant header files describing registers, interrupts and memory map of the SoCs. Those are licensed under a 3-clause BSD and we could use them directly so as to follow the trend we started with CMSIS to reuse whatever the manufacturer provides. However there are some coding convention clashes (IRQs listed as an enum instead of #define statements, coding style, etc). So the decision to take now is whether to use the Nordic header files unchanged or to provide our own that more closely match the rest of the architectures in terms of organization and coding style.

Is there a recommended approach for this type of dilemma?

Thanks!

Carles


Re: [RFC 0/3] Timer Fiber API

Luiz Augusto von Dentz
 

Hi Szymon,

On Tue, Apr 19, 2016 at 11:31 AM, Szymon Janc <ext.szymon.janc(a)tieto.com> wrote:
Hi Luiz,

On Monday 18 of April 2016 18:16:00 Luiz Augusto von Dentz wrote:
From: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>

Following the discussion about the Timer API I decided to prototype the
feature in the Bluetooth subsystem:

XX:XX:XX:XX:XX:XX (public)> security 2
bt: bt_timer_queue_add (0x0011a54c): tq 0x00119940 t 0x0011bb1c ticks 3000
XX:XX:XX:XX:XX:XX (public)> bt: timer_queue_fiber (0x0011994c): tq
0x00119940 thread_id 1153356 started bt: timer_queue_ticks_remains
(0x0011994c): tq 0x00119940 ticks 3000 bt: bt_timer_queue_cancel
(0x0011dc60): tq 0x00119940 t 0x0011bb1c bt: bt_timer_queue_add
(0x0011dc60): tq 0x00119940 t 0x0011bb1c ticks 3000 bt:
timer_queue_ticks_remains (0x0011994c): tq 0x00119940 ticks 3000 bt:
bt_timer_queue_cancel (0x0011dc60): tq 0x00119940 t 0x0011bb1c bt:
bt_timer_queue_add (0x0011dc60): tq 0x00119940 t 0x0011bb1c ticks 3000 bt:
timer_queue_ticks_remains (0x0011994c): tq 0x00119940 ticks 2990 Confirm
passkey for XX:XX:XX:XX:XX:XX (public): 775621
bt: timer_expired (0x0011994c): t 0x0011bb1c
bt: smp_timeout: SMP Timeout
bt: timer_queue_ticks_remains (0x0011994c): tq 0x00119940 ticks 0
bt: timer_queue_fiber (0x0011994c): tq 0x00119940 thread_id 1153356 stopped
Disconnected: XX:XX:XX:XX:XX:XX (public) (reason 19)

So at this point it works properly, I tested what could be the minimal stack
necessary in order to run the timer queue and arrive at 512 bytes which is
4 times bigger than what we used to have when using a delayed fiber in SMP
so the timer API only really payoff in terms of memory in case there is 4
or more timer active, which there will be since we will be adding more user
for that in ATT and L2CAP protocols.
I don't get this why you need 512bytes if only 128 was needed by SMP. This
should mostly depend on how heavy is the callback, right? Is overhead for
queue that big?
Actually this is due to printf usage in BT_ERR when smp_timeout is
called, something that perhaps we should not account in the system
wide timer and perhaps just stick with 128 bytes which should work in
most cases where the callback don't require to much stack.


Ive also make the timer queue abort if there is no timers left, this is
something that perhaps is not such a good idea if there is too much
overhead starting the fibers on demand, perhaps by the it cannot be used if
the ticks are low perhaps it is shorter then starting a fiber thus loosing
precision. Anyway the idea here is not to invent a high precision timer, in
fact later on we may introduce a function that takes the timeout in seconds
instead of ticks and then coalesce multiple timers that would happen in the
same second thus reducing the amount of wakeups.

Luiz Augusto von Dentz (3):
Bluetooth: Add timer API
Bluetooth: Kconfig: Add BLUETOOTH_DEBUG_TIMER
Bluetooth: SMP: Make use of bt_timer API

net/bluetooth/Kconfig | 17 ++++
net/bluetooth/Makefile | 1 +
net/bluetooth/smp.c | 40 ++++-----
net/bluetooth/timer.c | 216
+++++++++++++++++++++++++++++++++++++++++++++++++ net/bluetooth/timer.h |
48 +++++++++++
5 files changed, 299 insertions(+), 23 deletions(-)
create mode 100644 net/bluetooth/timer.c
create mode 100644 net/bluetooth/timer.h
--
BR
Szymon Janc


--
Luiz Augusto von Dentz


[RFCv2 2/2] Bluetooth: SMP: Make use of sys_timer API

Luiz Augusto von Dentz
 

From: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>

This replaces use of delayed fiber with sys_timer which shares a common
fiber and stack with other timers.

Change-Id: Ie8f0ea778d7a415a61bd326da70cfae4131156af
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>
---
net/bluetooth/smp.c | 40 +++++++++++++++++-----------------------
1 file changed, 17 insertions(+), 23 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 42f6ecf..53614f9 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -28,6 +28,7 @@
#include <misc/util.h>
#include <misc/byteorder.h>
#include <misc/stack.h>
+#include <misc/timer.h>

#include <net/buf.h>
#include <bluetooth/log.h>
@@ -101,9 +102,6 @@ struct bt_smp {
/* The channel this context is associated with */
struct bt_l2cap_chan chan;

- /* SMP Timeout fiber handle */
- nano_thread_id_t timeout;
-
/* Commands that remote is allowed to send */
atomic_t allowed_cmds;

@@ -155,8 +153,8 @@ struct bt_smp {
/* Remote key distribution */
uint8_t remote_dist;

- /* stack for timeout fiber */
- BT_STACK(stack, 128);
+ /* Timeout timer */
+ struct sys_timer timer;
};

/* based on table 2.8 Core Spec 2.3.5.1 Vol. 3 Part H */
@@ -571,12 +569,9 @@ static void smp_reset(struct bt_smp *smp)
{
struct bt_conn *conn = smp->chan.conn;

- if (smp->timeout) {
- fiber_fiber_delayed_start_cancel(smp->timeout);
- smp->timeout = NULL;
-
- stack_analyze("smp timeout stack", smp->stack,
- sizeof(smp->stack));
+ if (smp->timer.func) {
+ sys_timer_cancel(&smp->timer);
+ smp->timer.func = NULL;
}

smp->method = JUST_WORKS;
@@ -601,15 +596,13 @@ static void smp_reset(struct bt_smp *smp)
#endif /* CONFIG_BLUETOOTH_PERIPHERAL */
}

-static void smp_timeout(int arg1, int arg2)
+static void smp_timeout(void *user_data)
{
- struct bt_smp *smp = (struct bt_smp *)arg1;
-
- ARG_UNUSED(arg2);
+ struct bt_smp *smp = user_data;

BT_ERR("SMP Timeout");

- smp->timeout = NULL;
+ smp->timer.func = NULL;

/*
* If SMP timeout occurred during key distribution we should assume
@@ -627,13 +620,13 @@ static void smp_timeout(int arg1, int arg2)

static void smp_restart_timer(struct bt_smp *smp)
{
- if (smp->timeout) {
- fiber_fiber_delayed_start_cancel(smp->timeout);
+ if (smp->timer.func) {
+ sys_timer_cancel(&smp->timer);
+ } else {
+ sys_timer_init(&smp->timer, smp_timeout, smp);
}

- smp->timeout = fiber_delayed_start(smp->stack, sizeof(smp->stack),
- smp_timeout, (int)smp, 0, 7, 0,
- SMP_TIMEOUT);
+ sys_timer_add(&smp->timer, SMP_TIMEOUT);
}

static struct net_buf *smp_create_pdu(struct bt_conn *conn, uint8_t op,
@@ -2626,8 +2619,9 @@ static void bt_smp_disconnected(struct bt_l2cap_chan *chan)

BT_DBG("chan %p cid 0x%04x", chan, chan->tx.cid);

- if (smp->timeout) {
- fiber_fiber_delayed_start_cancel(smp->timeout);
+ if (smp->timer.func) {
+ sys_timer_cancel(&smp->timer);
+ smp->timer.func = NULL;
}

if (keys) {
--
2.5.5


[RFCv2 1/2] misc: Add timer API

Luiz Augusto von Dentz
 

From: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>

This adds a timer fiber which can be used track timeouts removing the
need to use one delayed fiber per timeout.

Change-Id: Id13347fbc69b1e83bca22094fbeb741e045ed516
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>
---
include/misc/timer.h | 106 ++++++++++++++++++++++++
misc/Kconfig | 37 +++++++++
misc/Makefile | 1 +
misc/timer.c | 224 ++++++++++++++++++++++++++++++++++++++++++++++++++
net/bluetooth/Kconfig | 1 +
5 files changed, 369 insertions(+)
create mode 100644 include/misc/timer.h
create mode 100644 misc/timer.c

diff --git a/include/misc/timer.h b/include/misc/timer.h
new file mode 100644
index 0000000..d3ce695
--- /dev/null
+++ b/include/misc/timer.h
@@ -0,0 +1,106 @@
+/** @file
+ * @brief System timer APIs.
+ */
+
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+extern struct sys_timer_queue *__global_tq;
+
+struct sys_timer_queue {
+ nano_thread_id_t __thread_id;
+ struct sys_timer *__head;
+ size_t stack_size;
+ char stack[0];
+};
+
+typedef void (*sys_timer_func)(void *user_data);
+
+struct sys_timer {
+ struct nano_timer __nano_timer;
+ sys_timer_func func;
+ void *user_data;
+ struct sys_timer *__next;
+};
+
+/**
+ * @brief Init timer queue
+ *
+ * @param tq Timer queue object that should be initialized
+ * @param stack_size The stack size in bytes
+ */
+int sys_timer_queue_init(struct sys_timer_queue *tq, size_t stack_size);
+
+/**
+ * @brief Add timer to a timer queue
+ *
+ * Both timer and timer queue must be initialized.
+ *
+ * @param tq Timer queue object to add the timer
+ * @param t Timer object to be added
+ * @param ticks Amount of time in ticks to wait
+ *
+ * @return Zero on success or (negative) error code otherwise.
+ */
+int sys_timer_queue_add(struct sys_timer_queue *tq, struct sys_timer *t,
+ int ticks);
+
+/**
+ * @brief Cancel timer
+ *
+ * Remove timer from timer queue and stop it so its callback is not called.
+ *
+ * @param tq Timer queue object where the timer was added
+ * @param t Timer object to be canceled
+ *
+ * @return Zero on success or (negative) error code otherwise.
+ */
+int sys_timer_queue_cancel(struct sys_timer_queue *tq, struct sys_timer *t);
+
+/**
+ * @brief Init timer
+ *
+ * @param t Timer object to be initialized
+ * @param func Function callback to be called when timer expires
+ * @param user_data Data to be passed in the callback
+ *
+ * @return Zero on success or (negative) error code otherwise.
+ */
+int sys_timer_init(struct sys_timer *t, sys_timer_func func, void *user_data);
+
+/**
+ * @brief Add timer to the global timer queue
+ *
+ * Timer must be initialized.
+ *
+ * @param _t Timer object to be added
+ * @param _ticks Amount of time in ticks to wait
+ *
+ * @return Zero on success or (negative) error code otherwise.
+ */
+#define sys_timer_add(_t, _ticks) sys_timer_queue_add(__global_tq, _t, _ticks)
+
+/**
+ * @brief Cancel global timer
+ *
+ * Remove timer from the global timer queue and stop it so its callback is not
+ * called.
+ *
+ * @param _t Timer object to be canceled
+ *
+ * @return Zero on success or (negative) error code otherwise.
+ */
+#define sys_timer_cancel(_t) sys_timer_queue_cancel(__global_tq, _t)
diff --git a/misc/Kconfig b/misc/Kconfig
index 4c05169..a9bd80f 100644
--- a/misc/Kconfig
+++ b/misc/Kconfig
@@ -374,3 +374,40 @@ config REBOOT
needed to perform a "safe" reboot (e.g. SYSTEM_CLOCK_DISABLE, to stop the
system clock before issuing a reset).
endmenu
+
+menu "Timer Options"
+
+config SYS_TIMER
+ bool
+ prompt "Enable System Timer"
+ default n
+ select NANO_TIMEOUTS
+ select NANO_TIMERS
+ help
+ Global switch for enabling sys_timer API.
+
+config SYS_TIMER_STACK_SIZE
+ int "Size of the global timer fiber stack"
+ depends on SYS_TIMER
+ default 512
+ range 512 65536
+ help
+ Size of the global timer fiber stack. This is the context from
+ which all global timer callbacks occur.
+
+config SYS_LOG_TIMER_LEVEL
+ int
+ prompt "System Timer Log level"
+ depends on SYS_LOG && SYS_TIMER
+ default 0
+ range 0 4
+ help
+ Sets log level for System Timers.
+ Levels are:
+ 0 OFF, do not write
+ 1 ERROR, only write SYS_LOG_ERR
+ 2 WARNING, write SYS_LOG_WRN in adition to previous level
+ 3 INFO, write SYS_LOG_INF in adition to previous levels
+ 4 DEBUG, write SYS_LOG_DBG in adition to previous levels
+
+endmenu
diff --git a/misc/Makefile b/misc/Makefile
index cb9a718..d57b8f2 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -3,5 +3,6 @@ obj-$(CONFIG_CPLUSPLUS) += cpp_virtual.o cpp_vtable.o \
cpp_init_array.o cpp_ctors.o cpp_dtors.o
obj-$(CONFIG_PRINTK) += printk.o
obj-$(CONFIG_REBOOT) += reboot.o
+obj-$(CONFIG_SYS_TIMER) += timer.o
obj-y += generated/
obj-y += debug/
diff --git a/misc/timer.c b/misc/timer.c
new file mode 100644
index 0000000..90bf196
--- /dev/null
+++ b/misc/timer.c
@@ -0,0 +1,224 @@
+/** @file
+ * @brief Internal APIs for Bluetooth timer handling.
+ */
+
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <nanokernel.h>
+#include <toolchain.h>
+#include <sections.h>
+#include <string.h>
+#include <errno.h>
+#include <misc/stack.h>
+#include <misc/timer.h>
+
+#define SYS_LOG_DOMAIN "System Timer"
+#define SYS_LOG_LEVEL CONFIG_SYS_LOG_TIMER_LEVEL
+#include <misc/sys_log.h>
+
+#if CONFIG_SYS_LOG_TIMER_LEVEL > 0
+/* Enabling debug increases stack size requirement considerably */
+#define STACK_DEBUG_EXTRA 512
+#else
+#define STACK_DEBUG_EXTRA 0
+#endif
+
+#define STACK(name, size) \
+ char __stack name[(size) + STACK_DEBUG_EXTRA]
+
+struct timer_queue {
+ struct sys_timer_queue tq;
+
+ STACK(stack, CONFIG_SYS_TIMER_STACK_SIZE);
+};
+
+static struct timer_queue global_tq = {
+ .tq.stack_size = CONFIG_SYS_TIMER_STACK_SIZE,
+};
+
+struct sys_timer_queue *__global_tq = &global_tq.tq;
+
+static void timer_expired(struct sys_timer *t)
+{
+ SYS_LOG_DBG("t %p", t);
+
+ /* Just to be safe stop the timer */
+ nano_fiber_timer_stop(&t->__nano_timer);
+
+ t->func(t->user_data);
+}
+
+static int32_t timer_queue_ticks_remains(struct sys_timer_queue *tq)
+{
+ int32_t ticks;
+
+ stack_analyze("timer queue stack", tq->stack, tq->stack_size);
+
+ while (tq->__head) {
+ struct sys_timer *cur;
+
+ /* If head is not expired sleep the remaining ticks */
+ ticks = nano_timer_ticks_remain(&tq->__head->__nano_timer);
+ if (ticks > 0) {
+ goto done;
+ }
+
+ /* Remove head since it has expired */
+ cur = tq->__head;
+ tq->__head = tq->__head->__next;
+
+ /* Execute callback */
+ timer_expired(cur);
+ }
+
+ /* No timers left, abort fiber */
+ ticks = 0;
+
+done:
+ SYS_LOG_DBG("tq %p ticks %d", tq, ticks);
+
+ return ticks;
+}
+
+static void timer_queue_fiber(struct sys_timer_queue *tq)
+{
+ int32_t ticks;
+
+ SYS_LOG_DBG("tq %p thread_id %d started", tq, tq->__thread_id);
+
+ while ((ticks = timer_queue_ticks_remains(tq))) {
+ fiber_sleep(ticks);
+ }
+
+ SYS_LOG_DBG("tq %p thread_id %d stopped", tq, tq->__thread_id);
+
+ tq->__thread_id = 0;
+ fiber_abort();
+}
+
+static int timer_queue_start(struct sys_timer_queue *tq)
+{
+ if (tq->__thread_id) {
+ return 0;
+ }
+
+ tq->__thread_id = fiber_start(tq->stack, tq->stack_size,
+ (nano_fiber_entry_t)timer_queue_fiber,
+ (int) tq, 0, 7, 0);
+
+ return 0;
+}
+
+int sys_timer_queue_init(struct sys_timer_queue *tq, size_t stack_size)
+{
+ if (!tq || !stack_size) {
+ return -EINVAL;
+ }
+
+ tq->stack_size = stack_size;
+
+ return 0;
+}
+
+static inline void timer_queue_wakeup(struct sys_timer_queue *tq)
+{
+ if (sys_thread_self_get() != tq->__thread_id) {
+ fiber_wakeup(tq->__thread_id);
+ }
+}
+
+int sys_timer_queue_add(struct sys_timer_queue *tq, struct sys_timer *t, int ticks)
+{
+ struct sys_timer *cur, *prev;
+
+ SYS_LOG_DBG("tq %p t %p ticks %d", tq, t, ticks);
+
+ if (!t || !t->func)
+ return -EINVAL;
+
+ timer_queue_start(tq);
+ nano_timer_start(&t->__nano_timer, ticks);
+
+ /* Sort the list of timers */
+ for (cur = tq->__head, prev = NULL; cur;
+ prev = cur, cur = cur->__next) {
+ if (ticks < nano_timer_ticks_remain(&cur->__nano_timer)) {
+ break;
+ }
+ }
+
+ t->__next = cur;
+
+ if (prev) {
+ prev->__next = t;
+ } else {
+ tq->__head = t;
+ /* Wakeup timer queue fiber since there is a new head */
+ timer_queue_wakeup(tq);
+ }
+
+ return 0;
+}
+
+int sys_timer_queue_cancel(struct sys_timer_queue *tq, struct sys_timer *t)
+{
+ struct sys_timer *cur, *prev;
+
+ SYS_LOG_DBG("tq %p t %p", tq, t);
+
+ if (!t) {
+ return -EINVAL;
+ }
+
+ /* Lookup existing timers */
+ for (cur = tq->__head, prev = NULL; cur;
+ prev = cur, cur = cur->__next) {
+ if (cur == t) {
+ break;
+ }
+ }
+
+ if (!cur) {
+ return -ENOENT;
+ }
+
+ nano_timer_stop(&t->__nano_timer);
+
+ /* Remove timer for the queue */
+ if (prev) {
+ prev->__next = t->__next;
+ } else {
+ tq->__head = t->__next;
+ /* Wakeup timer queue fiber since there is a new head */
+ timer_queue_wakeup(tq);
+ }
+
+ return 0;
+}
+
+int sys_timer_init(struct sys_timer *t, sys_timer_func func, void *user_data)
+{
+ if (!t || !func) {
+ return -EINVAL;
+ }
+
+ t->func = func;
+ t->user_data = user_data;
+ nano_timer_init(&t->__nano_timer, t);
+
+ return 0;
+}
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 2ffb0e0..aa2712b 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -129,6 +129,7 @@ config BLUETOOTH_CENTRAL

config BLUETOOTH_CONN
bool
+ select SYS_TIMER
default n

if BLUETOOTH_CONN
--
2.5.5


[RFCv2 0/2] System Timer API

Luiz Augusto von Dentz
 

From: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>

So at this point it works properly, I tested what could be the minimal stack
necessary in order to run the timer queue and arrive at 512 bytes which is 4
times bigger than what we used to have when using a delayed fiber in SMP so the
timer API only really payoff in terms of memory in case there is 4 or more
timer active, which there will be since we will be adding more user for that
in ATT and L2CAP protocols.

Ive also make the timer queue abort if there is no timers left, this is
something that perhaps is not such a good idea if there is too much
overhead starting the fibers on demand, perhaps by the it cannot be used if
the ticks are low perhaps it is shorter then starting a fiber thus loosing
precision. Anyway the idea here is not to invent a high precision timer, in
fact later on we may introduce a function that takes the timeout in seconds
instead of ticks and then coalesce multiple timers that would happen in the
same second thus reducing the amount of wakeups.

v2: Move timer under misc, make use of system log support.

Luiz Augusto von Dentz (2):
misc: Add timer API
Bluetooth: SMP: Make use of bt_timer API

include/misc/timer.h | 106 ++++++++++++++++++++++++
misc/Kconfig | 37 +++++++++
misc/Makefile | 1 +
misc/timer.c | 224 ++++++++++++++++++++++++++++++++++++++++++++++++++
net/bluetooth/Kconfig | 1 +
net/bluetooth/smp.c | 40 ++++-----
6 files changed, 386 insertions(+), 23 deletions(-)
create mode 100644 include/misc/timer.h
create mode 100644 misc/timer.c

--
2.5.5


Using IC manufacturer header files

Carles Cufi
 

Hi there,

We are working on a port to a new ARM SoC family (Nordic nRF5X) and are wondering about a couple of things.
There has been some discussion lately on whether to use the ARM CMSIS header files directly. After a short discussion with Ben, we decided to integrate them in our branch (include/arch/arm/cortex_m/cmsis-core) so as to use a standard API to interface with the Cortex-M cores.
But a new question arose when adding SoC-specific headers to the Zephyr codebase: Nordic provides an MDK with all the relevant header files describing registers, interrupts and memory map of the SoCs. Those are licensed under a 3-clause BSD and we could use them directly so as to follow the trend we started with CMSIS to reuse whatever the manufacturer provides. However there are some coding convention clashes (IRQs listed as an enum instead of #define statements, coding style, etc). So the decision to take now is whether to use the Nordic header files unchanged or to provide our own that more closely match the rest of the architectures in terms of organization and coding style.

Is there a recommended approach for this type of dilemma?

Thanks!

Carles


Re: [RFC 3/3] Bluetooth: SMP: Make use of bt_timer API

Szymon Janc <ext.szymon.janc@...>
 

Hi Luiz,

On Monday 18 of April 2016 18:16:03 Luiz Augusto von Dentz wrote:
From: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>

This replaces use of delayed fiber with bt_timer which uses a common
fiber and stack with other timers used by the stack.

Change-Id: Ie8f0ea778d7a415a61bd326da70cfae4131156af
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>
---
net/bluetooth/smp.c | 40 +++++++++++++++++-----------------------
1 file changed, 17 insertions(+), 23 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 42f6ecf..f54b6c9 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -50,6 +50,7 @@
#include "conn_internal.h"
#include "l2cap_internal.h"
#include "smp.h"
+#include "timer.h"

#define SMP_TIMEOUT (30 * sys_clock_ticks_per_sec)

@@ -101,9 +102,6 @@ struct bt_smp {
/* The channel this context is associated with */
struct bt_l2cap_chan chan;

- /* SMP Timeout fiber handle */
- nano_thread_id_t timeout;
-
/* Commands that remote is allowed to send */
atomic_t allowed_cmds;

@@ -155,8 +153,8 @@ struct bt_smp {
/* Remote key distribution */
uint8_t remote_dist;

- /* stack for timeout fiber */
- BT_STACK(stack, 128);
+ /* Timeout timer */
+ struct bt_timer timer;
};

/* based on table 2.8 Core Spec 2.3.5.1 Vol. 3 Part H */
@@ -571,12 +569,9 @@ static void smp_reset(struct bt_smp *smp)
{
struct bt_conn *conn = smp->chan.conn;

- if (smp->timeout) {
- fiber_fiber_delayed_start_cancel(smp->timeout);
- smp->timeout = NULL;
-
- stack_analyze("smp timeout stack", smp->stack,
- sizeof(smp->stack));
+ if (smp->timer.func) {
+ bt_timer_cancel(&smp->timer);
+ smp->timer.func = NULL;
}

smp->method = JUST_WORKS;
@@ -601,15 +596,13 @@ static void smp_reset(struct bt_smp *smp)
#endif /* CONFIG_BLUETOOTH_PERIPHERAL */
}

-static void smp_timeout(int arg1, int arg2)
+static void smp_timeout(void *user_data)
{
- struct bt_smp *smp = (struct bt_smp *)arg1;
-
- ARG_UNUSED(arg2);
+ struct bt_smp *smp = user_data;

BT_ERR("SMP Timeout");

- smp->timeout = NULL;
+ smp->timer.func = NULL;

/*
* If SMP timeout occurred during key distribution we should assume
@@ -627,13 +620,13 @@ static void smp_timeout(int arg1, int arg2)

static void smp_restart_timer(struct bt_smp *smp)
{
- if (smp->timeout) {
- fiber_fiber_delayed_start_cancel(smp->timeout);
+ if (smp->timer.func) {
+ bt_timer_cancel(&smp->timer);
+ } else {
+ bt_timer_init(&smp->timer, smp_timeout, smp);
}

- smp->timeout = fiber_delayed_start(smp->stack, sizeof(smp->stack),
- smp_timeout, (int)smp, 0, 7, 0,
- SMP_TIMEOUT);
+ bt_timer_add(&smp->timer, SMP_TIMEOUT);
This is something that will likely be common case (at least in networking)
so maybe we could have bt_timer_restart()?

}

static struct net_buf *smp_create_pdu(struct bt_conn *conn, uint8_t op,
@@ -2626,8 +2619,9 @@ static void bt_smp_disconnected(struct bt_l2cap_chan
*chan)

BT_DBG("chan %p cid 0x%04x", chan, chan->tx.cid);

- if (smp->timeout) {
- fiber_fiber_delayed_start_cancel(smp->timeout);
+ if (smp->timer.func) {
+ bt_timer_cancel(&smp->timer);
+ smp->timer.func = NULL;
}
We could have helpers like bt_timer_active/running() etc. Especially since
bt_timer_init() assigns func internally. That way all fields in struct
bt_timer would be internal only.


if (keys) {
--
BR
Szymon Janc


Re: [RFC 1/3] Bluetooth: Add timer API

Szymon Janc <ext.szymon.janc@...>
 

Hi Luiz,

On Monday 18 of April 2016 18:16:01 Luiz Augusto von Dentz wrote:
From: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>

This adds a timer fiber which can be used track timeouts removing the
need to use one delayed fiber per timeout.

Change-Id: Id13347fbc69b1e83bca22094fbeb741e045ed516
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz(a)intel.com>
---
net/bluetooth/Kconfig | 9 +++
net/bluetooth/Makefile | 1 +
net/bluetooth/timer.c | 211
+++++++++++++++++++++++++++++++++++++++++++++++++ net/bluetooth/timer.h |
48 +++++++++++
4 files changed, 269 insertions(+)
create mode 100644 net/bluetooth/timer.c
create mode 100644 net/bluetooth/timer.h

diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 2ffb0e0..2d703e3 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -20,6 +20,7 @@ menuconfig BLUETOOTH
bool "Bluetooth support"
default n
select NANO_TIMEOUTS
+ select NANO_TIMERS
select NET_BUF
select BLUETOOTH_LE if !BLUETOOTH_STACK_NBLE
help
@@ -132,6 +133,14 @@ config BLUETOOTH_CONN
default n

if BLUETOOTH_CONN
+config BLUETOOTH_TIMER_STACK_SIZE
+ int "Size of the timer fiber stack"
+ default 512
+ range 512 65536
+ help
+ Size of the timer fiber stack. This is the context from
+ which all timer callbacks occur.
I think it would be better to have kconfig option for callback needed stack
and add overhead internally. This should be easier to estimate for user.

+
config BLUETOOTH_ACL_IN_COUNT
int "Number of incoming ACL data buffers"
default 5
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index 160ba34..18f9231 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_BLUETOOTH_STACK_HCI) = \

ifeq ($(CONFIG_BLUETOOTH_CONN),y)
obj-y += conn.o \
+ timer.o \
l2cap.o \
att.o \
gatt.o
diff --git a/net/bluetooth/timer.c b/net/bluetooth/timer.c
new file mode 100644
index 0000000..608ee4f
--- /dev/null
+++ b/net/bluetooth/timer.c
@@ -0,0 +1,211 @@
+/** @file
+ * @brief Internal APIs for Bluetooth timer handling.
+ */
+
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and + *
limitations under the License.
+ */
+
+#include <nanokernel.h>
+#include <toolchain.h>
+#include <sections.h>
+#include <string.h>
+#include <errno.h>
+#include <misc/stack.h>
+
+#include <bluetooth/log.h>
+
+#include "timer.h"
+
+struct timer_queue {
+ struct bt_timer_queue tq;
+
+ BT_STACK(stack, CONFIG_BLUETOOTH_TIMER_STACK_SIZE);
+};
+
+static struct timer_queue global_tq = {
+ .tq.stack_size = CONFIG_BLUETOOTH_TIMER_STACK_SIZE,
+};
+
+struct bt_timer_queue *__global_tq = &global_tq.tq;
+
+static void timer_expired(struct bt_timer *t)
+{
+ BT_DBG("t %p", t);
+
+ /* Just to be safe stop the timer */
+ nano_fiber_timer_stop(&t->__nano_timer);
+
+ t->func(t->user_data);
+}
+
+static int32_t timer_queue_ticks_remains(struct bt_timer_queue *tq)
+{
+ int32_t ticks;
+
+ stack_analyze("timer queue stack", tq->stack, tq->stack_size);
+
+ while (tq->__head) {
+ struct bt_timer *cur;
+
+ /* If head is not expired sleep the remaining ticks */
+ ticks = nano_timer_ticks_remain(&tq->__head->__nano_timer);
+ if (ticks > 0)
+ goto done;
+
+ /* Remove head since it has expired */
+ cur = tq->__head;
+ tq->__head = tq->__head->__next;
+
+ /* Execute callback */
+ timer_expired(cur);
+ }
+
+ /* No timers left, abort fiber */
+ ticks = 0;
+
+done:
+ BT_DBG("tq %p ticks %d", tq, ticks);
+
+ return ticks;
+}
+
+static void timer_queue_fiber(struct bt_timer_queue *tq)
+{
+ int32_t ticks;
+
+ BT_DBG("tq %p thread_id %d started", tq, tq->__thread_id);
+
+ while ((ticks = timer_queue_ticks_remains(tq))) {
+ fiber_sleep(ticks);
+ }
+
+ BT_DBG("tq %p thread_id %d stopped", tq, tq->__thread_id);
+
+ tq->__thread_id = 0;
+ fiber_abort();
+}
+
+static int timer_queue_start(struct bt_timer_queue *tq)
+{
+ if (tq->__thread_id) {
+ return 0;
+ }
+
+ tq->__thread_id = fiber_start(tq->stack, tq->stack_size,
+ (nano_fiber_entry_t) timer_queue_fiber,
+ (int) tq, 0, 7, 0);
+
+ return 0;
+}
+
+int bt_timer_queue_init(struct bt_timer_queue *tq, size_t stack_size)
+{
+ if (!tq || !stack_size) {
+ return -EINVAL;
+ }
+
+ tq->stack_size = stack_size;
+
+ return 0;
+}
+
+static inline void timer_queue_wakeup(struct bt_timer_queue *tq)
+{
+ if (sys_thread_self_get() != tq->__thread_id)
+ fiber_wakeup(tq->__thread_id);
+}
+
+int bt_timer_queue_add(struct bt_timer_queue *tq, struct bt_timer *t, int
ticks) +{
+ struct bt_timer *cur, *prev;
+
+ BT_DBG("tq %p t %p ticks %d", tq, t, ticks);
+
+ if (!t || !t->func)
+ return -EINVAL;
+
+ timer_queue_start(tq);
+ nano_timer_start(&t->__nano_timer, ticks);
+
+ /* Sort the list of timers */
+ for (cur = tq->__head, prev = NULL; cur;
+ prev = cur, cur = cur->__next) {
+ if (ticks < nano_timer_ticks_remain(&cur->__nano_timer)) {
+ break;
+ }
+ }
+
+ t->__next = cur;
+
+ if (prev) {
+ prev->__next = t;
+ } else {
+ tq->__head = t;
+ /* Wakeup timer queue fiber since there is a new head */
+ timer_queue_wakeup(tq);
+ }
+
+ return 0;
+}
+
+int bt_timer_queue_cancel(struct bt_timer_queue *tq, struct bt_timer *t)
+{
+ struct bt_timer *cur, *prev;
+
+ BT_DBG("tq %p t %p", tq, t);
+
+ if (!t) {
+ return -EINVAL;
+ }
+
+ /* Lookup existing timers */
+ for (cur = tq->__head, prev = NULL; cur;
+ prev = cur, cur = cur->__next) {
+ if (cur == t) {
+ break;
+ }
+ }
+
+ if (!cur) {
+ return -ENOENT;
+ }
+
+ nano_timer_stop(&t->__nano_timer);
+
+ /* Remove timer for the queue */
+ if (prev) {
+ prev->__next = t->__next;
+ } else {
+ tq->__head = t->__next;
+ /* Wakeup timer queue fiber since there is a new head */
+ timer_queue_wakeup(tq);
+ }
+
+ return 0;
+}
+
+int bt_timer_init(struct bt_timer *t, bt_timer_func func, void *user_data)
+{
+ if (!t || !func) {
+ return -EINVAL;
+ }
+
+ t->func = func;
+ t->user_data = user_data;
+ nano_timer_init(&t->__nano_timer, t);
+
+ return 0;
+}
diff --git a/net/bluetooth/timer.h b/net/bluetooth/timer.h
new file mode 100644
index 0000000..82bee8f
--- /dev/null
+++ b/net/bluetooth/timer.h
@@ -0,0 +1,48 @@
+/** @file
+ * @brief Internal APIs for Bluetooth timer handling.
+ */
+
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and + *
limitations under the License.
+ */
+
+extern struct bt_timer_queue *__global_tq;
+
+struct bt_timer_queue {
+ nano_thread_id_t __thread_id;
+ struct bt_timer *__head;
+ size_t stack_size;
+ char stack[0];
+};
+
+typedef void (*bt_timer_func)(void *user_data);
+
+struct bt_timer {
+ struct nano_timer __nano_timer;
+ bt_timer_func func;
+ void *user_data;
+ struct bt_timer *__next;
+};
+
+int bt_timer_queue_init(struct bt_timer_queue *tq, size_t stack_size);
+
+int bt_timer_queue_add(struct bt_timer_queue *tq, struct bt_timer *t,
+ int ticks);
+int bt_timer_queue_cancel(struct bt_timer_queue *tq, struct bt_timer *t);
+
+int bt_timer_init(struct bt_timer *t, bt_timer_func func, void *user_data);
+
+#define bt_timer_add(_t, _ticks) bt_timer_queue_add(__global_tq, _t,
_ticks) +#define bt_timer_cancel(_t) bt_timer_queue_cancel(__global_tq, _t)
--
BR
Szymon Janc

7581 - 7600 of 8118