Giter Site home page Giter Site logo

redbear / firmware Goto Github PK

View Code? Open in Web Editor NEW

This project forked from particle-iot/device-os

9.0 5.0 12.0 120.51 MB

Firmware for Particle Devices: Spark Core (master branch) and Photon (latest branch)

Home Page: https://www.particle.io/

License: GNU Lesser General Public License v3.0

Makefile 0.19% C 80.02% Objective-C 6.17% Assembly 0.04% Shell 0.27% Batchfile 0.01% C++ 12.90% Python 0.20% HTML 0.04% CMake 0.03% Tcl 0.01% Perl 0.05% Ruby 0.01% Gherkin 0.01% JavaScript 0.05% CSS 0.01%

firmware's Issues

Known issue: Using D2/D3/D4 pins to drive servos or output PWMs may cause the status RGB working abnormally

Due to the hardware design, we have to use the TIM3/channel3, TIM3/channel4 and TIM2/channel4 to generate PWM to drive the on-board status RGB. At the same time the TIM3/channel2, TIM3/channel1 and TIM2/channel2 are mapped to D2/D3/D4 respectively. See the pinmap_hal.c.

While the channels belonging to the same timer share the same period, once you config the period for one certain channel, the other channels will work basing on this period. For example, when you output PWM on D2 in period 2 ms (i.e. 500 Hz), and then you drive a servo on D3, as the default period to drive a servo is 20 ms (i.e. 50 Hz), the period of the PWM on D2 will be changed to 20 ms as well. Thus the duty of the PWM on D2 is incorrect.

Since the period of the PWMs to drive the status RGB are set to 10 ms (i.e. 100 Hz) by default, so if you output PWMs or drive servos on D2/D3/D4, it maybe change the period of the PWMs for status RGB -- then the status RGB will works weirdly as you see. Unless you keep the period unchanged, then you can use D2 ~ D4 to output PWMs or drive servos.

Known issue: Tone on D2/D3/D4 is unavailable

Just as the issue #11 described, tone on D2/D3/D4 will definitely change the period of the PWMs for the status RGB. So we disable the tone function on D2/D3/D4. Calling tone APIs to drive these pins make no effect.

Severely outdated BTStack library

The last time the btstack library was pulled was over two years ago. Since then there has been over 2600 commits to btstack. Naturally there are some API changes but from my local-scale comparisons they seem mostly compatible.

bluekitchen/btstack@ebd8f44...master

At the very least updating will bring in bug fixes. As for feature improvements, the current version in the firmware does not even enable adding descriptors to a gatt characteristic definition, a basic feature. I'm sure there are more but that's the one I was looking at for my own application.

I would appreciate if the library was updated, or given guidance on how to do it myself.

User loop() function only called every 1 ms

I made a Particle cloud IDE sketch that toggles a LED as fast as possible. An oscilloscope shows the resulting waveform is exactly 500 Hz, meaning loop() is called every 1000 microseconds.

Redbear Duo on firmware 0.2.2 and 0.2.3. Simple test:

int led = D7, i;

void setup() {
pinMode(led, OUTPUT);
}

void loop() {
digitalWrite(led, (i++ & 1) ? LOW : HIGH);
}


Completeness:

  • Minimum test case added
  • Device, system and user firmware versions stated
  • [ ]
    redbear_duo_1ms_loop
    Particle confirmed

BLE APIs are not thread safe

The BTstack APIs used to implement the BLE wiring/HAL API are supposed to be single-threaded. The HAL code, however, spawns a thread that handles the BTstack execution loop. This can be done, but only when certain rules are followed, which is not the case.

Currently the APIs such as "ble.startAdvertising()" are documented to be safe to be executed in main thread in a pattern like

ble.init();
// do some setup
ble.startAdvertising();

This, in turn, triggers the calls to hal_btstack_init (for ble.init) for BTstack to be initialized, which spawns a thread at the end. By the time hal_btstack_startAdvertising (for ble.startAdvertising) is called the thread is already running and continuing the Bluetooth initialization (often the key exchange as part of BTstack's sm_run function).

Since the APIs are not thread safe one of the following things can occur:

  • hal_btstack_startAdvertising calls gap_advertisements_enable(1). It sets the necessary flags and proceeds to call hci_run. hci_run immediately quits on the if (!hci_can_send_command_packet_now()) return; condition because the worker thread is busy sending key exchange packets. In turn, the advertisements are never enabled and there's no error reported.
  • hal_btstack_startAdvertising calls gap_advertisements_enable(1). It sets the necessary flags and proceeds to call hci_run. hci_run goes past the if (!hci_can_send_command_packet_now()) return; check. Now depending on the thread interleaving one of these things can occur:
    • The sm_run key exchange on the worker fails because it can't send a packet now.
    • Both the worker thread and application thread pass through the hci_can_send_command_packet_now checks and end up messing up the command buffers and sending gibberish to the HCI USART communication port.

In some cases, the thread interleaving happens to be lucky and everything succeeds in the right order.

There are some ways to solve the problem, but each of them has its own drawbacks. These are the ones that I have come up with:

  • Do not spawn the BLE worker thread and introduce a ble.waitForEvents() API that will be run in the application thread.
    • Pros: Easy to implement. Easy to reason about thread safety, since BTstack would be run in a single thread as intended.
    • Cons: Breaking API change. Harder to manage for more complex applications, especially when power management gets involved. The BLE provisioning code would need to be changed.
  • Make the BLE worker thread spawning explicit by introducing a ble.startWorker() API. Allow all BLE API calls to be made on the application thread until the startWorker API is called. After that the APIs could only be called in the BLE timers and callbacks, with the exception of ble.deInit() (or possibly ble.stopWorker()). It can be combined with the ble.waitForEvents() API above to offer an alternative and introduce more flexibility for the application writers.
    • Pros: Easy to implement. Very deterministic and in line with how BTstack's official examples are written.
    • Cons: Breaking API change. Requires more understanding by the application developers (possibly a good thing).
  • Create an event queue on the worker thread and process the APIs on the queue along with the BTstack main look.
    • Pros: The APIs remain the same. It doesn't block any application code by delays.
    • Cons: Harder to implement since almost every BLE HAL API would have to be rewritten to be queued (possibly something could be achieved by C macros). Introduces memory management for the queue, which has to handle more states.
  • Implement a synchronization mechanism between the worker thread and the application thread in a way that the pauses the worker thread when an API is being executed and resumes it after. This could be achieved by a mutex that is held on the worker thread and released/reentered at a specified point. The APIs would have to enter the mutex, call the BTstack API and release the mutex, thus allowing the worker thread to proceed.
    • Pros: Easy to implement. No additional memory management.
    • Cons: Feels like a hack. May block the application thread when the BTstack thread is busy processing packets.

Note that this is very much not a theoretical problem. It keeps happening on my initialization sequence in various different ways. I spend days analyzing what is going wrong and I will happily provide more information and relevant logs. The race conditions often manifest as "invalid packet type" or "packet timeout" errors in the HCI code in hci_transport_h4_wiced.c.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.