Giter Site home page Giter Site logo

ruuvi / ruuvi.firmware.c Goto Github PK

View Code? Open in Web Editor NEW
52.0 16.0 37.0 17.64 MB

Ruuvi Firmware version 3. Built on top of Nordic SDK 15, uses both Ruuvi and external repositories as submodules. In Beta, no breaking changes are intended but may be done if absolutely necessary

License: BSD 3-Clause "New" or "Revised" License

C 81.87% Makefile 14.73% Shell 3.41%
ruuvi ruuvi-firmware

ruuvi.firmware.c's Introduction

ruuvi.firmware.c

Current git repository status:

Build Status Quality Gate Status Bugs Code Smells Coverage Duplicated Lines (%) Lines of Code Maintainability Rating Reliability Rating Technical Debt

Ruuvi Firmware version 3. Built on top of Nordic SDK 15, uses both Ruuvi and external repositories as submodules. Under development, please follow Ruuvi Blog for details. The project is in beta stage, no breaking changes are expected

Setting up

Prerequisites

Suggested

  • Ruuvi Dev kit board and a USB power & data cable.
  • Or any other SWD programmer and a cable matching your target board.

To validate you changes, for example before making Pull Requests

SDK 15.3.

Download Nordic SDK15.3 (.8GB)and install it at the project root. If you're working on multiple nRF projects, use symbolic linking to have only one copy.

Creating your fork

Use git to include all Submodules ( ruuvi.drivers.c, ruuvi.endpoint.c, etc )

Run git submodule sync --recursive and git submodule update --init --recursive to update the modules from the master repository .

Coding style

Use coding style consistant with BARR-C:2018. Coding style is enforced with Artistic Style. Some source files were inserted into the master repository before this was established and running astyle will revise the source as necessary. See .astylerc for non-default options (for example max-code-length=90). Run make astyle.

Compiling and Testing

Segger Embedded Studio should be used for developing.

Segger Embedded Studio is set up by installing nRF Connect for Desktop and following Getting Started instructions.

Start SES

File -> Open Solution -> ruuvi.firmware.c.emProject. Each of the target boards is in their own project. Sess 'build' compiles and links the firmware. In the Project Explorer select the correct project according to the appropriate tag name. Select the Build Configuration: Debug, Long Life or Release.

Build

Navigate to Build -> Build <project name> or press the F7 key.

Connect you board with either:

Debug

Navigate to Debug -> Go or press the F5 key. This will flash the firmware and start the debugger.

ARMGCC is used for Jenkins builds

