forked from platformio/platformio-core
Merge pull request #126 from valeros/develop
Add full support for MBED libraries: rtos, eth, dsp, fat, usb
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
21
examples/mbed/mbed-dsp/README.rst
Normal file
21
examples/mbed/mbed-dsp/README.rst
Normal file
@ -0,0 +1,21 @@
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
3. Extract ZIP archive
|
||||
4. Run these commands:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Change directory to example
|
||||
> cd platformio-develop/examples/mbed/mbed-dsp
|
||||
|
||||
# Process example project
|
||||
> platformio run
|
||||
|
||||
# Upload firmware
|
||||
> platformio run --target upload
|
||||
|
||||
# Clean build files
|
||||
> platformio run --target clean
|
43
examples/mbed/mbed-dsp/platformio.ini
Normal file
43
examples/mbed/mbed-dsp/platformio.ini
Normal file
@ -0,0 +1,43 @@
|
||||
#
|
||||
# Project Configuration File
|
||||
#
|
||||
# A detailed documentation with the EXAMPLES is located here:
|
||||
# http://docs.platformio.org/en/latest/projectconf.html
|
||||
#
|
||||
|
||||
# A sign `#` at the beginning of the line indicates a comment
|
||||
# Comment lines are ignored.
|
||||
|
||||
# Simple and base environment
|
||||
# [env:mybaseenv]
|
||||
# platform = %INSTALLED_PLATFORM_NAME_HERE%
|
||||
# framework =
|
||||
# board =
|
||||
#
|
||||
# Automatic targets - enable auto-uploading
|
||||
# targets = upload
|
||||
|
||||
|
||||
# NXP LPC Platform
|
||||
[env:lpc1768]
|
||||
platform = nxplpc
|
||||
framework = mbed
|
||||
board = lpc1768
|
||||
|
||||
# Nordic nRF51 Platform
|
||||
[env:nrf51_mkit]
|
||||
platform = nordicnrf51
|
||||
framework = mbed
|
||||
board = nrf51_mkit
|
||||
|
||||
# Freescale FRDM Platform
|
||||
[env:frdm_kl25z]
|
||||
platform = freescalekinetis
|
||||
framework = mbed
|
||||
board = frdm_kl25z
|
||||
|
||||
# ST STM32 Platform
|
||||
[env:nucleo_f401re]
|
||||
platform = ststm32
|
||||
framework = mbed
|
||||
board = nucleo_f401re
|
94
examples/mbed/mbed-dsp/src/data.cpp
Normal file
94
examples/mbed/mbed-dsp/src/data.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
#include "arm_math.h"
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
** Test input signal contains 1000Hz + 15000 Hz
|
||||
** ------------------------------------------------------------------- */
|
||||
|
||||
float32_t testInput_f32_1kHz_15kHz[320] =
|
||||
{
|
||||
+0.0000000000f, +0.5924659585f, -0.0947343455f, +0.1913417162f, +1.0000000000f, +0.4174197128f, +0.3535533906f, +1.2552931065f,
|
||||
+0.8660254038f, +0.4619397663f, +1.3194792169f, +1.1827865776f, +0.5000000000f, +1.1827865776f, +1.3194792169f, +0.4619397663f,
|
||||
+0.8660254038f, +1.2552931065f, +0.3535533906f, +0.4174197128f, +1.0000000000f, +0.1913417162f, -0.0947343455f, +0.5924659585f,
|
||||
-0.0000000000f, -0.5924659585f, +0.0947343455f, -0.1913417162f, -1.0000000000f, -0.4174197128f, -0.3535533906f, -1.2552931065f,
|
||||
-0.8660254038f, -0.4619397663f, -1.3194792169f, -1.1827865776f, -0.5000000000f, -1.1827865776f, -1.3194792169f, -0.4619397663f,
|
||||
-0.8660254038f, -1.2552931065f, -0.3535533906f, -0.4174197128f, -1.0000000000f, -0.1913417162f, +0.0947343455f, -0.5924659585f,
|
||||
+0.0000000000f, +0.5924659585f, -0.0947343455f, +0.1913417162f, +1.0000000000f, +0.4174197128f, +0.3535533906f, +1.2552931065f,
|
||||
+0.8660254038f, +0.4619397663f, +1.3194792169f, +1.1827865776f, +0.5000000000f, +1.1827865776f, +1.3194792169f, +0.4619397663f,
|
||||
+0.8660254038f, +1.2552931065f, +0.3535533906f, +0.4174197128f, +1.0000000000f, +0.1913417162f, -0.0947343455f, +0.5924659585f,
|
||||
+0.0000000000f, -0.5924659585f, +0.0947343455f, -0.1913417162f, -1.0000000000f, -0.4174197128f, -0.3535533906f, -1.2552931065f,
|
||||
-0.8660254038f, -0.4619397663f, -1.3194792169f, -1.1827865776f, -0.5000000000f, -1.1827865776f, -1.3194792169f, -0.4619397663f,
|
||||
-0.8660254038f, -1.2552931065f, -0.3535533906f, -0.4174197128f, -1.0000000000f, -0.1913417162f, +0.0947343455f, -0.5924659585f,
|
||||
+0.0000000000f, +0.5924659585f, -0.0947343455f, +0.1913417162f, +1.0000000000f, +0.4174197128f, +0.3535533906f, +1.2552931065f,
|
||||
+0.8660254038f, +0.4619397663f, +1.3194792169f, +1.1827865776f, +0.5000000000f, +1.1827865776f, +1.3194792169f, +0.4619397663f,
|
||||
+0.8660254038f, +1.2552931065f, +0.3535533906f, +0.4174197128f, +1.0000000000f, +0.1913417162f, -0.0947343455f, +0.5924659585f,
|
||||
+0.0000000000f, -0.5924659585f, +0.0947343455f, -0.1913417162f, -1.0000000000f, -0.4174197128f, -0.3535533906f, -1.2552931065f,
|
||||
-0.8660254038f, -0.4619397663f, -1.3194792169f, -1.1827865776f, -0.5000000000f, -1.1827865776f, -1.3194792169f, -0.4619397663f,
|
||||
-0.8660254038f, -1.2552931065f, -0.3535533906f, -0.4174197128f, -1.0000000000f, -0.1913417162f, +0.0947343455f, -0.5924659585f,
|
||||
-0.0000000000f, +0.5924659585f, -0.0947343455f, +0.1913417162f, +1.0000000000f, +0.4174197128f, +0.3535533906f, +1.2552931065f,
|
||||
+0.8660254038f, +0.4619397663f, +1.3194792169f, +1.1827865776f, +0.5000000000f, +1.1827865776f, +1.3194792169f, +0.4619397663f,
|
||||
+0.8660254038f, +1.2552931065f, +0.3535533906f, +0.4174197128f, +1.0000000000f, +0.1913417162f, -0.0947343455f, +0.5924659585f,
|
||||
-0.0000000000f, -0.5924659585f, +0.0947343455f, -0.1913417162f, -1.0000000000f, -0.4174197128f, -0.3535533906f, -1.2552931065f,
|
||||
-0.8660254038f, -0.4619397663f, -1.3194792169f, -1.1827865776f, -0.5000000000f, -1.1827865776f, -1.3194792169f, -0.4619397663f,
|
||||
-0.8660254038f, -1.2552931065f, -0.3535533906f, -0.4174197128f, -1.0000000000f, -0.1913417162f, +0.0947343455f, -0.5924659585f,
|
||||
+0.0000000000f, +0.5924659585f, -0.0947343455f, +0.1913417162f, +1.0000000000f, +0.4174197128f, +0.3535533906f, +1.2552931065f,
|
||||
+0.8660254038f, +0.4619397663f, +1.3194792169f, +1.1827865776f, +0.5000000000f, +1.1827865776f, +1.3194792169f, +0.4619397663f,
|
||||
+0.8660254038f, +1.2552931065f, +0.3535533906f, +0.4174197128f, +1.0000000000f, +0.1913417162f, -0.0947343455f, +0.5924659585f,
|
||||
+0.0000000000f, -0.5924659585f, +0.0947343455f, -0.1913417162f, -1.0000000000f, -0.4174197128f, -0.3535533906f, -1.2552931065f,
|
||||
-0.8660254038f, -0.4619397663f, -1.3194792169f, -1.1827865776f, -0.5000000000f, -1.1827865776f, -1.3194792169f, -0.4619397663f,
|
||||
-0.8660254038f, -1.2552931065f, -0.3535533906f, -0.4174197128f, -1.0000000000f, -0.1913417162f, +0.0947343455f, -0.5924659585f,
|
||||
-0.0000000000f, +0.5924659585f, -0.0947343455f, +0.1913417162f, +1.0000000000f, +0.4174197128f, +0.3535533906f, +1.2552931065f,
|
||||
+0.8660254038f, +0.4619397663f, +1.3194792169f, +1.1827865776f, +0.5000000000f, +1.1827865776f, +1.3194792169f, +0.4619397663f,
|
||||
+0.8660254038f, +1.2552931065f, +0.3535533906f, +0.4174197128f, +1.0000000000f, +0.1913417162f, -0.0947343455f, +0.5924659585f,
|
||||
+0.0000000000f, -0.5924659585f, +0.0947343455f, -0.1913417162f, -1.0000000000f, -0.4174197128f, -0.3535533906f, -1.2552931065f,
|
||||
-0.8660254038f, -0.4619397663f, -1.3194792169f, -1.1827865776f, -0.5000000000f, -1.1827865776f, -1.3194792169f, -0.4619397663f,
|
||||
-0.8660254038f, -1.2552931065f, -0.3535533906f, -0.4174197128f, -1.0000000000f, -0.1913417162f, +0.0947343455f, -0.5924659585f,
|
||||
-0.0000000000f, +0.5924659585f, -0.0947343455f, +0.1913417162f, +1.0000000000f, +0.4174197128f, +0.3535533906f, +1.2552931065f,
|
||||
+0.8660254038f, +0.4619397663f, +1.3194792169f, +1.1827865776f, +0.5000000000f, +1.1827865776f, +1.3194792169f, +0.4619397663f,
|
||||
+0.8660254038f, +1.2552931065f, +0.3535533906f, +0.4174197128f, +1.0000000000f, +0.1913417162f, -0.0947343455f, +0.5924659585f,
|
||||
+0.0000000000f, -0.5924659585f, +0.0947343455f, -0.1913417162f, -1.0000000000f, -0.4174197128f, -0.3535533906f, -1.2552931065f,
|
||||
};
|
||||
|
||||
float32_t refOutput[320] =
|
||||
{
|
||||
+0.0000000000f, -0.0010797829f, -0.0007681386f, -0.0001982932f, +0.0000644313f, +0.0020854271f, +0.0036891871f, +0.0015855941f,
|
||||
-0.0026280805f, -0.0075907658f, -0.0119390538f, -0.0086665968f, +0.0088981202f, +0.0430539279f, +0.0974468742f, +0.1740405600f,
|
||||
+0.2681416601f, +0.3747720089f, +0.4893362230f, +0.6024154672f, +0.7058740791f, +0.7968348987f, +0.8715901940f, +0.9277881093f,
|
||||
+0.9682182661f, +0.9934674267f, +1.0012052245f, +0.9925859371f, +0.9681538347f, +0.9257026822f, +0.8679010068f, +0.7952493046f,
|
||||
+0.7085021596f, +0.6100062330f, +0.5012752767f, +0.3834386057f, +0.2592435399f, +0.1309866321f, -0.0000000000f, -0.1309866321f,
|
||||
-0.2592435399f, -0.3834386057f, -0.5012752767f, -0.6100062330f, -0.7085021596f, -0.7952493046f, -0.8679010068f, -0.9257026822f,
|
||||
-0.9681538347f, -0.9936657199f, -1.0019733630f, -0.9936657199f, -0.9681538347f, -0.9257026822f, -0.8679010068f, -0.7952493046f,
|
||||
-0.7085021596f, -0.6100062330f, -0.5012752767f, -0.3834386057f, -0.2592435399f, -0.1309866321f, +0.0000000000f, +0.1309866321f,
|
||||
+0.2592435399f, +0.3834386057f, +0.5012752767f, +0.6100062330f, +0.7085021596f, +0.7952493046f, +0.8679010068f, +0.9257026822f,
|
||||
+0.9681538347f, +0.9936657199f, +1.0019733630f, +0.9936657199f, +0.9681538347f, +0.9257026822f, +0.8679010068f, +0.7952493046f,
|
||||
+0.7085021596f, +0.6100062330f, +0.5012752767f, +0.3834386057f, +0.2592435399f, +0.1309866321f, -0.0000000000f, -0.1309866321f,
|
||||
-0.2592435399f, -0.3834386057f, -0.5012752767f, -0.6100062330f, -0.7085021596f, -0.7952493046f, -0.8679010068f, -0.9257026822f,
|
||||
-0.9681538347f, -0.9936657199f, -1.0019733630f, -0.9936657199f, -0.9681538347f, -0.9257026822f, -0.8679010068f, -0.7952493046f,
|
||||
-0.7085021596f, -0.6100062330f, -0.5012752767f, -0.3834386057f, -0.2592435399f, -0.1309866321f, +0.0000000000f, +0.1309866321f,
|
||||
+0.2592435399f, +0.3834386057f, +0.5012752767f, +0.6100062330f, +0.7085021596f, +0.7952493046f, +0.8679010068f, +0.9257026822f,
|
||||
+0.9681538347f, +0.9936657199f, +1.0019733630f, +0.9936657199f, +0.9681538347f, +0.9257026822f, +0.8679010068f, +0.7952493046f,
|
||||
+0.7085021596f, +0.6100062330f, +0.5012752767f, +0.3834386057f, +0.2592435399f, +0.1309866321f, -0.0000000000f, -0.1309866321f,
|
||||
-0.2592435399f, -0.3834386057f, -0.5012752767f, -0.6100062330f, -0.7085021596f, -0.7952493046f, -0.8679010068f, -0.9257026822f,
|
||||
-0.9681538347f, -0.9936657199f, -1.0019733630f, -0.9936657199f, -0.9681538347f, -0.9257026822f, -0.8679010068f, -0.7952493046f,
|
||||
-0.7085021596f, -0.6100062330f, -0.5012752767f, -0.3834386057f, -0.2592435399f, -0.1309866321f, +0.0000000000f, +0.1309866321f,
|
||||
+0.2592435399f, +0.3834386057f, +0.5012752767f, +0.6100062330f, +0.7085021596f, +0.7952493046f, +0.8679010068f, +0.9257026822f,
|
||||
+0.9681538347f, +0.9936657199f, +1.0019733630f, +0.9936657199f, +0.9681538347f, +0.9257026822f, +0.8679010068f, +0.7952493046f,
|
||||
+0.7085021596f, +0.6100062330f, +0.5012752767f, +0.3834386057f, +0.2592435399f, +0.1309866321f, +0.0000000000f, -0.1309866321f,
|
||||
-0.2592435399f, -0.3834386057f, -0.5012752767f, -0.6100062330f, -0.7085021596f, -0.7952493046f, -0.8679010068f, -0.9257026822f,
|
||||
-0.9681538347f, -0.9936657199f, -1.0019733630f, -0.9936657199f, -0.9681538347f, -0.9257026822f, -0.8679010068f, -0.7952493046f,
|
||||
-0.7085021596f, -0.6100062330f, -0.5012752767f, -0.3834386057f, -0.2592435399f, -0.1309866321f, +0.0000000000f, +0.1309866321f,
|
||||
+0.2592435399f, +0.3834386057f, +0.5012752767f, +0.6100062330f, +0.7085021596f, +0.7952493046f, +0.8679010068f, +0.9257026822f,
|
||||
+0.9681538347f, +0.9936657199f, +1.0019733630f, +0.9936657199f, +0.9681538347f, +0.9257026822f, +0.8679010068f, +0.7952493046f,
|
||||
+0.7085021596f, +0.6100062330f, +0.5012752767f, +0.3834386057f, +0.2592435399f, +0.1309866321f, +0.0000000000f, -0.1309866321f,
|
||||
-0.2592435399f, -0.3834386057f, -0.5012752767f, -0.6100062330f, -0.7085021596f, -0.7952493046f, -0.8679010068f, -0.9257026822f,
|
||||
-0.9681538347f, -0.9936657199f, -1.0019733630f, -0.9936657199f, -0.9681538347f, -0.9257026822f, -0.8679010068f, -0.7952493046f,
|
||||
-0.7085021596f, -0.6100062330f, -0.5012752767f, -0.3834386057f, -0.2592435399f, -0.1309866321f, -0.0000000000f, +0.1309866321f,
|
||||
+0.2592435399f, +0.3834386057f, +0.5012752767f, +0.6100062330f, +0.7085021596f, +0.7952493046f, +0.8679010068f, +0.9257026822f,
|
||||
+0.9681538347f, +0.9936657199f, +1.0019733630f, +0.9936657199f, +0.9681538347f, +0.9257026822f, +0.8679010068f, +0.7952493046f,
|
||||
+0.7085021596f, +0.6100062330f, +0.5012752767f, +0.3834386057f, +0.2592435399f, +0.1309866321f, +0.0000000000f, -0.1309866321f,
|
||||
-0.2592435399f, -0.3834386057f, -0.5012752767f, -0.6100062330f, -0.7085021596f, -0.7952493046f, -0.8679010068f, -0.9257026822f,
|
||||
-0.9681538347f, -0.9936657199f, -1.0019733630f, -0.9936657199f, -0.9681538347f, -0.9257026822f, -0.8679010068f, -0.7952493046f,
|
||||
-0.7085021596f, -0.6100062330f, -0.5012752767f, -0.3834386057f, -0.2592435399f, -0.1309866321f, +0.0000000000f, +0.1309866321f,
|
||||
+0.2592435399f, +0.3834386057f, +0.5012752767f, +0.6100062330f, +0.7085021596f, +0.7952493046f, +0.8679010068f, +0.9257026822f,
|
||||
+0.9681538347f, +0.9936657199f, +1.0019733630f, +0.9936657199f, +0.9681538347f, +0.9257026822f, +0.8679010068f, +0.7952493046f
|
||||
};
|
||||
|
65
examples/mbed/mbed-dsp/src/main.cpp
Normal file
65
examples/mbed/mbed-dsp/src/main.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
#include "arm_math.h"
|
||||
#include "math_helper.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define BLOCK_SIZE 32
|
||||
#define NUM_BLOCKS 10
|
||||
|
||||
#define TEST_LENGTH_SAMPLES (BLOCK_SIZE * NUM_BLOCKS)
|
||||
|
||||
#define SNR_THRESHOLD_F32 140.0f
|
||||
#define NUM_TAPS 29
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* The input signal and reference output (computed with MATLAB)
|
||||
* are defined externally in arm_fir_lpf_data.c.
|
||||
* ------------------------------------------------------------------- */
|
||||
extern float32_t testInput_f32_1kHz_15kHz[TEST_LENGTH_SAMPLES];
|
||||
extern float32_t refOutput[TEST_LENGTH_SAMPLES];
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* Declare State buffer of size (numTaps + blockSize - 1)
|
||||
* ------------------------------------------------------------------- */
|
||||
static float32_t firStateF32[BLOCK_SIZE + NUM_TAPS - 1];
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* FIR Coefficients buffer generated using fir1() MATLAB function.
|
||||
* fir1(28, 6/24)
|
||||
* ------------------------------------------------------------------- */
|
||||
const float32_t firCoeffs32[NUM_TAPS] = {
|
||||
-0.0018225230f, -0.0015879294f, +0.0000000000f, +0.0036977508f, +0.0080754303f,
|
||||
+0.0085302217f, -0.0000000000f, -0.0173976984f, -0.0341458607f, -0.0333591565f,
|
||||
+0.0000000000f, +0.0676308395f, +0.1522061835f, +0.2229246956f, +0.2504960933f,
|
||||
+0.2229246956f, +0.1522061835f, +0.0676308395f, +0.0000000000f, -0.0333591565f,
|
||||
-0.0341458607f, -0.0173976984f, -0.0000000000f, +0.0085302217f, +0.0080754303f,
|
||||
+0.0036977508f, +0.0000000000f, -0.0015879294f, -0.0018225230f
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* FIR LPF Example
|
||||
* ------------------------------------------------------------------- */
|
||||
int main(void) {
|
||||
/* Call FIR init function to initialize the instance structure. */
|
||||
arm_fir_instance_f32 S;
|
||||
arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&firCoeffs32[0], &firStateF32[0], BLOCK_SIZE);
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Call the FIR process function for every blockSize samples
|
||||
* ------------------------------------------------------------------- */
|
||||
for (uint32_t i=0; i < NUM_BLOCKS; i++) {
|
||||
float32_t* signal = testInput_f32_1kHz_15kHz + (i * BLOCK_SIZE);
|
||||
arm_fir_f32(&S, signal, signal, BLOCK_SIZE);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Compare the generated output against the reference output computed
|
||||
* in MATLAB.
|
||||
* ------------------------------------------------------------------- */
|
||||
float32_t snr = arm_snr_f32(refOutput, testInput_f32_1kHz_15kHz, TEST_LENGTH_SAMPLES);
|
||||
printf("snr: %f\n\r", snr);
|
||||
if (snr < SNR_THRESHOLD_F32) {
|
||||
printf("Failed\n\r");
|
||||
} else {
|
||||
printf("Success\n\r");
|
||||
}
|
||||
}
|
21
examples/mbed/mbed-http-client/README.rst
Normal file
21
examples/mbed/mbed-http-client/README.rst
Normal file
@ -0,0 +1,21 @@
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
3. Extract ZIP archive
|
||||
4. Run these commands:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Change directory to example
|
||||
> cd platformio-develop/examples/mbed/mbed-http-client
|
||||
|
||||
# Process example project
|
||||
> platformio run
|
||||
|
||||
# Upload firmware
|
||||
> platformio run --target upload
|
||||
|
||||
# Clean build files
|
||||
> platformio run --target clean
|
739
examples/mbed/mbed-http-client/lib/HTTPClient/HTTPClient.cpp
Normal file
739
examples/mbed/mbed-http-client/lib/HTTPClient/HTTPClient.cpp
Normal file
@ -0,0 +1,739 @@
|
||||
/* HTTPClient.cpp */
|
||||
/* Copyright (C) 2012 mbed.org, MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
* and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
//Debug is disabled by default
|
||||
#if 0
|
||||
//Enable debug
|
||||
#include <cstdio>
|
||||
#define DBG(x, ...) std::printf("[HTTPClient : DBG]"x"\r\n", ##__VA_ARGS__);
|
||||
#define WARN(x, ...) std::printf("[HTTPClient : WARN]"x"\r\n", ##__VA_ARGS__);
|
||||
#define ERR(x, ...) std::printf("[HTTPClient : ERR]"x"\r\n", ##__VA_ARGS__);
|
||||
|
||||
#else
|
||||
//Disable debug
|
||||
#define DBG(x, ...)
|
||||
#define WARN(x, ...)
|
||||
#define ERR(x, ...)
|
||||
|
||||
#endif
|
||||
|
||||
#define HTTP_PORT 80
|
||||
|
||||
#define OK 0
|
||||
|
||||
#define MIN(x,y) (((x)<(y))?(x):(y))
|
||||
#define MAX(x,y) (((x)>(y))?(x):(y))
|
||||
|
||||
#define CHUNK_SIZE 256
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "HTTPClient.h"
|
||||
|
||||
HTTPClient::HTTPClient() :
|
||||
m_sock(), m_basicAuthUser(NULL), m_basicAuthPassword(NULL), m_httpResponseCode(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HTTPClient::~HTTPClient()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
void HTTPClient::basicAuth(const char* user, const char* password) //Basic Authentification
|
||||
{
|
||||
m_basicAuthUser = user;
|
||||
m_basicAuthPassword = password;
|
||||
}
|
||||
#endif
|
||||
|
||||
HTTPResult HTTPClient::get(const char* url, IHTTPDataIn* pDataIn, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
|
||||
{
|
||||
return connect(url, HTTP_GET, NULL, pDataIn, timeout);
|
||||
}
|
||||
|
||||
HTTPResult HTTPClient::get(const char* url, char* result, size_t maxResultLen, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
|
||||
{
|
||||
HTTPText str(result, maxResultLen);
|
||||
return get(url, &str, timeout);
|
||||
}
|
||||
|
||||
HTTPResult HTTPClient::post(const char* url, const IHTTPDataOut& dataOut, IHTTPDataIn* pDataIn, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
|
||||
{
|
||||
return connect(url, HTTP_POST, (IHTTPDataOut*)&dataOut, pDataIn, timeout);
|
||||
}
|
||||
|
||||
HTTPResult HTTPClient::put(const char* url, const IHTTPDataOut& dataOut, IHTTPDataIn* pDataIn, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
|
||||
{
|
||||
return connect(url, HTTP_PUT, (IHTTPDataOut*)&dataOut, pDataIn, timeout);
|
||||
}
|
||||
|
||||
HTTPResult HTTPClient::del(const char* url, IHTTPDataIn* pDataIn, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
|
||||
{
|
||||
return connect(url, HTTP_DELETE, NULL, pDataIn, timeout);
|
||||
}
|
||||
|
||||
|
||||
int HTTPClient::getHTTPResponseCode()
|
||||
{
|
||||
return m_httpResponseCode;
|
||||
}
|
||||
|
||||
#define CHECK_CONN_ERR(ret) \
|
||||
do{ \
|
||||
if(ret) { \
|
||||
m_sock.close(); \
|
||||
ERR("Connection error (%d)", ret); \
|
||||
return HTTP_CONN; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define PRTCL_ERR() \
|
||||
do{ \
|
||||
m_sock.close(); \
|
||||
ERR("Protocol error"); \
|
||||
return HTTP_PRTCL; \
|
||||
} while(0)
|
||||
|
||||
HTTPResult HTTPClient::connect(const char* url, HTTP_METH method, IHTTPDataOut* pDataOut, IHTTPDataIn* pDataIn, int timeout) //Execute request
|
||||
{
|
||||
m_httpResponseCode = 0; //Invalidate code
|
||||
m_timeout = timeout;
|
||||
|
||||
pDataIn->writeReset();
|
||||
if( pDataOut )
|
||||
{
|
||||
pDataOut->readReset();
|
||||
}
|
||||
|
||||
char scheme[8];
|
||||
uint16_t port;
|
||||
char host[32];
|
||||
char path[64];
|
||||
//First we need to parse the url (http[s]://host[:port][/[path]]) -- HTTPS not supported (yet?)
|
||||
HTTPResult res = parseURL(url, scheme, sizeof(scheme), host, sizeof(host), &port, path, sizeof(path));
|
||||
if(res != HTTP_OK)
|
||||
{
|
||||
ERR("parseURL returned %d", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if(port == 0) //TODO do handle HTTPS->443
|
||||
{
|
||||
port = 80;
|
||||
}
|
||||
|
||||
DBG("Scheme: %s", scheme);
|
||||
DBG("Host: %s", host);
|
||||
DBG("Port: %d", port);
|
||||
DBG("Path: %s", path);
|
||||
|
||||
//Connect
|
||||
DBG("Connecting socket to server");
|
||||
int ret = m_sock.connect(host, port);
|
||||
if (ret < 0)
|
||||
{
|
||||
m_sock.close();
|
||||
ERR("Could not connect");
|
||||
return HTTP_CONN;
|
||||
}
|
||||
|
||||
//Send request
|
||||
DBG("Sending request");
|
||||
char buf[CHUNK_SIZE];
|
||||
const char* meth = (method==HTTP_GET)?"GET":(method==HTTP_POST)?"POST":(method==HTTP_PUT)?"PUT":(method==HTTP_DELETE)?"DELETE":"";
|
||||
snprintf(buf, sizeof(buf), "%s %s HTTP/1.1\r\nHost: %s\r\n", meth, path, host); //Write request
|
||||
ret = send(buf);
|
||||
if(ret)
|
||||
{
|
||||
m_sock.close();
|
||||
ERR("Could not write request");
|
||||
return HTTP_CONN;
|
||||
}
|
||||
|
||||
//Send all headers
|
||||
|
||||
//Send default headers
|
||||
DBG("Sending headers");
|
||||
if( pDataOut != NULL )
|
||||
{
|
||||
if( pDataOut->getIsChunked() )
|
||||
{
|
||||
ret = send("Transfer-Encoding: chunked\r\n");
|
||||
CHECK_CONN_ERR(ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "Content-Length: %d\r\n", pDataOut->getDataLen());
|
||||
ret = send(buf);
|
||||
CHECK_CONN_ERR(ret);
|
||||
}
|
||||
char type[48];
|
||||
if( pDataOut->getDataType(type, 48) == HTTP_OK )
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "Content-Type: %s\r\n", type);
|
||||
ret = send(buf);
|
||||
CHECK_CONN_ERR(ret);
|
||||
}
|
||||
|
||||
//Send specific headers
|
||||
while( pDataOut->getHeader(buf, sizeof(buf) - 3) ) //must have space left for CRLF + 0 terminating char
|
||||
{
|
||||
size_t headerlen = strlen(buf);
|
||||
snprintf(buf + headerlen, sizeof(buf) - headerlen, "\r\n");
|
||||
ret = send(buf);
|
||||
CHECK_CONN_ERR(ret);
|
||||
}
|
||||
}
|
||||
|
||||
//Send specific headers
|
||||
while( pDataIn->getHeader(buf, sizeof(buf) - 3) )
|
||||
{
|
||||
size_t headerlen = strlen(buf);
|
||||
snprintf(buf + headerlen, sizeof(buf) - headerlen, "\r\n");
|
||||
ret = send(buf);
|
||||
CHECK_CONN_ERR(ret);
|
||||
}
|
||||
|
||||
//Close headers
|
||||
DBG("Headers sent");
|
||||
ret = send("\r\n");
|
||||
CHECK_CONN_ERR(ret);
|
||||
|
||||
size_t trfLen;
|
||||
|
||||
//Send data (if available)
|
||||
if( pDataOut != NULL )
|
||||
{
|
||||
DBG("Sending data");
|
||||
while(true)
|
||||
{
|
||||
size_t writtenLen = 0;
|
||||
pDataOut->read(buf, CHUNK_SIZE, &trfLen);
|
||||
if( pDataOut->getIsChunked() )
|
||||
{
|
||||
//Write chunk header
|
||||
char chunkHeader[16];
|
||||
snprintf(chunkHeader, sizeof(chunkHeader), "%X\r\n", trfLen); //In hex encoding
|
||||
ret = send(chunkHeader);
|
||||
CHECK_CONN_ERR(ret);
|
||||
}
|
||||
else if( trfLen == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
if( trfLen != 0 )
|
||||
{
|
||||
ret = send(buf, trfLen);
|
||||
CHECK_CONN_ERR(ret);
|
||||
}
|
||||
|
||||
if( pDataOut->getIsChunked() )
|
||||
{
|
||||
ret = send("\r\n"); //Chunk-terminating CRLF
|
||||
CHECK_CONN_ERR(ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
writtenLen += trfLen;
|
||||
if( writtenLen >= pDataOut->getDataLen() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( trfLen == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Receive response
|
||||
DBG("Receiving response");
|
||||
ret = recv(buf, 1, CHUNK_SIZE - 1, &trfLen); //Read n bytes
|
||||
CHECK_CONN_ERR(ret);
|
||||
|
||||
buf[trfLen] = '\0';
|
||||
|
||||
//Make sure we got the first response line
|
||||
char* crlfPtr = NULL;
|
||||
while( true )
|
||||
{
|
||||
crlfPtr = strstr(buf, "\r\n");
|
||||
if(crlfPtr == NULL)
|
||||
{
|
||||
if( trfLen < CHUNK_SIZE - 1 )
|
||||
{
|
||||
size_t newTrfLen;
|
||||
ret = recv(buf + trfLen, 1, CHUNK_SIZE - trfLen - 1, &newTrfLen);
|
||||
trfLen += newTrfLen;
|
||||
buf[trfLen] = '\0';
|
||||
DBG("Read %d chars; In buf: [%s]", newTrfLen, buf);
|
||||
CHECK_CONN_ERR(ret);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
PRTCL_ERR();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
int crlfPos = crlfPtr - buf;
|
||||
buf[crlfPos] = '\0';
|
||||
|
||||
//Parse HTTP response
|
||||
//if( sscanf(buf, "HTTP/%*d.%*d %d %*[^\r\n]", &m_httpResponseCode) != 1 )
|
||||
if(crlfPos > 13)
|
||||
{
|
||||
buf[13] = '\0';
|
||||
}
|
||||
if( sscanf(buf, "HTTP/%*d.%*d %d", &m_httpResponseCode) != 1 ) //Kludge for newlib nano
|
||||
{
|
||||
//Cannot match string, error
|
||||
ERR("Not a correct HTTP answer : %s\n", buf);
|
||||
PRTCL_ERR();
|
||||
}
|
||||
|
||||
if( (m_httpResponseCode < 200) || (m_httpResponseCode >= 300) )
|
||||
{
|
||||
//Did not return a 2xx code; TODO fetch headers/(&data?) anyway and implement a mean of writing/reading headers
|
||||
WARN("Response code %d", m_httpResponseCode);
|
||||
PRTCL_ERR();
|
||||
}
|
||||
|
||||
DBG("Reading headers");
|
||||
|
||||
memmove(buf, &buf[crlfPos+2], trfLen - (crlfPos + 2) + 1); //Be sure to move NULL-terminating char as well
|
||||
trfLen -= (crlfPos + 2);
|
||||
|
||||
size_t recvContentLength = 0;
|
||||
bool recvChunked = false;
|
||||
bool recvLengthUnknown = true;
|
||||
//Now get headers
|
||||
while( true )
|
||||
{
|
||||
crlfPtr = strstr(buf, "\r\n");
|
||||
if(crlfPtr == NULL)
|
||||
{
|
||||
if( trfLen < CHUNK_SIZE - 1 )
|
||||
{
|
||||
size_t newTrfLen;
|
||||
ret = recv(buf + trfLen, 1, CHUNK_SIZE - trfLen - 1, &newTrfLen);
|
||||
trfLen += newTrfLen;
|
||||
buf[trfLen] = '\0';
|
||||
DBG("Read %d chars; In buf: [%s]", newTrfLen, buf);
|
||||
CHECK_CONN_ERR(ret);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
PRTCL_ERR();
|
||||
}
|
||||
}
|
||||
|
||||
crlfPos = crlfPtr - buf;
|
||||
|
||||
if(crlfPos == 0) //End of headers
|
||||
{
|
||||
DBG("Headers read");
|
||||
memmove(buf, &buf[2], trfLen - 2 + 1); //Be sure to move NULL-terminating char as well
|
||||
trfLen -= 2;
|
||||
break;
|
||||
}
|
||||
|
||||
buf[crlfPos] = '\0';
|
||||
|
||||
char key[32];
|
||||
char value[32];
|
||||
|
||||
//key[31] = '\0';
|
||||
//value[31] = '\0';
|
||||
|
||||
memset(key, 0, 32);
|
||||
memset(value, 0, 32);
|
||||
|
||||
//int n = sscanf(buf, "%31[^:]: %31[^\r\n]", key, value);
|
||||
|
||||
int n = 0;
|
||||
|
||||
char* keyEnd = strchr(buf, ':');
|
||||
if(keyEnd != NULL)
|
||||
{
|
||||
*keyEnd = '\0';
|
||||
if(strlen(buf) < 32)
|
||||
{
|
||||
strcpy(key, buf);
|
||||
n++;
|
||||
char* valueStart = keyEnd + 2;
|
||||
if( (valueStart - buf) < crlfPos )
|
||||
{
|
||||
if(strlen(valueStart) < 32)
|
||||
{
|
||||
strcpy(value, valueStart);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( n == 2 )
|
||||
{
|
||||
DBG("Read header : %s: %s\n", key, value);
|
||||
if( !strcmp(key, "Content-Length") )
|
||||
{
|
||||
sscanf(value, "%d", &recvContentLength);
|
||||
recvLengthUnknown = false;
|
||||
pDataIn->setDataLen(recvContentLength);
|
||||
}
|
||||
else if( !strcmp(key, "Transfer-Encoding") )
|
||||
{
|
||||
if( !strcmp(value, "Chunked") || !strcmp(value, "chunked") )
|
||||
{
|
||||
recvChunked = true;
|
||||
recvLengthUnknown = false;
|
||||
pDataIn->setIsChunked(true);
|
||||
}
|
||||
}
|
||||
else if( !strcmp(key, "Content-Type") )
|
||||
{
|
||||
pDataIn->setDataType(value);
|
||||
}
|
||||
|
||||
memmove(buf, &buf[crlfPos+2], trfLen - (crlfPos + 2) + 1); //Be sure to move NULL-terminating char as well
|
||||
trfLen -= (crlfPos + 2);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Could not parse header");
|
||||
PRTCL_ERR();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Receive data
|
||||
DBG("Receiving data");
|
||||
while(true)
|
||||
{
|
||||
size_t readLen = 0;
|
||||
|
||||
if( recvChunked )
|
||||
{
|
||||
//Read chunk header
|
||||
bool foundCrlf;
|
||||
do
|
||||
{
|
||||
foundCrlf = false;
|
||||
crlfPos=0;
|
||||
buf[trfLen]=0;
|
||||
if(trfLen >= 2)
|
||||
{
|
||||
for(; crlfPos < trfLen - 2; crlfPos++)
|
||||
{
|
||||
if( buf[crlfPos] == '\r' && buf[crlfPos + 1] == '\n' )
|
||||
{
|
||||
foundCrlf = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!foundCrlf) //Try to read more
|
||||
{
|
||||
if( trfLen < CHUNK_SIZE )
|
||||
{
|
||||
size_t newTrfLen;
|
||||
ret = recv(buf + trfLen, 0, CHUNK_SIZE - trfLen - 1, &newTrfLen);
|
||||
trfLen += newTrfLen;
|
||||
CHECK_CONN_ERR(ret);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
PRTCL_ERR();
|
||||
}
|
||||
}
|
||||
} while(!foundCrlf);
|
||||
buf[crlfPos] = '\0';
|
||||
int n = sscanf(buf, "%x", &readLen);
|
||||
if(n!=1)
|
||||
{
|
||||
ERR("Could not read chunk length");
|
||||
PRTCL_ERR();
|
||||
}
|
||||
|
||||
memmove(buf, &buf[crlfPos+2], trfLen - (crlfPos + 2)); //Not need to move NULL-terminating char any more
|
||||
trfLen -= (crlfPos + 2);
|
||||
|
||||
if( readLen == 0 )
|
||||
{
|
||||
//Last chunk
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
readLen = recvContentLength;
|
||||
}
|
||||
|
||||
DBG("Retrieving %d bytes (%d bytes in buffer)", readLen, trfLen);
|
||||
|
||||
do
|
||||
{
|
||||
if(recvLengthUnknown )
|
||||
{
|
||||
readLen = trfLen;
|
||||
}
|
||||
pDataIn->write(buf, MIN(trfLen, readLen));
|
||||
if(!recvLengthUnknown)
|
||||
{
|
||||
if( trfLen > readLen )
|
||||
{
|
||||
memmove(buf, &buf[readLen], trfLen - readLen);
|
||||
trfLen -= readLen;
|
||||
readLen = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
readLen -= trfLen;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
trfLen = 0;
|
||||
}
|
||||
|
||||
if(readLen || recvLengthUnknown)
|
||||
{
|
||||
ret = recv(buf, 1, CHUNK_SIZE - trfLen - 1, &trfLen);
|
||||
if(recvLengthUnknown && (ret == HTTP_CLOSED))
|
||||
{
|
||||
//Write and exit
|
||||
pDataIn->write(buf, trfLen);
|
||||
break;
|
||||
}
|
||||
CHECK_CONN_ERR(ret);
|
||||
if(recvLengthUnknown && (trfLen == 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(readLen || recvLengthUnknown);
|
||||
|
||||
if( recvChunked )
|
||||
{
|
||||
if(trfLen < 2)
|
||||
{
|
||||
size_t newTrfLen;
|
||||
//Read missing chars to find end of chunk
|
||||
ret = recv(buf + trfLen, 2 - trfLen, CHUNK_SIZE - trfLen - 1, &newTrfLen);
|
||||
CHECK_CONN_ERR(ret);
|
||||
trfLen += newTrfLen;
|
||||
}
|
||||
if( (buf[0] != '\r') || (buf[1] != '\n') )
|
||||
{
|
||||
ERR("Format error");
|
||||
PRTCL_ERR();
|
||||
}
|
||||
memmove(buf, &buf[2], trfLen - 2);
|
||||
trfLen -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_sock.close();
|
||||
DBG("Completed HTTP transaction");
|
||||
|
||||
return HTTP_OK;
|
||||
}
|
||||
|
||||
HTTPResult HTTPClient::recv(char* buf, size_t minLen, size_t maxLen, size_t* pReadLen) //0 on success, err code on failure
|
||||
{
|
||||
DBG("Trying to read between %d and %d bytes", minLen, maxLen);
|
||||
size_t readLen = 0;
|
||||
|
||||
if(!m_sock.is_connected())
|
||||
{
|
||||
WARN("Connection was closed by server");
|
||||
return HTTP_CLOSED; //Connection was closed by server
|
||||
}
|
||||
|
||||
int ret;
|
||||
while(readLen < maxLen)
|
||||
{
|
||||
if(readLen < minLen)
|
||||
{
|
||||
DBG("Trying to read at most %d bytes [Blocking]", minLen - readLen);
|
||||
m_sock.set_blocking(false, m_timeout);
|
||||
ret = m_sock.receive_all(buf + readLen, minLen - readLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG("Trying to read at most %d bytes [Not blocking]", maxLen - readLen);
|
||||
m_sock.set_blocking(false, 0);
|
||||
ret = m_sock.receive(buf + readLen, maxLen - readLen);
|
||||
}
|
||||
|
||||
if( ret > 0)
|
||||
{
|
||||
readLen += ret;
|
||||
}
|
||||
else if( ret == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!m_sock.is_connected())
|
||||
{
|
||||
ERR("Connection error (recv returned %d)", ret);
|
||||
*pReadLen = readLen;
|
||||
return HTTP_CONN;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!m_sock.is_connected())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
DBG("Read %d bytes", readLen);
|
||||
*pReadLen = readLen;
|
||||
return HTTP_OK;
|
||||
}
|
||||
|
||||
HTTPResult HTTPClient::send(char* buf, size_t len) //0 on success, err code on failure
|
||||
{
|
||||
if(len == 0)
|
||||
{
|
||||
len = strlen(buf);
|
||||
}
|
||||
DBG("Trying to write %d bytes", len);
|
||||
size_t writtenLen = 0;
|
||||
|
||||
if(!m_sock.is_connected())
|
||||
{
|
||||
WARN("Connection was closed by server");
|
||||
return HTTP_CLOSED; //Connection was closed by server
|
||||
}
|
||||
|
||||
m_sock.set_blocking(false, m_timeout);
|
||||
int ret = m_sock.send_all(buf, len);
|
||||
if(ret > 0)
|
||||
{
|
||||
writtenLen += ret;
|
||||
}
|
||||
else if( ret == 0 )
|
||||
{
|
||||
WARN("Connection was closed by server");
|
||||
return HTTP_CLOSED; //Connection was closed by server
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Connection error (send returned %d)", ret);
|
||||
return HTTP_CONN;
|
||||
}
|
||||
|
||||
DBG("Written %d bytes", writtenLen);
|
||||
return HTTP_OK;
|
||||
}
|
||||
|
||||
HTTPResult HTTPClient::parseURL(const char* url, char* scheme, size_t maxSchemeLen, char* host, size_t maxHostLen, uint16_t* port, char* path, size_t maxPathLen) //Parse URL
|
||||
{
|
||||
char* schemePtr = (char*) url;
|
||||
char* hostPtr = (char*) strstr(url, "://");
|
||||
if(hostPtr == NULL)
|
||||
{
|
||||
WARN("Could not find host");
|
||||
return HTTP_PARSE; //URL is invalid
|
||||
}
|
||||
|
||||
if( maxSchemeLen < hostPtr - schemePtr + 1 ) //including NULL-terminating char
|
||||
{
|
||||
WARN("Scheme str is too small (%d >= %d)", maxSchemeLen, hostPtr - schemePtr + 1);
|
||||
return HTTP_PARSE;
|
||||
}
|
||||
memcpy(scheme, schemePtr, hostPtr - schemePtr);
|
||||
scheme[hostPtr - schemePtr] = '\0';
|
||||
|
||||
hostPtr+=3;
|
||||
|
||||
size_t hostLen = 0;
|
||||
|
||||
char* portPtr = strchr(hostPtr, ':');
|
||||
if( portPtr != NULL )
|
||||
{
|
||||
hostLen = portPtr - hostPtr;
|
||||
portPtr++;
|
||||
if( sscanf(portPtr, "%hu", port) != 1)
|
||||
{
|
||||
WARN("Could not find port");
|
||||
return HTTP_PARSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*port=0;
|
||||
}
|
||||
char* pathPtr = strchr(hostPtr, '/');
|
||||
if( hostLen == 0 )
|
||||
{
|
||||
hostLen = pathPtr - hostPtr;
|
||||
}
|
||||
|
||||
if( maxHostLen < hostLen + 1 ) //including NULL-terminating char
|
||||
{
|
||||
WARN("Host str is too small (%d >= %d)", maxHostLen, hostLen + 1);
|
||||
return HTTP_PARSE;
|
||||
}
|
||||
memcpy(host, hostPtr, hostLen);
|
||||
host[hostLen] = '\0';
|
||||
|
||||
size_t pathLen;
|
||||
char* fragmentPtr = strchr(hostPtr, '#');
|
||||
if(fragmentPtr != NULL)
|
||||
{
|
||||
pathLen = fragmentPtr - pathPtr;
|
||||
}
|
||||
else
|
||||
{
|
||||
pathLen = strlen(pathPtr);
|
||||
}
|
||||
|
||||
if( maxPathLen < pathLen + 1 ) //including NULL-terminating char
|
||||
{
|
||||
WARN("Path str is too small (%d >= %d)", maxPathLen, pathLen + 1);
|
||||
return HTTP_PARSE;
|
||||
}
|
||||
memcpy(path, pathPtr, pathLen);
|
||||
path[pathLen] = '\0';
|
||||
|
||||
return HTTP_OK;
|
||||
}
|
159
examples/mbed/mbed-http-client/lib/HTTPClient/HTTPClient.h
Normal file
159
examples/mbed/mbed-http-client/lib/HTTPClient/HTTPClient.h
Normal file
@ -0,0 +1,159 @@
|
||||
/* HTTPClient.h */
|
||||
/* Copyright (C) 2012 mbed.org, MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
* and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
HTTP Client header file
|
||||
*/
|
||||
|
||||
#ifndef HTTP_CLIENT_H
|
||||
#define HTTP_CLIENT_H
|
||||
|
||||
#include "TCPSocketConnection.h"
|
||||
|
||||
#define HTTP_CLIENT_DEFAULT_TIMEOUT 15000
|
||||
|
||||
class HTTPData;
|
||||
|
||||
#include "IHTTPData.h"
|
||||
#include "mbed.h"
|
||||
|
||||
///HTTP client results
|
||||
enum HTTPResult
|
||||
{
|
||||
HTTP_PROCESSING, ///<Processing
|
||||
HTTP_PARSE, ///<url Parse error
|
||||
HTTP_DNS, ///<Could not resolve name
|
||||
HTTP_PRTCL, ///<Protocol error
|
||||
HTTP_NOTFOUND, ///<HTTP 404 Error
|
||||
HTTP_REFUSED, ///<HTTP 403 Error
|
||||
HTTP_ERROR, ///<HTTP xxx error
|
||||
HTTP_TIMEOUT, ///<Connection timeout
|
||||
HTTP_CONN, ///<Connection error
|
||||
HTTP_CLOSED, ///<Connection was closed by remote host
|
||||
HTTP_OK = 0, ///<Success
|
||||
};
|
||||
|
||||
/**A simple HTTP Client
|
||||
The HTTPClient is composed of:
|
||||
- The actual client (HTTPClient)
|
||||
- Classes that act as a data repository, each of which deriving from the HTTPData class (HTTPText for short text content, HTTPFile for file I/O, HTTPMap for key/value pairs, and HTTPStream for streaming purposes)
|
||||
*/
|
||||
class HTTPClient
|
||||
{
|
||||
public:
|
||||
///Instantiate the HTTP client
|
||||
HTTPClient();
|
||||
~HTTPClient();
|
||||
|
||||
#if 0 //TODO add header handlers
|
||||
/**
|
||||
Provides a basic authentification feature (Base64 encoded username and password)
|
||||
Pass two NULL pointers to switch back to no authentication
|
||||
@param user username to use for authentication, must remain valid durlng the whole HTTP session
|
||||
@param user password to use for authentication, must remain valid durlng the whole HTTP session
|
||||
*/
|
||||
void basicAuth(const char* user, const char* password); //Basic Authentification
|
||||
#endif
|
||||
|
||||
//High Level setup functions
|
||||
/** Execute a GET request on the URL
|
||||
Blocks until completion
|
||||
@param url : url on which to execute the request
|
||||
@param pDataIn : pointer to an IHTTPDataIn instance that will collect the data returned by the request, can be NULL
|
||||
@param timeout waiting timeout in ms (osWaitForever for blocking function, not recommended)
|
||||
@return 0 on success, HTTP error (<0) on failure
|
||||
*/
|
||||
HTTPResult get(const char* url, IHTTPDataIn* pDataIn, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT); //Blocking
|
||||
|
||||
/** Execute a GET request on the URL
|
||||
Blocks until completion
|
||||
This is a helper to directly get a piece of text from a HTTP result
|
||||
@param url : url on which to execute the request
|
||||
@param result : pointer to a char array in which the result will be stored
|
||||
@param maxResultLen : length of the char array (including space for the NULL-terminating char)
|
||||
@param timeout waiting timeout in ms (osWaitForever for blocking function, not recommended)
|
||||
@return 0 on success, HTTP error (<0) on failure
|
||||
*/
|
||||
HTTPResult get(const char* url, char* result, size_t maxResultLen, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT); //Blocking
|
||||
|
||||
/** Execute a POST request on the URL
|
||||
Blocks until completion
|
||||
@param url : url on which to execute the request
|
||||
@param dataOut : a IHTTPDataOut instance that contains the data that will be posted
|
||||
@param pDataIn : pointer to an IHTTPDataIn instance that will collect the data returned by the request, can be NULL
|
||||
@param timeout waiting timeout in ms (osWaitForever for blocking function, not recommended)
|
||||
@return 0 on success, HTTP error (<0) on failure
|
||||
*/
|
||||
HTTPResult post(const char* url, const IHTTPDataOut& dataOut, IHTTPDataIn* pDataIn, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT); //Blocking
|
||||
|
||||
/** Execute a PUT request on the URL
|
||||
Blocks until completion
|
||||
@param url : url on which to execute the request
|
||||
@param dataOut : a IHTTPDataOut instance that contains the data that will be put
|
||||
@param pDataIn : pointer to an IHTTPDataIn instance that will collect the data returned by the request, can be NULL
|
||||
@param timeout waiting timeout in ms (osWaitForever for blocking function, not recommended)
|
||||
@return 0 on success, HTTP error (<0) on failure
|
||||
*/
|
||||
HTTPResult put(const char* url, const IHTTPDataOut& dataOut, IHTTPDataIn* pDataIn, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT); //Blocking
|
||||
|
||||
/** Execute a DELETE request on the URL
|
||||
Blocks until completion
|
||||
@param url : url on which to execute the request
|
||||
@param pDataIn : pointer to an IHTTPDataIn instance that will collect the data returned by the request, can be NULL
|
||||
@param timeout waiting timeout in ms (osWaitForever for blocking function, not recommended)
|
||||
@return 0 on success, HTTP error (<0) on failure
|
||||
*/
|
||||
HTTPResult del(const char* url, IHTTPDataIn* pDataIn, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT); //Blocking
|
||||
|
||||
/** Get last request's HTTP response code
|
||||
@return The HTTP response code of the last request
|
||||
*/
|
||||
int getHTTPResponseCode();
|
||||
|
||||
private:
|
||||
enum HTTP_METH
|
||||
{
|
||||
HTTP_GET,
|
||||
HTTP_POST,
|
||||
HTTP_PUT,
|
||||
HTTP_DELETE,
|
||||
HTTP_HEAD
|
||||
};
|
||||
|
||||
HTTPResult connect(const char* url, HTTP_METH method, IHTTPDataOut* pDataOut, IHTTPDataIn* pDataIn, int timeout); //Execute request
|
||||
HTTPResult recv(char* buf, size_t minLen, size_t maxLen, size_t* pReadLen); //0 on success, err code on failure
|
||||
HTTPResult send(char* buf, size_t len = 0); //0 on success, err code on failure
|
||||
HTTPResult parseURL(const char* url, char* scheme, size_t maxSchemeLen, char* host, size_t maxHostLen, uint16_t* port, char* path, size_t maxPathLen); //Parse URL
|
||||
|
||||
//Parameters
|
||||
TCPSocketConnection m_sock;
|
||||
|
||||
int m_timeout;
|
||||
|
||||
const char* m_basicAuthUser;
|
||||
const char* m_basicAuthPassword;
|
||||
int m_httpResponseCode;
|
||||
|
||||
};
|
||||
|
||||
//Including data containers here for more convenience
|
||||
#include "data/HTTPText.h"
|
||||
#include "data/HTTPMap.h"
|
||||
|
||||
#endif
|
105
examples/mbed/mbed-http-client/lib/HTTPClient/IHTTPData.h
Normal file
105
examples/mbed/mbed-http-client/lib/HTTPClient/IHTTPData.h
Normal file
@ -0,0 +1,105 @@
|
||||
/* IHTTPData.h */
|
||||
/* Copyright (C) 2012 mbed.org, MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
* and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef IHTTPDATA_H
|
||||
#define IHTTPDATA_H
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using std::size_t;
|
||||
|
||||
class IHTTPData
|
||||
{
|
||||
protected:
|
||||
/** Get a specific header
|
||||
*
|
||||
*/
|
||||
virtual bool getHeader(char* header, size_t maxHeaderLen) { return false; }
|
||||
};
|
||||
|
||||
///This is a simple interface for HTTP data storage (impl examples are Key/Value Pairs, File, etc...)
|
||||
class IHTTPDataOut : public IHTTPData
|
||||
{
|
||||
protected:
|
||||
friend class HTTPClient;
|
||||
|
||||
/** Reset stream to its beginning
|
||||
* Called by the HTTPClient on each new request
|
||||
*/
|
||||
virtual void readReset() = 0;
|
||||
|
||||
/** Read a piece of data to be transmitted
|
||||
* @param buf Pointer to the buffer on which to copy the data
|
||||
* @param len Length of the buffer
|
||||
* @param pReadLen Pointer to the variable on which the actual copied data length will be stored
|
||||
*/
|
||||
virtual int read(char* buf, size_t len, size_t* pReadLen) = 0;
|
||||
|
||||
/** Get MIME type
|
||||
* @param type Internet media type from Content-Type header
|
||||
*/
|
||||
virtual int getDataType(char* type, size_t maxTypeLen) = 0; //Internet media type for Content-Type header
|
||||
|
||||
/** Determine whether the HTTP client should chunk the data
|
||||
* Used for Transfer-Encoding header
|
||||
*/
|
||||
virtual bool getIsChunked() = 0;
|
||||
|
||||
/** If the data is not chunked, get its size
|
||||
* Used for Content-Length header
|
||||
*/
|
||||
virtual size_t getDataLen() = 0;
|
||||
|
||||
};
|
||||
|
||||
///This is a simple interface for HTTP data storage (impl examples are Key/Value Pairs, File, etc...)
|
||||
class IHTTPDataIn : public IHTTPData
|
||||
{
|
||||
protected:
|
||||
friend class HTTPClient;
|
||||
|
||||
/** Reset stream to its beginning
|
||||
* Called by the HTTPClient on each new request
|
||||
*/
|
||||
virtual void writeReset() = 0;
|
||||
|
||||
/** Write a piece of data transmitted by the server
|
||||
* @param buf Pointer to the buffer from which to copy the data
|
||||
* @param len Length of the buffer
|
||||
*/
|
||||
virtual int write(const char* buf, size_t len) = 0;
|
||||
|
||||
/** Set MIME type
|
||||
* @param type Internet media type from Content-Type header
|
||||
*/
|
||||
virtual void setDataType(const char* type) = 0;
|
||||
|
||||
/** Determine whether the data is chunked
|
||||
* Recovered from Transfer-Encoding header
|
||||
*/
|
||||
virtual void setIsChunked(bool chunked) = 0;
|
||||
|
||||
/** If the data is not chunked, set its size
|
||||
* From Content-Length header
|
||||
*/
|
||||
virtual void setDataLen(size_t len) = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
200
examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPMap.cpp
Normal file
200
examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPMap.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
/* HTTPMap.cpp */
|
||||
/* Copyright (C) 2012 mbed.org, MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
* and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "HTTPMap.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <cctype>
|
||||
|
||||
#define OK 0
|
||||
|
||||
using std::strncpy;
|
||||
|
||||
HTTPMap::HTTPMap() : m_pos(0), m_count(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void HTTPMap::put(const char* key, const char* value)
|
||||
{
|
||||
if(m_count >= HTTPMAP_TABLE_SIZE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_keys[m_count] = key;
|
||||
m_values[m_count] = value;
|
||||
m_count++;
|
||||
}
|
||||
|
||||
void HTTPMap::clear()
|
||||
{
|
||||
m_count = 0;
|
||||
m_pos = 0;
|
||||
}
|
||||
|
||||
/*virtual*/ void HTTPMap::readReset()
|
||||
{
|
||||
m_pos = 0;
|
||||
}
|
||||
|
||||
/*virtual*/ int HTTPMap::read(char* buf, size_t len, size_t* pReadLen)
|
||||
{
|
||||
if(m_pos >= m_count)
|
||||
{
|
||||
*pReadLen = 0;
|
||||
m_pos = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
//URL encode
|
||||
char* out = buf;
|
||||
const char* in = m_keys[m_pos];
|
||||
if( (m_pos != 0) && (out - buf < len - 1) )
|
||||
{
|
||||
*out='&';
|
||||
out++;
|
||||
}
|
||||
|
||||
while( (*in != '\0') && (out - buf < len - 3) )
|
||||
{
|
||||
if (std::isalnum(*in) || *in == '-' || *in == '_' || *in == '.' || *in == '~')
|
||||
{
|
||||
*out = *in;
|
||||
out++;
|
||||
}
|
||||
else if( *in == ' ' )
|
||||
{
|
||||
*out='+';
|
||||
out++;
|
||||
}
|
||||
else
|
||||
{
|
||||
char hex[] = "0123456789abcdef";
|
||||
*out='%';
|
||||
out++;
|
||||
*out=hex[(*in>>4)&0xf];
|
||||
out++;
|
||||
*out=hex[(*in)&0xf];
|
||||
out++;
|
||||
}
|
||||
in++;
|
||||
}
|
||||
|
||||
if( out - buf < len - 1 )
|
||||
{
|
||||
*out='=';
|
||||
out++;
|
||||
}
|
||||
|
||||
in = m_values[m_pos];
|
||||
while( (*in != '\0') && (out - buf < len - 3) )
|
||||
{
|
||||
if (std::isalnum(*in) || *in == '-' || *in == '_' || *in == '.' || *in == '~')
|
||||
{
|
||||
*out = *in;
|
||||
out++;
|
||||
}
|
||||
else if( *in == ' ' )
|
||||
{
|
||||
*out='+';
|
||||
out++;
|
||||
}
|
||||
else
|
||||
{
|
||||
char hex[] = "0123456789abcdef";
|
||||
*out='%';
|
||||
out++;
|
||||
*out=hex[(*in>>4)&0xf];
|
||||
out++;
|
||||
*out=hex[(*in)&0xf];
|
||||
out++;
|
||||
}
|
||||
in++;
|
||||
}
|
||||
|
||||
*pReadLen = out - buf;
|
||||
|
||||
m_pos++;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*virtual*/ int HTTPMap::getDataType(char* type, size_t maxTypeLen) //Internet media type for Content-Type header
|
||||
{
|
||||
strncpy(type, "application/x-www-form-urlencoded", maxTypeLen-1);
|
||||
type[maxTypeLen-1] = '\0';
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*virtual*/ bool HTTPMap::getIsChunked() //For Transfer-Encoding header
|
||||
{
|
||||
return false; ////Data is computed one key/value pair at a time
|
||||
}
|
||||
|
||||
/*virtual*/ size_t HTTPMap::getDataLen() //For Content-Length header
|
||||
{
|
||||
size_t count = 0;
|
||||
for(size_t i = 0; i< m_count; i++)
|
||||
{
|
||||
//URL encode
|
||||
const char* in = m_keys[i];
|
||||
if( i != 0 )
|
||||
{
|
||||
count++;
|
||||
}
|
||||
|
||||
while( (*in != '\0') )
|
||||
{
|
||||
if (std::isalnum(*in) || *in == '-' || *in == '_' || *in == '.' || *in == '~')
|
||||
{
|
||||
count++;
|
||||
}
|
||||
else if( *in == ' ' )
|
||||
{
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
count+=3;
|
||||
}
|
||||
in++;
|
||||
}
|
||||
|
||||
count ++;
|
||||
|
||||
in = m_values[i];
|
||||
while( (*in != '\0') )
|
||||
{
|
||||
if (std::isalnum(*in) || *in == '-' || *in == '_' || *in == '.' || *in == '~')
|
||||
{
|
||||
count++;
|
||||
}
|
||||
else if( *in == ' ' )
|
||||
{
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
count+=3;
|
||||
}
|
||||
in++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
71
examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPMap.h
Normal file
71
examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPMap.h
Normal file
@ -0,0 +1,71 @@
|
||||
/* HTTPMap.h */
|
||||
/* Copyright (C) 2012 mbed.org, MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
* and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HTTPMAP_H_
|
||||
#define HTTPMAP_H_
|
||||
|
||||
#include "../IHTTPData.h"
|
||||
|
||||
#define HTTPMAP_TABLE_SIZE 32
|
||||
|
||||
/** Map of key/value pairs
|
||||
* Used to transmit POST data using the application/x-www-form-urlencoded encoding
|
||||
*/
|
||||
class HTTPMap: public IHTTPDataOut
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Instantiates HTTPMap
|
||||
It supports at most 32 key/values pairs
|
||||
*/
|
||||
HTTPMap();
|
||||
|
||||
/** Put Key/Value pair
|
||||
The references to the parameters must remain valid as long as the clear() function is not called
|
||||
@param key The key to use
|
||||
@param value The corresponding value
|
||||
*/
|
||||
void put(const char* key, const char* value);
|
||||
|
||||
/** Clear table
|
||||
*/
|
||||
void clear();
|
||||
|
||||
protected:
|
||||
//IHTTPDataIn
|
||||
virtual void readReset();
|
||||
|
||||
virtual int read(char* buf, size_t len, size_t* pReadLen);
|
||||
|
||||
virtual int getDataType(char* type, size_t maxTypeLen); //Internet media type for Content-Type header
|
||||
|
||||
virtual bool getIsChunked(); //For Transfer-Encoding header
|
||||
|
||||
virtual size_t getDataLen(); //For Content-Length header
|
||||
|
||||
private:
|
||||
const char* m_keys[HTTPMAP_TABLE_SIZE];
|
||||
const char* m_values[HTTPMAP_TABLE_SIZE];
|
||||
|
||||
size_t m_pos;
|
||||
size_t m_count;
|
||||
};
|
||||
|
||||
#endif /* HTTPMAP_H_ */
|
104
examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPText.cpp
Normal file
104
examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPText.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
/* HTTPText.cpp */
|
||||
/* Copyright (C) 2012 mbed.org, MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
* and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "HTTPText.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#define OK 0
|
||||
|
||||
using std::memcpy;
|
||||
using std::strncpy;
|
||||
using std::strlen;
|
||||
|
||||
#define MIN(x,y) (((x)<(y))?(x):(y))
|
||||
|
||||
HTTPText::HTTPText(char* str) : m_str(str), m_pos(0)
|
||||
{
|
||||
m_size = strlen(str) + 1;
|
||||
}
|
||||
|
||||
HTTPText::HTTPText(char* str, size_t size) : m_str(str), m_size(size), m_pos(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//IHTTPDataIn
|
||||
/*virtual*/ void HTTPText::readReset()
|
||||
{
|
||||
m_pos = 0;
|
||||
}
|
||||
|
||||
/*virtual*/ int HTTPText::read(char* buf, size_t len, size_t* pReadLen)
|
||||
{
|
||||
*pReadLen = MIN(len, m_size - 1 - m_pos);
|
||||
memcpy(buf, m_str + m_pos, *pReadLen);
|
||||
m_pos += *pReadLen;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*virtual*/ int HTTPText::getDataType(char* type, size_t maxTypeLen) //Internet media type for Content-Type header
|
||||
{
|
||||
strncpy(type, "text/plain", maxTypeLen-1);
|
||||
type[maxTypeLen-1] = '\0';
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*virtual*/ bool HTTPText::getIsChunked() //For Transfer-Encoding header
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*virtual*/ size_t HTTPText::getDataLen() //For Content-Length header
|
||||
{
|
||||
return m_size - 1;
|
||||
}
|
||||
|
||||
//IHTTPDataOut
|
||||
/*virtual*/ void HTTPText::writeReset()
|
||||
{
|
||||
m_pos = 0;
|
||||
}
|
||||
|
||||
/*virtual*/ int HTTPText::write(const char* buf, size_t len)
|
||||
{
|
||||
size_t writeLen = MIN(len, m_size - 1 - m_pos);
|
||||
memcpy(m_str + m_pos, buf, writeLen);
|
||||
m_pos += writeLen;
|
||||
m_str[m_pos] = '\0';
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*virtual*/ void HTTPText::setDataType(const char* type) //Internet media type from Content-Type header
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*virtual*/ void HTTPText::setIsChunked(bool chunked) //From Transfer-Encoding header
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*virtual*/ void HTTPText::setDataLen(size_t len) //From Content-Length header, or if the transfer is chunked, next chunk length
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,72 @@
|
||||
/* HTTPText.h */
|
||||
/* Copyright (C) 2012 mbed.org, MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
* and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HTTPTEXT_H_
|
||||
#define HTTPTEXT_H_
|
||||
|
||||
#include "../IHTTPData.h"
|
||||
|
||||
/** A data endpoint to store text
|
||||
*/
|
||||
class HTTPText : public IHTTPDataIn, public IHTTPDataOut
|
||||
{
|
||||
public:
|
||||
/** Create an HTTPText instance for output
|
||||
* @param str String to be transmitted
|
||||
*/
|
||||
HTTPText(char* str);
|
||||
|
||||
/** Create an HTTPText instance for input
|
||||
* @param str Buffer to store the incoming string
|
||||
* @param size Size of the buffer
|
||||
*/
|
||||
HTTPText(char* str, size_t size);
|
||||
|
||||
protected:
|
||||
//IHTTPDataIn
|
||||
virtual void readReset();
|
||||
|
||||
virtual int read(char* buf, size_t len, size_t* pReadLen);
|
||||
|
||||
virtual int getDataType(char* type, size_t maxTypeLen); //Internet media type for Content-Type header
|
||||
|
||||
virtual bool getIsChunked(); //For Transfer-Encoding header
|
||||
|
||||
virtual size_t getDataLen(); //For Content-Length header
|
||||
|
||||
//IHTTPDataOut
|
||||
virtual void writeReset();
|
||||
|
||||
virtual int write(const char* buf, size_t len);
|
||||
|
||||
virtual void setDataType(const char* type); //Internet media type from Content-Type header
|
||||
|
||||
virtual void setIsChunked(bool chunked); //From Transfer-Encoding header
|
||||
|
||||
virtual void setDataLen(size_t len); //From Content-Length header, or if the transfer is chunked, next chunk length
|
||||
|
||||
private:
|
||||
char* m_str;
|
||||
size_t m_size;
|
||||
|
||||
size_t m_pos;
|
||||
};
|
||||
|
||||
#endif /* HTTPTEXT_H_ */
|
25
examples/mbed/mbed-http-client/platformio.ini
Normal file
25
examples/mbed/mbed-http-client/platformio.ini
Normal file
@ -0,0 +1,25 @@
|
||||
#
|
||||
# Project Configuration File
|
||||
#
|
||||
# A detailed documentation with the EXAMPLES is located here:
|
||||
# http://docs.platformio.org/en/latest/projectconf.html
|
||||
#
|
||||
|
||||
# A sign `#` at the beginning of the line indicates a comment
|
||||
# Comment lines are ignored.
|
||||
|
||||
# Simple and base environment
|
||||
# [env:mybaseenv]
|
||||
# platform = %INSTALLED_PLATFORM_NAME_HERE%
|
||||
# framework =
|
||||
# board =
|
||||
#
|
||||
# Automatic targets - enable auto-uploading
|
||||
# targets = upload
|
||||
|
||||
|
||||
# NXP LPC Platform
|
||||
[env:lpc1768]
|
||||
platform = nxplpc
|
||||
framework = mbed
|
||||
board = lpc1768
|
79
examples/mbed/mbed-http-client/src/main.cpp
Normal file
79
examples/mbed/mbed-http-client/src/main.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
#include "mbed.h"
|
||||
#include "EthernetInterface.h"
|
||||
#include "HTTPClient.h"
|
||||
|
||||
EthernetInterface eth;
|
||||
HTTPClient http;
|
||||
char str[512];
|
||||
|
||||
int main()
|
||||
{
|
||||
eth.init(); //Use DHCP
|
||||
|
||||
eth.connect();
|
||||
|
||||
//GET data
|
||||
printf("\nTrying to fetch page...\n");
|
||||
int ret = http.get("http://mbed.org/media/uploads/donatien/hello.txt", str, 128);
|
||||
if (!ret)
|
||||
{
|
||||
printf("Page fetched successfully - read %d characters\n", strlen(str));
|
||||
printf("Result: %s\n", str);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error - ret = %d - HTTP return code = %d\n", ret, http.getHTTPResponseCode());
|
||||
}
|
||||
|
||||
//POST data
|
||||
HTTPMap map;
|
||||
HTTPText inText(str, 512);
|
||||
map.put("Hello", "World");
|
||||
map.put("test", "1234");
|
||||
printf("\nTrying to post data...\n");
|
||||
ret = http.post("http://httpbin.org/post", map, &inText);
|
||||
if (!ret)
|
||||
{
|
||||
printf("Executed POST successfully - read %d characters\n", strlen(str));
|
||||
printf("Result: %s\n", str);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error - ret = %d - HTTP return code = %d\n", ret, http.getHTTPResponseCode());
|
||||
}
|
||||
|
||||
//PUT data
|
||||
strcpy(str, "This is a PUT test!");
|
||||
HTTPText outText(str);
|
||||
//HTTPText inText(str, 512);
|
||||
printf("\nTrying to put resource...\n");
|
||||
ret = http.put("http://httpbin.org/put", outText, &inText);
|
||||
if (!ret)
|
||||
{
|
||||
printf("Executed PUT successfully - read %d characters\n", strlen(str));
|
||||
printf("Result: %s\n", str);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error - ret = %d - HTTP return code = %d\n", ret, http.getHTTPResponseCode());
|
||||
}
|
||||
|
||||
//DELETE data
|
||||
//HTTPText inText(str, 512);
|
||||
printf("\nTrying to delete resource...\n");
|
||||
ret = http.del("http://httpbin.org/delete", &inText);
|
||||
if (!ret)
|
||||
{
|
||||
printf("Executed DELETE successfully - read %d characters\n", strlen(str));
|
||||
printf("Result: %s\n", str);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error - ret = %d - HTTP return code = %d\n", ret, http.getHTTPResponseCode());
|
||||
}
|
||||
|
||||
eth.disconnect();
|
||||
|
||||
while(1) {
|
||||
}
|
||||
}
|
21
examples/mbed/mbed-rtos/README.rst
Normal file
21
examples/mbed/mbed-rtos/README.rst
Normal file
@ -0,0 +1,21 @@
|
||||
How to build PlatformIO based project
|
||||
====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
3. Extract ZIP archive
|
||||
4. Run these commands:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Change directory to example
|
||||
> cd platformio-develop/examples/mbed/mbed-rtos
|
||||
|
||||
# Process example project
|
||||
> platformio run
|
||||
|
||||
# Upload firmware
|
||||
> platformio run --target upload
|
||||
|
||||
# Clean build files
|
||||
> platformio run --target clean
|
37
examples/mbed/mbed-rtos/platformio.ini
Normal file
37
examples/mbed/mbed-rtos/platformio.ini
Normal file
@ -0,0 +1,37 @@
|
||||
#
|
||||
# Project Configuration File
|
||||
#
|
||||
# A detailed documentation with the EXAMPLES is located here:
|
||||
# http://docs.platformio.org/en/latest/projectconf.html
|
||||
#
|
||||
|
||||
# A sign `#` at the beginning of the line indicates a comment
|
||||
# Comment lines are ignored.
|
||||
|
||||
# Simple and base environment
|
||||
# [env:mybaseenv]
|
||||
# platform = %INSTALLED_PLATFORM_NAME_HERE%
|
||||
# framework =
|
||||
# board =
|
||||
#
|
||||
# Automatic targets - enable auto-uploading
|
||||
# targets = upload
|
||||
|
||||
|
||||
# NXP LPC Platform
|
||||
[env:lpc1768]
|
||||
platform = nxplpc
|
||||
framework = mbed
|
||||
board = lpc1768
|
||||
|
||||
# Freescale FRDM Platform
|
||||
[env:frdm_kl25z]
|
||||
platform = freescalekinetis
|
||||
framework = mbed
|
||||
board = frdm_kl25z
|
||||
|
||||
# ST STM32 Platform
|
||||
[env:nucleo_f401re]
|
||||
platform = ststm32
|
||||
framework = mbed
|
||||
board = nucleo_f401re
|
38
examples/mbed/mbed-rtos/src/main.cpp
Normal file
38
examples/mbed/mbed-rtos/src/main.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include "mbed.h"
|
||||
#include "rtos.h"
|
||||
|
||||
/*
|
||||
* The stack size is defined in cmsis_os.h mainly dependent on the underlying toolchain and
|
||||
* the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes
|
||||
* and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize.
|
||||
*/
|
||||
#if defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)
|
||||
#define STACK_SIZE DEFAULT_STACK_SIZE/4
|
||||
#else
|
||||
#define STACK_SIZE DEFAULT_STACK_SIZE
|
||||
#endif
|
||||
|
||||
void print_char(char c = '*') {
|
||||
printf("%c", c);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
DigitalOut led1(LED1);
|
||||
DigitalOut led2(LED2);
|
||||
|
||||
void led2_thread(void const *argument) {
|
||||
while (true) {
|
||||
led2 = !led2;
|
||||
Thread::wait(1000);
|
||||
print_char();
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
Thread thread(led2_thread, NULL, osPriorityNormal, STACK_SIZE);
|
||||
|
||||
while (true) {
|
||||
led1 = !led1;
|
||||
Thread::wait(500);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -1,5 +1,5 @@
|
||||
How to buid PlatformIO based project
|
||||
====================================
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
|
||||
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
|
||||
|
@ -78,8 +78,7 @@
|
||||
},
|
||||
"url": "https://developer.mbed.org/platforms/FRDM-K20D50M/",
|
||||
"vendor": "Freescale"
|
||||
}
|
||||
,
|
||||
},
|
||||
"frdm_k22f": {
|
||||
"build": {
|
||||
"f_cpu": "120000000L",
|
||||
@ -95,5 +94,21 @@
|
||||
},
|
||||
"url": "https://developer.mbed.org/platforms/FRDM-K22F/",
|
||||
"vendor": "Freescale"
|
||||
},
|
||||
"IBMEthernetKit": {
|
||||
"build": {
|
||||
"f_cpu": "120000000L",
|
||||
"cpu": "cortex-m4",
|
||||
"mcu": "mk64fn1m0vll12"
|
||||
},
|
||||
"frameworks": ["mbed"],
|
||||
"name": "Ethernet IoT Starter Kit",
|
||||
"platform": "freescalekinetis",
|
||||
"upload": {
|
||||
"maximum_ram_size": 262144,
|
||||
"maximum_size": 1048576
|
||||
},
|
||||
"url": "http://developer.mbed.org/platforms/IBMEthernetKit/",
|
||||
"vendor": "Freescale"
|
||||
}
|
||||
}
|
@ -94,8 +94,7 @@
|
||||
},
|
||||
"url": "https://developer.mbed.org/platforms/Nordic-nRF51-Dongle/",
|
||||
"vendor": "Nordic"
|
||||
}
|
||||
,
|
||||
},
|
||||
"wallBotBLE": {
|
||||
"build": {
|
||||
"f_cpu": "16000000L",
|
||||
@ -111,6 +110,21 @@
|
||||
},
|
||||
"url": "https://developer.mbed.org/platforms/JKSoft-Wallbot-BLE/",
|
||||
"vendor": "JKSoft"
|
||||
},
|
||||
"seeedTinyBLE": {
|
||||
"build": {
|
||||
"f_cpu": "16000000L",
|
||||
"cpu": "cortex-m0",
|
||||
"mcu": "nrf51822"
|
||||
},
|
||||
"frameworks": ["mbed"],
|
||||
"name": "Seeed Tiny BLE",
|
||||
"platform": "nordicnrf51",
|
||||
"upload": {
|
||||
"maximum_ram_size": 16384,
|
||||
"maximum_size": 262144
|
||||
},
|
||||
"url": "http://developer.mbed.org/platforms/Seeed-Tiny-BLE/",
|
||||
"vendor": "SeeedStudio"
|
||||
}
|
||||
|
||||
}
|
@ -235,6 +235,22 @@
|
||||
"url": "https://developer.mbed.org/platforms/ST-Nucleo-F302R8/",
|
||||
"vendor": "ST"
|
||||
},
|
||||
"nucleo_f303re": {
|
||||
"build": {
|
||||
"f_cpu": "72000000L",
|
||||
"cpu": "cortex-m4",
|
||||
"mcu": "stm32f303ret6"
|
||||
},
|
||||
"frameworks": ["mbed"],
|
||||
"name": "ST Nucleo F303RE",
|
||||
"platform": "ststm32",
|
||||
"upload": {
|
||||
"maximum_ram_size": 65536,
|
||||
"maximum_size": 524288
|
||||
},
|
||||
"url": "http://developer.mbed.org/platforms/ST-Nucleo-F303RE/",
|
||||
"vendor": "ST"
|
||||
},
|
||||
"nucleo_f334r8": {
|
||||
"build": {
|
||||
"f_cpu": "72000000L",
|
||||
|
@ -15,11 +15,13 @@ the mbed Developer Community.
|
||||
http://mbed.org/
|
||||
"""
|
||||
|
||||
import re
|
||||
import xml.etree.ElementTree as ElementTree
|
||||
from binascii import crc32
|
||||
from os.path import join, normpath
|
||||
from os import walk
|
||||
from os.path import basename, isfile, join, normpath
|
||||
|
||||
from SCons.Script import DefaultEnvironment
|
||||
from SCons.Script import DefaultEnvironment, Exit
|
||||
|
||||
env = DefaultEnvironment()
|
||||
|
||||
@ -41,9 +43,10 @@ MBED_VARIANTS = {
|
||||
"lpc11u35": "LPC11U35_401",
|
||||
"mbuino": "LPC11U24",
|
||||
"nrf51_mkit": "NRF51822",
|
||||
"redBearLab": "NRF51822",
|
||||
"seeedTinyBLE": "SEEED_TINY_BLE",
|
||||
"redBearLab": "RBLAB_NRF51822",
|
||||
"nrf51-dt": "NRF51_DK",
|
||||
"redBearLabBLENano": "NRF51822",
|
||||
"redBearLabBLENano": "RBLAB_NRF51822",
|
||||
"wallBotBLE": "NRF51822",
|
||||
"frdm_kl25z": "KL25Z",
|
||||
"frdm_kl46z": "KL46Z",
|
||||
@ -53,6 +56,86 @@ MBED_VARIANTS = {
|
||||
"frdm_k22f": "K22F"
|
||||
}
|
||||
|
||||
MBED_LIBS_MAP = {
|
||||
"dsp": {"ar": ["dsp", "cmsis_dsp"]},
|
||||
"eth": {"ar": ["eth"], "deps": ["rtos"]},
|
||||
"fat": {"ar": ["fat"]},
|
||||
"rtos": {"ar": ["rtos", "rtx"]},
|
||||
"usb": {"ar": ["USBDevice"]},
|
||||
"usb_host": {"ar": ["USBHost"]}
|
||||
}
|
||||
|
||||
|
||||
def get_mbedlib_includes():
|
||||
result = []
|
||||
for lib in MBED_LIBS_MAP.keys():
|
||||
includes = []
|
||||
lib_dir = join(env.subst("$PLATFORMFW_DIR"), "libs", lib)
|
||||
for _, _, files in walk(lib_dir):
|
||||
for libfile in files:
|
||||
if libfile.endswith(".h"):
|
||||
includes.append(libfile)
|
||||
result.append((lib, set(includes)))
|
||||
return result
|
||||
|
||||
|
||||
def get_used_mbedlibs():
|
||||
re_includes = re.compile(r"^(#include\s+(?:\<|\")([^\r\n\"]+))",
|
||||
re.M | re.I)
|
||||
srcincs = []
|
||||
for root, _, files in walk(env.get("PROJECTSRC_DIR")):
|
||||
for pfile in files:
|
||||
if not any([pfile.endswith(ext) for ext in (".h", ".c", ".cpp")]):
|
||||
continue
|
||||
with open(join(root, pfile)) as fp:
|
||||
srcincs.extend([i[1] for i in re_includes.findall(fp.read())])
|
||||
srcincs = set(srcincs)
|
||||
|
||||
result = {}
|
||||
for libname, libincs in get_mbedlib_includes():
|
||||
if libincs & srcincs and libname not in result:
|
||||
result[libname] = MBED_LIBS_MAP[libname]
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def add_mbedlib(libname, libar):
|
||||
if libar in env.get("LIBS"):
|
||||
return
|
||||
|
||||
lib_dir = join(env.subst("$PLATFORMFW_DIR"), "libs", libname)
|
||||
if not isfile(join(lib_dir, "TARGET_%s" % variant,
|
||||
"TOOLCHAIN_GCC_ARM", "lib%s.a" % libar)):
|
||||
Exit("Error: %s board doesn't support %s library!" %
|
||||
(env.get("BOARD"), libname))
|
||||
|
||||
env.Append(
|
||||
LIBPATH=[
|
||||
join(env.subst("$PLATFORMFW_DIR"), "libs", libname,
|
||||
"TARGET_%s" % variant, "TOOLCHAIN_GCC_ARM")
|
||||
],
|
||||
LIBS=[libar]
|
||||
)
|
||||
|
||||
sysincdirs = (
|
||||
"eth",
|
||||
"include",
|
||||
"ipv4",
|
||||
"lwip-eth",
|
||||
"lwip-sys"
|
||||
)
|
||||
|
||||
for root, _, files in walk(lib_dir):
|
||||
if (not any(f.endswith(".h") for f in files) and
|
||||
basename(root) not in sysincdirs):
|
||||
continue
|
||||
var_dir = join("$BUILD_DIR", "FrameworkMbed%sInc%d" %
|
||||
(libname.upper(), crc32(root)))
|
||||
if var_dir in env.get("CPPPATH"):
|
||||
continue
|
||||
env.VariantDir(var_dir, root)
|
||||
env.Append(CPPPATH=[var_dir])
|
||||
|
||||
|
||||
def parse_eix_file(filename):
|
||||
result = {}
|
||||
@ -93,6 +176,7 @@ def get_build_flags(data):
|
||||
flags['CFLAGS'] = list(cflags - cppflags)
|
||||
return flags
|
||||
|
||||
|
||||
board_type = env.subst("$BOARD")
|
||||
variant = MBED_VARIANTS[
|
||||
board_type] if board_type in MBED_VARIANTS else board_type.upper()
|
||||
@ -123,7 +207,6 @@ for lib_path in eixdata.get("CPPPATH"):
|
||||
env.VariantDir(_vdir, join(variant_dir, lib_path))
|
||||
env.Append(CPPPATH=[_vdir])
|
||||
|
||||
|
||||
env.Append(
|
||||
LIBPATH=[join(variant_dir, lib_path)
|
||||
for lib_path in eixdata.get("LIBPATH", [])
|
||||
@ -135,7 +218,7 @@ env.Append(
|
||||
#
|
||||
|
||||
libs = [l for l in eixdata.get("STDLIBS", []) if l not in env.get("LIBS")]
|
||||
libs.append("mbed")
|
||||
libs.extend(["mbed", "c", "gcc"])
|
||||
|
||||
libs.append(env.Library(
|
||||
join("$BUILD_DIR", "FrameworkMbed"),
|
||||
@ -144,3 +227,12 @@ libs.append(env.Library(
|
||||
))
|
||||
|
||||
env.Append(LIBS=libs)
|
||||
|
||||
for _libname, _libdata in get_used_mbedlibs().iteritems():
|
||||
for _libar in _libdata['ar']:
|
||||
add_mbedlib(_libname, _libar)
|
||||
if "deps" not in _libdata:
|
||||
continue
|
||||
for libdep in _libdata['deps']:
|
||||
for _libar in MBED_LIBS_MAP[libdep]['ar']:
|
||||
add_mbedlib(libdep, _libar)
|
||||
|
@ -11,7 +11,7 @@ from sys import path
|
||||
|
||||
path.append("..")
|
||||
|
||||
from platformio.util import exec_command
|
||||
from platformio.util import exec_command, get_home_dir
|
||||
|
||||
|
||||
def _unzip_generated_file(mbed_dir, output_dir, mcu):
|
||||
@ -19,7 +19,6 @@ def _unzip_generated_file(mbed_dir, output_dir, mcu):
|
||||
mbed_dir, "build", "export", "MBED_A1_emblocks_%s.zip" % mcu)
|
||||
variant_dir = join(output_dir, "variant", mcu)
|
||||
if isfile(filename):
|
||||
print "Processing board: %s" % mcu
|
||||
with zipfile.ZipFile(filename) as zfile:
|
||||
mkdir(variant_dir)
|
||||
zfile.extractall(variant_dir)
|
||||
@ -34,6 +33,33 @@ def _unzip_generated_file(mbed_dir, output_dir, mcu):
|
||||
print "Warning! Skipped board: %s" % mcu
|
||||
|
||||
|
||||
def buildlib(mbed_dir, mcu, lib="mbed"):
|
||||
build_command = [
|
||||
"python",
|
||||
join(mbed_dir, "workspace_tools", "build.py"),
|
||||
"--mcu", mcu,
|
||||
"-t", "GCC_ARM"
|
||||
]
|
||||
if lib is not "mbed":
|
||||
build_command.append(lib)
|
||||
build_result = exec_command(build_command, cwd=getcwd())
|
||||
if build_result['returncode'] != 0:
|
||||
print "* %s doesn't support %s library!" % (mcu, lib)
|
||||
|
||||
|
||||
def copylibs(mbed_dir, output_dir):
|
||||
libs = ["dsp", "fat", "net", "rtos", "usb", "usb_host"]
|
||||
libs_dir = join(output_dir, "libs")
|
||||
makedirs(libs_dir)
|
||||
|
||||
print "Moving generated libraries to framework dir..."
|
||||
for lib in libs:
|
||||
if lib == "net":
|
||||
move(join(mbed_dir, "build", lib, "eth"), libs_dir)
|
||||
continue
|
||||
move(join(mbed_dir, "build", lib), libs_dir)
|
||||
|
||||
|
||||
def main(mbed_dir, output_dir):
|
||||
print "Starting..."
|
||||
|
||||
@ -44,18 +70,34 @@ def main(mbed_dir, output_dir):
|
||||
print "Deleting previous framework dir..."
|
||||
rmtree(output_dir)
|
||||
|
||||
settings_file = join(mbed_dir, "workspace_tools", "private_settings.py")
|
||||
if not isfile(settings_file):
|
||||
with open(settings_file, "w") as f:
|
||||
f.write("GCC_ARM_PATH = '%s'" %
|
||||
join(get_home_dir(), "packages", "toolchain-gccarmnoneeabi",
|
||||
"bin"))
|
||||
|
||||
makedirs(join(output_dir, "variant"))
|
||||
# make .eix files
|
||||
mbed_libs = ["--rtos", "--dsp", "--fat", "--eth", "--usb", "--usb_host"]
|
||||
|
||||
for mcu in set(gccarm.GccArm.TARGETS):
|
||||
exec_command(
|
||||
["python", join(mbed_dir, "workspace_tools", "build.py"),
|
||||
"--mcu", mcu, "-t", "GCC_ARM"], cwd=getcwd()
|
||||
)
|
||||
exec_command(
|
||||
print "Processing board: %s" % mcu
|
||||
buildlib(mbed_dir, mcu)
|
||||
for lib in mbed_libs:
|
||||
buildlib(mbed_dir, mcu, lib)
|
||||
result = exec_command(
|
||||
["python", join(mbed_dir, "workspace_tools", "project.py"),
|
||||
"--mcu", mcu, "-i", "emblocks", "-p", "0", "-b"], cwd=getcwd()
|
||||
)
|
||||
if result['returncode'] != 0:
|
||||
print "Unable to build the project for %s" % mcu
|
||||
continue
|
||||
_unzip_generated_file(mbed_dir, output_dir, mcu)
|
||||
copylibs(mbed_dir, output_dir)
|
||||
|
||||
with open(join(output_dir, "boards.txt"), "w") as fp:
|
||||
fp.write("\n".join(sorted(listdir(join(output_dir, "variant")))))
|
||||
|
||||
print "Complete!"
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user