Merge remote-tracking branch 'upstream/master'

pull/3789/head
Yogesh Pande 2017-02-23 08:15:51 +02:00
commit d3b48a8e2d
322 changed files with 10414 additions and 12114 deletions

2
.gitignore vendored
View File

@ -75,3 +75,5 @@ cscope.*
*.swp
*~
# Visual Studio Code
.vscode/

View File

@ -70,7 +70,7 @@ SIMPLE_POSTS_TEST(0)
void time_func(Timer *t, int ms) {
TEST_ASSERT_INT_WITHIN(2, ms, t->read_ms());
TEST_ASSERT_INT_WITHIN(5, ms, t->read_ms());
t->reset();
}
@ -210,7 +210,7 @@ void event_class_helper_test() {
void event_inference_test() {
counter = 0;
EventQueue queue (2048);
EventQueue queue(2048);
queue.event(count5, 1, 1, 1, 1, 1).post();
queue.event(count5, 1, 1, 1, 1).post(1);
@ -219,9 +219,16 @@ void event_inference_test() {
queue.event(count5, 1).post(1, 1, 1, 1);
queue.event(count5).post(1, 1, 1, 1, 1);
queue.event(callback(count5), 1, 1, 1, 1, 1).post();
queue.event(callback(count5), 1, 1, 1, 1).post(1);
queue.event(callback(count5), 1, 1, 1).post(1, 1);
queue.event(callback(count5), 1, 1).post(1, 1, 1);
queue.event(callback(count5), 1).post(1, 1, 1, 1);
queue.event(callback(count5)).post(1, 1, 1, 1, 1);
queue.dispatch(0);
TEST_ASSERT_EQUAL(counter, 30);
TEST_ASSERT_EQUAL(counter, 60);
}

View File

@ -0,0 +1,122 @@
#include "mbed_events.h"
#include "mbed.h"
#include "rtos.h"
#include "greentea-client/test_env.h"
#include "unity.h"
#include "utest.h"
#include <cstdlib>
#include <cmath>
using namespace utest::v1;
// Test delay
#ifndef TEST_EVENTS_TIMING_TIME
#define TEST_EVENTS_TIMING_TIME 20000
#endif
#ifndef TEST_EVENTS_TIMING_MEAN
#define TEST_EVENTS_TIMING_MEAN 25
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288
#endif
// Random number generation to skew timing values
float gauss(float mu, float sigma) {
float x = (float)rand() / ((float)RAND_MAX+1);
float y = (float)rand() / ((float)RAND_MAX+1);
float x2pi = x*2.0*M_PI;
float g2rad = sqrt(-2.0 * log(1.0-y));
float z = cos(x2pi) * g2rad;
return mu + z*sigma;
}
float chisq(float sigma) {
return pow(gauss(0, sqrt(sigma)), 2);
}
Timer timer;
DigitalOut led(LED1);
equeue_sema_t sema;
// Timer timing test
void timer_timing_test() {
timer.reset();
timer.start();
int prev = timer.read_us();
while (prev < TEST_EVENTS_TIMING_TIME*1000) {
int next = timer.read_us();
if (next < prev) {
printf("backwards drift %d -> %d (%08x -> %08x)\r\n",
prev, next, prev, next);
}
TEST_ASSERT(next >= prev);
prev = next;
}
}
// equeue tick timing test
void tick_timing_test() {
unsigned start = equeue_tick();
int prev = 0;
while (prev < TEST_EVENTS_TIMING_TIME) {
int next = equeue_tick() - start;
if (next < prev) {
printf("backwards drift %d -> %d (%08x -> %08x)\r\n",
prev, next, prev, next);
}
TEST_ASSERT(next >= prev);
prev = next;
}
}
// equeue semaphore timing test
void semaphore_timing_test() {
srand(0);
timer.reset();
timer.start();
int err = equeue_sema_create(&sema);
TEST_ASSERT_EQUAL(0, err);
while (timer.read_ms() < TEST_EVENTS_TIMING_TIME) {
int delay = chisq(TEST_EVENTS_TIMING_MEAN);
int start = timer.read_us();
equeue_sema_wait(&sema, delay);
int taken = timer.read_us() - start;
printf("delay %dms => error %dus\r\n", delay, abs(1000*delay - taken));
TEST_ASSERT_INT_WITHIN(5000, taken, delay * 1000);
led = !led;
}
equeue_sema_destroy(&sema);
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
GREENTEA_SETUP((number_of_cases+1)*TEST_EVENTS_TIMING_TIME, "default_auto");
return verbose_test_setup_handler(number_of_cases);
}
const Case cases[] = {
Case("Testing accuracy of timer", timer_timing_test),
Case("Testing accuracy of equeue tick", tick_timing_test),
Case("Testing accuracy of equeue semaphore", semaphore_timing_test),
};
Specification specification(test_setup, cases);
int main() {
return !Harness::run(specification);
}

View File

@ -0,0 +1,137 @@
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if !DEVICE_FLASH
#error [NOT_SUPPORTED] Flash API not supported for this target
#endif
#include "utest/utest.h"
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#include "mbed.h"
using namespace utest::v1;
void flashiap_init_test()
{
FlashIAP flash_device;
uint32_t ret = flash_device.init();
TEST_ASSERT_EQUAL_INT32(0, ret);
ret = flash_device.deinit();
TEST_ASSERT_EQUAL_INT32(0, ret);
}
void flashiap_program_test()
{
FlashIAP flash_device;
uint32_t ret = flash_device.init();
TEST_ASSERT_EQUAL_INT32(0, ret);
// get the last sector size (flash size - 1)
uint32_t sector_size = flash_device.get_sector_size(flash_device.get_flash_start() + flash_device.get_flash_size() - 1UL);
uint32_t page_size = flash_device.get_page_size();
TEST_ASSERT_NOT_EQUAL(0, sector_size);
TEST_ASSERT_NOT_EQUAL(0, page_size);
TEST_ASSERT_TRUE(sector_size % page_size == 0);
const uint8_t test_value = 0xCE;
uint8_t *data = new uint8_t[page_size];
for (uint32_t i = 0; i < page_size; i++) {
data[i] = test_value;
}
// the one before the last sector in the system
uint32_t address = (flash_device.get_flash_start() + flash_device.get_flash_size()) - (sector_size);
TEST_ASSERT_TRUE(address != 0UL);
ret = flash_device.erase(address, sector_size);
TEST_ASSERT_EQUAL_INT32(0, ret);
for (uint32_t i = 0; i < sector_size / page_size; i++) {
uint32_t page_addr = address + i * page_size;
ret = flash_device.program(data, page_addr, page_size);
TEST_ASSERT_EQUAL_INT32(0, ret);
}
uint8_t *data_flashed = new uint8_t[page_size];
for (uint32_t i = 0; i < sector_size / page_size; i++) {
uint32_t page_addr = address + i * page_size;
ret = flash_device.read(data_flashed, page_addr, page_size);
TEST_ASSERT_EQUAL_INT32(0, ret);
TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, page_size);
}
delete[] data;
delete[] data_flashed;
ret = flash_device.deinit();
TEST_ASSERT_EQUAL_INT32(0, ret);
}
void flashiap_program_error_test()
{
FlashIAP flash_device;
uint32_t ret = flash_device.init();
TEST_ASSERT_EQUAL_INT32(0, ret);
// get the last sector size (flash size - 1)
uint32_t sector_size = flash_device.get_sector_size(flash_device.get_flash_start() + flash_device.get_flash_size() - 1UL);
uint32_t page_size = flash_device.get_page_size();
TEST_ASSERT_NOT_EQUAL(0, sector_size);
TEST_ASSERT_NOT_EQUAL(0, page_size);
TEST_ASSERT_TRUE(sector_size % page_size == 0);
const uint8_t test_value = 0xCE;
uint8_t *data = new uint8_t[page_size];
for (uint32_t i = 0; i < page_size; i++) {
data[i] = test_value;
}
// the one before the last page in the system
uint32_t address = (flash_device.get_flash_start() + flash_device.get_flash_size()) - (sector_size);
TEST_ASSERT_TRUE(address != 0UL);
// unaligned address
ret = flash_device.erase(address + 1, sector_size);
TEST_ASSERT_EQUAL_INT32(-1, ret);
ret = flash_device.program(data, address + 1, page_size);
TEST_ASSERT_EQUAL_INT32(-1, ret);
// unaligned page size
ret = flash_device.program(data, address, page_size + 1);
TEST_ASSERT_EQUAL_INT32(-1, ret);
delete[] data;
ret = flash_device.deinit();
TEST_ASSERT_EQUAL_INT32(0, ret);
}
Case cases[] = {
Case("FlashIAP - init", flashiap_init_test),
Case("FlashIAP - program", flashiap_program_test),
Case("FlashIAP - program errors", flashiap_program_error_test),
};
utest::v1::status_t greentea_test_setup(const size_t number_of_cases) {
GREENTEA_SETUP(20, "default_auto");
return greentea_test_setup_handler(number_of_cases);
}
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
int main() {
Harness::run(specification);
}

View File

@ -0,0 +1,244 @@
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if !DEVICE_FLASH
#error [NOT_SUPPORTED] Flash API not supported for this target
#endif
#include "utest/utest.h"
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#include "mbed.h"
#include "flash_api.h"
#include "flash_data.h"
using namespace utest::v1;
#define TEST_CYCLES 1000000
#define ALLOWED_DRIFT_PPM 1000 //0.1%
/*
return values to be checked are documented at:
http://arm-software.github.io/CMSIS_5/Pack/html/algorithmFunc.html#Verify
*/
#ifndef ALIGN_DOWN
#define ALIGN_DOWN(x, a) ((x)& ~((a) - 1))
#endif
static int timer_diff_start;
static void erase_range(flash_t *flash, uint32_t addr, uint32_t size)
{
while (size > 0) {
uint32_t sector_size = flash_get_sector_size(flash, addr);
TEST_ASSERT_NOT_EQUAL(0, sector_size);
int32_t ret = flash_erase_sector(flash, addr);
TEST_ASSERT_EQUAL_INT32(0, ret);
size = size > sector_size ? size - sector_size : 0;
}
}
static int time_cpu_cycles(uint32_t cycles)
{
Timer timer;
timer.start();
int timer_start = timer.read_us();
volatile uint32_t delay = (volatile uint32_t)cycles;
while (delay--);
int timer_end = timer.read_us();
timer.stop();
return timer_end - timer_start;
}
void flash_init_test()
{
timer_diff_start = time_cpu_cycles(TEST_CYCLES);
flash_t test_flash;
int32_t ret = flash_init(&test_flash);
TEST_ASSERT_EQUAL_INT32(0, ret);
ret = flash_free(&test_flash);
TEST_ASSERT_EQUAL_INT32(0, ret);
}
void flash_mapping_alignment_test()
{
flash_t test_flash;
int32_t ret = flash_init(&test_flash);
TEST_ASSERT_EQUAL_INT32(0, ret);
const uint32_t page_size = flash_get_page_size(&test_flash);
const uint32_t flash_start = flash_get_start_address(&test_flash);
const uint32_t flash_size = flash_get_size(&test_flash);
TEST_ASSERT_TRUE(page_size != 0UL);
uint32_t sector_size = flash_get_sector_size(&test_flash, flash_start);
for (uint32_t offset = 0; offset < flash_size; offset += sector_size) {
const uint32_t sector_start = flash_start + offset;
sector_size = flash_get_sector_size(&test_flash, sector_start);
const uint32_t sector_end = sector_start + sector_size - 1;
const uint32_t end_sector_size = flash_get_sector_size(&test_flash, sector_end);
// Sector size must be a valid value
TEST_ASSERT_NOT_EQUAL(MBED_FLASH_INVALID_SIZE, sector_size);
// Sector size must be greater than zero
TEST_ASSERT_NOT_EQUAL(0, sector_size);
// All flash sectors must be a multiple of page size
TEST_ASSERT_EQUAL(0, sector_size % page_size);
// Sector address must be a multiple of sector size
TEST_ASSERT_EQUAL(0, sector_start % sector_size);
// All address in a sector must return the same sector size
TEST_ASSERT_EQUAL(sector_size, end_sector_size);
}
// Make sure unmapped flash is reported correctly
TEST_ASSERT_EQUAL(MBED_FLASH_INVALID_SIZE, flash_get_sector_size(&test_flash, flash_start - 1));
TEST_ASSERT_EQUAL(MBED_FLASH_INVALID_SIZE, flash_get_sector_size(&test_flash, flash_start + flash_size));
ret = flash_free(&test_flash);
TEST_ASSERT_EQUAL_INT32(0, ret);
}
void flash_erase_sector_test()
{
flash_t test_flash;
int32_t ret = flash_init(&test_flash);
TEST_ASSERT_EQUAL_INT32(0, ret);
uint32_t addr_after_last = flash_get_start_address(&test_flash) + flash_get_size(&test_flash);
uint32_t last_sector_size = flash_get_sector_size(&test_flash, addr_after_last - 1);
uint32_t last_sector = addr_after_last - last_sector_size;
TEST_ASSERT_EQUAL_INT32(0, last_sector % last_sector_size);
ret = flash_erase_sector(&test_flash, last_sector);
TEST_ASSERT_EQUAL_INT32(0, ret);
ret = flash_free(&test_flash);
TEST_ASSERT_EQUAL_INT32(0, ret);
}
// Erase sector, write one page, erase sector and write new data
void flash_program_page_test()
{
flash_t test_flash;
int32_t ret = flash_init(&test_flash);
TEST_ASSERT_EQUAL_INT32(0, ret);
uint32_t test_size = flash_get_page_size(&test_flash);
uint8_t *data = new uint8_t[test_size];
for (uint32_t i = 0; i < test_size; i++) {
data[i] = 0xCE;
}
// the one before the last page in the system
uint32_t address = flash_get_start_address(&test_flash) + flash_get_size(&test_flash) - (2*test_size);
// sector size might not be same as page size
uint32_t erase_sector_boundary = ALIGN_DOWN(address, flash_get_sector_size(&test_flash, address));
ret = flash_erase_sector(&test_flash, erase_sector_boundary);
TEST_ASSERT_EQUAL_INT32(0, ret);
ret = flash_program_page(&test_flash, address, data, test_size);
TEST_ASSERT_EQUAL_INT32(0, ret);
uint8_t *data_flashed = (uint8_t *)address;
TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, test_size);
// sector size might not be same as page size
erase_sector_boundary = ALIGN_DOWN(address, flash_get_sector_size(&test_flash, address));
ret = flash_erase_sector(&test_flash, erase_sector_boundary);
TEST_ASSERT_EQUAL_INT32(0, ret);
// write another data to be certain we are re-flashing
for (uint32_t i = 0; i < test_size; i++) {
data[i] = 0xAC;
}
ret = flash_program_page(&test_flash, address, data, test_size);
TEST_ASSERT_EQUAL_INT32(0, ret);
TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, test_size);
ret = flash_free(&test_flash);
TEST_ASSERT_EQUAL_INT32(0, ret);
delete[] data;
}
// make sure programming works with an unaligned data buffer
void flash_buffer_alignment_test()
{
flash_t test_flash;
int32_t ret = flash_init(&test_flash);
TEST_ASSERT_EQUAL_INT32(0, ret);
const uint32_t page_size = flash_get_page_size(&test_flash);
const uint32_t buf_size = page_size + 4;
uint8_t *data = new uint8_t[buf_size];
for (uint32_t i = 0; i < buf_size; i++) {
data[i] = i & 0xFF;
}
// use the last four pages for the alignment test
const uint32_t flash_end = flash_get_start_address(&test_flash) + flash_get_size(&test_flash);
const uint32_t test_addr = flash_end - page_size * 4;
const uint32_t erase_sector_boundary = ALIGN_DOWN(test_addr, flash_get_sector_size(&test_flash, test_addr));
erase_range(&test_flash, erase_sector_boundary, flash_end - erase_sector_boundary);
// make sure page program works with an unaligned data buffer
for (uint32_t i = 0; i < 4; i++) {
const uint32_t addr = test_addr + i * page_size;
ret = flash_program_page(&test_flash, addr, data + i, page_size);
TEST_ASSERT_EQUAL_INT32(0, ret);
uint8_t *data_flashed = (uint8_t *)addr;
TEST_ASSERT_EQUAL_UINT8_ARRAY(data + i, data_flashed, page_size);
}
ret = flash_free(&test_flash);
TEST_ASSERT_EQUAL_INT32(0, ret);
delete[] data;
}
// check the execution speed at the start and end of the test to make sure
// cache settings weren't changed
void flash_clock_and_cache_test()
{
const int timer_diff_end = time_cpu_cycles(TEST_CYCLES);
const int acceptable_range = timer_diff_start / (1000000 / ALLOWED_DRIFT_PPM);
TEST_ASSERT_UINT32_WITHIN(acceptable_range, timer_diff_start, timer_diff_end);
}
Case cases[] = {
Case("Flash - init", flash_init_test),
Case("Flash - mapping alignment", flash_mapping_alignment_test),
Case("Flash - erase sector", flash_erase_sector_test),
Case("Flash - program page", flash_program_page_test),
Case("Flash - buffer alignment test", flash_buffer_alignment_test),
Case("Flash - clock and cache test", flash_clock_and_cache_test),
};
utest::v1::status_t greentea_test_setup(const size_t number_of_cases) {
GREENTEA_SETUP(20, "default_auto");
return greentea_test_setup_handler(number_of_cases);
}
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
int main() {
Harness::run(specification);
}

View File