You can make the project and a single variant by runnning "make variantName" (for example "make ruuvitag_b" at top level of this repository

When building binaries for distribution, use the provided 'Makefile' script. This way you can be certain to have a repeatable build process. The Makefile uses the tag name of current git commit for filenames and version number. Tags should be valid semantic versions, starting with v and possibly having pre-release information such as -rc2. Do not add build information such as +TestFW. If you have tagged the version as v3.99.1 the files will be named $BOARD_armgcc_ruuvifw_$VARIANT_v3.99.1_$TYPE.extension. For example ruuvitag_b_armgcc_ruuvifw_default_v3.29.3-rc1_full.hex.

Flashing

Connect your board with either:

nRF Command Line Tools

Navigate to ruuvi.firmware.c/src/targets/<board name>/armgcc.
Run make to compile the application.
Run ./package.sh to generate the complete firmware HEX and ZIP files.
To flash the tag, run

nrfjprog  --eraseall   # including previous bootloader
nrfjprog  --program ruuvitag_b_armgcc_ruuvifw_v3.30.0-RC5_app.hex --verify --fast --reset 

Finishing up

Static analysis

The code can be checked with PVS Studio and Sonarcloud for some common errors, style issues and potential problems. Here is a link to generated report.

PVS

Obtain license and software from Viva64. Installation process is described in ruuvi.docs.com Make runs PVS Studio scan and outputs results under doxygen/html/fullhtml. This produces many warnings, you need to filter the warnings you're interested in. For example you probably want to filter out warnings related to 64-bit systems.

Sonar scan

Travis pushes the results to SonarCloud.IO. SonarCloud uses access token which is private to Ruuvi. You need to fork the project and setup the SonarCloud under your own account to run Sonar Scan on your own code.

Running unit tests

Ceedling

Unit tests are implemented with Ceedling. Run the tests with ceedling test:all

Gcov

Ceedling can also generate Gcov reports with ceedling gcov:all utils:gcov. The report can be found under build/artifacts/gcov.

Unit test continuous integration

Travis will fail the build if unit test fails and Gcov results will get pushed to SonarCloud.

How to contribute

Please let us know your thoughts on the direction and structure of the project. Does the project help you to understand how to build code for the RuuviTag? Is the structure of the project sensible to you?

If you want to assist in the project maintenance by fixing some issues doxygen.error is a good place to look for code which needs better commenting. Project badges at the top of the readme point to issues which range from trivial clarifications to complex refactoring.

If you want to add new features, please discuss the feature first at the Forum and then create ceedling unit tests for the functionality. Once the functionality is agreed and testable in can be integrated into project.

Licensing

Ruuvi code is BSD-3 licensed. Submodules and external dependencies have their own licenses, which are BSD-compatible.

Documentation

Document is generated with Doxygen. Run make doxygen to generate the docs locally, or browse to Travis built docs

ruuvi.firmware.c's People

Contributors

dg12 avatar kasumman avatar niksiboxi avatar ojousima avatar opsationby avatar reviewpad[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ruuvi.firmware.c's Issues

initialization: order of inits: BLE first

Although it seems that LEDs are easy and cannot reasonably fail,
It would be much better to initialize BLE and start advertising earliest.
Does BLE depend on TIMER? RTC?
Consider that BLE has no external GPIO solder connections.

GPIO, IC2 and SPI should be initialized LAST.

Is there any real-world data regarding failures?
From production final tests?

LIS2DH12: Initialization failure on first boot

Sometimes on first boot LIS2DH12 returns a test failure.

{
"firmware":"Ruuvi FW-debug",
"board":"RUUVITAG_B",
"ruuvi.boards.c":"0.7.0",
"ruuvi.drivers.c":"0.2.5",
"ruuvi.libraries.c":"0.2.0",
"libraries": {
"peak2peak":{
"valid_data":"pass",
"nan_data":"pass",
"overflow_fpu_errors":"FPU OFC Error",
"overflow_data":"pass",
"input_validation":"pass"
},
"rms":{
"valid_data":"pass",
"nan_data":"pass",
"overflow_fpu_errors":"FPU OFC ErrorFPU OFC Error",
"overflow_data":"pass",
"input_validation":"pass"
},
"variance":{
"valid_data":"pass",
"nan_data":"pass",
"overflow_fpu_errors":"FPU OFC ErrorFPU OFC Error",
"overflow_data":"pass",
"input_validation":"pass"
},
"ringbuffer":{
"put_get":"pass",
"overflow":"pass",
"overdrain":"pass"
},
"liblzf":{
"compress_decompress":"pass",
"decompress_twice":"pass",
"compress_ratio:""0.54%",
"compress_ratio_test":"pass",
"invalid_input":"pass"
},
"total_tests":"19",
"passed_tests":"19"
},
"drivers": {
"flash":{
"init":"pass",
"uninit":"pass",
"store":"pass",
"load":"pass",
"free":"pass",
"gc":"pass"
},
"power":{
"dcdc_internal":"pass"
},
"timer":{
"init":"pass",
"create":"pass",
"single_shot":"pass",
"repeat":"pass"
},
"scheduler":{
"init":"pass",
"execute":"pass",
"put":"pass"
},
"sensors": {
"SHTCX": {
"init":"pass",
"modes":"pass",
"configuration":"pass",
"interrupts":"skipped"
"data":{
"timestamp_ms": "4225",
"humidity_rh": "41.95",
"temperature_c": "24.81",
}
},
"BME280": {
"init":"pass",
"modes":"pass",
"configuration":"pass",
"interrupts":"skipped"
"data":{
"timestamp_ms": "4448",
"humidity_rh": "39.27",
"pressure_pa": "100923.18",
"temperature_c": "24.61",
}
},
"LIS2DH12": {
"init":"fail",
"modes":"fail",
"configuration":"fail",
"interrupts":"skipped"
}
},
"radio":{
"init":"pass,"
"address_set_get":"pass"
},
"ble_adv_1_mbit":{
"init":"pass",
"interval":"pass",
"extended":"pass",
"power":"pass",
"scan":"pass"
},
"ble_adv_2_mbit":{
"init":"pass",
"interval":"pass",
"extended":"pass",
"power":"pass",
"scan":"pass"
},
"ble_gatt_1_mbit":{
"init":"pass",
"tx":"timeout"
"throughput":"0.000 bps"
},
"ble_gatt_2_mbit":{
"init":"pass",
"tx":"timeout"
"throughput":"0.000 bps"
},
"uart":{
"init":"pass",
"tx_rx":"pass"
"rx_corrupt":"pass"
"rx_short":"pass"
},
"gpio":{
"init":"pass",
"configure":"pass",
"toggle":"pass"
},
"gpio_interrupt":{
"init":"pass",
"enable":"pass"
},
"gpio_pwm":{
"init":"pass",
"start":"pass"
},
"nfc":{
"init":"pass",
"tx_rx":"timeout"
},
}
}

This is probably related to #65. In some cases, such as when board is moved on boot, the selftest would fail as the LIS2DH12 selftest verifies change of sensor values against self-test excitation. The app_sensor.c works around the issue by retrying the initialization, but the root cause of initialization failures should be found and fixed.

versioning lost major.minor.update

NFC SW now reports 7 characters from GitHub.

Automatic versioning (only) by a tool looses the intelligence behind "This is a version".

I would like to suggest that SW "version" be returned to the traditional 3 numeric field format of major.minor.update.

Perhaps an additional field can be defined containing the GitHub ID ( and a date-time too!)

Feature: Combine data from different sensors

Currently (3.28.13) firmware only selects first available sensor, go through all sensor backends and fetch data as required to fill all the fields.

For example temperature + humidity from SHTC and air pressure from BME

Feature: Temperature,.. (env sensors )logging

Needeed:
Env sensors logging in a circular array every x minutes (configurable) and when mobile app connecto to tag get all logs.
if no smartphone connect and circular array go to end they back to init and replace the older by new.

Where is the Gatt code?

Hi
I am trying to learn with this code
I have already flash hex into ruuvi and it works but I can not find where characteristics and services were declared.

Thanks

Alex

Error in ruuviblog-branch

Branch ruuviblog has an error in ./targets/ruuvitag_b/armgcc/package.sh line 18:
wget $BOOTLOADER
Shouldn't it be
wget https://github.com/ruuvi/ruuvi.nrf5_sdk15_bootloader.c/releases/download/3.0.0/ $BOOTLOADER

Refactor tasks into submodule

Split functionality common to any firmware using Ruuvi drivers to their separate repository to allow working on common functionality across many projects using git workflow

initialization: init all subsystems before checking for failure

Previously, Version 2 initialized all subsystems and set a unique flag for any subsystem that failed. After all initializations were attempted the cumulative result was evaluated.
This permits a tag to continue to operate even if one subsystem cannot be initialized or causes a hangup.
The only peripheral subsystem that must be successfully initialized and operational is BLE (and a RTC which It depends on) since if the tag is being used as a proximity beacon, sensors are not necessary. Additionally failure of the accelerator to initialize may not be important in a "old-chain" application.

Logging measurements in advertise format would allow for storing much more data

in /app_log.h
Would it be better to keep measurements in app_log_element_t in integer hundredths rather than float?
I wonder if there are sever compression considerations especially dealing with successive readings that are not represented well in hexadecimal fractions which are actually nearly the same.

Consider the value 0.10 which in floating point results in 0x3dcccccd. YUCK while in integer hundredths is simply 0x00...0A

Try using https://www.h-schmidt.net/FloatConverter/IEEE754.html on other simple measurements.

That is also more consistent with the transmission format.

Cannot open the SeS

when im try to open the ses file it say crash . im using Seeger Embedded Studio for ARM v4.12

Sample battery voltage at interval

Current battery voltage sampling gets triggered on every radio transmission, which is unnecessarily often.
A logic to update the voltage only once per minute, with interval configurable in application_mode_default.h should be added.
Related to #86

/** @brief Resample battery voltage at this interval */
#ifndef APP_BATTERY_SAMPLE_MS
#   define APP_BATTERY__SAMPLEL_MS (60U*1000U)
#endif

Battery measurement works only on first sample(s)

Battery measurement is synchronized to radio, ADC is configured for sampling on before_radio_activity event and actual sample is taken on after_radio_activity event. The sampled data is stored in rt_adc and read later in app_heartbeat when sending data as BLE advertisement.

The ADC was uninitialized in 3.28 firmwares after sample to reduce power consumption. Now either uninitialization or reinitialization errors and the data won't be updated.

app_sensor.c:236 WARNING: INVALID_STATE
app_sensor.c:231 WARNING: BUSY
app_sensor.c:236 WARNING: INVALID_STATE
app_sensor.c:231 WARNING: BUSY

Relevant functions are in app_sensor, app_heartbeat and ruuvi_task_adc.

The sampling after radio transmission should be fixed. Ruuvi Station app can be used to check that ADC data is getting updated.

ruuvi_interface_lis2dh12.c:175 FATAL: SELFTEST

I've faced the problem with 2 of my RuuviTags - in connected state they were restarting with the

ruuvi_interface_lis2dh12.c:175 FATAL: SELFTEST

error. Re-programming didn't help. Next morning the issue was "fixed". Without any action from my side.

The tag advertised ok, but didn't heartbeat.

Initialization: Actions on failure: save status, BLE, log, LED and spin before boot

When the initialization determines that a fatal failure has occurred there is a series of actions that must be taken.

  1. The watchdog must be loaded with a very large value to prevent triggering.

  2. Status saving: Hardware never fixes itself. A battery nearing exhaustion may cause unexpected events to occur or other temporary external conditions may cause a failure. Once a subsystem fails initialization a permanent status must be saved. It must persist across resets and be easily locatable. Placing it in the UICR area satisfies these requirements. As other Configuration Information settings may be present, a good place is UICR[31], that is the last location. This status can be examined by the system which can avoid using the failing subsystem or by a user with a debugger like J-Link, Ozone or nRFproj. A future enhancement would be to include this in the NFC utility which manages the settings.

  3. BLE Message: The next action is to transmit, via BLE, a non-sensor data packet. This must include the version, configuration information and the status. This allows any data collection system to observe the failure, record it and take action on the failure. This is the only way that the problem can be observed without knowing in advance that a failure has occurred which the following listed actions require. A portion of the fault flag should contain a counter containing the number of messages sent. When a threshold is reached messages will no longer be sent. This prevents flooding the collection system. It would be beneficial if the system reduced this counter after returning to successful operation for several minutes.

  4. NFC message may be helpful in diagnosing the problem but will only be observed if a receiver is enabled and in range. This also requires an application that is capable of receiving and displaying the message.

  5. Log message will assist in diagnosing the problem but, as with NFC message, it is only helpful once it is known that there is a problem since there must be a log device attached (and of course logging must be enabled at compile time).

  6. The LED must be blinked in a manner that is easily recognizable as a failure in the initialization and not some other failure or the entry into the boot loader. A series of 13 blinks to indicate the unlucky event followed by a pause and then the flag. Again, this is only useful if it is known that there is a failure as it requires the cover to be removed and an observer present.

  7. A local CPU based interrupt disabled, delay spin, not dependent on the RTC must be executed. This must be very long, perhaps even minutes, to permit possible interaction with a connected debugger. Continuing too soon will only cause rapid, undesirable looping. As the tag has already been deemed to be in failure mode, resuming operation is not urgent.

  8. Finally a software initiated reset will invoke the boot loader and cause application initialization to set the static variables to zero!

Perhaps a condition that invoked initialization no longer exists and the system can resume operation.

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.