Add full support for MBED libraries: rtos, eth, dsp, fat, usb

This commit is contained in:
Valeriy Koval
2015-03-20 19:46:13 +02:00
parent 7cfb9db046
commit 726887732f
22 changed files with 2092 additions and 19 deletions

View 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

View 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

View 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
};

View 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");
}
}

View 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

View 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;
}

View 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

View 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

View 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;
}

View 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_ */

View 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
{
}

View File

@ -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_ */

View 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

View 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) {
}
}

View 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

View 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

View 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);
}
}

View File

@ -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"
}
}

View File

@ -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"
}
}

View File

@ -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",

View File

@ -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)

View File

@ -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!"