@ -1,54 +1,31 @@
#include "mbed.h"
#include "greentea-client/test_env.h"
#include "unity.h"
#include "utest.h"
#include "rtos.h"
#if defined(MBED_RTOS_SINGLE_THREAD)
#error [NOT_SUPPORTED] test not supported
#endif
#define THREAD_DELAY 50
#define SIGNALS_TO_EMIT 100
using namespace utest::v1;
/*
* 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_STM32F334R8) && defined(TOOLCHAIN_IAR)
#define STACK_SIZE DEFAULT_STACK_SIZE/4
#elif defined(TARGET_STM32F070RB)
#define STACK_SIZE DEFAULT_STACK_SIZE/2
#elif defined(TARGET_STM32F072RB)
#define STACK_SIZE DEFAULT_STACK_SIZE/2
#elif defined(TARGET_STM32F302R8) && defined(TOOLCHAIN_IAR)
#define STACK_SIZE DEFAULT_STACK_SIZE/2
#elif defined(TARGET_STM32F303K8) && defined(TOOLCHAIN_IAR)
#define STACK_SIZE DEFAULT_STACK_SIZE/2
#elif defined(TARGET_STM32L073RZ)
#define STACK_SIZE DEFAULT_STACK_SIZE/2
#elif (defined(TARGET_EFM32HG_STK3400)) && !defined(TOOLCHAIN_ARM_MICRO)
#define STACK_SIZE 512
#elif (defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32PG_STK3401)) && !defined(TOOLCHAIN_ARM_MICRO)
#define STACK_SIZE 768
#elif (defined(TARGET_EFM32GG_STK3700)) && !defined(TOOLCHAIN_ARM_MICRO)
#define STACK_SIZE 1536
#elif (defined(TARGET_EFR32)) && !defined(TOOLCHAIN_ARM_MICRO)
#define STACK_SIZE 768
#elif defined(TARGET_MCU_NRF51822) || defined(TARGET_MCU_NRF52832)
#define STACK_SIZE 1024
#elif defined(TARGET_XDOT_L151CC)
#define STACK_SIZE 1024
#else
#define STACK_SIZE DEFAULT_STACK_SIZE
#endif
#define TEST_STACK_SIZE 512
void print_char(char c = '*') {
printf("%c", c);
fflush(stdout);
}
#define TEST_ONE_SEC_MS (1000)
#define TEST_HALF_SEC_MS (500)
#define TEST_HALF_SEC_US (500000)
#define TEST_ONE_MS_US (1000)
#define THREAD_DELAY 50
#define SIGNALS_TO_EMIT 100
Mutex stdio_mutex;
DigitalOut led(LED1);
volatile int change_counter = 0;
volatile bool changing_counter = false;
@ -57,23 +34,20 @@ volatile bool mutex_defect = false;
bool manipulate_protected_zone(const int thread_delay) {
bool result = true;
stdio_mutex.lock(); // LOCK
osStatus stat = stdio_mutex.lock();
TEST_ASSERT_EQUAL(stat, osOK);
if (changing_counter == true) {
// 'e' stands for error. If changing_counter is true access is not exclusively
print_char('e');
result = false;
mutex_defect = true;
}
changing_counter = true;
// Some action on protected
led = !led;
change_counter++;
print_char('.');
Thread::wait(thread_delay);
changing_counter = false;
stdio_mutex.unlock(); // UNLOCK
stat = stdio_mutex.unlock();
TEST_ASSERT_EQUAL(stat, osOK);
return result;
}
@ -83,14 +57,14 @@ void test_thread(int const *thread_delay) {
}
}
int main() {
GREENTEA_SETUP(20, "default_auto");
void test_multiple_threads(void)
{
const int t1_delay = THREAD_DELAY * 1;
const int t2_delay = THREAD_DELAY * 2;
const int t3_delay = THREAD_DELAY * 3;
Thread t2(osPriorityNormal, STACK_SIZE);
Thread t3(osPriorityNormal, STACK_SIZE);
Thread t2(osPriorityNormal, TEST_STACK_SIZE);
Thread t3(osPriorityNormal, TEST_STACK_SIZE);
t2.start(callback(test_thread, &t2_delay));
t3.start(callback(test_thread, &t3_delay));
@ -99,6 +73,7 @@ int main() {
// Thread 1 action
Thread::wait(t1_delay);
manipulate_protected_zone(t1_delay);
if (change_counter >= SIGNALS_TO_EMIT or mutex_defect == true) {
t2.terminate();
t3.terminate();
@ -106,7 +81,154 @@ int main() {
}
}
fflush(stdout);
GREENTEA_TESTSUITE_RESULT(!mutex_defect);
return 0;
TEST_ASSERT_EQUAL(mutex_defect, false);
}
void test_dual_thread_nolock_lock_thread(Mutex *mutex)
{
bool stat_b = mutex->trylock();
TEST_ASSERT_EQUAL(stat_b, true);
osStatus stat = mutex->unlock();
TEST_ASSERT_EQUAL(stat, osOK);
}
void test_dual_thread_nolock_trylock_thread(Mutex *mutex)
{
bool stat_b = mutex->trylock();
TEST_ASSERT_EQUAL(stat_b, true);
osStatus stat = mutex->unlock();
TEST_ASSERT_EQUAL(stat, osOK);
}
template <void (*F)(Mutex *)>
void test_dual_thread_nolock(void)
{
Mutex mutex;
Thread thread;
thread.start(callback(F, &mutex));
wait_us(TEST_HALF_SEC_MS);
}
void test_dual_thread_lock_unlock_thread(Mutex *mutex)
{
osStatus stat = mutex->lock(osWaitForever);
TEST_ASSERT_EQUAL(stat, osOK);
}
void test_dual_thread_lock_unlock(void)
{
Mutex mutex;
osStatus stat;
Thread thread(osPriorityNormal, TEST_STACK_SIZE);
stat = mutex.lock();
TEST_ASSERT_EQUAL(stat, osOK);
thread.start(callback(test_dual_thread_lock_unlock_thread, &mutex));
stat = mutex.unlock();
TEST_ASSERT_EQUAL(stat, osOK);
wait_us(TEST_HALF_SEC_MS);
}
void test_dual_thread_lock_trylock_thread(Mutex *mutex)
{
bool stat = mutex->trylock();
TEST_ASSERT_EQUAL(stat, false);
}
void test_dual_thread_lock_lock_thread(Mutex *mutex)
{
uint32_t start = us_ticker_read();
osStatus stat = mutex->lock(TEST_HALF_SEC_MS);
TEST_ASSERT_EQUAL(stat, osEventTimeout);
TEST_ASSERT_UINT32_WITHIN(TEST_ONE_MS_US, TEST_HALF_SEC_US, us_ticker_read() - start);
}
template <void (*F)(Mutex *)>
void test_dual_thread_lock(void)
{
Mutex mutex;
osStatus stat;
Thread thread(osPriorityNormal, TEST_STACK_SIZE);
stat = mutex.lock();
TEST_ASSERT_EQUAL(stat, osOK);
thread.start(callback(F, &mutex));
wait_us(TEST_ONE_SEC_MS);
stat = mutex.unlock();
TEST_ASSERT_EQUAL(stat, osOK);
}
void test_single_thread_lock_recursive(void)
{
Mutex mutex;
osStatus stat;
stat = mutex.lock();
TEST_ASSERT_EQUAL(stat, osOK);
stat = mutex.lock();
TEST_ASSERT_EQUAL(stat, osOK);
stat = mutex.unlock();
TEST_ASSERT_EQUAL(stat, osOK);
stat = mutex.unlock();
TEST_ASSERT_EQUAL(stat, osOK);
}
void test_single_thread_trylock(void)
{
Mutex mutex;
bool stat_b = mutex.trylock();
TEST_ASSERT_EQUAL(stat_b, true);
osStatus stat = mutex.unlock();
TEST_ASSERT_EQUAL(stat, osOK);
}
void test_single_thread_lock(void)
{
Mutex mutex;
osStatus stat;
stat = mutex.lock();
TEST_ASSERT_EQUAL(stat, osOK);
stat = mutex.unlock();
TEST_ASSERT_EQUAL(stat, osOK);
}
utest::v1::status_t test_setup(const size_t number_of_cases) {
GREENTEA_SETUP(15, "default_auto");
return verbose_test_setup_handler(number_of_cases);
}
Case cases[] = {
Case("Test single thread lock", test_single_thread_lock),
Case("Test single thread trylock", test_single_thread_trylock),
Case("Test single thread lock recursive", test_single_thread_lock_recursive),
Case("Test dual thread lock locked", test_dual_thread_lock<test_dual_thread_lock_lock_thread>),
Case("Test dual thread trylock locked", test_dual_thread_lock<test_dual_thread_lock_trylock_thread>),
Case("Test dual thread lock unlock", test_dual_thread_lock_unlock),
Case("Test dual thread second thread lock", test_dual_thread_nolock<test_dual_thread_nolock_lock_thread>),
Case("Test dual thread second thread trylock", test_dual_thread_nolock<test_dual_thread_nolock_trylock_thread>),
Case("Test multiple thread", test_multiple_threads),
};
Specification specification(test_setup, cases);
int main() {
return !Harness::run(specification);
}

View File

@ -1,65 +0,0 @@
# About the exporters
The mbed exporters are used to export your code to various 3rd party tools and IDEs. Each exporter implements a `generate` function that produces an IDE specific project file. Exporters benefit from [mbed build tools](https://github.com/ARMmbed/mbed-os/blob/master/docs/BUILDING.md#build-mbed-sdk-library-from-sources). However, instead of using your source and [config data](https://github.com/ARMmbed/mbed-os/blob/master/docs/config_system.md) to create an executable, we use that information to populate an IDE project file that will be configured to build, flash, and debug your code. You can find exporter implementations [here](https://github.com/ARMmbed/mbed-os/tree/master/tools/export).
## mbed-cli command
`mbed export -m [target] -i [IDE]`
# Adding export support for a target
If you have added new target to the mbed SDK, exporting will allow users to transition from mbed source code to the offline development environment of their choice. This functionality activates the use of your device for larger number of users.
## Eclipse and Make
Eclipse project export utilizes a generated Makefile for building. Other than target configuration within the [config system](https://github.com/ARMmbed/mbed-os/blob/master/docs/mbed_targets.md) for mbed build system support, there is no additional work to provide Make export.
### Available mbed-cli commands
`mbed export -m [target] -i [make_gcc_arm, make_iar, make_armc5, eclipse_gcc_arm, eclipse_iar, eclipse_armc5]`
## UVision and IAR
### CMSIS Packs
UVision and IAR both utilize [CMSIS packs](http://www.keil.com/pack/doc/CMSIS/Pack/html/index.html) to find target information necessary to create a valid project file.
We utilize the tool [ArmPackManager](https://github.com/ARMmbed/mbed-os/tree/master/tools/arm_pack_manager) to scrape [MDK5 Software Packs](https://www.keil.com/dd2/Pack/) for target information. This is achieved by parsing [http://www.keil.com/pack/index.idx](http://sadevicepacksprod.blob.core.windows.net/idxfile/index.idx). The relevant information in the [PDSC (Pack Description)](http://www.keil.com/pack/doc/CMSIS/Pack/html/_pack_format.html) retrieved from each URL in the index is stored in [index.json](https://github.com/ARMmbed/mbed-os/blob/master/tools/arm_pack_manager/index.json). A `.pdsc` file typically describes a family of devices. Each device is uniquely identified by its [device name](https://github.com/ARMmbed/mbed-os/blob/master/docs/mbed_targets.md#device_name). Thus, this name makes a natural key to associate a device with its information in `index.json`.
#### What's in a device name?
There is no reliable way to map an mbed alias like [NUCLEO_F030R8](https://github.com/ARMmbed/mbed-os/blob/master/targets/targets.json#L603) to its unique identifier, [STM32F030R8](https://github.com/ARMmbed/mbed-os/blob/master/targets/targets.json#L615), as it is listed in a CMSIS pack (and subsequently `index.json`). So, we added a [device name](https://github.com/ARMmbed/mbed-os/blob/master/docs/mbed_targets.md#device_name) field in `targets.json`. **This field is required for IAR or UVision exporter support**.
#### Code Usage
http://www.keil.com/pack/Keil.Kinetis_K20_DFP.pdsc is the PDSC that contains TEENSY_31 device (MK20DX256xxx7). It has been parsed by ArmPackManager and stored in `index.json`. The device information begins on line 156:
```xml
<device Dname="MK20DX256xxx7">
<processor Dfpu="0" Dmpu="0" Dendian="Little-endian" Dclock="72000000"/>
<compile header="Device\Include\MK20D7.h" define="MK20DX256xxx7"/>
<debug svd="SVD\MK20D7.svd"/>
<memory id="IROM1" start="0x00000000" size="0x40000" startup="1" default="1"/>
<memory id="IROM2" start="0x10000000" size="0x8000" startup="0" default="0"/>
<memory id="IRAM1" start="0x20000000" size="0x8000" init ="0" default="1"/>
<memory id="IRAM2" start="0x1FFF8000" size="0x8000" init ="0" default="0"/>
<algorithm name="Flash\MK_P256.FLM" start="0x00000000" size="0x40000" default="1"/>
<algorithm name="Flash\MK_D32_72MHZ.FLM" start="0x10000000" size="0x8000" default="1"/>
<book name="Documents\K20P100M72SF1RM.pdf" title="MK20DX256xxx7 Reference Manual"/>
<book name="Documents\K20P100M72SF1.pdf" title="MK20DX256xxx7 Data Sheet"/>
</device>
```
##### Uvision
The dname (device name) field on line 156 directly corresponds to that in the Uvision5 IDE target selection window. [`tools/export/uvision/uvision.tmpl`](https://github.com/ARMmbed/mbed-os/blob/master/tools/export/uvision/uvision.tmpl#L15), uses target information from these packs is used to generate valid Uvision5 projects. If the device name is not found, we use a generic ARM CPU target in Uvision5.
##### IAR
[`tools/export/iar/iar_definitions.json`](https://github.com/ARMmbed/mbed-os/blob/master/tools/export/iar/iar_definitions.json) utilizes this device name to store information necessary to set the target in an IAR project.
##### Updating index.json
You can regenerate `index.json` to contain a newly made CMSIS pack with the following command:
`mbed export -i [IDE] --update-packs`
You should include the changes to `index.json` in your PR that adds support for the new target.

167
drivers/FlashIAP.cpp Normal file
View File

@ -0,0 +1,167 @@
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* 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 <string.h>
#include "FlashIAP.h"
#include "mbed_assert.h"
#ifdef DEVICE_FLASH
namespace mbed {
SingletonPtr<PlatformMutex> FlashIAP::_mutex;
static inline bool is_aligned(uint32_t number, uint32_t alignment)
{
if ((number % alignment) != 0) {
return false;
} else {
return true;
}
}
FlashIAP::FlashIAP()
{
}
FlashIAP::~FlashIAP()
{
}
int FlashIAP::init()
{
int ret = 0;
_mutex->lock();
if (flash_init(&_flash)) {
ret = -1;
}
_mutex->unlock();
return ret;
}
int FlashIAP::deinit()
{
int ret = 0;
_mutex->lock();
if (flash_free(&_flash)) {
ret = -1;
}
_mutex->unlock();
return ret;
}
int FlashIAP::read(void *buffer, uint32_t addr, uint32_t size)
{
_mutex->lock();
memcpy(buffer, (const void *)addr, size);
_mutex->unlock();
return 0;
}
int FlashIAP::program(const void *buffer, uint32_t addr, uint32_t size)
{
uint32_t page_size = get_page_size();
uint32_t current_sector_size = flash_get_sector_size(&_flash, addr);
// addr and size should be aligned to page size, and multiple of page size
// page program should not cross sector boundaries
if (!is_aligned(addr, page_size) ||
!is_aligned(size, page_size) ||
(size < page_size) ||
(((addr % current_sector_size) + size) > current_sector_size)) {
return -1;
}
int ret = 0;
_mutex->lock();
if (flash_program_page(&_flash, addr, (const uint8_t *)buffer, size)) {
ret = -1;
}
_mutex->unlock();
return ret;
}
bool FlashIAP::is_aligned_to_sector(uint32_t addr, uint32_t size)
{
uint32_t current_sector_size = flash_get_sector_size(&_flash, addr);
if (!is_aligned(size, current_sector_size) ||
!is_aligned(addr, current_sector_size)) {
return false;
} else {
return true;
}
}
int FlashIAP::erase(uint32_t addr, uint32_t size)
{
uint32_t current_sector_size = 0UL;
if (!is_aligned_to_sector(addr, size)) {
return -1;
}
int32_t ret = 0;
_mutex->lock();
while (size) {
ret = flash_erase_sector(&_flash, addr);
if (ret != 0) {
ret = -1;
break;
}
current_sector_size = flash_get_sector_size(&_flash, addr);
if (!is_aligned_to_sector(addr, size)) {
ret = -1;
break;
}
size -= current_sector_size;
addr += current_sector_size;
}
_mutex->unlock();
return ret;
}
uint32_t FlashIAP::get_page_size() const
{
return flash_get_page_size(&_flash);
}
uint32_t FlashIAP::get_sector_size(uint32_t addr) const
{
return flash_get_sector_size(&_flash, addr);
}
uint32_t FlashIAP::get_flash_start() const
{
return flash_get_start_address(&_flash);
}
uint32_t FlashIAP::get_flash_size() const
{
return flash_get_size(&_flash);
}
}
#endif

138
drivers/FlashIAP.h Normal file
View File

@ -0,0 +1,138 @@
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* 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 MBED_FLASHIAP_H
#define MBED_FLASHIAP_H
#ifdef DEVICE_FLASH
#include "flash_api.h"
#include "platform/SingletonPtr.h"
#include "platform/PlatformMutex.h"
namespace mbed {
/** \addtogroup drivers */
/** @{*/
/** Flash IAP driver. It invokes flash HAL functions.
*
* Note Synchronization level: Thread safe
*/
class FlashIAP {
public:
FlashIAP();
~FlashIAP();
/** Initialize a flash IAP device
*
* Should be called once per lifetime of the object.
* @return 0 on success or a negative error code on failure
*/
int init();
/** Deinitialize a flash IAP device
*
* @return 0 on success or a negative error code on failure
*/
int deinit();
/** Read data from a flash device.
*
* This method invokes memcpy - reads number of bytes from the address
*
* @param buffer Buffer to write to
* @param addr Flash address to begin reading from
* @param size Size to read in bytes
* @return 0 on success, negative error code on failure
*/
int read(void *buffer, uint32_t addr, uint32_t size);
/** Program data to pages
*
* The sectors must have been erased prior to being programmed
*
* @param buffer Buffer of data to be written
* @param addr Address of a page to begin writing to, must be a multiple of program and sector sizes
* @param size Size to write in bytes, must be a multiple of program and sector sizes
* @return 0 on success, negative error code on failure
*/
int program(const void *buffer, uint32_t addr, uint32_t size);
/** Erase sectors
*
* The state of an erased sector is undefined until it has been programmed
*
* @param addr Address of a sector to begin erasing, must be a multiple of the sector size
* @param size Size to erase in bytes, must be a multiple of the sector size
* @return 0 on success, negative error code on failure
*/
int erase(uint32_t addr, uint32_t size);
/** Get the sector size at the defined address
*
* Sector size might differ at address ranges.
* An example <0-0x1000, sector size=1024; 0x10000-0x20000, size=2048>
*
* @param addr Address of or inside the sector to query
* @return Size of a sector in bytes or MBED_FLASH_INVALID_SIZE if not mapped
*/
uint32_t get_sector_size(uint32_t addr) const;
/** Get the flash start address
*
* @return Flash start address
*/
uint32_t get_flash_start() const;
/** Get the flash size
*
* @return Flash size
*/
uint32_t get_flash_size() const;
/** Get the program page size
*
* @return Size of a program page in bytes
*/
uint32_t get_page_size() const;
private:
/** Check if address and size are aligned to a sector
*
* @param addr Address of block to check for alignment
* @param size Size of block to check for alignment
* @return true if the block is sector aligned, false otherwise
*/
bool is_aligned_to_sector(uint32_t addr, uint32_t size);
flash_t _flash;
static SingletonPtr<PlatformMutex> _mutex;
};
} /* namespace mbed */
#endif /* DEVICE_FLASH */
#endif /* MBED_FLASHIAP_H */
/** @}*/

View File

@ -27,8 +27,8 @@ InterruptIn::InterruptIn(PinName pin) : gpio(),
_fall() {
// No lock needed in the constructor
_rise.attach(donothing);
_fall.attach(donothing);
_rise = donothing;
_fall = donothing;
gpio_irq_init(&gpio_irq, pin, (&InterruptIn::_irq_handler), (uint32_t)this);
gpio_init_in(&gpio, pin);
@ -53,10 +53,10 @@ void InterruptIn::mode(PinMode pull) {
void InterruptIn::rise(Callback<void()> func) {
core_util_critical_section_enter();
if (func) {
_rise.attach(func);
_rise = func;
gpio_irq_set(&gpio_irq, IRQ_RISE, 1);
} else {
_rise.attach(donothing);
_rise = donothing;
gpio_irq_set(&gpio_irq, IRQ_RISE, 0);
}
core_util_critical_section_exit();
@ -65,10 +65,10 @@ void InterruptIn::rise(Callback<void()> func) {
void InterruptIn::fall(Callback<void()> func) {
core_util_critical_section_enter();
if (func) {
_fall.attach(func);
_fall = func;
gpio_irq_set(&gpio_irq, IRQ_FALL, 1);
} else {
_fall.attach(donothing);
_fall = donothing;
gpio_irq_set(&gpio_irq, IRQ_FALL, 0);
}
core_util_critical_section_exit();
@ -77,8 +77,8 @@ void InterruptIn::fall(Callback<void()> func) {
void InterruptIn::_irq_handler(uint32_t id, gpio_irq_event event) {
InterruptIn *handler = (InterruptIn*)id;
switch (event) {
case IRQ_RISE: handler->_rise.call(); break;
case IRQ_FALL: handler->_fall.call(); break;
case IRQ_RISE: handler->_rise(); break;
case IRQ_FALL: handler->_fall(); break;
case IRQ_NONE: break;
}
}

View File

@ -32,7 +32,7 @@ SerialBase::SerialBase(PinName tx, PinName rx, int baud) :
// No lock needed in the constructor
for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
_irq[i].attach(donothing);
_irq[i] = donothing;
}
serial_init(&_serial, tx, rx);
@ -73,10 +73,10 @@ void SerialBase::attach(Callback<void()> func, IrqType type) {
// Disable interrupts when attaching interrupt handler
core_util_critical_section_enter();
if (func) {
_irq[type].attach(func);
_irq[type] = func;
serial_irq_set(&_serial, (SerialIrq)type, 1);
} else {
_irq[type].attach(donothing);
_irq[type] = donothing;
serial_irq_set(&_serial, (SerialIrq)type, 0);
}
core_util_critical_section_exit();
@ -85,7 +85,7 @@ void SerialBase::attach(Callback<void()> func, IrqType type) {
void SerialBase::_irq_handler(uint32_t id, SerialIrq irq_type) {
SerialBase *handler = (SerialBase*)id;
handler->_irq[irq_type].call();
handler->_irq[irq_type]();
}
int SerialBase::_base_getc() {

View File

@ -25,7 +25,7 @@ namespace mbed {
void Ticker::detach() {
core_util_critical_section_enter();
remove();
_function.attach(0);
_function = 0;
core_util_critical_section_exit();
}
@ -39,7 +39,7 @@ void Ticker::setup(timestamp_t t) {
void Ticker::handler() {
insert(event.timestamp + _delay);
_function.call();
_function();
}
} // namespace mbed

View File

@ -101,7 +101,7 @@ public:
* @param t the time between calls in micro-seconds
*/
void attach_us(Callback<void()> func, timestamp_t t) {
_function.attach(func);
_function = func;
setup(t);
}

View File

@ -45,7 +45,10 @@ public:
*
* @param q Event queue to dispatch on
* @param f Function to execute when the event is dispatched
* @param a0..a4 Arguments to pass to the callback
* @param c0..c4 Arguments to bind to the callback, these arguments are
* allocated on an irq-safe allocator from the event queue's
* memory pool. Must be type-compatible with b0..b4, the
* arguments to the underlying callback.
*/
template <typename F>
Event(EventQueue *q, F f) {
@ -438,7 +441,10 @@ public:
*
* @param q Event queue to dispatch on
* @param f Function to execute when the event is dispatched
* @param a0..a4 Arguments to pass to the callback
* @param c0..c4 Arguments to bind to the callback, these arguments are
* allocated on an irq-safe allocator from the event queue's
* memory pool. Must be type-compatible with b0..b4, the
* arguments to the underlying callback.
*/
template <typename F>
Event(EventQueue *q, F f) {
@ -831,7 +837,10 @@ public:
*
* @param q Event queue to dispatch on
* @param f Function to execute when the event is dispatched
* @param a0..a4 Arguments to pass to the callback
* @param c0..c4 Arguments to bind to the callback, these arguments are
* allocated on an irq-safe allocator from the event queue's
* memory pool. Must be type-compatible with b0..b4, the
* arguments to the underlying callback.
*/
template <typename F>
Event(EventQueue *q, F f) {
@ -1224,7 +1233,10 @@ public:
*
* @param q Event queue to dispatch on
* @param f Function to execute when the event is dispatched
* @param a0..a4 Arguments to pass to the callback
* @param c0..c4 Arguments to bind to the callback, these arguments are
* allocated on an irq-safe allocator from the event queue's
* memory pool. Must be type-compatible with b0..b4, the
* arguments to the underlying callback.
*/
template <typename F>
Event(EventQueue *q, F f) {
@ -1617,7 +1629,10 @@ public:
*
* @param q Event queue to dispatch on
* @param f Function to execute when the event is dispatched
* @param a0..a4 Arguments to pass to the callback
* @param c0..c4 Arguments to bind to the callback, these arguments are
* allocated on an irq-safe allocator from the event queue's
* memory pool. Must be type-compatible with b0..b4, the
* arguments to the underlying callback.
*/
template <typename F>
Event(EventQueue *q, F f) {
@ -2010,7 +2025,10 @@ public:
*
* @param q Event queue to dispatch on
* @param f Function to execute when the event is dispatched
* @param a0..a4 Arguments to pass to the callback
* @param c0..c4 Arguments to bind to the callback, these arguments are
* allocated on an irq-safe allocator from the event queue's
* memory pool. Must be type-compatible with b0..b4, the
* arguments to the underlying callback.
*/
template <typename F>
Event(EventQueue *q, F f) {
@ -2417,6 +2435,11 @@ Event<void()> EventQueue::event(const volatile T *obj, R (T::*method)() const vo
return Event<void()>(this, mbed::callback(obj, method));
}
template <typename R>
Event<void()> EventQueue::event(mbed::Callback<R()> cb) {
return Event<void()>(this, cb);
}
template <typename R, typename B0, typename C0>
Event<void()> EventQueue::event(R (*func)(B0), C0 c0) {
return Event<void()>(this, func, c0);
@ -2442,6 +2465,11 @@ Event<void()> EventQueue::event(const volatile T *obj, R (T::*method)(B0) const
return Event<void()>(this, mbed::callback(obj, method), c0);
}
template <typename R, typename B0, typename C0>
Event<void()> EventQueue::event(mbed::Callback<R(B0)> cb, C0 c0) {
return Event<void()>(this, cb, c0);
}
template <typename R, typename B0, typename B1, typename C0, typename C1>
Event<void()> EventQueue::event(R (*func)(B0, B1), C0 c0, C1 c1) {
return Event<void()>(this, func, c0, c1);
@ -2467,6 +2495,11 @@ Event<void()> EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1) co
return Event<void()>(this, mbed::callback(obj, method), c0, c1);
}
template <typename R, typename B0, typename B1, typename C0, typename C1>
Event<void()> EventQueue::event(mbed::Callback<R(B0, B1)> cb, C0 c0, C1 c1) {
return Event<void()>(this, cb, c0, c1);
}
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2>
Event<void()> EventQueue::event(R (*func)(B0, B1, B2), C0 c0, C1 c1, C2 c2) {
return Event<void()>(this, func, c0, c1, c2);
@ -2492,6 +2525,11 @@ Event<void()> EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2
return Event<void()>(this, mbed::callback(obj, method), c0, c1, c2);
}
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2>
Event<void()> EventQueue::event(mbed::Callback<R(B0, B1, B2)> cb, C0 c0, C1 c1, C2 c2) {
return Event<void()>(this, cb, c0, c1, c2);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3>
Event<void()> EventQueue::event(R (*func)(B0, B1, B2, B3), C0 c0, C1 c1, C2 c2, C3 c3) {
return Event<void()>(this, func, c0, c1, c2, c3);
@ -2517,6 +2555,11 @@ Event<void()> EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2
return Event<void()>(this, mbed::callback(obj, method), c0, c1, c2, c3);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3>
Event<void()> EventQueue::event(mbed::Callback<R(B0, B1, B2, B3)> cb, C0 c0, C1 c1, C2 c2, C3 c3) {
return Event<void()>(this, cb, c0, c1, c2, c3);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4>
Event<void()> EventQueue::event(R (*func)(B0, B1, B2, B3, B4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) {
return Event<void()>(this, func, c0, c1, c2, c3, c4);
@ -2542,6 +2585,11 @@ Event<void()> EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2
return Event<void()>(this, mbed::callback(obj, method), c0, c1, c2, c3, c4);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4>
Event<void()> EventQueue::event(mbed::Callback<R(B0, B1, B2, B3, B4)> cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) {
return Event<void()>(this, cb, c0, c1, c2, c3, c4);
}
template <typename R, typename A0>
Event<void(A0)> EventQueue::event(R (*func)(A0)) {
return Event<void(A0)>(this, func);
@ -2567,6 +2615,11 @@ Event<void(A0)> EventQueue::event(const volatile T *obj, R (T::*method)(A0) cons
return Event<void(A0)>(this, mbed::callback(obj, method));
}
template <typename R, typename A0>
Event<void(A0)> EventQueue::event(mbed::Callback<R(A0)> cb) {
return Event<void(A0)>(this, cb);
}
template <typename R, typename B0, typename C0, typename A0>
Event<void(A0)> EventQueue::event(R (*func)(B0, A0), C0 c0) {
return Event<void(A0)>(this, func, c0);
@ -2592,6 +2645,11 @@ Event<void(A0)> EventQueue::event(const volatile T *obj, R (T::*method)(B0, A0)
return Event<void(A0)>(this, mbed::callback(obj, method), c0);
}
template <typename R, typename B0, typename C0, typename A0>
Event<void(A0)> EventQueue::event(mbed::Callback<R(B0, A0)> cb, C0 c0) {
return Event<void(A0)>(this, cb, c0);
}
template <typename R, typename B0, typename B1, typename C0, typename C1, typename A0>
Event<void(A0)> EventQueue::event(R (*func)(B0, B1, A0), C0 c0, C1 c1) {
return Event<void(A0)>(this, func, c0, c1);
@ -2617,6 +2675,11 @@ Event<void(A0)> EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1,
return Event<void(A0)>(this, mbed::callback(obj, method), c0, c1);
}
template <typename R, typename B0, typename B1, typename C0, typename C1, typename A0>
Event<void(A0)> EventQueue::event(mbed::Callback<R(B0, B1, A0)> cb, C0 c0, C1 c1) {
return Event<void(A0)>(this, cb, c0, c1);
}
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0>
Event<void(A0)> EventQueue::event(R (*func)(B0, B1, B2, A0), C0 c0, C1 c1, C2 c2) {
return Event<void(A0)>(this, func, c0, c1, c2);
@ -2642,6 +2705,11 @@ Event<void(A0)> EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1,
return Event<void(A0)>(this, mbed::callback(obj, method), c0, c1, c2);
}
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0>
Event<void(A0)> EventQueue::event(mbed::Callback<R(B0, B1, B2, A0)> cb, C0 c0, C1 c1, C2 c2) {
return Event<void(A0)>(this, cb, c0, c1, c2);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0>
Event<void(A0)> EventQueue::event(R (*func)(B0, B1, B2, B3, A0), C0 c0, C1 c1, C2 c2, C3 c3) {
return Event<void(A0)>(this, func, c0, c1, c2, c3);
@ -2667,6 +2735,11 @@ Event<void(A0)> EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1,
return Event<void(A0)>(this, mbed::callback(obj, method), c0, c1, c2, c3);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0>
Event<void(A0)> EventQueue::event(mbed::Callback<R(B0, B1, B2, B3, A0)> cb, C0 c0, C1 c1, C2 c2, C3 c3) {
return Event<void(A0)>(this, cb, c0, c1, c2, c3);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0>
Event<void(A0)> EventQueue::event(R (*func)(B0, B1, B2, B3, B4, A0), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) {
return Event<void(A0)>(this, func, c0, c1, c2, c3, c4);
@ -2692,6 +2765,11 @@ Event<void(A0)> EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1,
return Event<void(A0)>(this, mbed::callback(obj, method), c0, c1, c2, c3, c4);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0>
Event<void(A0)> EventQueue::event(mbed::Callback<R(B0, B1, B2, B3, B4, A0)> cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) {
return Event<void(A0)>(this, cb, c0, c1, c2, c3, c4);
}
template <typename R, typename A0, typename A1>
Event<void(A0, A1)> EventQueue::event(R (*func)(A0, A1)) {
return Event<void(A0, A1)>(this, func);
@ -2717,6 +2795,11 @@ Event<void(A0, A1)> EventQueue::event(const volatile T *obj, R (T::*method)(A0,
return Event<void(A0, A1)>(this, mbed::callback(obj, method));
}
template <typename R, typename A0, typename A1>
Event<void(A0, A1)> EventQueue::event(mbed::Callback<R(A0, A1)> cb) {
return Event<void(A0, A1)>(this, cb);
}
template <typename R, typename B0, typename C0, typename A0, typename A1>
Event<void(A0, A1)> EventQueue::event(R (*func)(B0, A0, A1), C0 c0) {
return Event<void(A0, A1)>(this, func, c0);
@ -2742,6 +2825,11 @@ Event<void(A0, A1)> EventQueue::event(const volatile T *obj, R (T::*method)(B0,
return Event<void(A0, A1)>(this, mbed::callback(obj, method), c0);
}
template <typename R, typename B0, typename C0, typename A0, typename A1>
Event<void(A0, A1)> EventQueue::event(mbed::Callback<R(B0, A0, A1)> cb, C0 c0) {
return Event<void(A0, A1)>(this, cb, c0);
}
template <typename R, typename B0, typename B1, typename C0, typename C1, typename A0, typename A1>
Event<void(A0, A1)> EventQueue::event(R (*func)(B0, B1, A0, A1), C0 c0, C1 c1) {
return Event<void(A0, A1)>(this, func, c0, c1);
@ -2767,6 +2855,11 @@ Event<void(A0, A1)> EventQueue::event(const volatile T *obj, R (T::*method)(B0,
return Event<void(A0, A1)>(this, mbed::callback(obj, method), c0, c1);
}
template <typename R, typename B0, typename B1, typename C0, typename C1, typename A0, typename A1>
Event<void(A0, A1)> EventQueue::event(mbed::Callback<R(B0, B1, A0, A1)> cb, C0 c0, C1 c1) {
return Event<void(A0, A1)>(this, cb, c0, c1);
}
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0, typename A1>
Event<void(A0, A1)> EventQueue::event(R (*func)(B0, B1, B2, A0, A1), C0 c0, C1 c1, C2 c2) {
return Event<void(A0, A1)>(this, func, c0, c1, c2);
@ -2792,6 +2885,11 @@ Event<void(A0, A1)> EventQueue::event(const volatile T *obj, R (T::*method)(B0,
return Event<void(A0, A1)>(this, mbed::callback(obj, method), c0, c1, c2);
}
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0, typename A1>
Event<void(A0, A1)> EventQueue::event(mbed::Callback<R(B0, B1, B2, A0, A1)> cb, C0 c0, C1 c1, C2 c2) {
return Event<void(A0, A1)>(this, cb, c0, c1, c2);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0, typename A1>
Event<void(A0, A1)> EventQueue::event(R (*func)(B0, B1, B2, B3, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3) {
return Event<void(A0, A1)>(this, func, c0, c1, c2, c3);
@ -2817,6 +2915,11 @@ Event<void(A0, A1)> EventQueue::event(const volatile T *obj, R (T::*method)(B0,
return Event<void(A0, A1)>(this, mbed::callback(obj, method), c0, c1, c2, c3);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0, typename A1>
Event<void(A0, A1)> EventQueue::event(mbed::Callback<R(B0, B1, B2, B3, A0, A1)> cb, C0 c0, C1 c1, C2 c2, C3 c3) {
return Event<void(A0, A1)>(this, cb, c0, c1, c2, c3);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0, typename A1>
Event<void(A0, A1)> EventQueue::event(R (*func)(B0, B1, B2, B3, B4, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) {
return Event<void(A0, A1)>(this, func, c0, c1, c2, c3, c4);
@ -2842,6 +2945,11 @@ Event<void(A0, A1)> EventQueue::event(const volatile T *obj, R (T::*method)(B0,
return Event<void(A0, A1)>(this, mbed::callback(obj, method), c0, c1, c2, c3, c4);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0, typename A1>
Event<void(A0, A1)> EventQueue::event(mbed::Callback<R(B0, B1, B2, B3, B4, A0, A1)> cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) {
return Event<void(A0, A1)>(this, cb, c0, c1, c2, c3, c4);
}
template <typename R, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> EventQueue::event(R (*func)(A0, A1, A2)) {
return Event<void(A0, A1, A2)>(this, func);
@ -2867,6 +2975,11 @@ Event<void(A0, A1, A2)> EventQueue::event(const volatile T *obj, R (T::*method)(
return Event<void(A0, A1, A2)>(this, mbed::callback(obj, method));
}
template <typename R, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> EventQueue::event(mbed::Callback<R(A0, A1, A2)> cb) {
return Event<void(A0, A1, A2)>(this, cb);
}
template <typename R, typename B0, typename C0, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> EventQueue::event(R (*func)(B0, A0, A1, A2), C0 c0) {
return Event<void(A0, A1, A2)>(this, func, c0);
@ -2892,6 +3005,11 @@ Event<void(A0, A1, A2)> EventQueue::event(const volatile T *obj, R (T::*method)(
return Event<void(A0, A1, A2)>(this, mbed::callback(obj, method), c0);
}
template <typename R, typename B0, typename C0, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> EventQueue::event(mbed::Callback<R(B0, A0, A1, A2)> cb, C0 c0) {
return Event<void(A0, A1, A2)>(this, cb, c0);
}
template <typename R, typename B0, typename B1, typename C0, typename C1, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> EventQueue::event(R (*func)(B0, B1, A0, A1, A2), C0 c0, C1 c1) {
return Event<void(A0, A1, A2)>(this, func, c0, c1);
@ -2917,6 +3035,11 @@ Event<void(A0, A1, A2)> EventQueue::event(const volatile T *obj, R (T::*method)(
return Event<void(A0, A1, A2)>(this, mbed::callback(obj, method), c0, c1);
}
template <typename R, typename B0, typename B1, typename C0, typename C1, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> EventQueue::event(mbed::Callback<R(B0, B1, A0, A1, A2)> cb, C0 c0, C1 c1) {
return Event<void(A0, A1, A2)>(this, cb, c0, c1);
}
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> EventQueue::event(R (*func)(B0, B1, B2, A0, A1, A2), C0 c0, C1 c1, C2 c2) {
return Event<void(A0, A1, A2)>(this, func, c0, c1, c2);
@ -2942,6 +3065,11 @@ Event<void(A0, A1, A2)> EventQueue::event(const volatile T *obj, R (T::*method)(
return Event<void(A0, A1, A2)>(this, mbed::callback(obj, method), c0, c1, c2);
}
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> EventQueue::event(mbed::Callback<R(B0, B1, B2, A0, A1, A2)> cb, C0 c0, C1 c1, C2 c2) {
return Event<void(A0, A1, A2)>(this, cb, c0, c1, c2);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> EventQueue::event(R (*func)(B0, B1, B2, B3, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3) {
return Event<void(A0, A1, A2)>(this, func, c0, c1, c2, c3);
@ -2967,6 +3095,11 @@ Event<void(A0, A1, A2)> EventQueue::event(const volatile T *obj, R (T::*method)(
return Event<void(A0, A1, A2)>(this, mbed::callback(obj, method), c0, c1, c2, c3);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> EventQueue::event(mbed::Callback<R(B0, B1, B2, B3, A0, A1, A2)> cb, C0 c0, C1 c1, C2 c2, C3 c3) {
return Event<void(A0, A1, A2)>(this, cb, c0, c1, c2, c3);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> EventQueue::event(R (*func)(B0, B1, B2, B3, B4, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) {
return Event<void(A0, A1, A2)>(this, func, c0, c1, c2, c3, c4);
@ -2992,6 +3125,11 @@ Event<void(A0, A1, A2)> EventQueue::event(const volatile T *obj, R (T::*method)(
return Event<void(A0, A1, A2)>(this, mbed::callback(obj, method), c0, c1, c2, c3, c4);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> EventQueue::event(mbed::Callback<R(B0, B1, B2, B3, B4, A0, A1, A2)> cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) {
return Event<void(A0, A1, A2)>(this, cb, c0, c1, c2, c3, c4);
}
template <typename R, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> EventQueue::event(R (*func)(A0, A1, A2, A3)) {
return Event<void(A0, A1, A2, A3)>(this, func);
@ -3017,6 +3155,11 @@ Event<void(A0, A1, A2, A3)> EventQueue::event(const volatile T *obj, R (T::*meth
return Event<void(A0, A1, A2, A3)>(this, mbed::callback(obj, method));
}
template <typename R, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> EventQueue::event(mbed::Callback<R(A0, A1, A2, A3)> cb) {
return Event<void(A0, A1, A2, A3)>(this, cb);
}
template <typename R, typename B0, typename C0, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> EventQueue::event(R (*func)(B0, A0, A1, A2, A3), C0 c0) {
return Event<void(A0, A1, A2, A3)>(this, func, c0);
@ -3042,6 +3185,11 @@ Event<void(A0, A1, A2, A3)> EventQueue::event(const volatile T *obj, R (T::*meth
return Event<void(A0, A1, A2, A3)>(this, mbed::callback(obj, method), c0);
}
template <typename R, typename B0, typename C0, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> EventQueue::event(mbed::Callback<R(B0, A0, A1, A2, A3)> cb, C0 c0) {
return Event<void(A0, A1, A2, A3)>(this, cb, c0);
}
template <typename R, typename B0, typename B1, typename C0, typename C1, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> EventQueue::event(R (*func)(B0, B1, A0, A1, A2, A3), C0 c0, C1 c1) {
return Event<void(A0, A1, A2, A3)>(this, func, c0, c1);
@ -3067,6 +3215,11 @@ Event<void(A0, A1, A2, A3)> EventQueue::event(const volatile T *obj, R (T::*meth
return Event<void(A0, A1, A2, A3)>(this, mbed::callback(obj, method), c0, c1);
}
template <typename R, typename B0, typename B1, typename C0, typename C1, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> EventQueue::event(mbed::Callback<R(B0, B1, A0, A1, A2, A3)> cb, C0 c0, C1 c1) {
return Event<void(A0, A1, A2, A3)>(this, cb, c0, c1);
}
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> EventQueue::event(R (*func)(B0, B1, B2, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2) {
return Event<void(A0, A1, A2, A3)>(this, func, c0, c1, c2);
@ -3092,6 +3245,11 @@ Event<void(A0, A1, A2, A3)> EventQueue::event(const volatile T *obj, R (T::*meth
return Event<void(A0, A1, A2, A3)>(this, mbed::callback(obj, method), c0, c1, c2);
}
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> EventQueue::event(mbed::Callback<R(B0, B1, B2, A0, A1, A2, A3)> cb, C0 c0, C1 c1, C2 c2) {
return Event<void(A0, A1, A2, A3)>(this, cb, c0, c1, c2);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> EventQueue::event(R (*func)(B0, B1, B2, B3, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3) {
return Event<void(A0, A1, A2, A3)>(this, func, c0, c1, c2, c3);
@ -3117,6 +3275,11 @@ Event<void(A0, A1, A2, A3)> EventQueue::event(const volatile T *obj, R (T::*meth
return Event<void(A0, A1, A2, A3)>(this, mbed::callback(obj, method), c0, c1, c2, c3);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> EventQueue::event(mbed::Callback<R(B0, B1, B2, B3, A0, A1, A2, A3)> cb, C0 c0, C1 c1, C2 c2, C3 c3) {
return Event<void(A0, A1, A2, A3)>(this, cb, c0, c1, c2, c3);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> EventQueue::event(R (*func)(B0, B1, B2, B3, B4, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) {
return Event<void(A0, A1, A2, A3)>(this, func, c0, c1, c2, c3, c4);
@ -3142,6 +3305,11 @@ Event<void(A0, A1, A2, A3)> EventQueue::event(const volatile T *obj, R (T::*meth
return Event<void(A0, A1, A2, A3)>(this, mbed::callback(obj, method), c0, c1, c2, c3, c4);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> EventQueue::event(mbed::Callback<R(B0, B1, B2, B3, B4, A0, A1, A2, A3)> cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) {
return Event<void(A0, A1, A2, A3)>(this, cb, c0, c1, c2, c3, c4);
}
template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> EventQueue::event(R (*func)(A0, A1, A2, A3, A4)) {
return Event<void(A0, A1, A2, A3, A4)>(this, func);
@ -3167,6 +3335,11 @@ Event<void(A0, A1, A2, A3, A4)> EventQueue::event(const volatile T *obj, R (T::*
return Event<void(A0, A1, A2, A3, A4)>(this, mbed::callback(obj, method));
}
template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> EventQueue::event(mbed::Callback<R(A0, A1, A2, A3, A4)> cb) {
return Event<void(A0, A1, A2, A3, A4)>(this, cb);
}
template <typename R, typename B0, typename C0, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> EventQueue::event(R (*func)(B0, A0, A1, A2, A3, A4), C0 c0) {
return Event<void(A0, A1, A2, A3, A4)>(this, func, c0);
@ -3192,6 +3365,11 @@ Event<void(A0, A1, A2, A3, A4)> EventQueue::event(const volatile T *obj, R (T::*
return Event<void(A0, A1, A2, A3, A4)>(this, mbed::callback(obj, method), c0);
}
template <typename R, typename B0, typename C0, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> EventQueue::event(mbed::Callback<R(B0, A0, A1, A2, A3, A4)> cb, C0 c0) {
return Event<void(A0, A1, A2, A3, A4)>(this, cb, c0);
}
template <typename R, typename B0, typename B1, typename C0, typename C1, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> EventQueue::event(R (*func)(B0, B1, A0, A1, A2, A3, A4), C0 c0, C1 c1) {
return Event<void(A0, A1, A2, A3, A4)>(this, func, c0, c1);
@ -3217,6 +3395,11 @@ Event<void(A0, A1, A2, A3, A4)> EventQueue::event(const volatile T *obj, R (T::*
return Event<void(A0, A1, A2, A3, A4)>(this, mbed::callback(obj, method), c0, c1);
}
template <typename R, typename B0, typename B1, typename C0, typename C1, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> EventQueue::event(mbed::Callback<R(B0, B1, A0, A1, A2, A3, A4)> cb, C0 c0, C1 c1) {
return Event<void(A0, A1, A2, A3, A4)>(this, cb, c0, c1);
}
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> EventQueue::event(R (*func)(B0, B1, B2, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2) {
return Event<void(A0, A1, A2, A3, A4)>(this, func, c0, c1, c2);
@ -3242,6 +3425,11 @@ Event<void(A0, A1, A2, A3, A4)> EventQueue::event(const volatile T *obj, R (T::*
return Event<void(A0, A1, A2, A3, A4)>(this, mbed::callback(obj, method), c0, c1, c2);
}
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> EventQueue::event(mbed::Callback<R(B0, B1, B2, A0, A1, A2, A3, A4)> cb, C0 c0, C1 c1, C2 c2) {
return Event<void(A0, A1, A2, A3, A4)>(this, cb, c0, c1, c2);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> EventQueue::event(R (*func)(B0, B1, B2, B3, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3) {
return Event<void(A0, A1, A2, A3, A4)>(this, func, c0, c1, c2, c3);
@ -3267,6 +3455,11 @@ Event<void(A0, A1, A2, A3, A4)> EventQueue::event(const volatile T *obj, R (T::*
return Event<void(A0, A1, A2, A3, A4)>(this, mbed::callback(obj, method), c0, c1, c2, c3);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> EventQueue::event(mbed::Callback<R(B0, B1, B2, B3, A0, A1, A2, A3, A4)> cb, C0 c0, C1 c1, C2 c2, C3 c3) {
return Event<void(A0, A1, A2, A3, A4)>(this, cb, c0, c1, c2, c3);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> EventQueue::event(R (*func)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) {
return Event<void(A0, A1, A2, A3, A4)>(this, func, c0, c1, c2, c3, c4);
@ -3292,6 +3485,11 @@ Event<void(A0, A1, A2, A3, A4)> EventQueue::event(const volatile T *obj, R (T::*
return Event<void(A0, A1, A2, A3, A4)>(this, mbed::callback(obj, method), c0, c1, c2, c3, c4);
}
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> EventQueue::event(mbed::Callback<R(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4)> cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) {
return Event<void(A0, A1, A2, A3, A4)>(this, cb, c0, c1, c2, c3, c4);
}
}
#endif

View File

@ -944,7 +944,10 @@ public:
* context of the event queue's dispatch loop once posted.
*
* @param f Function to execute when the event is dispatched
* @param a0..a4 Arguments to pass to the callback
* @param c0..c4 Arguments to bind to the callback, these arguments are
* allocated on an irq-safe allocator from the event queue's
* memory pool. Must be type-compatible with b0..b4, the
* arguments to the underlying callback.
* @return Event that will dispatch on the specific queue
*/
template <typename R>
@ -974,6 +977,12 @@ public:
template <typename T, typename R>
Event<void()> event(const volatile T *obj, R (T::*method)() const volatile);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R>
Event<void()> event(mbed::Callback<R()> cb);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1004,6 +1013,12 @@ public:
template <typename T, typename R, typename B0, typename C0>
Event<void()> event(const volatile T *obj, R (T::*method)(B0) const volatile, C0 c0);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename C0>
Event<void()> event(mbed::Callback<R(B0)> cb, C0 c0);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1034,6 +1049,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename C0, typename C1>
Event<void()> event(const volatile T *obj, R (T::*method)(B0, B1) const volatile, C0 c0, C1 c1);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename C0, typename C1>
Event<void()> event(mbed::Callback<R(B0, B1)> cb, C0 c0, C1 c1);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1064,6 +1085,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2>
Event<void()> event(const volatile T *obj, R (T::*method)(B0, B1, B2) const volatile, C0 c0, C1 c1, C2 c2);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2>
Event<void()> event(mbed::Callback<R(B0, B1, B2)> cb, C0 c0, C1 c1, C2 c2);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1094,6 +1121,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3>
Event<void()> event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3) const volatile, C0 c0, C1 c1, C2 c2, C3 c3);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3>
Event<void()> event(mbed::Callback<R(B0, B1, B2, B3)> cb, C0 c0, C1 c1, C2 c2, C3 c3);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1124,6 +1157,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4>
Event<void()> event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4) const volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4>
Event<void()> event(mbed::Callback<R(B0, B1, B2, B3, B4)> cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1154,6 +1193,12 @@ public:
template <typename T, typename R, typename A0>
Event<void(A0)> event(const volatile T *obj, R (T::*method)(A0) const volatile);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename A0>
Event<void(A0)> event(mbed::Callback<R(A0)> cb);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1184,6 +1229,12 @@ public:
template <typename T, typename R, typename B0, typename C0, typename A0>
Event<void(A0)> event(const volatile T *obj, R (T::*method)(B0, A0) const volatile, C0 c0);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename C0, typename A0>
Event<void(A0)> event(mbed::Callback<R(B0, A0)> cb, C0 c0);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1214,6 +1265,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename A0>
Event<void(A0)> event(const volatile T *obj, R (T::*method)(B0, B1, A0) const volatile, C0 c0, C1 c1);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename C0, typename C1, typename A0>
Event<void(A0)> event(mbed::Callback<R(B0, B1, A0)> cb, C0 c0, C1 c1);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1244,6 +1301,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0>
Event<void(A0)> event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0) const volatile, C0 c0, C1 c1, C2 c2);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0>
Event<void(A0)> event(mbed::Callback<R(B0, B1, B2, A0)> cb, C0 c0, C1 c1, C2 c2);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1274,6 +1337,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0>
Event<void(A0)> event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0) const volatile, C0 c0, C1 c1, C2 c2, C3 c3);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0>
Event<void(A0)> event(mbed::Callback<R(B0, B1, B2, B3, A0)> cb, C0 c0, C1 c1, C2 c2, C3 c3);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1304,6 +1373,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0>
Event<void(A0)> event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0) const volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0>
Event<void(A0)> event(mbed::Callback<R(B0, B1, B2, B3, B4, A0)> cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1334,6 +1409,12 @@ public:
template <typename T, typename R, typename A0, typename A1>
Event<void(A0, A1)> event(const volatile T *obj, R (T::*method)(A0, A1) const volatile);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename A0, typename A1>
Event<void(A0, A1)> event(mbed::Callback<R(A0, A1)> cb);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1364,6 +1445,12 @@ public:
template <typename T, typename R, typename B0, typename C0, typename A0, typename A1>
Event<void(A0, A1)> event(const volatile T *obj, R (T::*method)(B0, A0, A1) const volatile, C0 c0);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename C0, typename A0, typename A1>
Event<void(A0, A1)> event(mbed::Callback<R(B0, A0, A1)> cb, C0 c0);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1394,6 +1481,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename A0, typename A1>
Event<void(A0, A1)> event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1) const volatile, C0 c0, C1 c1);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename C0, typename C1, typename A0, typename A1>
Event<void(A0, A1)> event(mbed::Callback<R(B0, B1, A0, A1)> cb, C0 c0, C1 c1);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1424,6 +1517,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0, typename A1>
Event<void(A0, A1)> event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1) const volatile, C0 c0, C1 c1, C2 c2);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0, typename A1>
Event<void(A0, A1)> event(mbed::Callback<R(B0, B1, B2, A0, A1)> cb, C0 c0, C1 c1, C2 c2);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1454,6 +1553,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0, typename A1>
Event<void(A0, A1)> event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) const volatile, C0 c0, C1 c1, C2 c2, C3 c3);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0, typename A1>
Event<void(A0, A1)> event(mbed::Callback<R(B0, B1, B2, B3, A0, A1)> cb, C0 c0, C1 c1, C2 c2, C3 c3);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1484,6 +1589,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0, typename A1>
Event<void(A0, A1)> event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1) const volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0, typename A1>
Event<void(A0, A1)> event(mbed::Callback<R(B0, B1, B2, B3, B4, A0, A1)> cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1514,6 +1625,12 @@ public:
template <typename T, typename R, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> event(const volatile T *obj, R (T::*method)(A0, A1, A2) const volatile);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> event(mbed::Callback<R(A0, A1, A2)> cb);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1544,6 +1661,12 @@ public:
template <typename T, typename R, typename B0, typename C0, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> event(const volatile T *obj, R (T::*method)(B0, A0, A1, A2) const volatile, C0 c0);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename C0, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> event(mbed::Callback<R(B0, A0, A1, A2)> cb, C0 c0);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1574,6 +1697,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2) const volatile, C0 c0, C1 c1);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename C0, typename C1, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> event(mbed::Callback<R(B0, B1, A0, A1, A2)> cb, C0 c0, C1 c1);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1604,6 +1733,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) const volatile, C0 c0, C1 c1, C2 c2);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> event(mbed::Callback<R(B0, B1, B2, A0, A1, A2)> cb, C0 c0, C1 c1, C2 c2);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1634,6 +1769,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2) const volatile, C0 c0, C1 c1, C2 c2, C3 c3);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> event(mbed::Callback<R(B0, B1, B2, B3, A0, A1, A2)> cb, C0 c0, C1 c1, C2 c2, C3 c3);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1664,6 +1805,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) const volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0, typename A1, typename A2>
Event<void(A0, A1, A2)> event(mbed::Callback<R(B0, B1, B2, B3, B4, A0, A1, A2)> cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1694,6 +1841,12 @@ public:
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> event(const volatile T *obj, R (T::*method)(A0, A1, A2, A3) const volatile);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> event(mbed::Callback<R(A0, A1, A2, A3)> cb);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1724,6 +1877,12 @@ public:
template <typename T, typename R, typename B0, typename C0, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> event(const volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3) const volatile, C0 c0);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename C0, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> event(mbed::Callback<R(B0, A0, A1, A2, A3)> cb, C0 c0);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1754,6 +1913,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) const volatile, C0 c0, C1 c1);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename C0, typename C1, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> event(mbed::Callback<R(B0, B1, A0, A1, A2, A3)> cb, C0 c0, C1 c1);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1784,6 +1949,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) const volatile, C0 c0, C1 c1, C2 c2);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> event(mbed::Callback<R(B0, B1, B2, A0, A1, A2, A3)> cb, C0 c0, C1 c1, C2 c2);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1814,6 +1985,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) const volatile, C0 c0, C1 c1, C2 c2, C3 c3);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> event(mbed::Callback<R(B0, B1, B2, B3, A0, A1, A2, A3)> cb, C0 c0, C1 c1, C2 c2, C3 c3);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1844,6 +2021,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) const volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0, typename A1, typename A2, typename A3>
Event<void(A0, A1, A2, A3)> event(mbed::Callback<R(B0, B1, B2, B3, B4, A0, A1, A2, A3)> cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1874,6 +2057,12 @@ public:
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> event(const volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> event(mbed::Callback<R(A0, A1, A2, A3, A4)> cb);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1904,6 +2093,12 @@ public:
template <typename T, typename R, typename B0, typename C0, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> event(const volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) const volatile, C0 c0);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename C0, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> event(mbed::Callback<R(B0, A0, A1, A2, A3, A4)> cb, C0 c0);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1934,6 +2129,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) const volatile, C0 c0, C1 c1);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename C0, typename C1, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> event(mbed::Callback<R(B0, B1, A0, A1, A2, A3, A4)> cb, C0 c0, C1 c1);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1964,6 +2165,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) const volatile, C0 c0, C1 c1, C2 c2);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> event(mbed::Callback<R(B0, B1, B2, A0, A1, A2, A3, A4)> cb, C0 c0, C1 c1, C2 c2);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -1994,6 +2201,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) const volatile, C0 c0, C1 c1, C2 c2, C3 c3);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> event(mbed::Callback<R(B0, B1, B2, B3, A0, A1, A2, A3, A4)> cb, C0 c0, C1 c1, C2 c2, C3 c3);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
@ -2024,6 +2237,12 @@ public:
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) const volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
/** Creates an event bound to the event queue
* @see EventQueue::event
*/
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename A0, typename A1, typename A2, typename A3, typename A4>
Event<void(A0, A1, A2, A3, A4)> event(mbed::Callback<R(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4)> cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
protected:
template <typename F>
friend class Event;

View File

@ -26,15 +26,15 @@
// Ticker operations
static bool equeue_tick_inited = false;
static unsigned equeue_minutes = 0;
static volatile unsigned equeue_minutes = 0;
static unsigned equeue_timer[
(sizeof(Timer)+sizeof(unsigned)-1)/sizeof(unsigned)];
static unsigned equeue_ticker[
(sizeof(Ticker)+sizeof(unsigned)-1)/sizeof(unsigned)];
static void equeue_tick_update() {
equeue_minutes += reinterpret_cast<Timer*>(equeue_timer)->read_ms();
reinterpret_cast<Timer*>(equeue_timer)->reset();
equeue_minutes += 1;
}
static void equeue_tick_init() {
@ -48,7 +48,7 @@ static void equeue_tick_init() {
equeue_minutes = 0;
reinterpret_cast<Timer*>(equeue_timer)->start();
reinterpret_cast<Ticker*>(equeue_ticker)
->attach_us(equeue_tick_update, (1 << 16)*1000);
->attach_us(equeue_tick_update, 1000 << 16);
equeue_tick_inited = true;
}
@ -58,8 +58,15 @@ unsigned equeue_tick() {
equeue_tick_init();
}
unsigned equeue_ms = reinterpret_cast<Timer*>(equeue_timer)->read_ms();
return (equeue_minutes << 16) + equeue_ms;
unsigned minutes;
unsigned ms;
do {
minutes = equeue_minutes;
ms = reinterpret_cast<Timer*>(equeue_timer)->read_ms();
} while (minutes != equeue_minutes);
return minutes + ms;
}

View File

@ -20,6 +20,7 @@ import socket
import json
import random
import itertools
import time
from sys import stdout
from threading import Thread
from SocketServer import BaseRequestHandler, UDPServer
@ -42,6 +43,9 @@ class UDPEchoClientHandler(BaseRequestHandler):
data = ''.join(map(chr, data))
sock.sendto(data, self.client_address)
# Sleep a tiny bit to compensate for local network
time.sleep(0.01)
class UDPEchoClientTest(BaseHostTest):
def __init__(self):

View File

@ -87,6 +87,11 @@ static void mbed_lwip_arena_dealloc(struct lwip_socket *s)
static void mbed_lwip_socket_callback(struct netconn *nc, enum netconn_evt eh, u16_t len)
{
// Filter send minus events
if (eh == NETCONN_EVT_SENDMINUS && nc->state == NETCONN_WRITE) {
return;
}
sys_prot_t prot = sys_arch_protect();
for (int i = 0; i < MEMP_NUM_NETCONN; i++) {

View File

@ -26,6 +26,8 @@
#include "NanostackEthernetInterface.h"
#include "MeshInterfaceNanostack.h"
struct ns_address;
class NanostackInterface : public NetworkStack {
public:
static NanostackInterface *get_stack();
@ -229,6 +231,8 @@ protected:
virtual nsapi_error_t getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen);
private:
nsapi_size_or_error_t do_sendto(void *handle, const struct ns_address *address, const void *data, nsapi_size_t size);
char text_ip_address[40];
static NanostackInterface * _ns_interface;
};

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2017 ARM Limited. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NANOSTACK_LOCK_GUARD_H_
#define NANOSTACK_LOCK_GUARD_H_
#include "eventOS_scheduler.h"
/**
* RAII style Nanostack mutex acquisition.
* Mutex is held until object leaves scope.
*/
class NanostackLockGuard {
public:
NanostackLockGuard() {
eventOS_scheduler_mutex_wait();
}
~NanostackLockGuard() {
eventOS_scheduler_mutex_release();
}
private:
NanostackLockGuard(const NanostackLockGuard&);
NanostackLockGuard& operator=(const NanostackLockGuard&);
};
#endif /* NANOSTACK_LOCK_GUARD_H_ */

View File

@ -82,16 +82,17 @@ Member|Description
Event type|Description
----------|-----------
`SOCKET_DATA`|Data received.
`SOCKET_BIND_DONE`|TCP connection ready.
`SOCKET_BIND_FAIL`|TCP connection failed.
`SOCKET_BIND_AUTH_FAIL`|TCP connection authentication failed.
`SOCKET_CONNECT_DONE`|TCP connection ready.
`SOCKET_CONNECT_FAIL`|TCP connection failed.
`SOCKET_CONNECT_AUTH_FAIL`|TCP connection authentication failed.
`SOCKET_INCOMING_CONNECTION`|TCP connection state change from listen to establishment.
`SOCKET_TX_FAIL`|Socket data send failed.
`SOCKET_CONNECT_CLOSED`|TCP connection closed.
`SOCKET_CONNECTION_RESET`|TCP connection reset.
`SOCKET_NO_ROUTER`|No route available to destination.
`SOCKET_TX_DONE`|Last socket TX process done, in TCP case whole TCP process is ready.
`SOCKET_TX_DONE`|TX process done (one per datagram, or if stream will be called each time some data acknowledged)
`SOCKET_NO_RAM `|If no RAM is present.
`SOCKET_CONNECTION_PROBLEM`|If TCP is suffering a connection problem (a soft event, it continues to retry).
An example parsing socket event:
@ -102,7 +103,7 @@ An example parsing socket event:
static uint8_t rx_buffer[APP_SOCK_RX_SIZE];
void main_receive
(
(SOCKET_NO_ROUTER
void *cb
)
{
@ -248,6 +249,31 @@ Parameter|Description
<dd>-6 bind2addrsel is not supported on this type of socket.</dd>
</dl>
### How to connect a socket
To connect a socket to a remote host:
```
int8_t socket_connect
(
int8_t socket,
ns_address_t *address,
uint8_t randomly_take_src_numbers
)
```
Parameter|Description
---------|-----------
`socket`|The socket ID, which is used to connect to the remote host.
`address`|A pointer to an <code>address_t</code> structure that contains the address of the remote host.
`randomly_take_src_numbers`|Value 1 indicates that a randomly selected source port number is used.
<dl>
<dt>Return value</dt>
<dd>0 Valid request.</dd>
<dd>-1 Fail.</dd>
</dl>
### How to read data from a socket
To read received data from a socket:
@ -300,9 +326,9 @@ _Table 3-24_ describes the possible response events when the outcome of the func
Response Event|Socket Type|Description
--------------|-----------|-----------
`SOCKET_TX_DONE`|TCP/UDP|UDP link layer TX ready/TCP TX process ready by TCP _Acknowledgement_ (ACK).
`SOCKET_TX_FAIL`|UDP|UDP link layer TX fails.
`SOCKET_CONNECTION_RESET`|TCP|TX process fails and connection closed.
`SOCKET_TX_DONE`|TCP/UDP|UDP: link layer TX ready (d_len = length of datagram). TCP: some data acknowledged (d_len = unacknowledged data remaining in send queue).
`SOCKET_TX_FAIL`|TCP/UDP|UDP: link layer TX fails. TCP: transmit timeout (no ACKs) and connection closed.
`SOCKET_CONNECTION_RESET`|TCP|Either the peer reset the connection or there was a protocol error. Connection closed.
To transmit data on an unconnected socket:
@ -364,7 +390,7 @@ The TCP socket configuration API offers three function calls, as shown in _Table
Function|Description
--------|-----------
`socket_listen()`|Set socket to the listen state.
`socket_connect()`|Connect socket to a host.
`socket_accept()`|Accepts an incoming TCP connection.
`socket_shutdown()`|Shut down socket connection.
To set a TCP socket into the listen state:
@ -380,47 +406,50 @@ int8_t socket_listen
Parameter|Description
---------|-----------
`socket`|The socket ID that is to be set to the listen state.
`backlog`|The pending connections queue size. (Not yet implemented).
`backlog`|The pending connections queue size.
<dl>
<dt>Return value</dt>
<dd>0 Valid request.</dd>
<dd><b>Note:</b> This does not imply that the state of the socket has been successfully changed.</dd>
<dd>-1 Fail.</dd>
</dl>
To connect a socket to a remote host:
For connecting a socket, please refer to the section above [How to connect a socket](#how-to-connect-a-socket).
There are three possible responses from the stack for `socket_connect( )`:
- `SOCKET_CONNECT_DONE`
- TCP handshake ready.
- `SOCKET_CONNECT_FAIL`
- TCP handshake fail - connection actively refused or protocol error.
- `SOCKET_TX_FAIL`
- TCP handshake fail - timed out.
For accepting an incoming TCP connection, use `socket_accept()` function.
```
int8_t socket_connect
int8_t socket_accept()
(
int8_t socket,
ns_address_t *address,
uint8_t randomly_take_src_numbers
int8_t listen_socket_id,
ns_address_t *addr,
void (*passed_fptr) (void *)
)
```
Parameter|Description
---------|-----------
`socket`|The socket ID, which is used to connect to the remote host.
`address`|A pointer to an <code>address_t</code> structure that contains the address of the remote host.
`randomly_take_src_numbers`|Value 1 indicates that a randomly selected source port number is used.
`listen_socket_id`|The socket ID of the listening socket.
`addr`|Pointer to the address structure where you wish to save the address
`passed_fptr`|A function pointer to a function that is called whenever a data frame is received to the new socket
<dl>
<dt>Return value</dt>
<dd>0 Valid request.</dd>
<dd><b>Note:</b>This does not imply that the state of the socket has been successfully changed.</dd>
<dd>0 or greter than zero, i.e., id for the new socket.</dd>
<dd>-1 Fail.</dd>
</dl>
There are two possible responses from the stack for `socket_connect( )`:
- `SOCKET_BIND_DONE`
- TCP handshake ready.
- `SOCKET_CONNECT_FAIL_CLOSED`
- TCP handshake fail.
To shut down a TCP connection:
```

View File

@ -59,7 +59,9 @@ initializing.
![NanostackRfPhy](img/NanostackRfPhy.png)
Applications use only `LoWPANNDInterface` or `ThreadInterface` directly to set up the network and provide a driver. Rest of the classes provide an abstration between Nanostack and Socket layers of mbed OS.
Applications use only `LoWPANNDInterface`, `ThreadInterface` or `NanostackEthernetInterface`
directly to set up the network and provide a driver. Rest of the classes provide an abstration
between Nanostack and Socket layers of mbed OS.
See [NanostackRfPhy.h](https://github.com/ARMmbed/mbed-os/blob/master/features/nanostack/FEATURE_NANOSTACK/nanostack-interface/NanostackRfPhy.h) for an up-to-date header file and API.

View File

@ -1,28 +1,66 @@
@startuml
class NanostackRfPhy {
+int8_t rf_register()
+int8_t rf_register()
+void get_mac_address(uint8_t *mac)
+void set_mac_address(uint8_t *mac)
package "mbed OS Socket abstraction" {
abstract class MeshInterface -|> NetworkInterface
interface NetworkInterface {
+connect();
+disconnect();
+NetworkStack *get_stack();
}
interface NetworkStack
}
class MeshInterfaceNanostack {
package "Nanostack PHY driver interface" {
interface NanostackPhy {
+int8_t phy_register()
+void get_mac_address(uint8_t *mac)
+void set_mac_address(uint8_t *mac)
}
NanostackPhy <|-- abstract class NanostackRfPhy
NanostackPhy <|-- abstract class NanostackEthernetPhy
}
MeshInterfaceNanostack o-- NanostackRfPhy
MeshInterfaceNanostack o-- AbstractMesh
MeshInterfaceNanostack o-- NanostackInterface
class MeshInterface {
package "mesh API internals" {
class NanostackInterface {
{static} +NanostackInterface *get_stack()
#socket_open()
#socket_close()
#socket_bind()
#socket_listen()
#socket_connect()
#socket_accept()
#socket_send()
#socket_recv()
#socket_sendto()
#socket_recvfrom()
#socket_attach()
#setsockopt()
#getsockopt()
}
NetworkStack <|-- NanostackInterface
abstract class MeshInterfaceNanostack {
+initialize(NanostackPhy *phy)
+connect()
+disconnect()
#NetworkStack *get_stack(void)
}
MeshInterface <|-- MeshInterfaceNanostack
NanostackPhy --o MeshInterfaceNanostack
MeshInterfaceNanostack -left-> NanostackInterface : get_stack()
}
NanostackInterface --|> NetworkStack
MeshInterfaceNanostack --|> MeshInterface
MeshInterface --|> NetworkInterface
LoWPANNDInterface --|> MeshInterfaceNanostack
ThreadInterface --|> MeshInterfaceNanostack
package "mbed-mesh-api" {
MeshInterfaceNanostack <|-- LoWPANNDInterface
MeshInterfaceNanostack <|-- ThreadInterface
MeshInterfaceNanostack <|-- NanostackEthernetInterface
}
AbstractMesh --|> AbstractNetworkInterface
class AbstractNetworkInterface
@enduml
hide empty members
hide empty attributes
hide empty fields
@enduml

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,28 @@
@startuml
package "mbed OS Socket abstraction" {
interface NetworkStack
NetworkStack -o Socket
abstract class Socket
Socket <|-- UDPSocket
Socket <|-- TCPSocket
Socket <|-- TCPServer
}
interface NetworkInterface
NetworkInterface --> NetworkStack : get_stack()
EthernetInterface --|> NetworkInterface
CellularInterface --|> NetworkInterface
package "mbed-mesh-api" {
abstract class MeshInterfaceNanostack <|-- LoWPANNDInterface
MeshInterfaceNanostack <|-- ThreadInterface
MeshInterfaceNanostack --|> NetworkInterface
}
hide empty members
hide empty attributes
hide empty fields
@enduml

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View File

@ -380,14 +380,37 @@ Parameter|Description
### Collecting Thread management information
The function `thread_management_info_get()` is used to collect Thread management related information from the Leader Router.
#### Fetching Thread Management Information
The function `thread_management_get()` is used to collect Thread management related information from the any device in the Thread network.
Parameter|Description
-----------|-----------
`instance_id`|Instance ID of the management session.
`fields_ptr`|A pointer to management fields from which the information is fetched.
`field_count`|Number of fields in the field pointer array.
`cb_ptr`|A pointer to `management_get_response_cb` callback function.
`dst_addr` |Destination address; the address of a remote device from whome it is desirable to fetch management information. If however, the address is not provided, a request is sent to the leader of the network for this purpose. If a native commissioner is used, the request for management information is sent to the border router.
`uri_ptr` |The ASCII string for the URI. This string identifies the CoAP URI for the desired resource. For example, `/c/mg` identifies the management get information resource.
`fields_ptr`|A pointer to management fields; a set of TLVs. A list of such TLVs can be found in `thread_meshcop_lib.h`.
`field_count`|Number of fields in the field pointer array (set of TLVs).
`cb_ptr`|A pointer to `management_get_response_cb` callback function carrying the result of the operation.
<dl>
<dt>Response</dt>
<dd> 0, success.</dd>
<dd><0, failure.</dd>
</dl>
#### Setting up Thread Management Information
The function `thread_management_set()` is used to set up Thread management related information to any device in the Thread network.
Parameter|Description
-----------|-----------
`instance_id`|Instance ID of the management session.
`dst_addr` |Destination address; the address of a remote device where it is desired to set up management information. If however, the address is not provided, a request is sent to the leader of the network for this purpose. If a native commissioner is used, the request for setting up management information is sent to the border router.
`uri_ptr` |The ASCII string for the URI. This string identifies the CoAP URI for the desired resource. For example, `/c/ms` identifies the management set information resource.
`data_ptr`|A pointer to the desired set of TLVs.
`field_count`|Number of fields in the field pointer array (set of TLVs).
`cb_ptr`|A pointer to `management_get_response_cb` callback function carrying the result of the operation.
<dl>
<dt>Response</dt>

View File

@ -79,21 +79,21 @@ extern int8_t ethernet_mac_destroy(eth_mac_api_t *mac_api);
* @param api API to handle the request
* @param data Data containing request parameters
*/
typedef void data_request(const eth_mac_api_t* api, const eth_data_req_t *data);
typedef void eth_mac_data_request(const eth_mac_api_t* api, const eth_data_req_t *data);
/**
* @brief data_confirm confirm is called as a response to data_request
* @param api The API which handled the request
* @param data Data containing confirm parameters
*/
typedef void data_confirm(const eth_mac_api_t* api, const eth_data_conf_t *data );
typedef void eth_mac_data_confirm(const eth_mac_api_t* api, const eth_data_conf_t *data );
/**
* @brief data_indication Data indication is called when MAC layer has received data
* @param api The API which handled the response
* @param data Data containing indication parameters
*/
typedef void data_indication(const eth_mac_api_t* api, const eth_data_ind_t *data );
typedef void eth_mac_data_indication(const eth_mac_api_t* api, const eth_data_ind_t *data );
/**
* @brief Set 48 bit address from MAC
@ -119,15 +119,15 @@ typedef int8_t eth_mac_mac48_address_get(const eth_mac_api_t* api, uint8_t *mac4
* @param parent_id Upper layer identifier
* @return 0 if success; -1 if api is NULL or not found
*/
typedef int8_t eth_mac_api_initialize(eth_mac_api_t *api, data_confirm *conf_cb,
data_indication *ind_cb, uint8_t parent_id);
typedef int8_t eth_mac_api_initialize(eth_mac_api_t *api, eth_mac_data_confirm *conf_cb,
eth_mac_data_indication *ind_cb, uint8_t parent_id);
struct eth_mac_api_s {
eth_mac_api_initialize *mac_initialize;
data_request *data_req;
data_confirm *data_conf_cb;
data_indication *data_ind_cb;
eth_mac_data_request *data_req;
eth_mac_data_confirm *data_conf_cb;
eth_mac_data_indication *data_ind_cb;
eth_mac_mac48_address_set *mac48_set;
eth_mac_mac48_address_get *mac48_get;
@ -141,3 +141,4 @@ struct eth_mac_api_s {
#endif
#endif // ETHERNET_MAC_API_H

View File

@ -249,7 +249,7 @@ typedef enum {
macAutoRequestKeyIndex = 0x7b, /*>The index of the key used for automatic data*/
macDefaultKeySource = 0x7c, /*>Default key source*/
//NON standard extension
macLoadBalancingBeaconTxPeriod = 0xfd, /*> Set Beacon periodic Tx interval.Value size uint16_t in seconds, Use 0 to disable */
macLoadBalancingBeaconTx = 0xfd, /*> Trig Beacon from load balance module periodic */
macLoadBalancingAcceptAnyBeacon = 0xfe, /*>Beacon accept state control from other network. Value size bool, data true=Enable, false=disable .*/
macThreadForceLongAddressForBeacon = 0xff /*>Thread standard force beacon source address for extended 64-bit*/
} mlme_attr_t;

View File

@ -21,7 +21,7 @@
#ifndef NET_FHSS_H_
#define NET_FHSS_H_
#include <stdint.h>
#include "ns_types.h"
#ifndef RPL_SYNCHRONIZATION_INSTANCE_ID
#define RPL_SYNCHRONIZATION_INSTANCE_ID 1
@ -56,6 +56,7 @@ typedef struct
int (*fhss_timer_start)(uint32_t, void (*fhss_timer_callback)(int8_t, uint16_t), int8_t);
int (*fhss_timer_stop)(void);
uint32_t (*fhss_get_remaining_slots)(void);
uint32_t (*fhss_get_timestamp)(void);
int (*fhss_time_measure_start)(void);
uint32_t (*fhss_time_measure_read)(void);
int (*fhss_time_measure_stop)(void);
@ -120,9 +121,10 @@ extern int8_t arm_fhss_disable(int8_t interface_id);
extern int8_t arm_fhss_set_tuning_params(int8_t interface_id, const fhss_platform_tuning_params_s *fhss_tuning_params);
#else
#define arm_fhss_enable(interface_id, fhss_platform_functions,fhss_configuration) (int8_t) -1
#define arm_fhss_disable(interface_id) (int8_t) -1
#define arm_fhss_set_tuning_params(interface_id, fhss_tuning_params) (int8_t) -1
NS_DUMMY_DEFINITIONS_OK
#define arm_fhss_enable(interface_id, fhss_platform_functions,fhss_configuration) (-1)
#define arm_fhss_disable(interface_id) (-1)
#define arm_fhss_set_tuning_params(interface_id, fhss_tuning_params) (-1)
#endif
#endif /* NET_FHSS_H_ */

View File

@ -81,16 +81,16 @@ typedef enum arm_library_event_type_e {
/** Data received. */
#define SOCKET_DATA (0 << 4)
/** TCP connection ready. */
#define SOCKET_BIND_DONE (1 << 4)
#define SOCKET_CONNECT_DONE (1 << 4)
/** TCP connection failure. */
#define SOCKET_BIND_FAIL (2 << 4)
#define SOCKET_CONNECT_FAIL (2 << 4)
/** TCP connection authentication failed. */
#define SOCKET_BIND_AUTH_FAIL (3 << 4)
/** TCP incoming connection attempt to listening socket */
#define SOCKET_CONNECT_AUTH_FAIL (3 << 4)
/** TCP incoming connection on listening socket */
#define SOCKET_INCOMING_CONNECTION (4 << 4)
/** Socket data send failure. */
#define SOCKET_TX_FAIL (5 << 4)
/** TCP connection closed. */
/** TCP connection closed (received their FIN and ACK of our FIN). */
#define SOCKET_CONNECT_CLOSED (6 << 4)
/** TCP connection reset */
#define SOCKET_CONNECTION_RESET (7 << 4)
@ -100,6 +100,13 @@ typedef enum arm_library_event_type_e {
#define SOCKET_TX_DONE (9 << 4)
/** Out of memory failure. */
#define SOCKET_NO_RAM (10 << 4)
/** TCP connection problem indication (RFC 1122 R1) */
#define SOCKET_CONNECTION_PROBLEM (11 << 4)
/* Backwards compatibility */
#define SOCKET_BIND_DONE SOCKET_CONNECT_DONE
#define SOCKET_BIND_FAIL SOCKET_CONNECT_FAIL
#define SOCKET_BIND_AUTH_FAIL SOCKET_CONNECT_AUTH_FAIL
/*!
* \enum net_security_t
@ -992,6 +999,23 @@ void arm_print_neigh_cache(void);
*/
void arm_print_neigh_cache2(void (*print_fn)(const char *fmt, ...));
/**
* \brief Print PCB list
*
* Prints Protocol Control Block list to the command line
*/
void arm_print_protocols(void);
/**
* \brief Print PCB list
*
* Prints Protocol Control Block list using the given printf style function
*
* \param print_fn pointer to a printf style output function
* \param sep column separator character
*/
void arm_print_protocols2(void (*print_fn)(const char *fmt, ...), char sep);
/**
* \brief Get the library version information.
*

View File

@ -0,0 +1,105 @@
/*
* Copyright (c) 2016 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: LicenseRef-PBL
*
* Licensed under the Permissive Binary License, Version 1.0 (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.mbed.com/licenses/PBL-1.0
*
* See the License for the specific language governing permissions and limitations under the License.
*
*/
/**
* \file net_load_balance_api.h
* \brief 6Lowpan network load balance control API.
*/
#ifndef NET_LOAD_BALANCE_API_H_
#define NET_LOAD_BALANCE_API_H_
#include "ns_types.h"
/**
* \brief load_balance_network_switch_notify this function will be called by load balance when it have detected better network to switch
* \param interface id
*
* \return true Network switching can be performed immediately
* \return false means that load balance will ask at a later time for network switching, if a better network is still available at that time
*/
typedef bool net_load_balance_network_switch_notify(int8_t interface_id);
/**
* \brief Set user callback for accept network switch.
* \param network_switch_notify user callback
*/
void net_load_balance_network_switch_cb_set(net_load_balance_network_switch_notify *network_switch_notify);
/**
* \brief Create and enable load balance to selected interface.
* \param interface_id interface id
* \param enable_periodic_beacon_interval Set True when want activate load balance periodic beacon, false will work only properly with fhss system
*
* \return 0 Enable ok
* \return -1 unknown Interface or parameter error
* \return -2 Out of memory
* \return -3 Load balance already configured to this interface
*/
int8_t net_load_balance_create(int8_t interface_id, bool enable_periodic_beacon_interval);
/**
* \brief Disable and delete load balansing from interface
* \param interface_id interface id
*
* \return 0 Process ok
* \return -1 unknown Interface
*/
int8_t net_load_balance_delete(int8_t interface_id);
/**
* \brief Set Load balance threshold min and max
*
* Nework switch will work next diff_priority >= randLIB_get_random_in_range(threshold_min, threshold_max) --> switch network if true
* For border router Disable Network compare set threshold_min and threshold_max to 0.
* \param threshold_min min value define random minimal value for compare
* \param threshold_max max value for define random max value for compare
*
* \return 0 process ok -1 Unknown interface id
*/
int8_t net_load_balance_threshold_set(int8_t interface_id, uint8_t threshold_min, uint8_t threshold_max);
/**
* \brief Set Load balance expected device count and enable automatic network load level update
*
* This feature is just for RPL DoDAG root device!
*
* \param interface_id interface id
* \param expected_device_count Device count which will set max load level. If count is not expected_device_count % 8 it not zero function update number up to reach that.It is not hard limit it define max DoDAG preference
*
* \return 0 process ok -1 Unknown interface id -2 Out of memory
*/
int8_t net_load_balance_load_level_update_enable(int8_t interface_id, uint16_t expected_device_count);
/**
* \brief Disable automatic network load level update
*
* \param interface_id interface id
*
* \return 0 process ok -1 Unknown interface id
*/
int8_t net_load_balance_load_level_update_disable(int8_t interface_id);
/**
* \brief Set network probability percent when new network is better than threshold max
*
* \param interface_id interface id
* \param max_p is percent probability to switch network. Default is 40%. Accepted values are [1,100] recommend values are 15-50.
*
* \return 0 process ok -1 Unknown interface id or parameter fail
*/
int8_t net_load_balance_set_max_probability(int8_t interface_id , uint8_t max_p);
#endif /* NET_LOAD_BALANCE_API_H_ */

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2016 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: LicenseRef-PBL
*
* Licensed under the Permissive Binary License, Version 1.0 (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.mbed.com/licenses/PBL-1.0
*
* See the License for the specific language governing permissions and limitations under the License.
*
*/
/**
* \file net_ipv6_api.h
* \brief IPv6 configuration API.
*/
#ifndef NET_TEST_API_H_
#define NET_TEST_API_H_
#include "ns_types.h"
/**
* \brief Makes TCP protocol drop given number of packets from a particular state (TX side, tcp_down()).
*
* Testing API for TCP retransmission mechanism after a packet is dropped in a particular state.
*
* \param state Particular TCP state - Identified by its number from 1-11. Numbering is from the SNMP MIB - RFC 4022.
* \param count No. of packets to be dropped
* \return 0 OK
* \return <0 If request can't be fulfilled, i.e., Not test environment.
*/
int8_t arm_nwk_test_tcp_drop_tx(int state, uint8_t count);
/**
* \brief Makes TCP protocol drop given number of packets from a particular state (RX side, tcp_up()).
*
* Testing API for TCP to drop received packets.
*
* \param state Particular TCP state - Identified by its number from 1-11. Numbering is from the SNMP MIB - RFC 4022.
* \param count No. of packets to be dropped
* \return 0 OK
* \return <0 If request can't be fulfilled, i.e., Not test environment.
*/
int8_t arm_nwk_test_tcp_drop_rx(int state, uint8_t count);
/**
* \brief Resets drop counters.
*
* Testing API for TCP reset any packet drop counters.
*/
void arm_nwk_test_tcp_drop_reset(void);
#endif //NET_TEST_API_H_

View File

@ -220,6 +220,16 @@ int thread_test_version_set(int8_t interface_id, uint8_t version);
*/
int thread_test_router_selection_jitter_set(int8_t interface_id, uint32_t jitter);
/**
* \brief Sets the thread MIN_DELAY_TIMER default value.
*
* \param interface_id Network Interface
* \param delay_timer_value delay timer value in seconds used in leader
*
* \return 0, OK
* \return <0 Error
*/
int thread_test_min_delay_timer_set(int8_t interface_id, uint32_t delay_timer_value);
/**
* \brief Increment Thread key sequence counter
*

View File

@ -37,7 +37,7 @@ typedef enum address_type_t {
*/
typedef struct ns_address {
address_type_t type; /**< Address type. */
uint8_t address[16]; /**< Addresss. */
uint8_t address[16]; /**< Address. */
uint16_t identifier; /**< TCP/UDP port number. */
} ns_address_t;

View File

@ -52,6 +52,7 @@ typedef enum {
PHY_EXTENSION_READ_CHANNEL_ENERGY, /**< RF interface ED scan energy read. */
PHY_EXTENSION_READ_LINK_STATUS, /**< Net library could read link status. */
PHY_EXTENSION_CONVERT_SIGNAL_INFO, /**< Convert signal info. */
PHY_EXTENSION_ACCEPT_ANY_BEACON, /**< Set boolean true or false for accept beacon from other Pan-ID than configured. Default value should be false */
} phy_extension_type_e;
/** Address types */

View File

@ -24,20 +24,23 @@ extern "C" {
* \section socket-com Common socket API
* - socket_open(), A function to open a socket.
* - socket_close(), A function to close a socket.
* - socket_connect(), A function to connect to a remote peer.
* - socket_bind(), A function to bind a local address or port or both.
* - socket_getpeername(), A function to get remote address and port of a connected socket.
* - socket_getsockname(), A function to get local address and port of a bound socket.
*
* \section socket-read Socket read API at callback
* - socket_read(), A function to read received data buffer from a socket.
* - socket_recvmsg(), A function to read received data buffer from a socket to Posix defined message structure
* - socket_read_session_address(), A function to read session info for a TCP event.
*
* \section socket-tx Socket TX API
* - socket_send(), A function to write data buffer to a socket.
* - socket_sendto(), A function to write data to a specific destination in the socket.
* - socket_senmsg(), A function which support socket_send and socket_sendto functionality which supports ancillary data
* - socket_sendmsg(), A function which support socket_send and socket_sendto functionality which supports ancillary data
*
* \section sock-connect TCP socket connection handle
* - socket_listen(), A function to set the socket to listening mode.
* - socket_connect(), A function to connect to a remote peer.
* - socket_accept(), A function to accept an incoming connection.
* - socket_shutdown(), A function to shut down a connection.
*
* Sockets are a common abstraction model for network communication and are used in most operating systems.
@ -98,13 +101,17 @@ extern "C" {
* | :------------------------: | :---: | :-----------------------------------------------------------------: |
* | SOCKET_EVENT_MASK | 0xF0 | NC Socket event mask. |
* | SOCKET_DATA | 0x00 | Data received, read data length available in d_len field. |
* | SOCKET_BIND_DONE | 0x10 | TCP connection ready. |
* | SOCKET_CONNECT_DONE | 0x10 | TCP connection ready. |
* | SOCKET_CONNECT_FAIL | 0x20 | TCP connection failed. |
* | SOCKET_INCOMING_CONNECTION | 0x40 | TCP incoming connection on listening socket. |
* | SOCKET_TX_FAIL | 0x50 | Socket data send failed. |
* | SOCKET_CONNECT_CLOSED | 0x60 | TCP connection closed. |
* | SOCKET_CONNECTION_RESET | 0x70 | TCP connection reset. |
* | SOCKET_NO_ROUTER | 0x80 | No route available to destination. |
* | SOCKET_TX_DONE | 0x90 | Last socket TX process done, in TCP, whole TCP process is ready. |
* | SOCKET_TX_DONE | 0x90 | UDP: link layer TX ready (d_len = length of datagram). |
* | | | TCP: some data acknowledged (d_len = data remaining in send queue) |
* | SOCKET_NO_RAM | 0xA0 | No RAM available. |
* | SOCKET_CONNECTION_PROBLEM | 0xB0 | TCP connection is retrying. |
*
*
* \section socket-tcp How to use TCP sockets:
@ -112,28 +119,26 @@ extern "C" {
* | API | Socket Type | Description |
* | :---------------------------: | :-----------: | :------------------------------------------------------------: |
* | socket_open() | Server/Client | Open socket to specific or dynamic port number. |
* | socket_shutdown() | Client | Shut down opened TCP connection. |
* | socket_shutdown() | Server/Client | Shut down opened TCP connection. |
* | socket_listen() | Server | Set server port to listen state. |
* | socket_accept() | Server | Accept a connection to a listening socket as a new socket. |
* | socket_connect() | Client | Connect client socket to specific destination. |
* | socket_close() | Server/Client | Closes the TCP Socket. |
* | socket_send() | Client | Send data to session based destination. |
* | socket_sendto() | Server/Client | Send data to specific destination. |
* | socket_read_session_address() | Server/Client | Read socket TCP session address and port information. |
* | socket_close() | Server/Client | Closes the TCP Socket. |
* | socket_send() | Server/Client | Send data to peer. |
* | socket_recv() | Server/Client | Receive data from peer. |
*
* When the TCP socket is opened it is in closed state. It must be set either to listen or to connect state before it can be used to receive or transmit data.
*
* A socket can be set to listen mode with the socket_listen() function. After the call, the socket can accept an incoming connection from a remote host.
* The listen mode closes the connection automatically after server timeout or when the client or application closes the connection manually by socket_shutdown() function.
*
* A TCP socket can be connected to a remote host with socket_connect() with correct arguments. After the function call, a (non-blocking) application must wait for the socket event to confirm the successful state change of the socket.
* After the successful state change, data can be sent using socket_send() by client and socket_send() by server.
* The connection can be shut down with socket_shutdown() function or by server timeout.
* After the successful state change, data can be sent using socket_send().
* The connection can be shut down in either direction with socket_shutdown() function - shutting down write signals end-of-data to the peer.
*
* \section socket-udpicmp How to use UDP and RAW socket:
*
* A UDP socket is ready to receive and send data immediately after a successful call of socket_open() and a NET_READY event is received.
* Data can be transmitted with the socket_sendto() function. An ICMP socket works with same function call.
*
*/
#include "ns_address.h"
@ -199,7 +204,7 @@ typedef struct ns_msghdr {
uint_fast16_t msg_iovlen; /**< Data vector count in msg_iov */
void *msg_control; /**< Ancillary data list of ns_cmsghdr_t pointer */
uint_fast16_t msg_controllen; /**< Ancillary data length */
int flags; /**< Flags for received messages */
int msg_flags; /**< Flags for received messages */
} ns_msghdr_t;
/*!
@ -212,8 +217,15 @@ typedef struct ns_cmsghdr {
uint8_t cmsg_type; /**< Protocol Specific types for example SOCKET_IPV6_PKTINFO, */
} ns_cmsghdr_t;
/** \name Error values
* \anchor ERROR_CODES
*/
///@{
/** No data currently available to read, or insufficient queue space for write */
#define NS_EWOULDBLOCK (-100)
///@}
/** \name socket_recvmsg() message error flags.
/** \name socket_recvfrom() or socket_recvmsg() flags.
* \anchor MSG_HEADER_FLAGS
*/
///@{
@ -221,6 +233,10 @@ typedef struct ns_cmsghdr {
#define NS_MSG_TRUNC 1
/** Indicates that given ancillary data buffer was smaller than enabled at socket msg->msg_controllen define proper writed data lengths. */
#define NS_MSG_CTRUNC 2
/** Can be passed as an input flag to socket_recvfrom() to not consume data */
#define NS_MSG_PEEK 4
/** \deprecated Can be passed as an input flag to get legacy returns of zero - used by socket_read() and socket_sendto() */
#define NS_MSG_LEGACY0 0x4000
///@}
/*!
* \struct ns_in6_pktinfo_t
@ -231,15 +247,22 @@ typedef struct ns_in6_pktinfo {
int8_t ipi6_ifindex; /**< send/recv interface index */
} ns_in6_pktinfo_t;
/** \privatesection Alignment macros for control message headers
* \anchor CMSG_ALIGN_FLAGS
*/
///@{
/** Base header alignment size */
#define CMSG_HEADER_ALIGN sizeof(long)
/** Base data alignment size */
#define CMSG_DATA_ALIGN CMSG_HEADER_ALIGN
/** Returns control message alignment size for data or header based upon alignment base */
#ifndef NS_ALIGN_SIZE
#define NS_ALIGN_SIZE(length, aligment_base) \
((length + (aligment_base -1 )) & ~(aligment_base -1))
#endif
///@}
/// \publicsection
/**
* \brief Parse first control message header from message ancillary data.
*
@ -327,7 +350,7 @@ int8_t socket_close(int8_t socket);
* \brief A function to set a socket to listening mode.
*
* \param socket The socket ID.
* \param backlog The pending connections queue size. (Not yet implemented).
* \param backlog The pending connections queue size.
* \return 0 on success.
* \return -1 on failure.
*/
@ -336,13 +359,12 @@ int8_t socket_listen(int8_t socket, uint8_t backlog);
/**
* \brief A function to accept a new connection on an socket.
*
* NOT YET IMPLEMENTED - PLACEHOLDER FOR FUTURE TCP CHANGES
*
* \param socket_id The socket ID of the listening socket.
* \param addr Either NULL pointer or pointer to structure where the remote address of the connecting host is copied.
* \param passed_fptr A function pointer to a function that is called whenever a data frame is received to the new socket.
* \return 0 or greater on success; return value is the new socket ID.
* \return -1 on failure.
* \return NS_EWOULDBLOCK if no pending connections.
*/
int8_t socket_accept(int8_t socket_id, ns_address_t *addr, void (*passed_fptr)(void *));
@ -367,11 +389,14 @@ int8_t socket_connect(int8_t socket, ns_address_t *address, uint8_t randomly_tak
/**
* \brief Bind socket to address.
*
* Used by the application to bind a socket to a port and/or an address. Binding can
* be done only once. The port or address cannot be changed after binding.
* Used by the application to bind a socket to a port and/or an address. Binding of each
* of address and port can only be done once.
*
* If address is ns_in6addr_any, the address binding is not changed. If port is 0,
* the port binding is not changed.
*
* \param socket Socket ID of the socket to bind.
* \param address Address structure containing the port and address to bind.
* \param address Address structure containing the port and/or address to bind.
*
* \return 0 on success.
* \return -1 if the given address is NULL.
@ -386,6 +411,7 @@ int8_t socket_bind(int8_t socket, const ns_address_t *address);
/**
* \brief Bind a local address to a socket based on the destination address and
* the address selection preferences.
*
* Binding happens to the same address that socket_connect() would bind to.
* Reference: RFC5014 IPv6 Socket API for Source Address Selection.
*
@ -417,70 +443,119 @@ int8_t socket_bind2addrsel(int8_t socket, const ns_address_t *dst_address);
*
* \return 0 on success.
* \return -1 if the given socket ID is not found, if the socket type is wrong or TCP layer returns a failure.
* \return -2 if no active TCP session was found.
* \return -2 if socket is not connected.
*/
int8_t socket_shutdown(int8_t socket, uint8_t how);
/**
* \brief Send data via a connected TCP socket by client.
* \brief Send data via a connected socket by client.
*
* Note: The socket connection must be ready before using this function.
* The stack uses automatically the address of the remote connected host as the destination address for the packet.
*
* This call is equivalent to socket_sendto() with address set to NULL - see
* that call for more details.
*
* \param socket The socket ID.
* \param buffer A pointer to data.
* \param length Data length.
*
* \return 0 done
* \return -1 Invalid socket ID.
* \return -2 Socket memory allocation fail.
* \return -3 TCP state not established or address scope not defined .
* \return -4 Socket TX process busy or unknown interface.
* \return -5 Socket not connected
* \return -6 Packet too short (ICMP raw socket error).
*/
int8_t socket_send(int8_t socket, uint8_t *buffer, uint16_t length);
int16_t socket_send(int8_t socket, const void *buffer, uint16_t length);
/**
* \brief A function to read received data buffer from a socket.
* \deprecated
*
* Used by the application to get data from a socket. This method must be called once
* from a socket callback when handling event SOCKET_DATA. If the received data does not fit
* in the buffer provided the excess data bytes are discarded.
* Used by the application to get data from a socket. See socket_recvfrom()
* for more details.
*
* This is equivalent to socket_recvfrom, except that it passes the
* flag NS_MSG_LEGACY0, which modifies the return behaviour for zero data.
*
* \param socket The socket ID.
* \param src_addr A pointer to a structure where the sender's address is stored.
* May be NULL if not required.
* \param buffer A pointer to an array where the read data is written to.
* \param length The maximum length of the allocated buffer.
*
* \return greater than 0 indicates the length of the data copied to buffer.
* \return 0 if no data is available to read.
* \return >0 indicates the length of the data copied to buffer.
* \return 0 if no data was read (includes zero-length datagram,
* end of stream and no data currently available)
* \return -1 invalid input parameters.
*/
int16_t socket_read(int8_t socket, ns_address_t *src_addr, uint8_t *buffer, uint16_t length);
/**
* \brief A function to read received message with ancillary data from a socket.
* \brief A function to read received data buffer from a socket,
*
* Used by the application to get data from a socket. This method must be called once
* from a socket callback when handling event SOCKET_DATA. If the received data does not fit
* in the buffer provided the excess data bytes are discarded.
* Equivalent to socket_recvfrom with src_address set to NULL.
*
* Ancillary data must request by socket_setsockopt().
* \param socket The socket ID.
* \param buffer A pointer to an array where the read data is written to.
* \param length The maximum length of the allocated buffer.
* \param flags Flags for read call
*
* msg->msg_controllen is updated to indicate actual length of ancillary data output
* \return as for socket_recvfrom
*/
int16_t socket_recv(int8_t socket, void *buffer, uint16_t length, int flags);
/**
* \brief A function to read received data buffer from a socket
*
* Used by the application to get data from a socket.
*
* This has two modes of operation.
*
* 1) For non-stream sockets, if the receive queue is disabled (set to 0 via
* SOCKET_SO_RCVBUF), which is the non-stream default and original Nanostack
* behaviour, then applications receive exactly one SOCKET_DATA callback per
* datagram, indicating that datagram's length. They must make 1 read call
* in that callback, and they will be given the data. If not read, the
* datagram is discarded on return from the callback.
*
* 2) Otherwise - stream sockets or SOCKET_SO_RCVBUF non-zero - behaviour is
* akin to traditional BSD. SOCKET_DATA callbacks occur when new data arrives,
* and read calls can be made any time. Data will be queued to an extent
* determined by the receive buffer size. The length in the data callback
* is the total amount of data in the receive queue - possibly multiple
* datagrams.
*
* \param socket The socket ID.
* \param buffer A pointer to an array where the read data is written to.
* \param length The maximum length of the allocated buffer.
* \param flags Flags for read call
* \param src_addr A pointer to a structure where the sender's address is stored.
* May be NULL if not required.
*
* The returned length is normally the length of data actually written to the buffer; if
* NS_MSG_TRUNC is set in flags, then for non-stream sockets, the actual datagram length is
* returned instead, which may be larger than the buffer size.
*
* Return values assume flag NS_MSG_LEGACY0 is not set - if it is set, they are
* as per socket_read().
*
* \return >0 indicates the length of the data copied to buffer (or original datagram size)
* \return 0 if end of stream or zero-length datagram
* \return -1 invalid input parameters.
* \return NS_EWOULDBLOCK if no data is currently available
*/
int16_t socket_recvfrom(int8_t socket, void *buffer, uint16_t length, int flags, ns_address_t *src_addr);
/**
* \brief A function to read received message with ancillary data from a socket.
*
* Used by the application to get data from a socket. See socket_recvfrom for
* details of the two delivery mechanisms.
*
* Ancillary data must request by socket_setsockopt().
*
* msg->msg_controllen is updated to indicate actual length of ancillary data output
*
* \param socket The socket ID.
* \param msg A pointer to a structure where messages is stored with or without ancillary data
* \param flags A flags for message read.
*
* \return greater than 0 indicates the length of the data.
* \return 0 if no data is available to read.
* \return -1 invalid input parameters.
* \return as for socket_recvfrom
*/
int16_t socket_recvmsg(int8_t socket, ns_msghdr_t *msg, int flags);
@ -489,20 +564,28 @@ int16_t socket_recvmsg(int8_t socket, ns_msghdr_t *msg, int flags);
*
* Used by the application to send data.
*
* The return of 0 on success is unconventional, and obtained by passing
* NS_MSG_LEGACY0 to socket_sendmsg internally - to get conventional
* return values, you can use socket_sendmsg() instead.
*
* \param socket The socket ID.
* \param address A pointer to the destination address information.
* \param buffer A pointer to data to be sent.
* \param length Length of the data to be sent.
*
* \return 0 on success.
* \return 0 On success (whole packet queued)
* \return NS_EWOULDBLOCK if nothing written due to lack of queue space.
*
* Error returns:
*
* \return -1 Invalid socket ID.
* \return -2 Socket memory allocation fail.
* \return -3 TCP state not established or address scope not defined .
* \return -4 Socket TX process busy or unknown interface.
* \return -4 Unknown interface.
* \return -5 Socket not connected
* \return -6 Packet too short (ICMP raw socket error).
*/
int8_t socket_sendto(int8_t socket, ns_address_t *address, uint8_t *buffer, uint16_t length);
int16_t socket_sendto(int8_t socket, const ns_address_t *address, const void *buffer, uint16_t length);
/**
* \brief A function to send UDP, TCP or raw ICMP data via the socket with or without ancillary data or destination address.
@ -511,7 +594,7 @@ int8_t socket_sendto(int8_t socket, ns_address_t *address, uint8_t *buffer, uint
*
* \param socket The socket ID.
* \param msg A pointer to the Message header which include address, payload and ancillary data.
* \param flags A flags for message send for future usage (not supported yet)
* \param flags A flags for message send (eg NS_MSG_LEGACY0)
*
* Messages destination address is defined by msg->msg_name which must be ns_address_t. If msg->msg_nme is NULL socket select connected address
*
@ -519,34 +602,56 @@ int8_t socket_sendto(int8_t socket, ns_address_t *address, uint8_t *buffer, uint
*
* Supported ancillary data for send defined by msg->msg_control and msg->msg_controllen.
*
* msg->flags and flags is ignored
* msg->msg_flags is unused, and need not be initialised.
*
* \return 0 on success.
* \return -1 Invalid socket ID or message structure.
* The following main return values assume flag NS_MSG_LEGACY0 is not set -
* if it is set, they are as per socket_sendto().
*
* \return length if entire amount written (which could be 0)
* \return value >0 and <length if partial amount written (stream only)
* \return NS_EWOULDBLOCK if nothing written due to lack of queue space.
* Error returns:
*
* \return -1 Invalid socket ID.
* \return -2 Socket memory allocation fail.
* \return -3 TCP state not established or address scope not defined .
* \return -4 Socket TX process busy or unknown interface.
* \return -4 Unknown interface.
* \return -5 Socket not connected
* \return -6 Packet too short (ICMP raw socket error).
*/
int8_t socket_sendmsg(int8_t socket, const ns_msghdr_t *msg, int flags);
int16_t socket_sendmsg(int8_t socket, const ns_msghdr_t *msg, int flags);
/**
* \brief A function to read session info for TCP event.
* \brief A function to read local address and port for a bound socket.
*
* This call writes ns_in6addr_any if address is not bound and 0 if the port is not bound.
*
* \param socket The socket ID.
* \param address A pointer to the address structure where the session address information is read to.
* \param address A pointer to the address structure where the local address information is written to.
*
* \return 0 on success.
* \return -1 if no socket is found or TCP is not compiled into this project.
* \return -2 if no session information is found.
*
* Note: This function should be called only at socket callback when the socket event is SOCKET_BIND_DONE or SOCKET_TX_DONE.
* The following sections introduce those functions.
* \return -1 if no socket is found.
*/
int8_t socket_read_session_address(int8_t socket, ns_address_t *address);
int8_t socket_getsockname(int8_t socket, ns_address_t *address);
/**
* \brief A function to read remote address and port for a connected socket.
*
* \param socket The socket ID.
* \param address A pointer to the address structure where the remote address information is written to.
*
* \return 0 on success.
* \return -1 if no socket is found.
* \return -2 if no socket is not connected.
*/
int8_t socket_getpeername(int8_t socket, ns_address_t *address);
/* Backwards compatibility */
static inline int8_t socket_read_session_address(int8_t socket, ns_address_t *address)
{
return socket_getpeername(socket, address);
}
/** \name Flags for SOCKET_IPV6_ADDR_PREFERENCES - opposites 16 bits apart. */
///@{
@ -564,9 +669,24 @@ int8_t socket_read_session_address(int8_t socket, ns_address_t *address);
/** \name Protocol levels used for socket_setsockopt. */
///@{
#define SOCKET_SOL_SOCKET 0 /**< Socket level */
#define SOCKET_IPPROTO_IPV6 41 /**< IPv6. */
///@}
/** \name Option names for protocol level SOCKET_SOL_SOCKET.
* \anchor OPTNAMES_SOCKET
*/
///@{
/** Specify receive buffer size in payload bytes, as int32_t. 0 means traditional Nanostack behaviour - unread data dropped unless read in data callback */
#define SOCKET_SO_RCVBUF 1
/** Specify send buffer size in payload bytes, as int32_t. Only currently used for stream sockets. */
#define SOCKET_SO_SNDBUF 2
/** Specify receive low water mark in payload bytes, as int32_t. Not yet implemented. */
#define SOCKET_SO_RCVLOWAT 3
/** Specify send low water mark in payload bytes, as int32_t. Queued sends will only be accepted if this many bytes of send queue space are available, else NS_EWOULDBLOCK is returned. */
#define SOCKET_SO_SNDLOWAT 4
///@}
/** \name Option names for protocol level SOCKET_IPPROTO_IPV6.
* \anchor OPTNAMES_IPV6
*/
@ -602,7 +722,7 @@ int8_t socket_read_session_address(int8_t socket, ns_address_t *address);
#define SOCKET_INTERFACE_SELECT 0xfe /**< Not standard socket interface ID. */
#define SOCKET_IPV6_ADDRESS_SELECT 0xff /**< Deprecated - use SOCKET_IPV6_ADDR_PREFERENCES instead. */
/** Socket options summary
/** IPv6 socket options summary
*
* | opt_name / cmsg_type | Data type | set/getsockopt | sendmsg | recvmsg |
* | :--------------------------: | :--------------: | :-------------: | :-----: | :-------------------------------: |
@ -635,7 +755,8 @@ int8_t socket_read_session_address(int8_t socket, ns_address_t *address);
*
* \param socket The socket ID.
* \param level The protocol level.
* \param opt_name The option name (interpretation depends on level). See \ref OPTNAMES_IPV6.
* \param opt_name The option name (interpretation depends on level).
* See \ref OPTNAMES_SOCKET and \ref OPTNAMES_IPV6.
* \param opt_value A pointer to value for the specified option.
* \param opt_len Size of the data pointed to by the value.
*

View File

@ -103,32 +103,34 @@ int thread_border_router_route_add(int8_t interface_id, uint8_t *prefix_ptr, uin
int thread_border_router_route_delete(int8_t interface_id, uint8_t *prefix_ptr, uint8_t prefix_len);
/**
* \brief Add local service.
* \brief Add or modify a local service.
*
* \param interface_id Network interface ID.
* \param service_ptr Pointer to service data.
* \param service_len Length of service.
* \param thread_enteprise True if Thread enterprise number is used.
* \param sid Service identifier.
* \param enterprise_number If thread_enteprise is false this must be given.
* \param service_data Pointer to a byte string specifying the type of service.
* \param service_len Length of service data.
* \param sid Service Type ID, a value between 0 and 15, inclusive, assigned to this service data.
* \param enterprise_number Enterprise number of the vendor that defined the type of the server.
* \param server_data Pointer to a byte string containing server-specific information.
* \param server_data_len Length of server data.
* \param stable This data is stable and expected to be available at least 48h.
*
* \return 0, Set OK.
* \return <0 Set not OK.
* \return 0, Addition OK.
* \return <0 Addition not OK.
*/
//TODO PUUTTUUU SERVER data
int thread_border_router_service_add(int8_t interface_id, uint8_t *service_ptr, uint8_t service_len, bool thread_enteprise, uint8_t sid, uint32_t enterprise_number);
int thread_border_router_service_add(int8_t interface_id, uint8_t *service_data, uint8_t service_len, uint8_t sid, uint32_t enterprise_number, uint8_t *server_data, uint8_t server_data_len, bool stable);
/**
* \brief Delete local service.
* \brief Delete local service by service data and enterprise number.
*
* \param interface_id Network interface ID.
* \param service_ptr Pointer to service data.
* \param service_data Pointer to a byte string specifying the type of service.
* \param service_len Length of service.
* \param enterprise_number Enterprise number of the vendor that defined the type of the server.
*
* \return 0, Set OK.
* \return <0 Set not OK.
* \return 0, Delete OK.
* \return <0 Delete not OK.
*/
int thread_border_router_service_delete(int8_t interface_id, uint8_t *service_ptr, uint8_t service_len);
int thread_border_router_service_delete(int8_t interface_id, uint8_t *service_data, uint8_t service_len, uint32_t enterprise_number);
/**
* \brief Publish local services to Thread network.
@ -180,4 +182,90 @@ int thread_border_router_recursive_dns_server_option_set(int8_t interface_id, ui
*/
int thread_border_router_dns_search_list_option_set(int8_t interface_id, uint8_t *dns_search_list_option, uint16_t search_list_option_len);
#endif /* THREAD_DHCPV6_SERVER_H_ */
/**
* \brief Callback type for Thread network data TLV registration
*
* \param interface_id Network interface ID.
* \param network_data_tlv Thread Network data TLV as specified in Thread specification.
* \param network_data_tlv_length length of the network data TLV.
*/
typedef void (thread_network_data_tlv_cb)(int8_t interface_id, uint8_t *network_data_tlv, uint16_t network_data_tlv_length);
/**
* \brief Register callback function to receive thread network data TLV in byte array. For the first time the callback
* will be called before returning from the function. Afterwards the callback will be called when there is a change
* to the network data or when the network data is advertised. Application is not allowed to block the callback execution
* and must make a copy of the network data if it is needed afterwards.
*
* Setting nwk_data_cb to NULL will prevent further calls to the callback function.
*
* \param interface_id Network interface ID.
* \param nwk_data_cb callback function to receive network data TLV in byte array as specified in the Thread specification.
*
* \return 0, Callback function registered successfully.
* \return <0 when error occurs during registering the callback function.
*/
int thread_border_router_network_data_callback_register(int8_t interface_id, thread_network_data_tlv_cb* nwk_data_cb);
/**
* Find Prefix TLV from the Network Data TLV byte array.
*
* \param network_data_tlv [IN] Network data TLV in byte array.
* \param network_data_tlv_length [IN] Length of the network data TLV byte array in bytes.
* \param prefix_tlv [IN] pointer to the previous prefix_tlv, NULL if previous TLV not known.
* [OUT] Pointer to the prefix TLV found.
* \param stable [OUT] value set to true if found TLV is stable, false otherwise.
*
* \return Length of the found Prefix TLV
* \return 0 if TLV is empty or no Prefix TLV found.
* \return negative value indicates error in input parameters.
*/
int thread_border_router_prefix_tlv_find(uint8_t* network_data_tlv, uint16_t network_data_tlv_length, uint8_t** prefix_tlv, bool* stable);
/**
* Find Border router TLV from the Network Data TLV (under Prefix TLV) byte array.
*
* \param prefix_tlv [IN] Network data TLV in byte array.
* \param prefix_tlv_length [IN] Length of the Network data TLV byte array in bytes.
* \param border_router_tlv [IN] pointer to the previous Border Router TLV, NULL if not known.
* [OUT] Pointer to the Border Router TLV found.
* \param stable [OUT] value set to true if found TLV is stable, false otherwise
*
* \return Length of the Prefix found
* \return 0 if TLV is empty or no TLV found.
* \return negative value indicates error in input parameters.
*/
int thread_border_router_tlv_find(uint8_t* prefix_tlv, uint16_t prefix_tlv_length, uint8_t** border_router_tlv, bool* stable);
/**
* Find Service TLV from the Network Data TLV byte array.
*
* \param network_data_tlv [IN] Network data TLV in byte array.
* \param network_data_tlv_length [IN] Length of the network data TLV byte array in bytes.
* \param service_tlv [IN] pointer to the previous Service TLV, NULL if previous TLV not known.
* [OUT] Pointer to the Service TLV found.
* \param stable [OUT] value set to true if found TLV is stable, false otherwise.
*
* \return Length of the found Service TLV
* \return 0 if TLV is empty or no Service TLV found.
* \return negative value indicates error in input parameters.
*/
int thread_border_router_service_tlv_find(uint8_t* network_data_tlv, uint16_t network_data_tlv_length, uint8_t** service_tlv, bool* stable);
/**
* Find Server TLV from the Network Data TLV (under Service TLV) byte array.
*
* \param service_tlv [IN] Network data TLV in byte array.
* \param service_tlv_length [IN] Length of the Network data TLV byte array in bytes.
* \param server_tlv [IN] pointer to the previous Server TLV, NULL if not known.
* [OUT] Pointer to the Server TLV found.
* \param stable [OUT] value set to true if found TLV is stable, false otherwise
*
* \return Length of the Prefix found
* \return 0 if TLV is empty or no TLV found.
* \return negative value indicates error in input parameters.
*/
int thread_border_router_server_tlv_find(uint8_t* service_tlv, uint16_t service_tlv_length, uint8_t** server_tlv, bool* stable);
#endif /* THREAD_BORDER_ROUTER_API_H_ */

View File

@ -106,7 +106,7 @@ int thread_management_set_security_policy(int8_t instance_id, uint8_t options, u
* filter indicates whether to use 0 == EUI-64 or 1 == bottom 24 bits of EUI-64.
*
* \param instance_id The ID of the management session.
* \param session_id The commissioning session id that needs to be added
* \param session_id The commissioning session ID that needs to be added.
* \param steering_data_ptr A pointer to new steering data.
* \param steering_data_len The length of the new steering data.
* \param cb_ptr A callback function indicating the result of the operation. Can be NULL if no result code needed.
@ -118,7 +118,7 @@ int thread_management_set_steering_data(int8_t instance_id, uint16_t session_id,
/** \brief Set the Thread commissioning data timestamp
*
* \param instance_id the ID of the management session.
* \param instance_id The ID of the management session.
* \param time Upper 48 bits is the timestamp in seconds since the start of unix time, lower 16 bits are fractional portion of time. If the last bit is set to 1, the commissioner has accurate time.
* \param cb_ptr A callback function indicating the result of the operation. Can be NULL if no result code needed.
*
@ -143,15 +143,14 @@ int thread_management_set_commissioning_data_timestamp(int8_t instance_id, uint6
typedef int (management_get_response_cb)(int8_t instance_id, management_state_e status, uint8_t *response_message_ptr, uint16_t response_message_len);
/** \brief Get Thread management fields.
* Comments from PEKKA: please rewrite the parameter descriptions below.
* Read Thread management field values from the leader of the Thread network.
* Fetching Thread management field values from any device in the Thread network.
*
* \param interface_id The interface ID where the request was made.
* \param dst_addr Destination address for remote if address is not given sent to leader of network or if native commissioner sent to Border router.
* \param uri_ptr The ASCII string for the URI. Can be Active (default if NULL)/Pending/Commissioner URI.
* \param fields_ptr The fields to be read from the leader from the network. Array of MESHCOP TLV defines from thread_meshcop_lib.h
* \param fields_len count of fields in the fields_ptr array.
* \param cb_ptr callback function to inform the result of the operation. Can be NULL if no result code needed.
* \param instance_id Instance ID of the management session.
* \param dst_addr Destination address; the address of a remote device from whome it is desirable to fetch management information. If however, the address is not provided, a request is sent to the leader of the network for this purpose. If a native commissioner is used, the request for management information is sent to the border router.
* \param uri_ptr The ASCII string for the URI. This string identifies the CoAP URI for the desired resource. For example, /c/mg identifies the management get information resource.
* \param fields_ptr A pointer that points to an array of desirable MESHCOP TLVs. A list of such TLVs can be found in thread_meshcop_lib.h
* \param fields_count Number of fields in the field pointer array (set of TLVs).
* \param cb_ptr A callback function carrying the result of the operation.
*
* \return 0, Success.
* \return <0 Fail.
@ -160,14 +159,14 @@ int thread_management_get(int8_t instance_id, uint8_t dst_addr[static 16], char
/** \brief Set Thread management fields
*
* Set Thread management field values to the leader of the Thread network.
* Set Thread management field values to a device in Thread network.
*
* \param interface_id Interface id where the request was made.
* \param dst_addr Destination address for remote if address is not given sent to leader of network or if native commissioner sent to Border router.
* \param uri_ptr Ascii string for the URI. Can be Active(default if NULL)/Pending/Commissioner URI.
* \param data_ptr fields wanted to set to the leader. Array of MESHCOP TLV defines from thread_meshcop_lib.h
* \param data_len length of data in the data_ptr.
* \param cb_ptr callback function to inform the result of the operation. Can be NULL if no result code needed.
* \param instance_id Instance ID of the management session.
* \param dst_addr Destination address, the address of a remote device where it is desired to setup management information. If however, the address is not provided, a request is sent to leader of the network for this purpose. If a native commissioner is being used, the rquest for setting up management information is sent to the Border router.
* \param uri_ptr The ASCII string for the URI. This string identifies the CoAP URI for the desired resource, for example, /c/ms identifies the the management set information resource.
* \param data_ptr A pointer to the desired set of TLVs.
* \param data_len count of the members (no. of TLVs) in the TLV set.
* \param cb_ptr A callback function carrying the result of the operation.
*
*/
int thread_management_set(int8_t instance_id, uint8_t dst_addr[static 16], char *uri_ptr, uint8_t *data_ptr, uint8_t data_len, management_set_response_cb *cb_ptr);

View File

@ -189,6 +189,19 @@ bool thread_meshcop_tlv_exist(const uint8_t *ptr, const uint16_t length, const u
*/
uint16_t thread_meshcop_tlv_find(const uint8_t *ptr, const uint16_t length, const uint8_t type, uint8_t **result_ptr);
/**
* Find next TLV from message.
*
* \param tlv_ba TLV message buffer.
* \param tlv_ba_length Length of the TLV message buffer.
* \param tlv_id ID of the TLV to be searched.
* \param found_tlv [IN] Pointer value is given as result if length is > 0. Can be NULL which only searches for the length.
* \ [OUT] Pointer to previous TLV found
*
* \return The length of the TLV data found and found_tlv updated to point beginning of value field. 0 if TLV is not found.
*/
uint16_t thread_meshcop_tlv_find_next(uint8_t* tlv_ba, uint16_t tlv_ba_length, uint8_t tlv_id, uint8_t** found_tlv);
/**
* Read 1 byte length TLV.
*

View File

@ -43,6 +43,15 @@ typedef struct whiteboard_entry_t {
* \return A pointer to whiteboard_entry_t structure.
*/
extern whiteboard_entry_t *whiteboard_get(whiteboard_entry_t *cur);
/**
* @brief Whiteboard_set_device_hard_limit Sets the absolut limit of child devices this device can handle.
* This is very useful in situations, where 1 GW drops from network and causes it's children
* to join other GW networks. This might cause other GWs to run out of memory.
* @param limit Absolute maximum amount of devices allowed to join. Default value=0 means unlimited (as long as there is memory)
*/
extern void whiteboard_set_device_hard_limit(uint16_t limit);
#ifdef __cplusplus
}
#endif

Some files were not shown because too many files have changed in this diff Show More