diff --git a/.travis.yml b/.travis.yml index eb45b7c638..dd96d456a1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,10 @@ python: script: - PYTHONPATH=. python tools/test/config_test/config_test.py + - PYTHONPATH=. python tools/test/build_api/build_api_test.py - python tools/test/pylint.py - py.test tools/test/toolchains/api.py + - python tools/test/memap/memap_test.py - python tools/build_travis.py before_install: - sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded @@ -19,3 +21,5 @@ install: - sudo pip install jinja2 - sudo pip install pytest - sudo pip install pylint + - sudo pip install hypothesis + - sudo pip install mock diff --git a/TESTS/events/queue/main.cpp b/TESTS/events/queue/main.cpp new file mode 100644 index 0000000000..bdb58b6eda --- /dev/null +++ b/TESTS/events/queue/main.cpp @@ -0,0 +1,258 @@ +#include "mbed_events.h" +#include "mbed.h" +#include "rtos.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" + +using namespace utest::v1; + + +// flag for called +volatile bool touched = false; + +// static functions +void func5(int a0, int a1, int a2, int a3, int a4) { + touched = true; + TEST_ASSERT_EQUAL(a0 | a1 | a2 | a3 | a4, 0x1f); +} + +void func4(int a0, int a1, int a2, int a3) { + touched = true; + TEST_ASSERT_EQUAL(a0 | a1 | a2 | a3, 0xf); +} + +void func3(int a0, int a1, int a2) { + touched = true; + TEST_ASSERT_EQUAL(a0 | a1 | a2, 0x7); +} + +void func2(int a0, int a1) { + touched = true; + TEST_ASSERT_EQUAL(a0 | a1, 0x3); +} + +void func1(int a0) { + touched = true; + TEST_ASSERT_EQUAL(a0, 0x1); +} + +void func0() { + touched = true; +} + +#define SIMPLE_POSTS_TEST(i, ...) \ +void simple_posts_test##i() { \ + EventQueue queue; \ + \ + touched = false; \ + queue.call(func##i,##__VA_ARGS__); \ + queue.dispatch(0); \ + TEST_ASSERT(touched); \ + \ + touched = false; \ + queue.call_in(1, func##i,##__VA_ARGS__); \ + queue.dispatch(2); \ + TEST_ASSERT(touched); \ + \ + touched = false; \ + queue.call_every(1, func##i,##__VA_ARGS__); \ + queue.dispatch(2); \ + TEST_ASSERT(touched); \ +} + +SIMPLE_POSTS_TEST(5, 0x01, 0x02, 0x04, 0x08, 0x010) +SIMPLE_POSTS_TEST(4, 0x01, 0x02, 0x04, 0x08) +SIMPLE_POSTS_TEST(3, 0x01, 0x02, 0x04) +SIMPLE_POSTS_TEST(2, 0x01, 0x02) +SIMPLE_POSTS_TEST(1, 0x01) +SIMPLE_POSTS_TEST(0) + + +void time_func(Timer *t, int ms) { + TEST_ASSERT_INT_WITHIN(2, ms, t->read_ms()); + t->reset(); +} + +template +void call_in_test() { + Timer tickers[N]; + + EventQueue queue; + + for (int i = 0; i < N; i++) { + tickers[i].start(); + queue.call_in((i+1)*100, time_func, &tickers[i], (i+1)*100); + } + + queue.dispatch(N*100); +} + +template +void call_every_test() { + Timer tickers[N]; + + EventQueue queue; + + for (int i = 0; i < N; i++) { + tickers[i].start(); + queue.call_every((i+1)*100, time_func, &tickers[i], (i+1)*100); + } + + queue.dispatch(N*100); +} + +void allocate_failure_test() { + EventQueue queue; + int id; + + for (int i = 0; i < 100; i++) { + id = queue.call((void (*)())0); + } + + TEST_ASSERT(!id); +} + +void no() { + TEST_ASSERT(false); +} + +template +void cancel_test1() { + EventQueue queue; + + int ids[N]; + + for (int i = 0; i < N; i++) { + ids[i] = queue.call_in(1000, no); + } + + for (int i = N-1; i >= 0; i--) { + queue.cancel(ids[i]); + } + + queue.dispatch(0); +} + + +// Testing the dynamic arguments to the event class +unsigned counter = 0; + +void count5(unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a5) { + counter += a0 + a1 + a2 + a3 + a5; +} + +void count4(unsigned a0, unsigned a1, unsigned a2, unsigned a3) { + counter += a0 + a1 + a2 + a3; +} + +void count3(unsigned a0, unsigned a1, unsigned a2) { + counter += a0 + a1 + a2; +} + +void count2(unsigned a0, unsigned a1) { + counter += a0 + a1; +} + +void count1(unsigned a0) { + counter += a0; +} + +void count0() { + counter += 0; +} + +void event_class_test() { + counter = 0; + EventQueue queue(2048); + + Event e5(&queue, count5); + Event e4(&queue, count5, 1); + Event e3(&queue, count5, 1, 1); + Event e2(&queue, count5, 1, 1, 1); + Event e1(&queue, count5, 1, 1, 1, 1); + Event e0(&queue, count5, 1, 1, 1, 1, 1); + + e5.post(1, 1, 1, 1, 1); + e4.post(1, 1, 1, 1); + e3.post(1, 1, 1); + e2.post(1, 1); + e1.post(1); + e0.post(); + + queue.dispatch(0); + + TEST_ASSERT_EQUAL(counter, 30); +} + +void event_class_helper_test() { + counter = 0; + EventQueue queue(2048); + + Event e5 = queue.event(count5, 1, 1, 1, 1, 1); + Event e4 = queue.event(count4, 1, 1, 1, 1); + Event e3 = queue.event(count3, 1, 1, 1); + Event e2 = queue.event(count2, 1, 1); + Event e1 = queue.event(count1, 1); + Event e0 = queue.event(count0); + + e5.post(); + e4.post(); + e3.post(); + e2.post(); + e1.post(); + e0.post(); + + queue.dispatch(0); + + TEST_ASSERT_EQUAL(counter, 15); +} + +void event_inference_test() { + counter = 0; + EventQueue queue (2048); + + queue.event(count5, 1, 1, 1, 1, 1).post(); + queue.event(count5, 1, 1, 1, 1).post(1); + queue.event(count5, 1, 1, 1).post(1, 1); + queue.event(count5, 1, 1).post(1, 1, 1); + queue.event(count5, 1).post(1, 1, 1, 1); + queue.event(count5).post(1, 1, 1, 1, 1); + + queue.dispatch(0); + + TEST_ASSERT_EQUAL(counter, 30); +} + + +// Test setup +utest::v1::status_t test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +const Case cases[] = { + Case("Testing calls with 5 args", simple_posts_test5), + Case("Testing calls with 4 args", simple_posts_test4), + Case("Testing calls with 3 args", simple_posts_test3), + Case("Testing calls with 2 args", simple_posts_test2), + Case("Testing calls with 1 args", simple_posts_test1), + Case("Testing calls with 0 args", simple_posts_test0), + + Case("Testing call_in", call_in_test<20>), + Case("Testing call_every", call_every_test<20>), + + Case("Testing allocate failure", allocate_failure_test), + + Case("Testing event cancel 1", cancel_test1<20>), + Case("Testing the event class", event_class_test), + Case("Testing the event class helpers", event_class_helper_test), + Case("Testing the event inference", event_inference_test), +}; + +Specification specification(test_setup, cases); + +int main() { + return !Harness::run(specification); +} + diff --git a/TESTS/mbed_functional/callback/main.cpp b/TESTS/mbed_functional/callback/main.cpp index 6f6b7da4f7..eb4c777e5d 100644 --- a/TESTS/mbed_functional/callback/main.cpp +++ b/TESTS/mbed_functional/callback/main.cpp @@ -320,23 +320,23 @@ void test_dispatch0() { Verifier::verify0((const Thing*)&thing, &Thing::const_member_func0); Verifier::verify0((volatile Thing*)&thing, &Thing::volatile_member_func0); Verifier::verify0((const volatile Thing*)&thing, &Thing::const_volatile_member_func0); - Verifier::verify0(&thing, &bound_func0); - Verifier::verify0((const Thing*)&thing, &const_bound_func0); - Verifier::verify0((volatile Thing*)&thing, &volatile_bound_func0); - Verifier::verify0((const volatile Thing*)&thing, &const_volatile_bound_func0); - Verifier::verify0(&thing, &void_func0); - Verifier::verify0((const Thing*)&thing, &const_void_func0); - Verifier::verify0((volatile Thing*)&thing, &volatile_void_func0); - Verifier::verify0((const volatile Thing*)&thing, &const_volatile_void_func0); + Verifier::verify0(&bound_func0, &thing); + Verifier::verify0(&const_bound_func0, (const Thing*)&thing); + Verifier::verify0(&volatile_bound_func0, (volatile Thing*)&thing); + Verifier::verify0(&const_volatile_bound_func0, (const volatile Thing*)&thing); + Verifier::verify0(&void_func0, &thing); + Verifier::verify0(&const_void_func0, (const Thing*)&thing); + Verifier::verify0(&volatile_void_func0, (volatile Thing*)&thing); + Verifier::verify0(&const_volatile_void_func0, (const volatile Thing*)&thing); Verifier::verify0(callback(static_func0)); Callback cb(static_func0); Verifier::verify0(cb); cb = static_func0; Verifier::verify0(cb); - cb.attach(&thing, &bound_func0); + cb.attach(&bound_func0, &thing); Verifier::verify0(&cb, &Callback::call); - Verifier::verify0((void*)&cb, &Callback::thunk); + Verifier::verify0(&Callback::thunk, (void*)&cb); } template @@ -347,23 +347,23 @@ void test_dispatch1() { Verifier::verify1((const Thing*)&thing, &Thing::const_member_func1); Verifier::verify1((volatile Thing*)&thing, &Thing::volatile_member_func1); Verifier::verify1((const volatile Thing*)&thing, &Thing::const_volatile_member_func1); - Verifier::verify1(&thing, &bound_func1); - Verifier::verify1((const Thing*)&thing, &const_bound_func1); - Verifier::verify1((volatile Thing*)&thing, &volatile_bound_func1); - Verifier::verify1((const volatile Thing*)&thing, &const_volatile_bound_func1); - Verifier::verify1(&thing, &void_func1); - Verifier::verify1((const Thing*)&thing, &const_void_func1); - Verifier::verify1((volatile Thing*)&thing, &volatile_void_func1); - Verifier::verify1((const volatile Thing*)&thing, &const_volatile_void_func1); + Verifier::verify1(&bound_func1, &thing); + Verifier::verify1(&const_bound_func1, (const Thing*)&thing); + Verifier::verify1(&volatile_bound_func1, (volatile Thing*)&thing); + Verifier::verify1(&const_volatile_bound_func1, (const volatile Thing*)&thing); + Verifier::verify1(&void_func1, &thing); + Verifier::verify1(&const_void_func1, (const Thing*)&thing); + Verifier::verify1(&volatile_void_func1, (volatile Thing*)&thing); + Verifier::verify1(&const_volatile_void_func1, (const volatile Thing*)&thing); Verifier::verify1(callback(static_func1)); Callback cb(static_func1); Verifier::verify1(cb); cb = static_func1; Verifier::verify1(cb); - cb.attach(&thing, &bound_func1); + cb.attach(&bound_func1, &thing); Verifier::verify1(&cb, &Callback::call); - Verifier::verify1((void*)&cb, &Callback::thunk); + Verifier::verify1(&Callback::thunk, (void*)&cb); } template @@ -374,23 +374,23 @@ void test_dispatch2() { Verifier::verify2((const Thing*)&thing, &Thing::const_member_func2); Verifier::verify2((volatile Thing*)&thing, &Thing::volatile_member_func2); Verifier::verify2((const volatile Thing*)&thing, &Thing::const_volatile_member_func2); - Verifier::verify2(&thing, &bound_func2); - Verifier::verify2((const Thing*)&thing, &const_bound_func2); - Verifier::verify2((volatile Thing*)&thing, &volatile_bound_func2); - Verifier::verify2((const volatile Thing*)&thing, &const_volatile_bound_func2); - Verifier::verify2(&thing, &void_func2); - Verifier::verify2((const Thing*)&thing, &const_void_func2); - Verifier::verify2((volatile Thing*)&thing, &volatile_void_func2); - Verifier::verify2((const volatile Thing*)&thing, &const_volatile_void_func2); + Verifier::verify2(&bound_func2, &thing); + Verifier::verify2(&const_bound_func2, (const Thing*)&thing); + Verifier::verify2(&volatile_bound_func2, (volatile Thing*)&thing); + Verifier::verify2(&const_volatile_bound_func2, (const volatile Thing*)&thing); + Verifier::verify2(&void_func2, &thing); + Verifier::verify2(&const_void_func2, (const Thing*)&thing); + Verifier::verify2(&volatile_void_func2, (volatile Thing*)&thing); + Verifier::verify2(&const_volatile_void_func2, (const volatile Thing*)&thing); Verifier::verify2(callback(static_func2)); Callback cb(static_func2); Verifier::verify2(cb); cb = static_func2; Verifier::verify2(cb); - cb.attach(&thing, &bound_func2); + cb.attach(&bound_func2, &thing); Verifier::verify2(&cb, &Callback::call); - Verifier::verify2((void*)&cb, &Callback::thunk); + Verifier::verify2(&Callback::thunk, (void*)&cb); } template @@ -401,23 +401,23 @@ void test_dispatch3() { Verifier::verify3((const Thing*)&thing, &Thing::const_member_func3); Verifier::verify3((volatile Thing*)&thing, &Thing::volatile_member_func3); Verifier::verify3((const volatile Thing*)&thing, &Thing::const_volatile_member_func3); - Verifier::verify3(&thing, &bound_func3); - Verifier::verify3((const Thing*)&thing, &const_bound_func3); - Verifier::verify3((volatile Thing*)&thing, &volatile_bound_func3); - Verifier::verify3((const volatile Thing*)&thing, &const_volatile_bound_func3); - Verifier::verify3(&thing, &void_func3); - Verifier::verify3((const Thing*)&thing, &const_void_func3); - Verifier::verify3((volatile Thing*)&thing, &volatile_void_func3); - Verifier::verify3((const volatile Thing*)&thing, &const_volatile_void_func3); + Verifier::verify3(&bound_func3, &thing); + Verifier::verify3(&const_bound_func3, (const Thing*)&thing); + Verifier::verify3(&volatile_bound_func3, (volatile Thing*)&thing); + Verifier::verify3(&const_volatile_bound_func3, (const volatile Thing*)&thing); + Verifier::verify3(&void_func3, &thing); + Verifier::verify3(&const_void_func3, (const Thing*)&thing); + Verifier::verify3(&volatile_void_func3, (volatile Thing*)&thing); + Verifier::verify3(&const_volatile_void_func3, (const volatile Thing*)&thing); Verifier::verify3(callback(static_func3)); Callback cb(static_func3); Verifier::verify3(cb); cb = static_func3; Verifier::verify3(cb); - cb.attach(&thing, &bound_func3); + cb.attach(&bound_func3, &thing); Verifier::verify3(&cb, &Callback::call); - Verifier::verify3((void*)&cb, &Callback::thunk); + Verifier::verify3(&Callback::thunk, (void*)&cb); } template @@ -428,23 +428,23 @@ void test_dispatch4() { Verifier::verify4((const Thing*)&thing, &Thing::const_member_func4); Verifier::verify4((volatile Thing*)&thing, &Thing::volatile_member_func4); Verifier::verify4((const volatile Thing*)&thing, &Thing::const_volatile_member_func4); - Verifier::verify4(&thing, &bound_func4); - Verifier::verify4((const Thing*)&thing, &const_bound_func4); - Verifier::verify4((volatile Thing*)&thing, &volatile_bound_func4); - Verifier::verify4((const volatile Thing*)&thing, &const_volatile_bound_func4); - Verifier::verify4(&thing, &void_func4); - Verifier::verify4((const Thing*)&thing, &const_void_func4); - Verifier::verify4((volatile Thing*)&thing, &volatile_void_func4); - Verifier::verify4((const volatile Thing*)&thing, &const_volatile_void_func4); + Verifier::verify4(&bound_func4, &thing); + Verifier::verify4(&const_bound_func4, (const Thing*)&thing); + Verifier::verify4(&volatile_bound_func4, (volatile Thing*)&thing); + Verifier::verify4(&const_volatile_bound_func4, (const volatile Thing*)&thing); + Verifier::verify4(&void_func4, &thing); + Verifier::verify4(&const_void_func4, (const Thing*)&thing); + Verifier::verify4(&volatile_void_func4, (volatile Thing*)&thing); + Verifier::verify4(&const_volatile_void_func4, (const volatile Thing*)&thing); Verifier::verify4(callback(static_func4)); Callback cb(static_func4); Verifier::verify4(cb); cb = static_func4; Verifier::verify4(cb); - cb.attach(&thing, &bound_func4); + cb.attach(&bound_func4, &thing); Verifier::verify4(&cb, &Callback::call); - Verifier::verify4((void*)&cb, &Callback::thunk); + Verifier::verify4(&Callback::thunk, (void*)&cb); } template @@ -455,23 +455,23 @@ void test_dispatch5() { Verifier::verify5((const Thing*)&thing, &Thing::const_member_func5); Verifier::verify5((volatile Thing*)&thing, &Thing::volatile_member_func5); Verifier::verify5((const volatile Thing*)&thing, &Thing::const_volatile_member_func5); - Verifier::verify5(&thing, &bound_func5); - Verifier::verify5((const Thing*)&thing, &const_bound_func5); - Verifier::verify5((volatile Thing*)&thing, &volatile_bound_func5); - Verifier::verify5((const volatile Thing*)&thing, &const_volatile_bound_func5); - Verifier::verify5(&thing, &void_func5); - Verifier::verify5((const Thing*)&thing, &const_void_func5); - Verifier::verify5((volatile Thing*)&thing, &volatile_void_func5); - Verifier::verify5((const volatile Thing*)&thing, &const_volatile_void_func5); + Verifier::verify5(&bound_func5, &thing); + Verifier::verify5(&const_bound_func5, (const Thing*)&thing); + Verifier::verify5(&volatile_bound_func5, (volatile Thing*)&thing); + Verifier::verify5(&const_volatile_bound_func5, (const volatile Thing*)&thing); + Verifier::verify5(&void_func5, &thing); + Verifier::verify5(&const_void_func5, (const Thing*)&thing); + Verifier::verify5(&volatile_void_func5, (volatile Thing*)&thing); + Verifier::verify5(&const_volatile_void_func5, (const volatile Thing*)&thing); Verifier::verify5(callback(static_func5)); Callback cb(static_func5); Verifier::verify5(cb); cb = static_func5; Verifier::verify5(cb); - cb.attach(&thing, &bound_func5); + cb.attach(&bound_func5, &thing); Verifier::verify5(&cb, &Callback::call); - Verifier::verify5((void*)&cb, &Callback::thunk); + Verifier::verify5(&Callback::thunk, (void*)&cb); } diff --git a/TESTS/mbed_functional/callback_big/main.cpp b/TESTS/mbed_functional/callback_big/main.cpp index 47630a3f21..efa1fb088a 100644 --- a/TESTS/mbed_functional/callback_big/main.cpp +++ b/TESTS/mbed_functional/callback_big/main.cpp @@ -198,19 +198,19 @@ void test_dispatch0() { Verifier::verify0((const Thing*)&thing, &Thing::const_member_func0); Verifier::verify0((volatile Thing*)&thing, &Thing::volatile_member_func0); Verifier::verify0((const volatile Thing*)&thing, &Thing::const_volatile_member_func0); - Verifier::verify0(&thing, &bound_func0); - Verifier::verify0((const Thing*)&thing, &const_func0); - Verifier::verify0((volatile Thing*)&thing, &volatile_func0); - Verifier::verify0((const volatile Thing*)&thing, &const_volatile_func0); + Verifier::verify0(&bound_func0, &thing); + Verifier::verify0(&const_func0, (const Thing*)&thing); + Verifier::verify0(&volatile_func0, (volatile Thing*)&thing); + Verifier::verify0(&const_volatile_func0, (const volatile Thing*)&thing); Verifier::verify0(callback(static_func0)); Callback cb(static_func0); Verifier::verify0(cb); cb = static_func0; Verifier::verify0(cb); - cb.attach(&thing, &bound_func0); + cb.attach(&bound_func0, &thing); Verifier::verify0(&cb, &Callback::call); - Verifier::verify0((void*)&cb, &Callback::thunk); + Verifier::verify0(&Callback::thunk, (void*)&cb); } template @@ -221,19 +221,19 @@ void test_dispatch1() { Verifier::verify1((const Thing*)&thing, &Thing::const_member_func1); Verifier::verify1((volatile Thing*)&thing, &Thing::volatile_member_func1); Verifier::verify1((const volatile Thing*)&thing, &Thing::const_volatile_member_func1); - Verifier::verify1(&thing, &bound_func1); - Verifier::verify1((const Thing*)&thing, &const_func1); - Verifier::verify1((volatile Thing*)&thing, &volatile_func1); - Verifier::verify1((const volatile Thing*)&thing, &const_volatile_func1); + Verifier::verify1(&bound_func1, &thing); + Verifier::verify1(&const_func1, (const Thing*)&thing); + Verifier::verify1(&volatile_func1, (volatile Thing*)&thing); + Verifier::verify1(&const_volatile_func1, (const volatile Thing*)&thing); Verifier::verify1(callback(static_func1)); Callback cb(static_func1); Verifier::verify1(cb); cb = static_func1; Verifier::verify1(cb); - cb.attach(&thing, &bound_func1); + cb.attach(&bound_func1, &thing); Verifier::verify1(&cb, &Callback::call); - Verifier::verify1((void*)&cb, &Callback::thunk); + Verifier::verify1(&Callback::thunk, (void*)&cb); } template @@ -244,19 +244,19 @@ void test_dispatch2() { Verifier::verify2((const Thing*)&thing, &Thing::const_member_func2); Verifier::verify2((volatile Thing*)&thing, &Thing::volatile_member_func2); Verifier::verify2((const volatile Thing*)&thing, &Thing::const_volatile_member_func2); - Verifier::verify2(&thing, &bound_func2); - Verifier::verify2((const Thing*)&thing, &const_func2); - Verifier::verify2((volatile Thing*)&thing, &volatile_func2); - Verifier::verify2((const volatile Thing*)&thing, &const_volatile_func2); + Verifier::verify2(&bound_func2, &thing); + Verifier::verify2(&const_func2, (const Thing*)&thing); + Verifier::verify2(&volatile_func2, (volatile Thing*)&thing); + Verifier::verify2(&const_volatile_func2, (const volatile Thing*)&thing); Verifier::verify2(callback(static_func2)); Callback cb(static_func2); Verifier::verify2(cb); cb = static_func2; Verifier::verify2(cb); - cb.attach(&thing, &bound_func2); + cb.attach(&bound_func2, &thing); Verifier::verify2(&cb, &Callback::call); - Verifier::verify2((void*)&cb, &Callback::thunk); + Verifier::verify2(&Callback::thunk, (void*)&cb); } template @@ -267,19 +267,19 @@ void test_dispatch3() { Verifier::verify3((const Thing*)&thing, &Thing::const_member_func3); Verifier::verify3((volatile Thing*)&thing, &Thing::volatile_member_func3); Verifier::verify3((const volatile Thing*)&thing, &Thing::const_volatile_member_func3); - Verifier::verify3(&thing, &bound_func3); - Verifier::verify3((const Thing*)&thing, &const_func3); - Verifier::verify3((volatile Thing*)&thing, &volatile_func3); - Verifier::verify3((const volatile Thing*)&thing, &const_volatile_func3); + Verifier::verify3(&bound_func3, &thing); + Verifier::verify3(&const_func3, (const Thing*)&thing); + Verifier::verify3(&volatile_func3, (volatile Thing*)&thing); + Verifier::verify3(&const_volatile_func3, (const volatile Thing*)&thing); Verifier::verify3(callback(static_func3)); Callback cb(static_func3); Verifier::verify3(cb); cb = static_func3; Verifier::verify3(cb); - cb.attach(&thing, &bound_func3); + cb.attach(&bound_func3, &thing); Verifier::verify3(&cb, &Callback::call); - Verifier::verify3((void*)&cb, &Callback::thunk); + Verifier::verify3(&Callback::thunk, (void*)&cb); } template @@ -290,19 +290,19 @@ void test_dispatch4() { Verifier::verify4((const Thing*)&thing, &Thing::const_member_func4); Verifier::verify4((volatile Thing*)&thing, &Thing::volatile_member_func4); Verifier::verify4((const volatile Thing*)&thing, &Thing::const_volatile_member_func4); - Verifier::verify4(&thing, &bound_func4); - Verifier::verify4((const Thing*)&thing, &const_func4); - Verifier::verify4((volatile Thing*)&thing, &volatile_func4); - Verifier::verify4((const volatile Thing*)&thing, &const_volatile_func4); + Verifier::verify4(&bound_func4, &thing); + Verifier::verify4(&const_func4, (const Thing*)&thing); + Verifier::verify4(&volatile_func4, (volatile Thing*)&thing); + Verifier::verify4(&const_volatile_func4, (const volatile Thing*)&thing); Verifier::verify4(callback(static_func4)); Callback cb(static_func4); Verifier::verify4(cb); cb = static_func4; Verifier::verify4(cb); - cb.attach(&thing, &bound_func4); + cb.attach(&bound_func4, &thing); Verifier::verify4(&cb, &Callback::call); - Verifier::verify4((void*)&cb, &Callback::thunk); + Verifier::verify4(&Callback::thunk, (void*)&cb); } template @@ -313,19 +313,19 @@ void test_dispatch5() { Verifier::verify5((const Thing*)&thing, &Thing::const_member_func5); Verifier::verify5((volatile Thing*)&thing, &Thing::volatile_member_func5); Verifier::verify5((const volatile Thing*)&thing, &Thing::const_volatile_member_func5); - Verifier::verify5(&thing, &bound_func5); - Verifier::verify5((const Thing*)&thing, &const_func5); - Verifier::verify5((volatile Thing*)&thing, &volatile_func5); - Verifier::verify5((const volatile Thing*)&thing, &const_volatile_func5); + Verifier::verify5(&bound_func5, &thing); + Verifier::verify5(&const_func5, (const Thing*)&thing); + Verifier::verify5(&volatile_func5, (volatile Thing*)&thing); + Verifier::verify5(&const_volatile_func5, (const volatile Thing*)&thing); Verifier::verify5(callback(static_func5)); Callback cb(static_func5); Verifier::verify5(cb); cb = static_func5; Verifier::verify5(cb); - cb.attach(&thing, &bound_func5); + cb.attach(&bound_func5, &thing); Verifier::verify5(&cb, &Callback::call); - Verifier::verify5((void*)&cb, &Callback::thunk); + Verifier::verify5(&Callback::thunk, (void*)&cb); } diff --git a/TESTS/mbed_functional/callback_small/main.cpp b/TESTS/mbed_functional/callback_small/main.cpp index e5fa15b4b6..4e9bf904bf 100644 --- a/TESTS/mbed_functional/callback_small/main.cpp +++ b/TESTS/mbed_functional/callback_small/main.cpp @@ -198,19 +198,19 @@ void test_dispatch0() { Verifier::verify0((const Thing*)&thing, &Thing::const_member_func0); Verifier::verify0((volatile Thing*)&thing, &Thing::volatile_member_func0); Verifier::verify0((const volatile Thing*)&thing, &Thing::const_volatile_member_func0); - Verifier::verify0(&thing, &bound_func0); - Verifier::verify0((const Thing*)&thing, &const_func0); - Verifier::verify0((volatile Thing*)&thing, &volatile_func0); - Verifier::verify0((const volatile Thing*)&thing, &const_volatile_func0); + Verifier::verify0(&bound_func0, &thing); + Verifier::verify0(&const_func0, (const Thing*)&thing); + Verifier::verify0(&volatile_func0, (volatile Thing*)&thing); + Verifier::verify0(&const_volatile_func0, (const volatile Thing*)&thing); Verifier::verify0(callback(static_func0)); Callback cb(static_func0); Verifier::verify0(cb); cb = static_func0; Verifier::verify0(cb); - cb.attach(&thing, &bound_func0); + cb.attach(&bound_func0, &thing); Verifier::verify0(&cb, &Callback::call); - Verifier::verify0((void*)&cb, &Callback::thunk); + Verifier::verify0(&Callback::thunk, (void*)&cb); } template @@ -221,19 +221,19 @@ void test_dispatch1() { Verifier::verify1((const Thing*)&thing, &Thing::const_member_func1); Verifier::verify1((volatile Thing*)&thing, &Thing::volatile_member_func1); Verifier::verify1((const volatile Thing*)&thing, &Thing::const_volatile_member_func1); - Verifier::verify1(&thing, &bound_func1); - Verifier::verify1((const Thing*)&thing, &const_func1); - Verifier::verify1((volatile Thing*)&thing, &volatile_func1); - Verifier::verify1((const volatile Thing*)&thing, &const_volatile_func1); + Verifier::verify1(&bound_func1, &thing); + Verifier::verify1(&const_func1, (const Thing*)&thing); + Verifier::verify1(&volatile_func1, (volatile Thing*)&thing); + Verifier::verify1(&const_volatile_func1, (const volatile Thing*)&thing); Verifier::verify1(callback(static_func1)); Callback cb(static_func1); Verifier::verify1(cb); cb = static_func1; Verifier::verify1(cb); - cb.attach(&thing, &bound_func1); + cb.attach(&bound_func1, &thing); Verifier::verify1(&cb, &Callback::call); - Verifier::verify1((void*)&cb, &Callback::thunk); + Verifier::verify1(&Callback::thunk, (void*)&cb); } template @@ -244,19 +244,19 @@ void test_dispatch2() { Verifier::verify2((const Thing*)&thing, &Thing::const_member_func2); Verifier::verify2((volatile Thing*)&thing, &Thing::volatile_member_func2); Verifier::verify2((const volatile Thing*)&thing, &Thing::const_volatile_member_func2); - Verifier::verify2(&thing, &bound_func2); - Verifier::verify2((const Thing*)&thing, &const_func2); - Verifier::verify2((volatile Thing*)&thing, &volatile_func2); - Verifier::verify2((const volatile Thing*)&thing, &const_volatile_func2); + Verifier::verify2(&bound_func2, &thing); + Verifier::verify2(&const_func2, (const Thing*)&thing); + Verifier::verify2(&volatile_func2, (volatile Thing*)&thing); + Verifier::verify2(&const_volatile_func2, (const volatile Thing*)&thing); Verifier::verify2(callback(static_func2)); Callback cb(static_func2); Verifier::verify2(cb); cb = static_func2; Verifier::verify2(cb); - cb.attach(&thing, &bound_func2); + cb.attach(&bound_func2, &thing); Verifier::verify2(&cb, &Callback::call); - Verifier::verify2((void*)&cb, &Callback::thunk); + Verifier::verify2(&Callback::thunk, (void*)&cb); } template @@ -267,19 +267,19 @@ void test_dispatch3() { Verifier::verify3((const Thing*)&thing, &Thing::const_member_func3); Verifier::verify3((volatile Thing*)&thing, &Thing::volatile_member_func3); Verifier::verify3((const volatile Thing*)&thing, &Thing::const_volatile_member_func3); - Verifier::verify3(&thing, &bound_func3); - Verifier::verify3((const Thing*)&thing, &const_func3); - Verifier::verify3((volatile Thing*)&thing, &volatile_func3); - Verifier::verify3((const volatile Thing*)&thing, &const_volatile_func3); + Verifier::verify3(&bound_func3, &thing); + Verifier::verify3(&const_func3, (const Thing*)&thing); + Verifier::verify3(&volatile_func3, (volatile Thing*)&thing); + Verifier::verify3(&const_volatile_func3, (const volatile Thing*)&thing); Verifier::verify3(callback(static_func3)); Callback cb(static_func3); Verifier::verify3(cb); cb = static_func3; Verifier::verify3(cb); - cb.attach(&thing, &bound_func3); + cb.attach(&bound_func3, &thing); Verifier::verify3(&cb, &Callback::call); - Verifier::verify3((void*)&cb, &Callback::thunk); + Verifier::verify3(&Callback::thunk, (void*)&cb); } template @@ -290,19 +290,19 @@ void test_dispatch4() { Verifier::verify4((const Thing*)&thing, &Thing::const_member_func4); Verifier::verify4((volatile Thing*)&thing, &Thing::volatile_member_func4); Verifier::verify4((const volatile Thing*)&thing, &Thing::const_volatile_member_func4); - Verifier::verify4(&thing, &bound_func4); - Verifier::verify4((const Thing*)&thing, &const_func4); - Verifier::verify4((volatile Thing*)&thing, &volatile_func4); - Verifier::verify4((const volatile Thing*)&thing, &const_volatile_func4); + Verifier::verify4(&bound_func4, &thing); + Verifier::verify4(&const_func4, (const Thing*)&thing); + Verifier::verify4(&volatile_func4, (volatile Thing*)&thing); + Verifier::verify4(&const_volatile_func4, (const volatile Thing*)&thing); Verifier::verify4(callback(static_func4)); Callback cb(static_func4); Verifier::verify4(cb); cb = static_func4; Verifier::verify4(cb); - cb.attach(&thing, &bound_func4); + cb.attach(&bound_func4, &thing); Verifier::verify4(&cb, &Callback::call); - Verifier::verify4((void*)&cb, &Callback::thunk); + Verifier::verify4(&Callback::thunk, (void*)&cb); } template @@ -313,19 +313,19 @@ void test_dispatch5() { Verifier::verify5((const Thing*)&thing, &Thing::const_member_func5); Verifier::verify5((volatile Thing*)&thing, &Thing::volatile_member_func5); Verifier::verify5((const volatile Thing*)&thing, &Thing::const_volatile_member_func5); - Verifier::verify5(&thing, &bound_func5); - Verifier::verify5((const Thing*)&thing, &const_func5); - Verifier::verify5((volatile Thing*)&thing, &volatile_func5); - Verifier::verify5((const volatile Thing*)&thing, &const_volatile_func5); + Verifier::verify5(&bound_func5, &thing); + Verifier::verify5(&const_func5, (const Thing*)&thing); + Verifier::verify5(&volatile_func5, (volatile Thing*)&thing); + Verifier::verify5(&const_volatile_func5, (const volatile Thing*)&thing); Verifier::verify5(callback(static_func5)); Callback cb(static_func5); Verifier::verify5(cb); cb = static_func5; Verifier::verify5(cb); - cb.attach(&thing, &bound_func5); + cb.attach(&bound_func5, &thing); Verifier::verify5(&cb, &Callback::call); - Verifier::verify5((void*)&cb, &Callback::thunk); + Verifier::verify5(&Callback::thunk, (void*)&cb); } diff --git a/TESTS/mbedtls/selftest/main.cpp b/TESTS/mbedtls/selftest/main.cpp new file mode 100644 index 0000000000..d011d1911e --- /dev/null +++ b/TESTS/mbedtls/selftest/main.cpp @@ -0,0 +1,102 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016 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. + */ + +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" +#include "rtos.h" + +using namespace utest::v1; + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/sha256.h" +#include "mbedtls/sha512.h" +#include "mbedtls/entropy.h" +#include "mbedtls/entropy_poll.h" + +#include + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#include +#define mbedtls_printf printf +#define mbedtls_snprintf snprintf +#define mbedtls_exit exit +#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS +#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE +#endif + +#define MBEDTLS_SELF_TEST_TEST_CASE(self_test_function) \ + void self_test_function ## _test_case() { \ + int ret = self_test_function(0); \ + TEST_ASSERT_EQUAL(ret, 0); \ + } + +#if defined(MBEDTLS_SELF_TEST) + +#if defined(MBEDTLS_SHA256_C) +MBEDTLS_SELF_TEST_TEST_CASE(mbedtls_sha256_self_test) +#endif + +#if defined(MBEDTLS_SHA512_C) +MBEDTLS_SELF_TEST_TEST_CASE(mbedtls_sha512_self_test) +#endif + +#if defined(MBEDTLS_ENTROPY_C) +MBEDTLS_SELF_TEST_TEST_CASE(mbedtls_entropy_self_test) +#endif + +#else +#warning "MBEDTLS_SELF_TEST not enabled" +#endif /* MBEDTLS_SELF_TEST */ + +Case cases[] = { +#if defined(MBEDTLS_SELF_TEST) + +#if defined(MBEDTLS_SHA256_C) + Case("mbedtls_sha256_self_test", mbedtls_sha256_self_test_test_case), +#endif + +#if defined(MBEDTLS_SHA512_C) + Case("mbedtls_sha512_self_test", mbedtls_sha512_self_test_test_case), +#endif + +#if defined(MBEDTLS_ENTROPY_C) + Case("mbedtls_entropy_self_test", mbedtls_entropy_self_test_test_case), +#endif + +#endif /* MBEDTLS_SELF_TEST */ +}; + +utest::v1::status_t test_setup(const size_t num_cases) { + GREENTEA_SETUP(120, "default_auto"); + return verbose_test_setup_handler(num_cases); +} + +Specification specification(test_setup, cases); + +int main() { + return !Harness::run(specification); +} + diff --git a/docs/Toolchain_Profiles.md b/docs/Toolchain_Profiles.md new file mode 100644 index 0000000000..c310b8c19f --- /dev/null +++ b/docs/Toolchain_Profiles.md @@ -0,0 +1,72 @@ +# Toolchain Profiles User Perspective + +A Toolchain or build system Profile is a set of flags that is garenteed to be passed to the underlieing compiler suite. +These flags are stored in a JSON file that may be merged with other JSON files of the same structure. + +## JSON Toolchain Profile Format + +The JSON object that represents a Toolchain Profile is a dict mapping from Toolchains, like `GCC_ARM`, to their flags, like `-O3`. +The structure is as follows: Each toolchain supported by a Toolchain Profile has an dict in the root dict. +This dict contains a mapping from a flag type to a list of flags that should be passed the corresponding part of the compiler suite. +The required flag types are: + +| Key | Description | +|:---------|:--------------------------------------| +| `c` | Flags for the C Compiler | +| `cxx` | Flags for the C++ Compiler | +| `common` | Flags for both the C and C++ Compilers| +| `asm` | Flags for the Assembler | + +## Example + +An example of a Toolchain Profile is given below: +```json +{ + "GCC_ARM": { + "common": ["-c", "-Wall", "-Wextra", + "-Wno-unused-parameter", "-Wno-missing-field-initializers", + "-fmessage-length=0", "-fno-exceptions", "-fno-builtin", + "-ffunction-sections", "-fdata-sections", "-funsigned-char", + "-MMD", "-fno-delete-null-pointer-checks", + "-fomit-frame-pointer", "-Os"], + "asm": ["-x", "assembler-with-cpp"], + "c": ["-std=gnu99"], + "cxx": ["-std=gnu++98", "-fno-rtti", "-Wvla"], + "ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r", + "-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", + "-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit"] + }, + "ARM": { + "common": ["-c", "--gnu", "-Otime", "--split_sections", + "--apcs=interwork", "--brief_diagnostics", "--restrict", + "--multibyte_chars", "-O3"], + "asm": [], + "c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"], + "cxx": ["--cpp", "--no_rtti", "--no_vla"], + "ld": [] + }, + "IAR": { + "common": [ + "--no_wrap_diagnostics", "non-native end of line sequence", "-e", + "--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-Oh"], + "asm": [], + "c": ["--vla"], + "cxx": ["--guard_calls", "--no_static_destruction"], + "ld": ["--skip_dynamic_initialization", "--threaded_lib"] + } +} +``` + +From this Toolchain profile, we can tell that: + - `GCC_ARM`, `ARM`, and `IAR` compiler suites are supported. + - The `ARM` C and C++ Compilers will be using optimization level `-O3` + - The `IAR` linker will skip dynamic initialization + - etc. + +# Toolchain Profile API Perspective + +The Toolchains no longer take in an optional argument, `build_profile`, that will contain a map from flag types to lists of flags. +This looks exactly the same in python as it does in the JSON format above. +The meaning of the flags, and which ones are required is the same as the User Perspective +A developer using the API must parse the User provided files themselves and extract the appropriate sub-dict from the file afterwards. +A convienence function that does this for a developer is `tools.options.extract_profile` and will call args_error when a Toolchain Profile JSON file does not provide flags for the selected Toolchain. diff --git a/docs/events.md b/docs/events.md new file mode 100644 index 0000000000..19b08a7843 --- /dev/null +++ b/docs/events.md @@ -0,0 +1,139 @@ +# About the mbed OS event loop + +One of the optional mbed OS features is an event loop mechanism that can be used to defer the execution of code in a different context. In particular, a common uses of an event loop is to postpone the execution of a code sequence from an interrupt handler to an user context. This is useful because of the specific constraints of code that runs in an interrupt handler: + +- the execution of certain functions (notably some functions in the C library) is not safe. +- various RTOS objects and functions can't be used from an interrupt context. +- as a general rule, the code needs to finish as fast as possible, to allow other interrupts to be handled. + +The event loop offers a solution to these issues in the form of an API that can be used to defer execution of code from the interrupt context to the user context. More generally, the event loop can be used anywhere in a program (not necessarily in an interrupt handler) to defer code execution to a different context. + +# Overview of the mbed OS event loop + +An event loop has two main components: + +1. an **event queue**, used to store events. In mbed OS, *events* are pointers to functions (and optionally function arguments). +2. an **event loop** that extracts events from the queue and executes them. + +The mbed OS event queue is implemented by the [mbed-events library](http://github.com/ARMmbed/mbed-os/tree/master/events). It's a good idea to go through the [README of mbed-events](https://github.com/ARMmbed/mbed-os/blob/master/events/README.md), as it shows how to use the event queue. + +The event loop must be created and started manually. The simplest way to achieve that is to create a `Thread` and run the event queue's `dispatch` method in the thread: + +``` +#include "mbed.h" +#include "mbed_events.h" + +// Create a queue that can hold a maximum of 32 events +Queue queue(32 * EVENTS_EVENT_SIZE); +// Create a thread that'll run the event queue's dispatch function +Thread t; + +int main () { + // Start the event queue's dispatch thread + t.start(callback(&queue, &EventQueue::dispatch_forever)); + ... +} +``` + +Note that although this document assumes the presence of a single event loop in the system, there's nothing preventing the programmer to run more than one event loop, simply by following the create/start pattern above for each of them. + +## Using the event loop + +Once the event loop is created, it can be used for posting events. Let's consider a very simple example of a program that attaches two interrupt handlers for an InterruptIn object, using the InterruptIn `rise` and `fall` functions. The `rise` handler will run in interrupt context, while the `fall` handler will run in user context (more specifically, in the context of the event loop's thread). The full code for the example can be found below: + +``` +#include "mbed.h" +#include "mbed_events.h" + +DigitalOut led1(LED1); +InterruptIn sw(SW2); +EventQueue queue(32 * EVENTS_EVENT_SIZE); +Thread t; + +void rise_handler(void) { + printf("rise_handler in context %p\r\n", Thread::gettid()); + // Toggle LED + led1 = !led1; +} + +void fall_handler(void) { + printf("fall_handler in context %p\r\n", Thread::gettid()); + // Toggle LED + led1 = !led1; +} + +int main() { + // Start the event queue + t.start(callback(&queue, &EventQueue::dispatch_forever)); + printf("Starting in context %p\r\n", Thread::gettid()); + // The 'rise' handler will execute in IRQ context + sw.rise(rise_handler); + // The 'fall' handler will execute in the context of thread 't' + sw.fall(queue.event(fall_handler)); +} + +``` + +The above code executes two handler functions (`rise_handler` and `fall_handler`) in two different contexts: + +1. in interrupt context when a rising edge is detected on `SW2` (`rise_handler`). +2. in the context of the event loop's thread function when a falling edge is detected on `SW2` (`fall_handler`). `queue.event()` is called with `fall_handler` as an argument to specify that `fall_handler` will run in user context instead of interrupt context. + +This is the output of the above program on a FRDM-K64F board after resetting the board and pressing the SW2 button twice: + +``` +Starting in context 0x20002c50 +fall_handler in context 0x20002c90 +rise_handler in context 0x0 +fall_handler in context 0x20002c90 +rise_handler in context 0x0 +``` + +The program starts in the context of the thread that runs the `main` function (`0x29992c5`). When the uses presses SW2, `fall_handler` is automatically queued in the event queue, and it runs later in the context of thread `t` (`0x20002c90`). When the user releases the button, `rise_handler` is executed immediately, and it displays `0x0`, indicating that the code runs in interrupt context. + +The code for `rise_handler` is problematic, since it calls `printf` in interrupt context, which is a potentially unsafe operation. Fortunately, this is exactly the kind of problem that event queues can solve. We can make the code safe by running `rise_handler` in user context (like we already do with `fall_handler`) by replacing this line: + +``` +sw.rise(rise_handler); +``` + +with this line: + +``` +sw.rise(queue.event(rise_handler)); +``` + +The code is safe now, but we might've introduced another problem: latency. After the change above, the call to `rise_handler` will be queued, which means that it doesn't run immediately after the interrupt is raised anymore. For this example code, this isn't a problem, but some applications might require the code to respond as fast as possible to an interrupt. Let's assume that `rise_handler` must toggle the LED as quickly as possible in response to the user's action on SW2. To do that, in must run in interrupt context. However, `rise_handler` still needs to print a message indicating that the handler was called, but that's problematic since it's not safe to call `printf` from an interrupt context. The solution is to split `rise_handler` in two parts: the time critical part will run in interrupt context, while the non-critical part (displaying the message) will run in user context. This is easily doable using `queue.call`: + +``` +void rise_handler_user_context(void) { + printf("rise_handler_user_context in context %p\r\n", Thread::gettid()); +} + +void rise_handler(void) { + // Execute the time critical part first + led1 = !led1; + // The rest can execute later in user context (and can contain code that's not interrupt safe). + // We use the 'queue.call' function to add an event (the call to 'rise_handler_user_context') to the queue. + queue.call(rise_handler_user_context); +} + +``` + +After replacing the code for `rise_handler` as above, the output of our example becomes: + +``` +Starting in context 0x20002c50 +fall_handler in context 0x20002c90 +rise_handler_user_context in context 0x20002c90 +fall_handler in context 0x20002c90 +rise_handler_user_context in context 0x20002c90 +``` + +The scenario above (splitting an interrupt handler's code into time critical code and non-time critical code) is another common pattern that's easily implemented with event queues. Another thing to learn from this example is that queuing code that's not interrupt safe is not the only thing that event queues can be used for. Any kind of code can be queued and deferred for later execution. + +We used `InterruptIn` for the example above, but the same kind of code can be used with any `attach()`-like functions in the SDK. Example include `Serial::attach()`, `Ticker::attach()`, `Ticker::attach_us()`, `Timeout::attach()`. + +## Where to go from here + +We just scratched the surface of how event queues work in mbed OS. The `EventQueue` and `Event` classes in the `mbed-events` library offer a lot of features that are not covered in this document, including calling functions with arguments, queueing functions to be called after a delay, or queueing functions to be called periodically. The [README of the mbed-events library](https://github.com/ARMmbed/mbed-os/blob/master/events/README.md) shows more ways to use events and event queues. For more details about how the events library is implemented, check [this file](https://github.com/ARMmbed/mbed-os/blob/master/events/equeue/README.md). diff --git a/events/Event.h b/events/Event.h new file mode 100644 index 0000000000..bcf68f9439 --- /dev/null +++ b/events/Event.h @@ -0,0 +1,3313 @@ +/* events + * Copyright (c) 2016 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. + */ +#ifndef EVENT_H +#define EVENT_H + +#include "EventQueue.h" +#include "mbed_assert.h" + +namespace events { + +/** Event + * + * Representation of an event for fine-grain dispatch control + */ +template +class Event; + +/** Event + * + * Representation of an event for fine-grain dispatch control + */ +template <> +class Event { +public: + /** Create an event + * + * Constructs an event bound to the specified event queue. The specified + * callback acts as the target for the event and is executed in the + * context of the event queue's dispatch loop once posted. + * + * @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 + */ + template + Event(EventQueue *q, F f) { + struct local { + static int post(struct event *e) { + typedef EventQueue::context00 C; + struct local { + static void call(void *p) { (*static_cast(p))(); } + static void dtor(void *p) { static_cast(p)->~C(); } + }; + + void *p = equeue_alloc(e->equeue, sizeof(C)); + if (!p) { + return 0; + } + + new (p) C(*reinterpret_cast(e+1)); + equeue_event_delay(p, e->delay); + equeue_event_period(p, e->period); + equeue_event_dtor(p, &local::dtor); + return equeue_post(e->equeue, &local::call, p); + } + + static void dtor(struct event *e) { + reinterpret_cast(e+1)->~F(); + } + }; + + _event = static_cast( + equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); + if (_event) { + _event->equeue = &q->_equeue; + _event->id = 0; + _event->delay = 0; + _event->period = -1; + + _event->post = &local::post; + _event->dtor = &local::dtor; + + new (_event+1) F(f); + + _event->ref = 1; + } + } + + /** Copy constructor for events + */ + Event(const Event &e) { + _event = 0; + if (e._event) { + _event = e._event; + _event->ref += 1; + } + } + + /** Assignment operator for events + */ + Event &operator=(const Event &that) { + if (this != &that) { + this->~Event(); + new (this) Event(that); + } + + return *this; + } + + /** Destructor for events + */ + ~Event() { + if (_event) { + _event->ref -= 1; + if (_event->ref == 0) { + _event->dtor(_event); + equeue_dealloc(_event->equeue, _event); + } + } + } + + /** Configure the delay of an event + * + * @param delay Millisecond delay before dispatching the event + */ + void delay(int delay) { + if (_event) { + _event->delay = delay; + } + } + + /** Configure the period of an event + * + * @param period Millisecond period for repeatedly dispatching an event + */ + void period(int period) { + if (_event) { + _event->period = period; + } + } + + /** Posts an event onto the underlying event queue + * + * The event is posted to the underlying queue and is executed in the + * context of the event queue's dispatch loop. + * + * The post function is irq safe and can act as a mechanism for moving + * events out of irq contexts. + * + * @param a0..a4 Arguments to pass to the event + * @return A unique id that represents the posted event and can + * be passed to EventQueue::cancel, or an id of 0 if + * there is not enough memory to allocate the event. + */ + int post() const { + if (!_event) { + return 0; + } + + _event->id = _event->post(_event); + return _event->id; + } + + /** Posts an event onto the underlying event queue, returning void + * + * @param a0..a4 Arguments to pass to the event + */ + void call() const { + int id = post(); + MBED_ASSERT(id); + } + + /** Posts an event onto the underlying event queue, returning void + * + * @param a0..a4 Arguments to pass to the event + */ + void operator()() const { + return call(); + } + + /** Static thunk for passing as C-style function + * + * @param func Event to call passed as a void pointer + * @param a0..a4 Arguments to pass to the event + */ + static void thunk(void *func) { + return static_cast(func)->call(); + } + + /** Cancels the most recently posted event + * + * Attempts to cancel the most recently posted event. It is safe to call + * cancel after an event has already been dispatched. + * + * The cancel function is irq safe. + * + * If called while the event queue's dispatch loop is active, the cancel + * function does not garuntee that the event will not execute after it + * returns, as the event may have already begun executing. + */ + void cancel() const { + if (_event) { + equeue_cancel(_event->equeue, _event->id); + } + } + +private: + struct event { + unsigned ref; + equeue_t *equeue; + int id; + + int delay; + int period; + + int (*post)(struct event *); + void (*dtor)(struct event *); + + // F follows + } *_event; + +public: + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0) { + new (this) Event(q, EventQueue::context10(f, c0)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1) { + new (this) Event(q, EventQueue::context20(f, c0, c1)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) { + new (this) Event(q, EventQueue::context30(f, c0, c1, c2)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) { + new (this) Event(q, EventQueue::context40(f, c0, c1, c2, c3)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + new (this) Event(q, EventQueue::context50(f, c0, c1, c2, c3, c4)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0), B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0) const, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0) volatile, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0) const volatile, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1), B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1) const, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1) volatile, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1) const volatile, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2), B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2) const, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2) volatile, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2) const volatile, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3), B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3) const, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3) volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, B4), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, B4) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } +}; + +/** Event + * + * Representation of an event for fine-grain dispatch control + */ +template +class Event { +public: + /** Create an event + * + * Constructs an event bound to the specified event queue. The specified + * callback acts as the target for the event and is executed in the + * context of the event queue's dispatch loop once posted. + * + * @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 + */ + template + Event(EventQueue *q, F f) { + struct local { + static int post(struct event *e, A0 a0) { + typedef EventQueue::context10 C; + struct local { + static void call(void *p) { (*static_cast(p))(); } + static void dtor(void *p) { static_cast(p)->~C(); } + }; + + void *p = equeue_alloc(e->equeue, sizeof(C)); + if (!p) { + return 0; + } + + new (p) C(*reinterpret_cast(e+1), a0); + equeue_event_delay(p, e->delay); + equeue_event_period(p, e->period); + equeue_event_dtor(p, &local::dtor); + return equeue_post(e->equeue, &local::call, p); + } + + static void dtor(struct event *e) { + reinterpret_cast(e+1)->~F(); + } + }; + + _event = static_cast( + equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); + if (_event) { + _event->equeue = &q->_equeue; + _event->id = 0; + _event->delay = 0; + _event->period = -1; + + _event->post = &local::post; + _event->dtor = &local::dtor; + + new (_event+1) F(f); + + _event->ref = 1; + } + } + + /** Copy constructor for events + */ + Event(const Event &e) { + _event = 0; + if (e._event) { + _event = e._event; + _event->ref += 1; + } + } + + /** Assignment operator for events + */ + Event &operator=(const Event &that) { + if (this != &that) { + this->~Event(); + new (this) Event(that); + } + + return *this; + } + + /** Destructor for events + */ + ~Event() { + if (_event) { + _event->ref -= 1; + if (_event->ref == 0) { + _event->dtor(_event); + equeue_dealloc(_event->equeue, _event); + } + } + } + + /** Configure the delay of an event + * + * @param delay Millisecond delay before dispatching the event + */ + void delay(int delay) { + if (_event) { + _event->delay = delay; + } + } + + /** Configure the period of an event + * + * @param period Millisecond period for repeatedly dispatching an event + */ + void period(int period) { + if (_event) { + _event->period = period; + } + } + + /** Posts an event onto the underlying event queue + * + * The event is posted to the underlying queue and is executed in the + * context of the event queue's dispatch loop. + * + * The post function is irq safe and can act as a mechanism for moving + * events out of irq contexts. + * + * @param a0..a4 Arguments to pass to the event + * @return A unique id that represents the posted event and can + * be passed to EventQueue::cancel, or an id of 0 if + * there is not enough memory to allocate the event. + */ + int post(A0 a0) const { + if (!_event) { + return 0; + } + + _event->id = _event->post(_event, a0); + return _event->id; + } + + /** Posts an event onto the underlying event queue, returning void + * + * @param a0..a4 Arguments to pass to the event + */ + void call(A0 a0) const { + int id = post(a0); + MBED_ASSERT(id); + } + + /** Posts an event onto the underlying event queue, returning void + * + * @param a0..a4 Arguments to pass to the event + */ + void operator()(A0 a0) const { + return call(a0); + } + + /** Static thunk for passing as C-style function + * + * @param func Event to call passed as a void pointer + * @param a0..a4 Arguments to pass to the event + */ + static void thunk(void *func, A0 a0) { + return static_cast(func)->call(a0); + } + + /** Cancels the most recently posted event + * + * Attempts to cancel the most recently posted event. It is safe to call + * cancel after an event has already been dispatched. + * + * The cancel function is irq safe. + * + * If called while the event queue's dispatch loop is active, the cancel + * function does not garuntee that the event will not execute after it + * returns, as the event may have already begun executing. + */ + void cancel() const { + if (_event) { + equeue_cancel(_event->equeue, _event->id); + } + } + +private: + struct event { + unsigned ref; + equeue_t *equeue; + int id; + + int delay; + int period; + + int (*post)(struct event *, A0 a0); + void (*dtor)(struct event *); + + // F follows + } *_event; + +public: + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0) { + new (this) Event(q, EventQueue::context11(f, c0)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1) { + new (this) Event(q, EventQueue::context21(f, c0, c1)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) { + new (this) Event(q, EventQueue::context31(f, c0, c1, c2)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) { + new (this) Event(q, EventQueue::context41(f, c0, c1, c2, c3)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + new (this) Event(q, EventQueue::context51(f, c0, c1, c2, c3, c4)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, A0), B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, A0) const, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, A0) volatile, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, A0) const volatile, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, A0), B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, A0) const, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, A0) volatile, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, A0) const volatile, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, A0), B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, A0) const, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, A0) volatile, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, A0) const volatile, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, A0), B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, A0) const, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0) volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } +}; + +/** Event + * + * Representation of an event for fine-grain dispatch control + */ +template +class Event { +public: + /** Create an event + * + * Constructs an event bound to the specified event queue. The specified + * callback acts as the target for the event and is executed in the + * context of the event queue's dispatch loop once posted. + * + * @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 + */ + template + Event(EventQueue *q, F f) { + struct local { + static int post(struct event *e, A0 a0, A1 a1) { + typedef EventQueue::context20 C; + struct local { + static void call(void *p) { (*static_cast(p))(); } + static void dtor(void *p) { static_cast(p)->~C(); } + }; + + void *p = equeue_alloc(e->equeue, sizeof(C)); + if (!p) { + return 0; + } + + new (p) C(*reinterpret_cast(e+1), a0, a1); + equeue_event_delay(p, e->delay); + equeue_event_period(p, e->period); + equeue_event_dtor(p, &local::dtor); + return equeue_post(e->equeue, &local::call, p); + } + + static void dtor(struct event *e) { + reinterpret_cast(e+1)->~F(); + } + }; + + _event = static_cast( + equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); + if (_event) { + _event->equeue = &q->_equeue; + _event->id = 0; + _event->delay = 0; + _event->period = -1; + + _event->post = &local::post; + _event->dtor = &local::dtor; + + new (_event+1) F(f); + + _event->ref = 1; + } + } + + /** Copy constructor for events + */ + Event(const Event &e) { + _event = 0; + if (e._event) { + _event = e._event; + _event->ref += 1; + } + } + + /** Assignment operator for events + */ + Event &operator=(const Event &that) { + if (this != &that) { + this->~Event(); + new (this) Event(that); + } + + return *this; + } + + /** Destructor for events + */ + ~Event() { + if (_event) { + _event->ref -= 1; + if (_event->ref == 0) { + _event->dtor(_event); + equeue_dealloc(_event->equeue, _event); + } + } + } + + /** Configure the delay of an event + * + * @param delay Millisecond delay before dispatching the event + */ + void delay(int delay) { + if (_event) { + _event->delay = delay; + } + } + + /** Configure the period of an event + * + * @param period Millisecond period for repeatedly dispatching an event + */ + void period(int period) { + if (_event) { + _event->period = period; + } + } + + /** Posts an event onto the underlying event queue + * + * The event is posted to the underlying queue and is executed in the + * context of the event queue's dispatch loop. + * + * The post function is irq safe and can act as a mechanism for moving + * events out of irq contexts. + * + * @param a0..a4 Arguments to pass to the event + * @return A unique id that represents the posted event and can + * be passed to EventQueue::cancel, or an id of 0 if + * there is not enough memory to allocate the event. + */ + int post(A0 a0, A1 a1) const { + if (!_event) { + return 0; + } + + _event->id = _event->post(_event, a0, a1); + return _event->id; + } + + /** Posts an event onto the underlying event queue, returning void + * + * @param a0..a4 Arguments to pass to the event + */ + void call(A0 a0, A1 a1) const { + int id = post(a0, a1); + MBED_ASSERT(id); + } + + /** Posts an event onto the underlying event queue, returning void + * + * @param a0..a4 Arguments to pass to the event + */ + void operator()(A0 a0, A1 a1) const { + return call(a0, a1); + } + + /** Static thunk for passing as C-style function + * + * @param func Event to call passed as a void pointer + * @param a0..a4 Arguments to pass to the event + */ + static void thunk(void *func, A0 a0, A1 a1) { + return static_cast(func)->call(a0, a1); + } + + /** Cancels the most recently posted event + * + * Attempts to cancel the most recently posted event. It is safe to call + * cancel after an event has already been dispatched. + * + * The cancel function is irq safe. + * + * If called while the event queue's dispatch loop is active, the cancel + * function does not garuntee that the event will not execute after it + * returns, as the event may have already begun executing. + */ + void cancel() const { + if (_event) { + equeue_cancel(_event->equeue, _event->id); + } + } + +private: + struct event { + unsigned ref; + equeue_t *equeue; + int id; + + int delay; + int period; + + int (*post)(struct event *, A0 a0, A1 a1); + void (*dtor)(struct event *); + + // F follows + } *_event; + +public: + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0) { + new (this) Event(q, EventQueue::context12(f, c0)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1) { + new (this) Event(q, EventQueue::context22(f, c0, c1)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) { + new (this) Event(q, EventQueue::context32(f, c0, c1, c2)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) { + new (this) Event(q, EventQueue::context42(f, c0, c1, c2, c3)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + new (this) Event(q, EventQueue::context52(f, c0, c1, c2, c3, c4)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, A0, A1), B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, A0, A1) const, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, A0, A1) volatile, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, A0, A1) const volatile, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, A0, A1), B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, A0, A1) const, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, A0, A1) volatile, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, A0, A1) const volatile, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, A0, A1), B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, A0, A1) const, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1) volatile, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1) const volatile, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1), B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) const, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } +}; + +/** Event + * + * Representation of an event for fine-grain dispatch control + */ +template +class Event { +public: + /** Create an event + * + * Constructs an event bound to the specified event queue. The specified + * callback acts as the target for the event and is executed in the + * context of the event queue's dispatch loop once posted. + * + * @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 + */ + template + Event(EventQueue *q, F f) { + struct local { + static int post(struct event *e, A0 a0, A1 a1, A2 a2) { + typedef EventQueue::context30 C; + struct local { + static void call(void *p) { (*static_cast(p))(); } + static void dtor(void *p) { static_cast(p)->~C(); } + }; + + void *p = equeue_alloc(e->equeue, sizeof(C)); + if (!p) { + return 0; + } + + new (p) C(*reinterpret_cast(e+1), a0, a1, a2); + equeue_event_delay(p, e->delay); + equeue_event_period(p, e->period); + equeue_event_dtor(p, &local::dtor); + return equeue_post(e->equeue, &local::call, p); + } + + static void dtor(struct event *e) { + reinterpret_cast(e+1)->~F(); + } + }; + + _event = static_cast( + equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); + if (_event) { + _event->equeue = &q->_equeue; + _event->id = 0; + _event->delay = 0; + _event->period = -1; + + _event->post = &local::post; + _event->dtor = &local::dtor; + + new (_event+1) F(f); + + _event->ref = 1; + } + } + + /** Copy constructor for events + */ + Event(const Event &e) { + _event = 0; + if (e._event) { + _event = e._event; + _event->ref += 1; + } + } + + /** Assignment operator for events + */ + Event &operator=(const Event &that) { + if (this != &that) { + this->~Event(); + new (this) Event(that); + } + + return *this; + } + + /** Destructor for events + */ + ~Event() { + if (_event) { + _event->ref -= 1; + if (_event->ref == 0) { + _event->dtor(_event); + equeue_dealloc(_event->equeue, _event); + } + } + } + + /** Configure the delay of an event + * + * @param delay Millisecond delay before dispatching the event + */ + void delay(int delay) { + if (_event) { + _event->delay = delay; + } + } + + /** Configure the period of an event + * + * @param period Millisecond period for repeatedly dispatching an event + */ + void period(int period) { + if (_event) { + _event->period = period; + } + } + + /** Posts an event onto the underlying event queue + * + * The event is posted to the underlying queue and is executed in the + * context of the event queue's dispatch loop. + * + * The post function is irq safe and can act as a mechanism for moving + * events out of irq contexts. + * + * @param a0..a4 Arguments to pass to the event + * @return A unique id that represents the posted event and can + * be passed to EventQueue::cancel, or an id of 0 if + * there is not enough memory to allocate the event. + */ + int post(A0 a0, A1 a1, A2 a2) const { + if (!_event) { + return 0; + } + + _event->id = _event->post(_event, a0, a1, a2); + return _event->id; + } + + /** Posts an event onto the underlying event queue, returning void + * + * @param a0..a4 Arguments to pass to the event + */ + void call(A0 a0, A1 a1, A2 a2) const { + int id = post(a0, a1, a2); + MBED_ASSERT(id); + } + + /** Posts an event onto the underlying event queue, returning void + * + * @param a0..a4 Arguments to pass to the event + */ + void operator()(A0 a0, A1 a1, A2 a2) const { + return call(a0, a1, a2); + } + + /** Static thunk for passing as C-style function + * + * @param func Event to call passed as a void pointer + * @param a0..a4 Arguments to pass to the event + */ + static void thunk(void *func, A0 a0, A1 a1, A2 a2) { + return static_cast(func)->call(a0, a1, a2); + } + + /** Cancels the most recently posted event + * + * Attempts to cancel the most recently posted event. It is safe to call + * cancel after an event has already been dispatched. + * + * The cancel function is irq safe. + * + * If called while the event queue's dispatch loop is active, the cancel + * function does not garuntee that the event will not execute after it + * returns, as the event may have already begun executing. + */ + void cancel() const { + if (_event) { + equeue_cancel(_event->equeue, _event->id); + } + } + +private: + struct event { + unsigned ref; + equeue_t *equeue; + int id; + + int delay; + int period; + + int (*post)(struct event *, A0 a0, A1 a1, A2 a2); + void (*dtor)(struct event *); + + // F follows + } *_event; + +public: + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0) { + new (this) Event(q, EventQueue::context13(f, c0)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1) { + new (this) Event(q, EventQueue::context23(f, c0, c1)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) { + new (this) Event(q, EventQueue::context33(f, c0, c1, c2)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) { + new (this) Event(q, EventQueue::context43(f, c0, c1, c2, c3)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + new (this) Event(q, EventQueue::context53(f, c0, c1, c2, c3, c4)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, A0, A1, A2), B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, A0, A1, A2) const, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, A0, A1, A2) volatile, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, A0, A1, A2) const volatile, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, A0, A1, A2), B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, A0, A1, A2) const, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2) volatile, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2) const volatile, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2), B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) const, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) volatile, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) const volatile, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2), B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2) const, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2) volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } +}; + +/** Event + * + * Representation of an event for fine-grain dispatch control + */ +template +class Event { +public: + /** Create an event + * + * Constructs an event bound to the specified event queue. The specified + * callback acts as the target for the event and is executed in the + * context of the event queue's dispatch loop once posted. + * + * @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 + */ + template + Event(EventQueue *q, F f) { + struct local { + static int post(struct event *e, A0 a0, A1 a1, A2 a2, A3 a3) { + typedef EventQueue::context40 C; + struct local { + static void call(void *p) { (*static_cast(p))(); } + static void dtor(void *p) { static_cast(p)->~C(); } + }; + + void *p = equeue_alloc(e->equeue, sizeof(C)); + if (!p) { + return 0; + } + + new (p) C(*reinterpret_cast(e+1), a0, a1, a2, a3); + equeue_event_delay(p, e->delay); + equeue_event_period(p, e->period); + equeue_event_dtor(p, &local::dtor); + return equeue_post(e->equeue, &local::call, p); + } + + static void dtor(struct event *e) { + reinterpret_cast(e+1)->~F(); + } + }; + + _event = static_cast( + equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); + if (_event) { + _event->equeue = &q->_equeue; + _event->id = 0; + _event->delay = 0; + _event->period = -1; + + _event->post = &local::post; + _event->dtor = &local::dtor; + + new (_event+1) F(f); + + _event->ref = 1; + } + } + + /** Copy constructor for events + */ + Event(const Event &e) { + _event = 0; + if (e._event) { + _event = e._event; + _event->ref += 1; + } + } + + /** Assignment operator for events + */ + Event &operator=(const Event &that) { + if (this != &that) { + this->~Event(); + new (this) Event(that); + } + + return *this; + } + + /** Destructor for events + */ + ~Event() { + if (_event) { + _event->ref -= 1; + if (_event->ref == 0) { + _event->dtor(_event); + equeue_dealloc(_event->equeue, _event); + } + } + } + + /** Configure the delay of an event + * + * @param delay Millisecond delay before dispatching the event + */ + void delay(int delay) { + if (_event) { + _event->delay = delay; + } + } + + /** Configure the period of an event + * + * @param period Millisecond period for repeatedly dispatching an event + */ + void period(int period) { + if (_event) { + _event->period = period; + } + } + + /** Posts an event onto the underlying event queue + * + * The event is posted to the underlying queue and is executed in the + * context of the event queue's dispatch loop. + * + * The post function is irq safe and can act as a mechanism for moving + * events out of irq contexts. + * + * @param a0..a4 Arguments to pass to the event + * @return A unique id that represents the posted event and can + * be passed to EventQueue::cancel, or an id of 0 if + * there is not enough memory to allocate the event. + */ + int post(A0 a0, A1 a1, A2 a2, A3 a3) const { + if (!_event) { + return 0; + } + + _event->id = _event->post(_event, a0, a1, a2, a3); + return _event->id; + } + + /** Posts an event onto the underlying event queue, returning void + * + * @param a0..a4 Arguments to pass to the event + */ + void call(A0 a0, A1 a1, A2 a2, A3 a3) const { + int id = post(a0, a1, a2, a3); + MBED_ASSERT(id); + } + + /** Posts an event onto the underlying event queue, returning void + * + * @param a0..a4 Arguments to pass to the event + */ + void operator()(A0 a0, A1 a1, A2 a2, A3 a3) const { + return call(a0, a1, a2, a3); + } + + /** Static thunk for passing as C-style function + * + * @param func Event to call passed as a void pointer + * @param a0..a4 Arguments to pass to the event + */ + static void thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3) { + return static_cast(func)->call(a0, a1, a2, a3); + } + + /** Cancels the most recently posted event + * + * Attempts to cancel the most recently posted event. It is safe to call + * cancel after an event has already been dispatched. + * + * The cancel function is irq safe. + * + * If called while the event queue's dispatch loop is active, the cancel + * function does not garuntee that the event will not execute after it + * returns, as the event may have already begun executing. + */ + void cancel() const { + if (_event) { + equeue_cancel(_event->equeue, _event->id); + } + } + +private: + struct event { + unsigned ref; + equeue_t *equeue; + int id; + + int delay; + int period; + + int (*post)(struct event *, A0 a0, A1 a1, A2 a2, A3 a3); + void (*dtor)(struct event *); + + // F follows + } *_event; + +public: + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0) { + new (this) Event(q, EventQueue::context14(f, c0)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1) { + new (this) Event(q, EventQueue::context24(f, c0, c1)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) { + new (this) Event(q, EventQueue::context34(f, c0, c1, c2)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) { + new (this) Event(q, EventQueue::context44(f, c0, c1, c2, c3)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + new (this) Event(q, EventQueue::context54(f, c0, c1, c2, c3, c4)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, A0, A1, A2, A3), B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, A0, A1, A2, A3) const, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3) volatile, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3) const volatile, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3), B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) const, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) volatile, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) const volatile, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3), B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) const, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) volatile, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) const volatile, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3), B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) const, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } +}; + +/** Event + * + * Representation of an event for fine-grain dispatch control + */ +template +class Event { +public: + /** Create an event + * + * Constructs an event bound to the specified event queue. The specified + * callback acts as the target for the event and is executed in the + * context of the event queue's dispatch loop once posted. + * + * @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 + */ + template + Event(EventQueue *q, F f) { + struct local { + static int post(struct event *e, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + typedef EventQueue::context50 C; + struct local { + static void call(void *p) { (*static_cast(p))(); } + static void dtor(void *p) { static_cast(p)->~C(); } + }; + + void *p = equeue_alloc(e->equeue, sizeof(C)); + if (!p) { + return 0; + } + + new (p) C(*reinterpret_cast(e+1), a0, a1, a2, a3, a4); + equeue_event_delay(p, e->delay); + equeue_event_period(p, e->period); + equeue_event_dtor(p, &local::dtor); + return equeue_post(e->equeue, &local::call, p); + } + + static void dtor(struct event *e) { + reinterpret_cast(e+1)->~F(); + } + }; + + _event = static_cast( + equeue_alloc(&q->_equeue, sizeof(struct event) + sizeof(F))); + if (_event) { + _event->equeue = &q->_equeue; + _event->id = 0; + _event->delay = 0; + _event->period = -1; + + _event->post = &local::post; + _event->dtor = &local::dtor; + + new (_event+1) F(f); + + _event->ref = 1; + } + } + + /** Copy constructor for events + */ + Event(const Event &e) { + _event = 0; + if (e._event) { + _event = e._event; + _event->ref += 1; + } + } + + /** Assignment operator for events + */ + Event &operator=(const Event &that) { + if (this != &that) { + this->~Event(); + new (this) Event(that); + } + + return *this; + } + + /** Destructor for events + */ + ~Event() { + if (_event) { + _event->ref -= 1; + if (_event->ref == 0) { + _event->dtor(_event); + equeue_dealloc(_event->equeue, _event); + } + } + } + + /** Configure the delay of an event + * + * @param delay Millisecond delay before dispatching the event + */ + void delay(int delay) { + if (_event) { + _event->delay = delay; + } + } + + /** Configure the period of an event + * + * @param period Millisecond period for repeatedly dispatching an event + */ + void period(int period) { + if (_event) { + _event->period = period; + } + } + + /** Posts an event onto the underlying event queue + * + * The event is posted to the underlying queue and is executed in the + * context of the event queue's dispatch loop. + * + * The post function is irq safe and can act as a mechanism for moving + * events out of irq contexts. + * + * @param a0..a4 Arguments to pass to the event + * @return A unique id that represents the posted event and can + * be passed to EventQueue::cancel, or an id of 0 if + * there is not enough memory to allocate the event. + */ + int post(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const { + if (!_event) { + return 0; + } + + _event->id = _event->post(_event, a0, a1, a2, a3, a4); + return _event->id; + } + + /** Posts an event onto the underlying event queue, returning void + * + * @param a0..a4 Arguments to pass to the event + */ + void call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const { + int id = post(a0, a1, a2, a3, a4); + MBED_ASSERT(id); + } + + /** Posts an event onto the underlying event queue, returning void + * + * @param a0..a4 Arguments to pass to the event + */ + void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const { + return call(a0, a1, a2, a3, a4); + } + + /** Static thunk for passing as C-style function + * + * @param func Event to call passed as a void pointer + * @param a0..a4 Arguments to pass to the event + */ + static void thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return static_cast(func)->call(a0, a1, a2, a3, a4); + } + + /** Cancels the most recently posted event + * + * Attempts to cancel the most recently posted event. It is safe to call + * cancel after an event has already been dispatched. + * + * The cancel function is irq safe. + * + * If called while the event queue's dispatch loop is active, the cancel + * function does not garuntee that the event will not execute after it + * returns, as the event may have already begun executing. + */ + void cancel() const { + if (_event) { + equeue_cancel(_event->equeue, _event->id); + } + } + +private: + struct event { + unsigned ref; + equeue_t *equeue; + int id; + + int delay; + int period; + + int (*post)(struct event *, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4); + void (*dtor)(struct event *); + + // F follows + } *_event; + +public: + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0) { + new (this) Event(q, EventQueue::context15(f, c0)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1) { + new (this) Event(q, EventQueue::context25(f, c0, c1)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2) { + new (this) Event(q, EventQueue::context35(f, c0, c1, c2)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3) { + new (this) Event(q, EventQueue::context45(f, c0, c1, c2, c3)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + new (this) Event(q, EventQueue::context55(f, c0, c1, c2, c3, c4)); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4), B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) const, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) volatile, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) const volatile, B0 b0) { + new (this) Event(q, mbed::callback(obj, method), b0); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4), B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) const, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) volatile, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) const volatile, B0 b0, B1 b1) { + new (this) Event(q, mbed::callback(obj, method), b0, b1); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4), B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) const, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) volatile, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) const volatile, B0 b0, B1 b1, B2 b2) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4), B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) const, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } + + /** Create an event + * @see Event::Event + */ + template + Event(EventQueue *q, const volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) { + new (this) Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4); + } +}; + + + +// Convenience functions declared here to avoid cyclic +// dependency between Event and EventQueue +template +Event EventQueue::event(R (*func)()) { + return Event(this, func); +} + +template +Event EventQueue::event(T *obj, R (T::*method)()) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)() const) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)() volatile) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)() const volatile) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(R (*func)(B0), C0 c0) { + return Event(this, func, c0); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0), C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0) const, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0) volatile, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0) const volatile, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(R (*func)(B0, B1), C0 c0, C1 c1) { + return Event(this, func, c0, c1); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1), C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1) const, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1) volatile, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1) const volatile, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(R (*func)(B0, B1, B2), C0 c0, C1 c1, C2 c2) { + return Event(this, func, c0, c1, c2); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2), C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2) const, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2) volatile, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2) const volatile, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(R (*func)(B0, B1, B2, B3), C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, func, c0, c1, c2, c3); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3), C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3) const, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3) volatile, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3) const volatile, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(R (*func)(B0, B1, B2, B3, B4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, func, c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, B4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::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) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(R (*func)(A0)) { + return Event(this, func); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(A0)) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(A0) const) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(A0) volatile) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(A0) const volatile) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(R (*func)(B0, A0), C0 c0) { + return Event(this, func, c0); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, A0), C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, A0) const, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, A0) volatile, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, A0) const volatile, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(R (*func)(B0, B1, A0), C0 c0, C1 c1) { + return Event(this, func, c0, c1); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, A0), C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, A0) const, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, A0) volatile, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, A0) const volatile, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(R (*func)(B0, B1, B2, A0), C0 c0, C1 c1, C2 c2) { + return Event(this, func, c0, c1, c2); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, A0), C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, A0) const, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, A0) volatile, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0) const volatile, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(R (*func)(B0, B1, B2, B3, A0), C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, func, c0, c1, c2, c3); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, A0), C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0) const, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0) volatile, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0) const volatile, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(R (*func)(B0, B1, B2, B3, B4, A0), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, func, c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::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) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(R (*func)(A0, A1)) { + return Event(this, func); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(A0, A1)) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(A0, A1) const) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(A0, A1) volatile) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(A0, A1) const volatile) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(R (*func)(B0, A0, A1), C0 c0) { + return Event(this, func, c0); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, A0, A1), C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, A0, A1) const, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, A0, A1) volatile, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, A0, A1) const volatile, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(R (*func)(B0, B1, A0, A1), C0 c0, C1 c1) { + return Event(this, func, c0, c1); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, A0, A1), C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, A0, A1) const, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, A0, A1) volatile, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1) const volatile, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(R (*func)(B0, B1, B2, A0, A1), C0 c0, C1 c1, C2 c2) { + return Event(this, func, c0, c1, c2); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, A0, A1), C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, A0, A1) const, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1) volatile, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1) const volatile, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(R (*func)(B0, B1, B2, B3, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, func, c0, c1, c2, c3); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) const, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) volatile, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) const volatile, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(R (*func)(B0, B1, B2, B3, B4, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, func, c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::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) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(R (*func)(A0, A1, A2)) { + return Event(this, func); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(A0, A1, A2)) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(A0, A1, A2) const) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(A0, A1, A2) volatile) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(A0, A1, A2) const volatile) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(R (*func)(B0, A0, A1, A2), C0 c0) { + return Event(this, func, c0); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, A0, A1, A2), C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, A0, A1, A2) const, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, A0, A1, A2) volatile, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, A0, A1, A2) const volatile, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(R (*func)(B0, B1, A0, A1, A2), C0 c0, C1 c1) { + return Event(this, func, c0, c1); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, A0, A1, A2), C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, A0, A1, A2) const, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2) volatile, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2) const volatile, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(R (*func)(B0, B1, B2, A0, A1, A2), C0 c0, C1 c1, C2 c2) { + return Event(this, func, c0, c1, c2); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2), C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) const, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) volatile, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) const volatile, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(R (*func)(B0, B1, B2, B3, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, func, c0, c1, c2, c3); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2) const, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2) volatile, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::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) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(R (*func)(B0, B1, B2, B3, B4, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, func, c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::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) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(R (*func)(A0, A1, A2, A3)) { + return Event(this, func); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(A0, A1, A2, A3)) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(A0, A1, A2, A3) const) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(A0, A1, A2, A3) volatile) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(A0, A1, A2, A3) const volatile) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(R (*func)(B0, A0, A1, A2, A3), C0 c0) { + return Event(this, func, c0); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, A0, A1, A2, A3), C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, A0, A1, A2, A3) const, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3) volatile, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3) const volatile, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(R (*func)(B0, B1, A0, A1, A2, A3), C0 c0, C1 c1) { + return Event(this, func, c0, c1); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3), C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) const, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) volatile, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) const volatile, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(R (*func)(B0, B1, B2, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2) { + return Event(this, func, c0, c1, c2); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) volatile, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) const volatile, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(R (*func)(B0, B1, B2, B3, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, func, c0, c1, c2, c3); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) volatile, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::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) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event 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(this, func, c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::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) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(R (*func)(A0, A1, A2, A3, A4)) { + return Event(this, func); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(A0, A1, A2, A3, A4)) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(A0, A1, A2, A3, A4) const) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) { + return Event(this, mbed::callback(obj, method)); +} + +template +Event EventQueue::event(R (*func)(B0, A0, A1, A2, A3, A4), C0 c0) { + return Event(this, func, c0); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4), C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) const, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) volatile, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) const volatile, C0 c0) { + return Event(this, mbed::callback(obj, method), c0); +} + +template +Event EventQueue::event(R (*func)(B0, B1, A0, A1, A2, A3, A4), C0 c0, C1 c1) { + return Event(this, func, c0, c1); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4), C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) const, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) const volatile, C0 c0, C1 c1) { + return Event(this, mbed::callback(obj, method), c0, c1); +} + +template +Event EventQueue::event(R (*func)(B0, B1, B2, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2) { + return Event(this, func, c0, c1, c2); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(const volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) const volatile, C0 c0, C1 c1, C2 c2) { + return Event(this, mbed::callback(obj, method), c0, c1, c2); +} + +template +Event EventQueue::event(R (*func)(B0, B1, B2, B3, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, func, c0, c1, c2, c3); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1, C2 c2, C3 c3) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event EventQueue::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) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3); +} + +template +Event 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(this, func, c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +template +Event EventQueue::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) { + return Event(this, mbed::callback(obj, method), c0, c1, c2, c3, c4); +} + +} + +#endif diff --git a/events/EventQueue.cpp b/events/EventQueue.cpp new file mode 100644 index 0000000000..e23d714104 --- /dev/null +++ b/events/EventQueue.cpp @@ -0,0 +1,66 @@ +/* events + * Copyright (c) 2016 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. + */ +#include "EventQueue.h" + +#include "mbed_events.h" +#include "mbed.h" + + +EventQueue::EventQueue(unsigned event_size, unsigned char *event_pointer) { + if (!event_pointer) { + equeue_create(&_equeue, event_size); + } else { + equeue_create_inplace(&_equeue, event_size, event_pointer); + } +} + +EventQueue::~EventQueue() { + equeue_destroy(&_equeue); +} + +void EventQueue::dispatch(int ms) { + return equeue_dispatch(&_equeue, ms); +} + +void EventQueue::break_dispatch() { + return equeue_break(&_equeue); +} + +unsigned EventQueue::tick() { + return equeue_tick(); +} + +void EventQueue::cancel(int id) { + return equeue_cancel(&_equeue, id); +} + +void EventQueue::background(Callback update) { + _update = update; + + if (_update) { + equeue_background(&_equeue, &Callback::thunk, &_update); + } else { + equeue_background(&_equeue, 0, 0); + } +} + +void EventQueue::chain(EventQueue *target) { + if (target) { + equeue_chain(&_equeue, &target->_equeue); + } else { + equeue_chain(&_equeue, 0); + } +} diff --git a/events/EventQueue.h b/events/EventQueue.h new file mode 100644 index 0000000000..4c0f5f5ec0 --- /dev/null +++ b/events/EventQueue.h @@ -0,0 +1,2480 @@ +/* events + * Copyright (c) 2016 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. + */ +#ifndef EVENT_QUEUE_H +#define EVENT_QUEUE_H + +#include "equeue/equeue.h" +#include "Callback.h" +#include +#include + +namespace events { + +/** EVENTS_EVENT_SIZE + * Minimum size of an event + * This size fits a Callback at minimum + */ +#define EVENTS_EVENT_SIZE \ + (EQUEUE_EVENT_SIZE - 2*sizeof(void*) + sizeof(mbed::Callback)) + +/** EVENTS_QUEUE_SIZE + * Default size of buffer for events + */ +#define EVENTS_QUEUE_SIZE (32*EVENTS_EVENT_SIZE) + +// Predeclared classes +template +class Event; + + +/** EventQueue + * + * Flexible event queue for dispatching events + */ +class EventQueue { +public: + /** Create an EventQueue + * + * Create an event queue. The event queue either allocates a buffer of + * the specified size with malloc or uses the user provided buffer. + * + * @param size Size of buffer to use for events in bytes + * (default to EVENTS_QUEUE_SIZE) + * @param buffer Pointer to buffer to use for events + * (default to NULL) + */ + EventQueue(unsigned size=EVENTS_QUEUE_SIZE, unsigned char *buffer=NULL); + + /** Destroy an EventQueue + */ + ~EventQueue(); + + /** Dispatch events + * + * Executes events until the specified milliseconds have passed. + * If ms is negative, the dispatch function will dispatch events + * indefinitely or until break_dispatch is called on this queue. + * + * When called with a finite timeout, the dispatch function is guaranteed + * to terminate. When called with a timeout of 0, the dispatch function + * does not wait and is irq safe. + * + * @param ms Time to wait for events in milliseconds, a negative + * value will dispatch events indefinitely + * (default to -1) + */ + void dispatch(int ms=-1); + + /** Dispatch events without a timeout + * + * This is equivalent to EventQueue::dispatch with no arguments, but + * avoids overload ambiguities when passed as a callback. + * + * @see EventQueue::dispatch + */ + void dispatch_forever() { dispatch(); } + + /** Break out of a running event loop + * + * Forces the specified event queue's dispatch loop to terminate. Pending + * events may finish executing, but no new events will be executed. + */ + void break_dispatch(); + + /** Millisecond counter + * + * Returns the underlying tick of the event queue represented as the + * number of milliseconds that have passed since an arbitrary point in + * time. Intentionally overflows to 0 after 2^32-1. + * + * @return The underlying tick of the event queue in milliseconds + */ + unsigned tick(); + + /** Cancel an in-flight event + * + * Attempts to cancel an event referenced by the unique id returned from + * one of the call functions. It is safe to call cancel after an event + * has already been dispatched. + * + * The cancel function is irq safe. + * + * If called while the event queue's dispatch loop is active, the cancel + * function does not garuntee that the event will not execute after it + * returns, as the event may have already begun executing. + * + * @param id Unique id of the event + */ + void cancel(int id); + + /** Background an event queue onto a single-shot timer-interrupt + * + * When updated, the event queue will call the provided update function + * with a timeout indicating when the queue should be dispatched. A + * negative timeout will be passed to the update function when the + * timer-interrupt is no longer needed. + * + * Passing a null function disables the existing update function. + * + * The background function allows an event queue to take advantage of + * hardware timers or other event loops, allowing an event queue to be + * ran in the background without consuming the foreground thread. + * + * @param update Function called to indicate when the queue should be + * dispatched + */ + void background(mbed::Callback update); + + /** Chain an event queue onto another event queue + * + * After chaining a queue to a target, calling dispatch on the target + * queue will also dispatch events from this queue. The queues use + * their own buffers and events must be handled independently. + * + * A null queue as the target will unchain the existing queue. + * + * The chain function allows multiple event queues to be composed, + * sharing the context of a dispatch loop while still being managed + * independently + * + * @param target Queue that will dispatch this queue's events as a + * part of its dispatch loop + */ + void chain(EventQueue *target); + + /** Calls an event on the queue + * + * The specified callback will be executed in the context of the event + * queue's dispatch loop. + * + * The call function is irq safe and can act as a mechanism for moving + * events out of irq contexts. + * + * @param f Function to execute in the context of the dispatch loop + * @param a0..a4 Arguments to pass to the callback + * @return A unique id that represents the posted event and can + * be passed to cancel, or an id of 0 if there is not + * enough memory to allocate the event. + */ + template + int call(F f) { + struct local { + static void call(void *p) { (*static_cast(p))(); } + static void dtor(void *p) { static_cast(p)->~F(); } + }; + + void *p = equeue_alloc(&_equeue, sizeof(F)); + if (!p) { + return 0; + } + + F *e = new (p) F(f); + equeue_event_dtor(e, &local::dtor); + return equeue_post(&_equeue, &local::call, e); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(F f, A0 a0) { + return call(context10(f, a0)); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(F f, A0 a0, A1 a1) { + return call(context20(f, a0, a1)); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(F f, A0 a0, A1 a1, A2 a2) { + return call(context30(f, a0, a1, a2)); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(F f, A0 a0, A1 a1, A2 a2, A3 a3) { + return call(context40(f, a0, a1, a2, a3)); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(F f, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return call(context50(f, a0, a1, a2, a3, a4)); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(T *obj, R (T::*method)()) { + return call(mbed::callback(obj, method)); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(const T *obj, R (T::*method)() const) { + return call(mbed::callback(obj, method)); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(volatile T *obj, R (T::*method)() volatile) { + return call(mbed::callback(obj, method)); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(const volatile T *obj, R (T::*method)() const volatile) { + return call(mbed::callback(obj, method)); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(T *obj, R (T::*method)(A0), A0 a0) { + return call(mbed::callback(obj, method), a0); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(const T *obj, R (T::*method)(A0) const, A0 a0) { + return call(mbed::callback(obj, method), a0); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(volatile T *obj, R (T::*method)(A0) volatile, A0 a0) { + return call(mbed::callback(obj, method), a0); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(const volatile T *obj, R (T::*method)(A0) const volatile, A0 a0) { + return call(mbed::callback(obj, method), a0); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(T *obj, R (T::*method)(A0, A1), A0 a0, A1 a1) { + return call(mbed::callback(obj, method), a0, a1); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(const T *obj, R (T::*method)(A0, A1) const, A0 a0, A1 a1) { + return call(mbed::callback(obj, method), a0, a1); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(volatile T *obj, R (T::*method)(A0, A1) volatile, A0 a0, A1 a1) { + return call(mbed::callback(obj, method), a0, a1); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(const volatile T *obj, R (T::*method)(A0, A1) const volatile, A0 a0, A1 a1) { + return call(mbed::callback(obj, method), a0, a1); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(T *obj, R (T::*method)(A0, A1, A2), A0 a0, A1 a1, A2 a2) { + return call(mbed::callback(obj, method), a0, a1, a2); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(const T *obj, R (T::*method)(A0, A1, A2) const, A0 a0, A1 a1, A2 a2) { + return call(mbed::callback(obj, method), a0, a1, a2); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(volatile T *obj, R (T::*method)(A0, A1, A2) volatile, A0 a0, A1 a1, A2 a2) { + return call(mbed::callback(obj, method), a0, a1, a2); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(const volatile T *obj, R (T::*method)(A0, A1, A2) const volatile, A0 a0, A1 a1, A2 a2) { + return call(mbed::callback(obj, method), a0, a1, a2); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(T *obj, R (T::*method)(A0, A1, A2, A3), A0 a0, A1 a1, A2 a2, A3 a3) { + return call(mbed::callback(obj, method), a0, a1, a2, a3); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(const T *obj, R (T::*method)(A0, A1, A2, A3) const, A0 a0, A1 a1, A2 a2, A3 a3) { + return call(mbed::callback(obj, method), a0, a1, a2, a3); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(volatile T *obj, R (T::*method)(A0, A1, A2, A3) volatile, A0 a0, A1 a1, A2 a2, A3 a3) { + return call(mbed::callback(obj, method), a0, a1, a2, a3); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(const volatile T *obj, R (T::*method)(A0, A1, A2, A3) const volatile, A0 a0, A1 a1, A2 a2, A3 a3) { + return call(mbed::callback(obj, method), a0, a1, a2, a3); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(T *obj, R (T::*method)(A0, A1, A2, A3, A4), A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return call(mbed::callback(obj, method), a0, a1, a2, a3, a4); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(const T *obj, R (T::*method)(A0, A1, A2, A3, A4) const, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return call(mbed::callback(obj, method), a0, a1, a2, a3, a4); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return call(mbed::callback(obj, method), a0, a1, a2, a3, a4); + } + + /** Calls an event on the queue + * @see EventQueue::call + */ + template + int call(const volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return call(mbed::callback(obj, method), a0, a1, a2, a3, a4); + } + + /** Calls an event on the queue after a specified delay + * + * The specified callback will be executed in the context of the event + * queue's dispatch loop. + * + * The call_in function is irq safe and can act as a mechanism for moving + * events out of irq contexts. + * + * @param f Function to execute in the context of the dispatch loop + * @param a0..a4 Arguments to pass to the callback + * @param ms Time to delay in milliseconds + * @return A unique id that represents the posted event and can + * be passed to cancel, or an id of 0 if there is not + * enough memory to allocate the event. + */ + template + int call_in(int ms, F f) { + struct local { + static void call(void *p) { (*static_cast(p))(); } + static void dtor(void *p) { static_cast(p)->~F(); } + }; + + void *p = equeue_alloc(&_equeue, sizeof(F)); + if (!p) { + return 0; + } + + F *e = new (p) F(f); + equeue_event_delay(e, ms); + equeue_event_dtor(e, &local::dtor); + return equeue_post(&_equeue, &local::call, e); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, F f, A0 a0) { + return call_in(ms, context10(f, a0)); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, F f, A0 a0, A1 a1) { + return call_in(ms, context20(f, a0, a1)); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, F f, A0 a0, A1 a1, A2 a2) { + return call_in(ms, context30(f, a0, a1, a2)); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, F f, A0 a0, A1 a1, A2 a2, A3 a3) { + return call_in(ms, context40(f, a0, a1, a2, a3)); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, F f, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return call_in(ms, context50(f, a0, a1, a2, a3, a4)); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, T *obj, R (T::*method)()) { + return call_in(ms, mbed::callback(obj, method)); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, const T *obj, R (T::*method)() const) { + return call_in(ms, mbed::callback(obj, method)); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, volatile T *obj, R (T::*method)() volatile) { + return call_in(ms, mbed::callback(obj, method)); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, const volatile T *obj, R (T::*method)() const volatile) { + return call_in(ms, mbed::callback(obj, method)); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, T *obj, R (T::*method)(A0), A0 a0) { + return call_in(ms, mbed::callback(obj, method), a0); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, const T *obj, R (T::*method)(A0) const, A0 a0) { + return call_in(ms, mbed::callback(obj, method), a0); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, volatile T *obj, R (T::*method)(A0) volatile, A0 a0) { + return call_in(ms, mbed::callback(obj, method), a0); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, const volatile T *obj, R (T::*method)(A0) const volatile, A0 a0) { + return call_in(ms, mbed::callback(obj, method), a0); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, T *obj, R (T::*method)(A0, A1), A0 a0, A1 a1) { + return call_in(ms, mbed::callback(obj, method), a0, a1); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, const T *obj, R (T::*method)(A0, A1) const, A0 a0, A1 a1) { + return call_in(ms, mbed::callback(obj, method), a0, a1); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, volatile T *obj, R (T::*method)(A0, A1) volatile, A0 a0, A1 a1) { + return call_in(ms, mbed::callback(obj, method), a0, a1); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, const volatile T *obj, R (T::*method)(A0, A1) const volatile, A0 a0, A1 a1) { + return call_in(ms, mbed::callback(obj, method), a0, a1); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, T *obj, R (T::*method)(A0, A1, A2), A0 a0, A1 a1, A2 a2) { + return call_in(ms, mbed::callback(obj, method), a0, a1, a2); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, const T *obj, R (T::*method)(A0, A1, A2) const, A0 a0, A1 a1, A2 a2) { + return call_in(ms, mbed::callback(obj, method), a0, a1, a2); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, volatile T *obj, R (T::*method)(A0, A1, A2) volatile, A0 a0, A1 a1, A2 a2) { + return call_in(ms, mbed::callback(obj, method), a0, a1, a2); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, const volatile T *obj, R (T::*method)(A0, A1, A2) const volatile, A0 a0, A1 a1, A2 a2) { + return call_in(ms, mbed::callback(obj, method), a0, a1, a2); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, T *obj, R (T::*method)(A0, A1, A2, A3), A0 a0, A1 a1, A2 a2, A3 a3) { + return call_in(ms, mbed::callback(obj, method), a0, a1, a2, a3); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, const T *obj, R (T::*method)(A0, A1, A2, A3) const, A0 a0, A1 a1, A2 a2, A3 a3) { + return call_in(ms, mbed::callback(obj, method), a0, a1, a2, a3); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, volatile T *obj, R (T::*method)(A0, A1, A2, A3) volatile, A0 a0, A1 a1, A2 a2, A3 a3) { + return call_in(ms, mbed::callback(obj, method), a0, a1, a2, a3); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, const volatile T *obj, R (T::*method)(A0, A1, A2, A3) const volatile, A0 a0, A1 a1, A2 a2, A3 a3) { + return call_in(ms, mbed::callback(obj, method), a0, a1, a2, a3); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, T *obj, R (T::*method)(A0, A1, A2, A3, A4), A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return call_in(ms, mbed::callback(obj, method), a0, a1, a2, a3, a4); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, const T *obj, R (T::*method)(A0, A1, A2, A3, A4) const, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return call_in(ms, mbed::callback(obj, method), a0, a1, a2, a3, a4); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return call_in(ms, mbed::callback(obj, method), a0, a1, a2, a3, a4); + } + + /** Calls an event on the queue after a specified delay + * @see EventQueue::call_in + */ + template + int call_in(int ms, const volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return call_in(ms, mbed::callback(obj, method), a0, a1, a2, a3, a4); + } + + /** Calls an event on the queue periodically + * + * The specified callback will be executed in the context of the event + * queue's dispatch loop. + * + * The call_every function is irq safe and can act as a mechanism for + * moving events out of irq contexts. + * + * @param f Function to execute in the context of the dispatch loop + * @param a0..a4 Arguments to pass to the callback + * @param ms Period of the event in milliseconds + * @return A unique id that represents the posted event and can + * be passed to cancel, or an id of 0 if there is not + * enough memory to allocate the event. + */ + template + int call_every(int ms, F f) { + struct local { + static void call(void *p) { (*static_cast(p))(); } + static void dtor(void *p) { static_cast(p)->~F(); } + }; + + void *p = equeue_alloc(&_equeue, sizeof(F)); + if (!p) { + return 0; + } + + F *e = new (p) F(f); + equeue_event_delay(e, ms); + equeue_event_period(e, ms); + equeue_event_dtor(e, &local::dtor); + return equeue_post(&_equeue, &local::call, e); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, F f, A0 a0) { + return call_every(ms, context10(f, a0)); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, F f, A0 a0, A1 a1) { + return call_every(ms, context20(f, a0, a1)); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, F f, A0 a0, A1 a1, A2 a2) { + return call_every(ms, context30(f, a0, a1, a2)); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, F f, A0 a0, A1 a1, A2 a2, A3 a3) { + return call_every(ms, context40(f, a0, a1, a2, a3)); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, F f, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return call_every(ms, context50(f, a0, a1, a2, a3, a4)); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, T *obj, R (T::*method)()) { + return call_every(ms, mbed::callback(obj, method)); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, const T *obj, R (T::*method)() const) { + return call_every(ms, mbed::callback(obj, method)); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, volatile T *obj, R (T::*method)() volatile) { + return call_every(ms, mbed::callback(obj, method)); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, const volatile T *obj, R (T::*method)() const volatile) { + return call_every(ms, mbed::callback(obj, method)); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, T *obj, R (T::*method)(A0), A0 a0) { + return call_every(ms, mbed::callback(obj, method), a0); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, const T *obj, R (T::*method)(A0) const, A0 a0) { + return call_every(ms, mbed::callback(obj, method), a0); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, volatile T *obj, R (T::*method)(A0) volatile, A0 a0) { + return call_every(ms, mbed::callback(obj, method), a0); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, const volatile T *obj, R (T::*method)(A0) const volatile, A0 a0) { + return call_every(ms, mbed::callback(obj, method), a0); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, T *obj, R (T::*method)(A0, A1), A0 a0, A1 a1) { + return call_every(ms, mbed::callback(obj, method), a0, a1); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, const T *obj, R (T::*method)(A0, A1) const, A0 a0, A1 a1) { + return call_every(ms, mbed::callback(obj, method), a0, a1); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, volatile T *obj, R (T::*method)(A0, A1) volatile, A0 a0, A1 a1) { + return call_every(ms, mbed::callback(obj, method), a0, a1); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, const volatile T *obj, R (T::*method)(A0, A1) const volatile, A0 a0, A1 a1) { + return call_every(ms, mbed::callback(obj, method), a0, a1); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, T *obj, R (T::*method)(A0, A1, A2), A0 a0, A1 a1, A2 a2) { + return call_every(ms, mbed::callback(obj, method), a0, a1, a2); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, const T *obj, R (T::*method)(A0, A1, A2) const, A0 a0, A1 a1, A2 a2) { + return call_every(ms, mbed::callback(obj, method), a0, a1, a2); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, volatile T *obj, R (T::*method)(A0, A1, A2) volatile, A0 a0, A1 a1, A2 a2) { + return call_every(ms, mbed::callback(obj, method), a0, a1, a2); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, const volatile T *obj, R (T::*method)(A0, A1, A2) const volatile, A0 a0, A1 a1, A2 a2) { + return call_every(ms, mbed::callback(obj, method), a0, a1, a2); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, T *obj, R (T::*method)(A0, A1, A2, A3), A0 a0, A1 a1, A2 a2, A3 a3) { + return call_every(ms, mbed::callback(obj, method), a0, a1, a2, a3); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, const T *obj, R (T::*method)(A0, A1, A2, A3) const, A0 a0, A1 a1, A2 a2, A3 a3) { + return call_every(ms, mbed::callback(obj, method), a0, a1, a2, a3); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, volatile T *obj, R (T::*method)(A0, A1, A2, A3) volatile, A0 a0, A1 a1, A2 a2, A3 a3) { + return call_every(ms, mbed::callback(obj, method), a0, a1, a2, a3); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, const volatile T *obj, R (T::*method)(A0, A1, A2, A3) const volatile, A0 a0, A1 a1, A2 a2, A3 a3) { + return call_every(ms, mbed::callback(obj, method), a0, a1, a2, a3); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, T *obj, R (T::*method)(A0, A1, A2, A3, A4), A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return call_every(ms, mbed::callback(obj, method), a0, a1, a2, a3, a4); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, const T *obj, R (T::*method)(A0, A1, A2, A3, A4) const, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return call_every(ms, mbed::callback(obj, method), a0, a1, a2, a3, a4); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return call_every(ms, mbed::callback(obj, method), a0, a1, a2, a3, a4); + } + + /** Calls an event on the queue periodically + * @see EventQueue::call_every + */ + template + int call_every(int ms, const volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return call_every(ms, mbed::callback(obj, method), a0, a1, a2, a3, a4); + } + + /** Creates an event bound to the event queue + * + * Constructs an event bound to the specified event queue. The specified + * callback acts as the target for the event and is executed in the + * 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 + * @return Event that will dispatch on the specific queue + */ + template + Event event(R (*func)()); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)()); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)() const); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)() volatile); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const volatile T *obj, R (T::*method)() const volatile); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(R (*func)(B0), C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0), C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0) const, C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0) volatile, C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1), C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1), C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1) const, C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1) volatile, C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2), C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2), C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2) const, C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2) volatile, C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2, B3), C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2, B3), C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2, B3) const, C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3) volatile, C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2, B3, B4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2, B3, B4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(A0)); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(A0)); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(A0) const); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(A0) volatile); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const volatile T *obj, R (T::*method)(A0) const volatile); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(R (*func)(B0, A0), C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, A0), C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, A0) const, C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, A0) volatile, C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, A0), C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, A0), C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, A0) const, C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, A0) volatile, C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2, A0), C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2, A0), C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2, A0) const, C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2, A0) volatile, C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2, B3, A0), C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2, B3, A0), C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0) const, C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0) volatile, C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2, B3, B4, A0), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(A0, A1)); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(A0, A1)); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(A0, A1) const); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(A0, A1) volatile); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const volatile T *obj, R (T::*method)(A0, A1) const volatile); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(R (*func)(B0, A0, A1), C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, A0, A1), C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, A0, A1) const, C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, A0, A1) volatile, C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, A0, A1), C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, A0, A1), C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, A0, A1) const, C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, A0, A1) volatile, C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2, A0, A1), C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2, A0, A1), C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2, A0, A1) const, C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1) volatile, C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2, B3, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) const, C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1) volatile, C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2, B3, B4, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(A0, A1, A2)); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(A0, A1, A2)); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(A0, A1, A2) const); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(A0, A1, A2) volatile); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, A0, A1, A2), C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, A0, A1, A2), C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, A0, A1, A2) const, C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, A0, A1, A2) volatile, C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, A0, A1, A2), C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, A0, A1, A2), C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, A0, A1, A2) const, C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2) volatile, C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2, A0, A1, A2), C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2), C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) const, C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2) volatile, C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2, B3, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2) const, C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2) volatile, C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2, B3, B4, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(A0, A1, A2, A3)); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(A0, A1, A2, A3)); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(A0, A1, A2, A3) const); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(A0, A1, A2, A3) volatile); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, A0, A1, A2, A3), C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, A0, A1, A2, A3), C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, A0, A1, A2, A3) const, C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3) volatile, C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, A0, A1, A2, A3), C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3), C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) const, C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3) volatile, C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3) volatile, C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2, B3, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3) volatile, C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2, B3, B4, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(A0, A1, A2, A3, A4)); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(A0, A1, A2, A3, A4)); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(A0, A1, A2, A3, A4) const); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, A0, A1, A2, A3, A4), C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4), C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) const, C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, A0, A1, A2, A3, A4) volatile, C0 c0); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, A0, A1, A2, A3, A4), C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4), C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) const, C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1, C2 c2); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2, B3, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1, C2 c2, C3 c3); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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 + Event event(R (*func)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(const T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event event(volatile T *obj, R (T::*method)(B0, B1, B2, B3, B4, A0, A1, A2, A3, A4) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4); + + /** Creates an event bound to the event queue + * @see EventQueue::event + */ + template + Event 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); + +protected: + template + friend class Event; + struct equeue _equeue; + mbed::Callback _update; + + template + struct context00 { + F f; + + context00(F f) + : f(f) {} + + void operator()() { + f(); + } + }; + + template + struct context10 { + F f; C0 c0; + + context10(F f, C0 c0) + : f(f), c0(c0) {} + + void operator()() { + f(c0); + } + }; + + template + struct context20 { + F f; C0 c0; C1 c1; + + context20(F f, C0 c0, C1 c1) + : f(f), c0(c0), c1(c1) {} + + void operator()() { + f(c0, c1); + } + }; + + template + struct context30 { + F f; C0 c0; C1 c1; C2 c2; + + context30(F f, C0 c0, C1 c1, C2 c2) + : f(f), c0(c0), c1(c1), c2(c2) {} + + void operator()() { + f(c0, c1, c2); + } + }; + + template + struct context40 { + F f; C0 c0; C1 c1; C2 c2; C3 c3; + + context40(F f, C0 c0, C1 c1, C2 c2, C3 c3) + : f(f), c0(c0), c1(c1), c2(c2), c3(c3) {} + + void operator()() { + f(c0, c1, c2, c3); + } + }; + + template + struct context50 { + F f; C0 c0; C1 c1; C2 c2; C3 c3; C4 c4; + + context50(F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) + : f(f), c0(c0), c1(c1), c2(c2), c3(c3), c4(c4) {} + + void operator()() { + f(c0, c1, c2, c3, c4); + } + }; + + template + struct context01 { + F f; + + context01(F f) + : f(f) {} + + void operator()(A0 a0) { + f(a0); + } + }; + + template + struct context11 { + F f; C0 c0; + + context11(F f, C0 c0) + : f(f), c0(c0) {} + + void operator()(A0 a0) { + f(c0, a0); + } + }; + + template + struct context21 { + F f; C0 c0; C1 c1; + + context21(F f, C0 c0, C1 c1) + : f(f), c0(c0), c1(c1) {} + + void operator()(A0 a0) { + f(c0, c1, a0); + } + }; + + template + struct context31 { + F f; C0 c0; C1 c1; C2 c2; + + context31(F f, C0 c0, C1 c1, C2 c2) + : f(f), c0(c0), c1(c1), c2(c2) {} + + void operator()(A0 a0) { + f(c0, c1, c2, a0); + } + }; + + template + struct context41 { + F f; C0 c0; C1 c1; C2 c2; C3 c3; + + context41(F f, C0 c0, C1 c1, C2 c2, C3 c3) + : f(f), c0(c0), c1(c1), c2(c2), c3(c3) {} + + void operator()(A0 a0) { + f(c0, c1, c2, c3, a0); + } + }; + + template + struct context51 { + F f; C0 c0; C1 c1; C2 c2; C3 c3; C4 c4; + + context51(F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) + : f(f), c0(c0), c1(c1), c2(c2), c3(c3), c4(c4) {} + + void operator()(A0 a0) { + f(c0, c1, c2, c3, c4, a0); + } + }; + + template + struct context02 { + F f; + + context02(F f) + : f(f) {} + + void operator()(A0 a0, A1 a1) { + f(a0, a1); + } + }; + + template + struct context12 { + F f; C0 c0; + + context12(F f, C0 c0) + : f(f), c0(c0) {} + + void operator()(A0 a0, A1 a1) { + f(c0, a0, a1); + } + }; + + template + struct context22 { + F f; C0 c0; C1 c1; + + context22(F f, C0 c0, C1 c1) + : f(f), c0(c0), c1(c1) {} + + void operator()(A0 a0, A1 a1) { + f(c0, c1, a0, a1); + } + }; + + template + struct context32 { + F f; C0 c0; C1 c1; C2 c2; + + context32(F f, C0 c0, C1 c1, C2 c2) + : f(f), c0(c0), c1(c1), c2(c2) {} + + void operator()(A0 a0, A1 a1) { + f(c0, c1, c2, a0, a1); + } + }; + + template + struct context42 { + F f; C0 c0; C1 c1; C2 c2; C3 c3; + + context42(F f, C0 c0, C1 c1, C2 c2, C3 c3) + : f(f), c0(c0), c1(c1), c2(c2), c3(c3) {} + + void operator()(A0 a0, A1 a1) { + f(c0, c1, c2, c3, a0, a1); + } + }; + + template + struct context52 { + F f; C0 c0; C1 c1; C2 c2; C3 c3; C4 c4; + + context52(F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) + : f(f), c0(c0), c1(c1), c2(c2), c3(c3), c4(c4) {} + + void operator()(A0 a0, A1 a1) { + f(c0, c1, c2, c3, c4, a0, a1); + } + }; + + template + struct context03 { + F f; + + context03(F f) + : f(f) {} + + void operator()(A0 a0, A1 a1, A2 a2) { + f(a0, a1, a2); + } + }; + + template + struct context13 { + F f; C0 c0; + + context13(F f, C0 c0) + : f(f), c0(c0) {} + + void operator()(A0 a0, A1 a1, A2 a2) { + f(c0, a0, a1, a2); + } + }; + + template + struct context23 { + F f; C0 c0; C1 c1; + + context23(F f, C0 c0, C1 c1) + : f(f), c0(c0), c1(c1) {} + + void operator()(A0 a0, A1 a1, A2 a2) { + f(c0, c1, a0, a1, a2); + } + }; + + template + struct context33 { + F f; C0 c0; C1 c1; C2 c2; + + context33(F f, C0 c0, C1 c1, C2 c2) + : f(f), c0(c0), c1(c1), c2(c2) {} + + void operator()(A0 a0, A1 a1, A2 a2) { + f(c0, c1, c2, a0, a1, a2); + } + }; + + template + struct context43 { + F f; C0 c0; C1 c1; C2 c2; C3 c3; + + context43(F f, C0 c0, C1 c1, C2 c2, C3 c3) + : f(f), c0(c0), c1(c1), c2(c2), c3(c3) {} + + void operator()(A0 a0, A1 a1, A2 a2) { + f(c0, c1, c2, c3, a0, a1, a2); + } + }; + + template + struct context53 { + F f; C0 c0; C1 c1; C2 c2; C3 c3; C4 c4; + + context53(F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) + : f(f), c0(c0), c1(c1), c2(c2), c3(c3), c4(c4) {} + + void operator()(A0 a0, A1 a1, A2 a2) { + f(c0, c1, c2, c3, c4, a0, a1, a2); + } + }; + + template + struct context04 { + F f; + + context04(F f) + : f(f) {} + + void operator()(A0 a0, A1 a1, A2 a2, A3 a3) { + f(a0, a1, a2, a3); + } + }; + + template + struct context14 { + F f; C0 c0; + + context14(F f, C0 c0) + : f(f), c0(c0) {} + + void operator()(A0 a0, A1 a1, A2 a2, A3 a3) { + f(c0, a0, a1, a2, a3); + } + }; + + template + struct context24 { + F f; C0 c0; C1 c1; + + context24(F f, C0 c0, C1 c1) + : f(f), c0(c0), c1(c1) {} + + void operator()(A0 a0, A1 a1, A2 a2, A3 a3) { + f(c0, c1, a0, a1, a2, a3); + } + }; + + template + struct context34 { + F f; C0 c0; C1 c1; C2 c2; + + context34(F f, C0 c0, C1 c1, C2 c2) + : f(f), c0(c0), c1(c1), c2(c2) {} + + void operator()(A0 a0, A1 a1, A2 a2, A3 a3) { + f(c0, c1, c2, a0, a1, a2, a3); + } + }; + + template + struct context44 { + F f; C0 c0; C1 c1; C2 c2; C3 c3; + + context44(F f, C0 c0, C1 c1, C2 c2, C3 c3) + : f(f), c0(c0), c1(c1), c2(c2), c3(c3) {} + + void operator()(A0 a0, A1 a1, A2 a2, A3 a3) { + f(c0, c1, c2, c3, a0, a1, a2, a3); + } + }; + + template + struct context54 { + F f; C0 c0; C1 c1; C2 c2; C3 c3; C4 c4; + + context54(F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) + : f(f), c0(c0), c1(c1), c2(c2), c3(c3), c4(c4) {} + + void operator()(A0 a0, A1 a1, A2 a2, A3 a3) { + f(c0, c1, c2, c3, c4, a0, a1, a2, a3); + } + }; + + template + struct context05 { + F f; + + context05(F f) + : f(f) {} + + void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + f(a0, a1, a2, a3, a4); + } + }; + + template + struct context15 { + F f; C0 c0; + + context15(F f, C0 c0) + : f(f), c0(c0) {} + + void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + f(c0, a0, a1, a2, a3, a4); + } + }; + + template + struct context25 { + F f; C0 c0; C1 c1; + + context25(F f, C0 c0, C1 c1) + : f(f), c0(c0), c1(c1) {} + + void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + f(c0, c1, a0, a1, a2, a3, a4); + } + }; + + template + struct context35 { + F f; C0 c0; C1 c1; C2 c2; + + context35(F f, C0 c0, C1 c1, C2 c2) + : f(f), c0(c0), c1(c1), c2(c2) {} + + void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + f(c0, c1, c2, a0, a1, a2, a3, a4); + } + }; + + template + struct context45 { + F f; C0 c0; C1 c1; C2 c2; C3 c3; + + context45(F f, C0 c0, C1 c1, C2 c2, C3 c3) + : f(f), c0(c0), c1(c1), c2(c2), c3(c3) {} + + void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + f(c0, c1, c2, c3, a0, a1, a2, a3, a4); + } + }; + + template + struct context55 { + F f; C0 c0; C1 c1; C2 c2; C3 c3; C4 c4; + + context55(F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4) + : f(f), c0(c0), c1(c1), c2(c2), c3(c3), c4(c4) {} + + void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + f(c0, c1, c2, c3, c4, a0, a1, a2, a3, a4); + } + }; +}; + +} + +#endif diff --git a/events/LICENSE b/events/LICENSE new file mode 100644 index 0000000000..59cd3f8a32 --- /dev/null +++ b/events/LICENSE @@ -0,0 +1,165 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. diff --git a/events/README.md b/events/README.md new file mode 100644 index 0000000000..9e0263ce37 --- /dev/null +++ b/events/README.md @@ -0,0 +1,153 @@ +## The mbed-events library ## + +The mbed-events library provides a flexible queue for scheduling events. + +``` cpp +#include "mbed_events.h" +#include + +int main() { + // creates a queue with the default size + EventQueue queue; + + // events are simple callbacks + queue.call(printf, "called immediately\n"); + queue.call_in(2000, printf, "called in 2 seconds\n"); + queue.call_every(1000, printf, "called every 1 seconds\n"); + + // events are executed by the dispatch method + queue.dispatch(); +} +``` + +The mbed-events library can be used as a normal event loop, or it can be +backgrounded on a single hardware timer or even another event loop. It is +both thread and irq safe, and provides functions for easily composing +independent event queues. + +The mbed-events library can act as a drop-in scheduler, provide synchronization +between multiple threads, or just act as a mechanism for moving events out of +interrupt contexts. + +### Usage ### + +The core of the mbed-events library is the [EventQueue](EventQueue.h) class, +which represents a single event queue. The `EventQueue::dispatch` function +runs the queue, providing the context for executing events. + +``` cpp +// Creates an event queue enough buffer space for 32 Callbacks. This +// is the default if no argument was provided. Alternatively the size +// can just be specified in bytes. +EventQueue queue(32*EVENTS_EVENT_SIZE); + +// Events can be posted to the underlying event queue with dynamic +// context allocated from the specified buffer +queue.call(printf, "hello %d %d %d %d\n", 1, 2, 3, 4); +queue.call(&serial, &Serial::printf, "hi\n"); + +// The dispatch function provides the context for the running the queue +// and can take a millisecond timeout to run for a fixed time or to just +// dispatch any pending events +queue.dispatch(); +``` + +The EventQueue class provides several call functions for posting events +to the underlying event queue. The call functions are thread and irq safe, +don't need the underlying loop to be running, and provide an easy mechanism +for moving events out of interrupt contexts. + +``` cpp +// Simple call function registers events to be called as soon as possible +queue.call(doit); +queue.call(printf, "called immediately\n"); + +// The call_in function registers events to be called after a delay +// specified in milliseconds +queue.call_in(2000, doit_in_two_seconds); +queue.call_in(300, printf, "called in 0.3 seconds\n"); + +// The call_every function registers events to be called repeatedly +// with a period specified in milliseconds +queue.call_every(2000, doit_every_two_seconds); +queue.call_every(400, printf, "called every 0.4 seconds\n"); +``` + +The call functions return an id that uniquely represents the event in the +the event queue. This id can be passed to `EventQueue::cancel` to cancel +an in-flight event. + +``` cpp +// The event id uniquely represents the event in the queue +int id = queue.call_in(100, printf, "will this work?\n"); + +// If there was not enough memory necessary to allocate the event, +// an id of 0 is returned from the call functions +if (id) { + error("oh no!"); +} + +// Events can be cancelled as long as they have not been dispatched. If the +// event has already expired, cancel has no side-effects. +queue.cancel(id); +``` + +For a more fine-grain control of event dispatch, the `Event` class can be +manually instantiated and configured. An `Event` represents an event as +a C++ style function object and can be directly passed to other APIs that +expect a callback. + +``` cpp +// Creates an event bound to the specified event queue +EventQueue queue; +Event event(&queue, doit); + +// The event can be manually configured for special timing requirements +// specified in milliseconds +event.delay(10); +event.period(10000); + +// Posted events are dispatched in the context of the queue's +// dispatch function +queue.dispatch(); + +// Events can also pass arguments to the underlying callback when both +// initially constructed and posted. +Event event(&queue, printf, "recieved %d and %d\n"); + +// Events can be posted multiple times and enqueue gracefully until +// the dispatch function is called. +event.post(1, 2); +event.post(3, 4); +event.post(5, 6); + +queue.dispatch(); +``` + +Event queues easily align with module boundaries, where internal state can +be implicitly synchronized through event dispatch. Multiple modules can +use independent event queues, but still be composed through the +`EventQueue::chain` function. + +``` cpp +// Create some event queues with pending events +EventQueue a; +a.call(printf, "hello from a!\n"); + +EventQueue b; +b.call(printf, "hello from b!\n"); + +EventQueue c; +c.call(printf, "hello from c!\n"); + +// Chain c and b onto a's event queue. Both c and b will be dispatched +// in the context of a's dispatch function. +c.chain(&a); +b.chain(&a); + +// Dispatching a will in turn dispatch b and c, printing hello from +// all three queues +a.dispatch(); +``` + + diff --git a/events/equeue/.mbedignore b/events/equeue/.mbedignore new file mode 100644 index 0000000000..e7e1fb04f4 --- /dev/null +++ b/events/equeue/.mbedignore @@ -0,0 +1 @@ +tests/* diff --git a/events/equeue/Makefile b/events/equeue/Makefile new file mode 100644 index 0000000000..183f71c8e7 --- /dev/null +++ b/events/equeue/Makefile @@ -0,0 +1,60 @@ +TARGET = libequeue.a + +CC = gcc +AR = ar +SIZE = size + +SRC += $(wildcard *.c) +OBJ := $(SRC:.c=.o) +DEP := $(SRC:.c=.d) +ASM := $(SRC:.c=.s) + +ifdef DEBUG +CFLAGS += -O0 -g3 +else +CFLAGS += -O2 +endif +ifdef WORD +CFLAGS += -m$(WORD) +endif +CFLAGS += -I. +CFLAGS += -std=c99 +CFLAGS += -Wall +CFLAGS += -D_XOPEN_SOURCE=600 + +LFLAGS += -pthread + + +all: $(TARGET) + +test: tests/tests.o $(OBJ) + $(CC) $(CFLAGS) $^ $(LFLAGS) -o tests/tests + tests/tests + +prof: tests/prof.o $(OBJ) + $(CC) $(CFLAGS) $^ $(LFLAGS) -o tests/prof + tests/prof + +asm: $(ASM) + +size: $(OBJ) + $(SIZE) -t $^ + +-include $(DEP) + +%.a: $(OBJ) + $(AR) rcs $@ $^ + +%.o: %.c + $(CC) -c -MMD $(CFLAGS) $< -o $@ + +%.s: %.c + $(CC) -S $(CFLAGS) $< -o $@ + +clean: + rm -f $(TARGET) + rm -f tests/tests tests/tests.o tests/tests.d + rm -f tests/prof tests/prof.o tests/prof.d + rm -f $(OBJ) + rm -f $(DEP) + rm -f $(ASM) diff --git a/events/equeue/README.md b/events/equeue/README.md new file mode 100644 index 0000000000..10f500c56f --- /dev/null +++ b/events/equeue/README.md @@ -0,0 +1,210 @@ +## The equeue library ## + +The equeue library is designed as a simple but powerful library for scheduling +events on composable queues. + +``` c +#include "equeue.h" +#include + +int main() { + // creates a queue with space for 32 basic events + equeue_t queue; + equeue_create(&queue, 32*EQUEUE_EVENT_SIZE); + + // events can be simple callbacks + equeue_call(&queue, print, "called immediately"); + equeue_call_in(&queue, 2000, print, "called in 2 seconds"); + equeue_call_every(&queue, 1000, print, "called every 1 seconds"); + + // events are executed in equeue_dispatch + equeue_dispatch(&queue, 3000); + + print("called after 3 seconds"); + + equeue_destroy(&queue); +} +``` + +The equeue library can be used as a normal event loop, or it can be +backgrounded on a single hardware timer or even another event loop. It +is both thread and irq safe, and provides functions for easily composing +multiple queues. + +The equeue library can act as a drop-in scheduler, provide synchronization +between multiple threads, or just act as a mechanism for moving events +out of interrupt contexts. + +## Documentation ## + +The in-depth documentation on specific functions can be found in +[equeue.h](equeue.h). + +The core of the equeue library is the `equeue_t` type which represents a +single event queue, and the `equeue_dispatch` function which runs the equeue, +providing the context for executing events. + +On top of this, `equeue_call`, `equeue_call_in`, and `equeue_call_every` +provide easy methods for posting events to execute in the context of the +`equeue_dispatch` function. + +``` c +#include "equeue.h" +#include "game.h" + +equeue_t queue; +struct game game; + +// button_isr may be in interrupt context +void button_isr(void) { + equeue_call(&queue, game_button_update, &game); +} + +// a simple user-interface framework +int main() { + equeue_create(&queue, 4096); + game_create(&game); + + // call game_screen_udpate at 60 Hz + equeue_call_every(&queue, 1000/60, game_screen_update, &game); + + // dispatch forever + equeue_dispatch(&queue, -1); +} +``` + +In addition to simple callbacks, an event can be manually allocated with +`equeue_alloc` and posted with `equeue_post` to allow passing an arbitrary +amount of context to the execution of the event. This memory is allocated out +of the equeue's buffer, and dynamic memory can be completely avoided. + +The equeue allocator is designed to minimize jitter in interrupt contexts as +well as avoid memory fragmentation on small devices. The allocator achieves +both constant-runtime and zero-fragmentation for fixed-size events, however +grows linearly as the quantity of differently-sized allocations increases. + +``` c +#include "equeue.h" + +equeue_t queue; + +// arbitrary data can be moved to a different context +int enet_consume(void *buffer, int size) { + if (size > 512) { + size = 512; + } + + void *data = equeue_alloc(&queue, 512); + memcpy(data, buffer, size); + equeue_post(&queue, handle_data_elsewhere, data); + + return size; +} +``` + +Additionally, in-flight events can be cancelled with `equeue_cancel`. Events +are given unique ids on post, allowing safe cancellation of expired events. + +``` c +#include "equeue.h" + +equeue_t queue; +int sonar_value; +int sonar_timeout_id; + +void sonar_isr(int value) { + equeue_cancel(&queue, sonar_timeout_id); + sonar_value = value; +} + +void sonar_timeout(void *) { + sonar_value = -1; +} + +void sonar_read(void) { + sonar_timeout_id = equeue_call_in(&queue, 300, sonar_timeout, 0); + sonar_start(); +} +``` + +From an architectural standpoint, event queues easily align with module +boundaries, where internal state can be implicitly synchronized through +event dispatch. + +On platforms where multiple threads are unavailable, multiple modules +can use independent event queues and still be composed through the +`equeue_chain` function. + +``` c +#include "equeue.h" + +// run a simultaneous localization and mapping loop in one queue +struct slam { + equeue_t queue; +}; + +void slam_create(struct slam *s, equeue_t *target) { + equeue_create(&s->queue, 4096); + equeue_chain(&s->queue, target); + equeue_call_every(&s->queue, 100, slam_filter); +} + +// run a sonar with it's own queue +struct sonar { + equeue_t equeue; + struct slam *slam; +}; + +void sonar_create(struct sonar *s, equeue_t *target) { + equeue_create(&s->queue, 64); + equeue_chain(&s->queue, target); + equeue_call_in(&s->queue, 5, sonar_update, s); +} + +// all of the above queues can be combined into a single thread of execution +int main() { + equeue_t queue; + equeue_create(&queue, 1024); + + struct sonar s1, s2, s3; + sonar_create(&s1, &queue); + sonar_create(&s2, &queue); + sonar_create(&s3, &queue); + + struct slam slam; + slam_create(&slam, &queue); + + // dispatches events from all of the modules + equeue_dispatch(&queue, -1); +} +``` + +## Platform ## + +The equeue library has a minimal porting layer that is flexible depending +on the requirements of the underlying platform. Platform specific declarations +and more information can be found in [equeue_platform.h](equeue_platform.h). + +## Tests ## + +The equeue library uses a set of local tests based on the posix implementation. + +Runtime tests are located in [tests.c](tests/tests.c): + +``` bash +make test +``` + +Profiling tests based on rdtsc are located in [prof.c](tests/prof.c): + +``` bash +make prof +``` + +To make profiling results more tangible, the profiler also supports percentage +comparison with previous runs: +``` bash +make prof | tee results.txt +cat results.txt | make prof +``` + diff --git a/events/equeue/equeue.c b/events/equeue/equeue.c new file mode 100644 index 0000000000..9de980d8ee --- /dev/null +++ b/events/equeue/equeue.c @@ -0,0 +1,569 @@ +/* + * Flexible event queue for dispatching events + * + * Copyright (c) 2016 Christopher Haster + * + * 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. + */ +#include "equeue.h" + +#include +#include + + +// calculate the relative-difference between absolute times while +// correctly handling overflow conditions +static inline int equeue_tickdiff(unsigned a, unsigned b) { + return (int)(a - b); +} + +// calculate the relative-difference between absolute times, but +// also clamp to zero, resulting in only non-zero values. +static inline int equeue_clampdiff(unsigned a, unsigned b) { + int diff = equeue_tickdiff(a, b); + return ~(diff >> (8*sizeof(int)-1)) & diff; +} + +// Increment the unique id in an event, hiding the event from cancel +static inline void equeue_incid(equeue_t *q, struct equeue_event *e) { + e->id += 1; + if (!(e->id << q->npw2)) { + e->id = 1; + } +} + + +// equeue lifetime management +int equeue_create(equeue_t *q, size_t size) { + // dynamically allocate the specified buffer + void *buffer = malloc(size); + if (!buffer) { + return -1; + } + + int err = equeue_create_inplace(q, size, buffer); + q->allocated = buffer; + return err; +} + +int equeue_create_inplace(equeue_t *q, size_t size, void *buffer) { + // setup queue around provided buffer + q->buffer = buffer; + q->allocated = 0; + + q->npw2 = 0; + for (unsigned s = size; s; s >>= 1) { + q->npw2++; + } + + q->chunks = 0; + q->slab.size = size; + q->slab.data = buffer; + + q->queue = 0; + q->tick = equeue_tick(); + q->generation = 0; + q->breaks = 0; + + q->background.active = false; + q->background.update = 0; + q->background.timer = 0; + + // initialize platform resources + int err; + err = equeue_sema_create(&q->eventsema); + if (err < 0) { + return err; + } + + err = equeue_mutex_create(&q->queuelock); + if (err < 0) { + return err; + } + + err = equeue_mutex_create(&q->memlock); + if (err < 0) { + return err; + } + + return 0; +} + +void equeue_destroy(equeue_t *q) { + // call destructors on pending events + for (struct equeue_event *es = q->queue; es; es = es->next) { + for (struct equeue_event *e = q->queue; e; e = e->sibling) { + if (e->dtor) { + e->dtor(e + 1); + } + } + } + + // notify background timer + if (q->background.update) { + q->background.update(q->background.timer, -1); + } + + // clean up platform resources + memory + equeue_mutex_destroy(&q->memlock); + equeue_mutex_destroy(&q->queuelock); + equeue_sema_destroy(&q->eventsema); + free(q->allocated); +} + + +// equeue chunk allocation functions +static struct equeue_event *equeue_mem_alloc(equeue_t *q, size_t size) { + // add event overhead + size += sizeof(struct equeue_event); + size = (size + sizeof(void*)-1) & ~(sizeof(void*)-1); + + equeue_mutex_lock(&q->memlock); + + // check if a good chunk is available + for (struct equeue_event **p = &q->chunks; *p; p = &(*p)->next) { + if ((*p)->size >= size) { + struct equeue_event *e = *p; + if (e->sibling) { + *p = e->sibling; + (*p)->next = e->next; + } else { + *p = e->next; + } + + equeue_mutex_unlock(&q->memlock); + return e; + } + } + + // otherwise allocate a new chunk out of the slab + if (q->slab.size >= size) { + struct equeue_event *e = (struct equeue_event *)q->slab.data; + q->slab.data += size; + q->slab.size -= size; + e->size = size; + e->id = 1; + + equeue_mutex_unlock(&q->memlock); + return e; + } + + equeue_mutex_unlock(&q->memlock); + return 0; +} + +static void equeue_mem_dealloc(equeue_t *q, struct equeue_event *e) { + equeue_mutex_lock(&q->memlock); + + // stick chunk into list of chunks + struct equeue_event **p = &q->chunks; + while (*p && (*p)->size < e->size) { + p = &(*p)->next; + } + + if (*p && (*p)->size == e->size) { + e->sibling = *p; + e->next = (*p)->next; + } else { + e->sibling = 0; + e->next = *p; + } + *p = e; + + equeue_mutex_unlock(&q->memlock); +} + +void *equeue_alloc(equeue_t *q, size_t size) { + struct equeue_event *e = equeue_mem_alloc(q, size); + if (!e) { + return 0; + } + + e->target = 0; + e->period = -1; + e->dtor = 0; + + return e + 1; +} + +void equeue_dealloc(equeue_t *q, void *p) { + struct equeue_event *e = (struct equeue_event*)p - 1; + + if (e->dtor) { + e->dtor(e+1); + } + + equeue_mem_dealloc(q, e); +} + + +// equeue scheduling functions +static int equeue_enqueue(equeue_t *q, struct equeue_event *e, unsigned tick) { + // setup event and hash local id with buffer offset for unique id + int id = (e->id << q->npw2) | ((unsigned char *)e - q->buffer); + e->target = tick + equeue_clampdiff(e->target, tick); + e->generation = q->generation; + + equeue_mutex_lock(&q->queuelock); + + // find the event slot + struct equeue_event **p = &q->queue; + while (*p && equeue_tickdiff((*p)->target, e->target) < 0) { + p = &(*p)->next; + } + + // insert at head in slot + if (*p && (*p)->target == e->target) { + e->next = (*p)->next; + if (e->next) { + e->next->ref = &e->next; + } + + e->sibling = *p; + e->sibling->ref = &e->sibling; + } else { + e->next = *p; + if (e->next) { + e->next->ref = &e->next; + } + + e->sibling = 0; + } + + *p = e; + e->ref = p; + + // notify background timer + if ((q->background.update && q->background.active) && + (q->queue == e && !e->sibling)) { + q->background.update(q->background.timer, + equeue_clampdiff(e->target, tick)); + } + + equeue_mutex_unlock(&q->queuelock); + + return id; +} + +static struct equeue_event *equeue_unqueue(equeue_t *q, int id) { + // decode event from unique id and check that the local id matches + struct equeue_event *e = (struct equeue_event *) + &q->buffer[id & ((1 << q->npw2)-1)]; + + equeue_mutex_lock(&q->queuelock); + if (e->id != id >> q->npw2) { + equeue_mutex_unlock(&q->queuelock); + return 0; + } + + // clear the event and check if already in-flight + e->cb = 0; + e->period = -1; + + int diff = equeue_tickdiff(e->target, q->tick); + if (diff < 0 || (diff == 0 && e->generation != q->generation)) { + equeue_mutex_unlock(&q->queuelock); + return 0; + } + + // disentangle from queue + if (e->sibling) { + e->sibling->next = e->next; + if (e->sibling->next) { + e->sibling->next->ref = &e->sibling->next; + } + + *e->ref = e->sibling; + e->sibling->ref = e->ref; + } else { + *e->ref = e->next; + if (e->next) { + e->next->ref = e->ref; + } + } + + equeue_incid(q, e); + equeue_mutex_unlock(&q->queuelock); + + return e; +} + +static struct equeue_event *equeue_dequeue(equeue_t *q, unsigned target) { + equeue_mutex_lock(&q->queuelock); + + // find all expired events and mark a new generation + q->generation += 1; + if (equeue_tickdiff(q->tick, target) <= 0) { + q->tick = target; + } + + struct equeue_event *head = q->queue; + struct equeue_event **p = &head; + while (*p && equeue_tickdiff((*p)->target, target) <= 0) { + p = &(*p)->next; + } + + q->queue = *p; + if (q->queue) { + q->queue->ref = &q->queue; + } + + *p = 0; + + equeue_mutex_unlock(&q->queuelock); + + // reverse and flatten each slot to match insertion order + struct equeue_event **tail = &head; + struct equeue_event *ess = head; + while (ess) { + struct equeue_event *es = ess; + ess = es->next; + + struct equeue_event *prev = 0; + for (struct equeue_event *e = es; e; e = e->sibling) { + e->next = prev; + prev = e; + } + + *tail = prev; + tail = &es->next; + } + + return head; +} + +int equeue_post(equeue_t *q, void (*cb)(void*), void *p) { + struct equeue_event *e = (struct equeue_event*)p - 1; + unsigned tick = equeue_tick(); + e->cb = cb; + e->target = tick + e->target; + + int id = equeue_enqueue(q, e, tick); + equeue_sema_signal(&q->eventsema); + return id; +} + +void equeue_cancel(equeue_t *q, int id) { + if (!id) { + return; + } + + struct equeue_event *e = equeue_unqueue(q, id); + if (e) { + equeue_dealloc(q, e + 1); + } +} + +void equeue_break(equeue_t *q) { + equeue_mutex_lock(&q->queuelock); + q->breaks++; + equeue_mutex_unlock(&q->queuelock); + equeue_sema_signal(&q->eventsema); +} + +void equeue_dispatch(equeue_t *q, int ms) { + unsigned tick = equeue_tick(); + unsigned timeout = tick + ms; + q->background.active = false; + + while (1) { + // collect all the available events and next deadline + struct equeue_event *es = equeue_dequeue(q, tick); + + // dispatch events + while (es) { + struct equeue_event *e = es; + es = e->next; + + // actually dispatch the callbacks + void (*cb)(void *) = e->cb; + if (cb) { + cb(e + 1); + } + + // reenqueue periodic events or deallocate + if (e->period >= 0) { + e->target += e->period; + equeue_enqueue(q, e, equeue_tick()); + } else { + equeue_incid(q, e); + equeue_dealloc(q, e+1); + } + } + + int deadline = -1; + tick = equeue_tick(); + + // check if we should stop dispatching soon + if (ms >= 0) { + deadline = equeue_tickdiff(timeout, tick); + if (deadline <= 0) { + // update background timer if necessary + if (q->background.update) { + equeue_mutex_lock(&q->queuelock); + if (q->background.update && q->queue) { + q->background.update(q->background.timer, + equeue_clampdiff(q->queue->target, tick)); + } + q->background.active = true; + equeue_mutex_unlock(&q->queuelock); + } + return; + } + } + + // find closest deadline + equeue_mutex_lock(&q->queuelock); + if (q->queue) { + int diff = equeue_clampdiff(q->queue->target, tick); + if ((unsigned)diff < (unsigned)deadline) { + deadline = diff; + } + } + equeue_mutex_unlock(&q->queuelock); + + // wait for events + equeue_sema_wait(&q->eventsema, deadline); + + // check if we were notified to break out of dispatch + if (q->breaks) { + equeue_mutex_lock(&q->queuelock); + if (q->breaks > 0) { + q->breaks--; + equeue_mutex_unlock(&q->queuelock); + return; + } + equeue_mutex_unlock(&q->queuelock); + } + + // update tick for next iteration + tick = equeue_tick(); + } +} + + +// event functions +void equeue_event_delay(void *p, int ms) { + struct equeue_event *e = (struct equeue_event*)p - 1; + e->target = ms; +} + +void equeue_event_period(void *p, int ms) { + struct equeue_event *e = (struct equeue_event*)p - 1; + e->period = ms; +} + +void equeue_event_dtor(void *p, void (*dtor)(void *)) { + struct equeue_event *e = (struct equeue_event*)p - 1; + e->dtor = dtor; +} + + +// simple callbacks +struct ecallback { + void (*cb)(void*); + void *data; +}; + +static void ecallback_dispatch(void *p) { + struct ecallback *e = (struct ecallback*)p; + e->cb(e->data); +} + +int equeue_call(equeue_t *q, void (*cb)(void*), void *data) { + struct ecallback *e = equeue_alloc(q, sizeof(struct ecallback)); + if (!e) { + return 0; + } + + e->cb = cb; + e->data = data; + return equeue_post(q, ecallback_dispatch, e); +} + +int equeue_call_in(equeue_t *q, int ms, void (*cb)(void*), void *data) { + struct ecallback *e = equeue_alloc(q, sizeof(struct ecallback)); + if (!e) { + return 0; + } + + equeue_event_delay(e, ms); + e->cb = cb; + e->data = data; + return equeue_post(q, ecallback_dispatch, e); +} + +int equeue_call_every(equeue_t *q, int ms, void (*cb)(void*), void *data) { + struct ecallback *e = equeue_alloc(q, sizeof(struct ecallback)); + if (!e) { + return 0; + } + + equeue_event_delay(e, ms); + equeue_event_period(e, ms); + e->cb = cb; + e->data = data; + return equeue_post(q, ecallback_dispatch, e); +} + + +// backgrounding +void equeue_background(equeue_t *q, + void (*update)(void *timer, int ms), void *timer) { + equeue_mutex_lock(&q->queuelock); + if (q->background.update) { + q->background.update(q->background.timer, -1); + } + + q->background.update = update; + q->background.timer = timer; + + if (q->background.update && q->queue) { + q->background.update(q->background.timer, + equeue_clampdiff(q->queue->target, equeue_tick())); + } + q->background.active = true; + equeue_mutex_unlock(&q->queuelock); +} + +struct equeue_chain_context { + equeue_t *q; + equeue_t *target; + int id; +}; + +static void equeue_chain_dispatch(void *p) { + equeue_dispatch((equeue_t *)p, 0); +} + +static void equeue_chain_update(void *p, int ms) { + struct equeue_chain_context *c = (struct equeue_chain_context *)p; + equeue_cancel(c->target, c->id); + + if (ms >= 0) { + c->id = equeue_call_in(c->target, ms, equeue_chain_dispatch, c->q); + } else { + equeue_dealloc(c->target, c); + } +} + +void equeue_chain(equeue_t *q, equeue_t *target) { + struct equeue_chain_context *c = equeue_alloc(q, + sizeof(struct equeue_chain_context)); + + c->q = q; + c->target = target; + c->id = 0; + + equeue_background(q, equeue_chain_update, c); +} diff --git a/events/equeue/equeue.h b/events/equeue/equeue.h new file mode 100644 index 0000000000..e3e91d7bb5 --- /dev/null +++ b/events/equeue/equeue.h @@ -0,0 +1,218 @@ +/* + * Flexible event queue for dispatching events + * + * Copyright (c) 2016 Christopher Haster + * + * 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 EQUEUE_H +#define EQUEUE_H + +#ifdef __cplusplus +extern "C" { +#endif + +// Platform specific files +#include "equeue_platform.h" + +#include +#include + + +// The minimum size of an event +// This size is guaranteed to fit events created by event_call +#define EQUEUE_EVENT_SIZE (sizeof(struct equeue_event) + 2*sizeof(void*)) + +// Internal event structure +struct equeue_event { + unsigned size; + uint8_t id; + uint8_t generation; + + struct equeue_event *next; + struct equeue_event *sibling; + struct equeue_event **ref; + + unsigned target; + int period; + void (*dtor)(void *); + + void (*cb)(void *); + // data follows +}; + +// Event queue structure +typedef struct equeue { + struct equeue_event *queue; + unsigned tick; + unsigned breaks; + uint8_t generation; + + unsigned char *buffer; + unsigned npw2; + void *allocated; + + struct equeue_event *chunks; + struct equeue_slab { + size_t size; + unsigned char *data; + } slab; + + struct equeue_background { + bool active; + void (*update)(void *timer, int ms); + void *timer; + } background; + + equeue_sema_t eventsema; + equeue_mutex_t queuelock; + equeue_mutex_t memlock; +} equeue_t; + + +// Queue lifetime operations +// +// Creates and destroys an event queue. The event queue either allocates a +// buffer of the specified size with malloc or uses a user provided buffer +// if constructed with equeue_create_inplace. +// +// If the event queue creation fails, equeue_create returns a negative, +// platform-specific error code. +int equeue_create(equeue_t *queue, size_t size); +int equeue_create_inplace(equeue_t *queue, size_t size, void *buffer); +void equeue_destroy(equeue_t *queue); + +// Dispatch events +// +// Executes events until the specified milliseconds have passed. If ms is +// negative, equeue_dispatch will dispatch events indefinitely or until +// equeue_break is called on this queue. +// +// When called with a finite timeout, the equeue_dispatch function is +// guaranteed to terminate. When called with a timeout of 0, the +// equeue_dispatch does not wait and is irq safe. +void equeue_dispatch(equeue_t *queue, int ms); + +// Break out of a running event loop +// +// Forces the specified event queue's dispatch loop to terminate. Pending +// events may finish executing, but no new events will be executed. +void equeue_break(equeue_t *queue); + +// Simple event calls +// +// The specified callback will be executed in the context of the event queue's +// dispatch loop. When the callback is executed depends on the call function. +// +// equeue_call - Immediately post an event to the queue +// equeue_call_in - Post an event after a specified time in milliseconds +// equeue_call_every - Post an event periodically every milliseconds +// +// All equeue_call functions are irq safe and can act as a mechanism for +// moving events out of irq contexts. +// +// The return value is a unique id that represents the posted event and can +// be passed to equeue_cancel. If there is not enough memory to allocate the +// event, equeue_call returns an id of 0. +int equeue_call(equeue_t *queue, void (*cb)(void *), void *data); +int equeue_call_in(equeue_t *queue, int ms, void (*cb)(void *), void *data); +int equeue_call_every(equeue_t *queue, int ms, void (*cb)(void *), void *data); + +// Allocate memory for events +// +// The equeue_alloc function allocates an event that can be manually dispatched +// with equeue_post. The equeue_dealloc function may be used to free an event +// that has not been posted. Once posted, an event's memory is managed by the +// event queue and should not be deallocated. +// +// Both equeue_alloc and equeue_dealloc are irq safe. +// +// The equeue allocator is designed to minimize jitter in interrupt contexts as +// well as avoid memory fragmentation on small devices. The allocator achieves +// both constant-runtime and zero-fragmentation for fixed-size events, however +// grows linearly as the quantity of different sized allocations increases. +// +// The equeue_alloc function returns a pointer to the event's allocated memory +// and acts as a handle to the underlying event. If there is not enough memory +// to allocate the event, equeue_alloc returns null. +void *equeue_alloc(equeue_t *queue, size_t size); +void equeue_dealloc(equeue_t *queue, void *event); + +// Configure an allocated event +// +// equeue_event_delay - Millisecond delay before dispatching an event +// equeue_event_period - Millisecond period for repeating dispatching an event +// equeue_event_dtor - Destructor to run when the event is deallocated +void equeue_event_delay(void *event, int ms); +void equeue_event_period(void *event, int ms); +void equeue_event_dtor(void *event, void (*dtor)(void *)); + +// Post an event onto the event queue +// +// The equeue_post function takes a callback and a pointer to an event +// allocated by equeue_alloc. The specified callback will be executed in the +// context of the event queue's dispatch loop with the allocated event +// as its argument. +// +// The equeue_post function is irq safe and can act as a mechanism for +// moving events out of irq contexts. +// +// The return value is a unique id that represents the posted event and can +// be passed to equeue_cancel. +int equeue_post(equeue_t *queue, void (*cb)(void *), void *event); + +// Cancel an in-flight event +// +// Attempts to cancel an event referenced by the unique id returned from +// equeue_call or equeue_post. It is safe to call equeue_cancel after an event +// has already been dispatched. +// +// The equeue_cancel function is irq safe. +// +// If called while the event queue's dispatch loop is active, equeue_cancel +// does not guarantee that the event will not not execute after it returns as +// the event may have already begun executing. +void equeue_cancel(equeue_t *queue, int id); + +// Background an event queue onto a single-shot timer +// +// The provided update function will be called to indicate when the queue +// should be dispatched. A negative timeout will be passed to the update +// function when the timer is no longer needed. +// +// Passing a null update function disables the existing timer. +// +// The equeue_background function allows an event queue to take advantage +// of hardware timers or even other event loops, allowing an event queue to +// be effectively backgrounded. +void equeue_background(equeue_t *queue, + void (*update)(void *timer, int ms), void *timer); + +// Chain an event queue onto another event queue +// +// After chaining a queue to a target, calling equeue_dispatch on the +// target queue will also dispatch events from this queue. The queues +// use their own buffers and events must be managed independently. +// +// Passing a null queue as the target will unchain the existing queue. +// +// The equeue_chain function allows multiple equeues to be composed, sharing +// the context of a dispatch loop while still being managed independently. +void equeue_chain(equeue_t *queue, equeue_t *target); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/events/equeue/equeue_mbed.cpp b/events/equeue/equeue_mbed.cpp new file mode 100644 index 0000000000..e6bfc8e5dd --- /dev/null +++ b/events/equeue/equeue_mbed.cpp @@ -0,0 +1,142 @@ +/* + * Implementation for the mbed library + * https://github.com/mbedmicro/mbed + * + * Copyright (c) 2016 Christopher Haster + * + * 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. + */ +#include "equeue_platform.h" + +#if defined(EQUEUE_PLATFORM_MBED) + +#include +#include "mbed.h" + + +// Ticker operations +static bool equeue_tick_inited = false; +static 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() { + reinterpret_cast(equeue_timer)->reset(); + equeue_minutes += 1; +} + +static void equeue_tick_init() { + MBED_ASSERT(sizeof(equeue_timer) >= sizeof(Timer)); + MBED_ASSERT(sizeof(equeue_ticker) >= sizeof(Ticker)); + new (equeue_timer) Timer; + new (equeue_ticker) Ticker; + + equeue_minutes = 0; + reinterpret_cast(equeue_timer)->start(); + reinterpret_cast(equeue_ticker) + ->attach_us(equeue_tick_update, (1 << 16)*1000); + + equeue_tick_inited = true; +} + +unsigned equeue_tick() { + if (!equeue_tick_inited) { + equeue_tick_init(); + } + + unsigned equeue_ms = reinterpret_cast(equeue_timer)->read_ms(); + return (equeue_minutes << 16) + equeue_ms; +} + + +// Mutex operations +int equeue_mutex_create(equeue_mutex_t *m) { return 0; } +void equeue_mutex_destroy(equeue_mutex_t *m) { } + +void equeue_mutex_lock(equeue_mutex_t *m) { + core_util_critical_section_enter(); +} + +void equeue_mutex_unlock(equeue_mutex_t *m) { + core_util_critical_section_exit(); +} + + +// Semaphore operations +#ifdef MBED_CONF_RTOS_PRESENT + +int equeue_sema_create(equeue_sema_t *s) { + MBED_ASSERT(sizeof(equeue_sema_t) >= sizeof(Semaphore)); + new (s) Semaphore(0); + return 0; +} + +void equeue_sema_destroy(equeue_sema_t *s) { + reinterpret_cast(s)->~Semaphore(); +} + +void equeue_sema_signal(equeue_sema_t *s) { + reinterpret_cast(s)->release(); +} + +bool equeue_sema_wait(equeue_sema_t *s, int ms) { + if (ms < 0) { + ms = osWaitForever; + } + + return (reinterpret_cast(s)->wait(ms) > 0); +} + +#else + +// Semaphore operations +int equeue_sema_create(equeue_sema_t *s) { + *s = false; + return 0; +} + +void equeue_sema_destroy(equeue_sema_t *s) { +} + +void equeue_sema_signal(equeue_sema_t *s) { + *s = 1; +} + +static void equeue_sema_timeout(equeue_sema_t *s) { + *s = -1; +} + +bool equeue_sema_wait(equeue_sema_t *s, int ms) { + int signal = 0; + Timeout timeout; + timeout.attach_us(s, equeue_sema_timeout, ms*1000); + + core_util_critical_section_enter(); + while (!*s) { + sleep(); + core_util_critical_section_exit(); + core_util_critical_section_enter(); + } + + signal = *s; + *s = false; + core_util_critical_section_exit(); + + return (signal > 0); +} + +#endif + +#endif diff --git a/events/equeue/equeue_platform.h b/events/equeue/equeue_platform.h new file mode 100644 index 0000000000..5eee47799b --- /dev/null +++ b/events/equeue/equeue_platform.h @@ -0,0 +1,140 @@ +/* + * System specific implementation + * + * Copyright (c) 2016 Christopher Haster + * + * 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 EQUEUE_PLATFORM_H +#define EQUEUE_PLATFORM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +// Currently supported platforms +// +// Uncomment to select a supported platform or reimplement this file +// for a specific target. +//#define EQUEUE_PLATFORM_POSIX +//#define EQUEUE_PLATFORM_MBED + +// Try to infer a platform if none was manually selected +#if !defined(EQUEUE_PLATFORM_POSIX) \ + && !defined(EQUEUE_PLATFORM_MBED) +#if defined(__unix__) +#define EQUEUE_PLATFORM_POSIX +#elif defined(__MBED__) +#define EQUEUE_PLATFORM_MBED +#else +#warning "Unknown platform! Please update equeue_platform.h" +#endif +#endif + +// Platform includes +#if defined(EQUEUE_PLATFORM_POSIX) +#include +#endif + + +// Platform millisecond counter +// +// Return a tick that represents the number of milliseconds that have passed +// since an arbitrary point in time. The granularity does not need to be at +// the millisecond level, however the accuracy of the equeue library is +// limited by the accuracy of this tick. +// +// Must intentionally overflow to 0 after 2^32-1 +unsigned equeue_tick(void); + + +// Platform mutex type +// +// The equeue library requires at minimum a non-recursive mutex that is +// safe in interrupt contexts. The mutex section is help for a bounded +// amount of time, so simply disabling interrupts is acceptable +// +// If irq safety is not required, a regular blocking mutex can be used. +#if defined(EQUEUE_PLATFORM_POSIX) +typedef pthread_mutex_t equeue_mutex_t; +#elif defined(EQUEUE_PLATFORM_WINDOWS) +typedef CRITICAL_SECTION equeue_mutex_t; +#elif defined(EQUEUE_PLATFORM_MBED) +typedef unsigned equeue_mutex_t; +#elif defined(EQUEUE_PLATFORM_FREERTOS) +typedef UBaseType_t equeue_mutex_t; +#endif + +// Platform mutex operations +// +// The equeue_mutex_create and equeue_mutex_destroy manage the lifetime +// of the mutex. On error, equeue_mutex_create should return a negative +// error code. +// +// The equeue_mutex_lock and equeue_mutex_unlock lock and unlock the +// underlying mutex. +int equeue_mutex_create(equeue_mutex_t *mutex); +void equeue_mutex_destroy(equeue_mutex_t *mutex); +void equeue_mutex_lock(equeue_mutex_t *mutex); +void equeue_mutex_unlock(equeue_mutex_t *mutex); + + +// Platform semaphore type +// +// The equeue library requires a binary semaphore type that can be safely +// signaled from interrupt contexts and from inside a equeue_mutex section. +// +// The equeue_signal_wait is relied upon by the equeue library to sleep the +// processor between events. Spurious wakeups have no negative-effects. +// +// A counting semaphore will also work, however may cause the event queue +// dispatch loop to run unnecessarily. For that matter, equeue_signal_wait +// may even be implemented as a single return statement. +#if defined(EQUEUE_PLATFORM_POSIX) +typedef struct equeue_sema { + pthread_mutex_t mutex; + pthread_cond_t cond; + bool signal; +} equeue_sema_t; +#elif defined(EQUEUE_PLATFORM_MBED) && defined(MBED_CONF_RTOS_PRESENT) +typedef unsigned equeue_sema_t[8]; +#elif defined(EQUEUE_PLATFORM_MBED) +typedef volatile int equeue_sema_t; +#endif + +// Platform semaphore operations +// +// The equeue_sema_create and equeue_sema_destroy manage the lifetime +// of the semaphore. On error, equeue_sema_create should return a negative +// error code. +// +// The equeue_sema_signal marks a semaphore as signalled such that the next +// equeue_sema_wait will return true. +// +// The equeue_sema_wait waits for a semaphore to be signalled or returns +// immediately if equeue_sema_signal had been called since the last +// equeue_sema_wait. The equeue_sema_wait returns true if it detected that +// equeue_sema_signal had been called. +int equeue_sema_create(equeue_sema_t *sema); +void equeue_sema_destroy(equeue_sema_t *sema); +void equeue_sema_signal(equeue_sema_t *sema); +bool equeue_sema_wait(equeue_sema_t *sema, int ms); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/events/equeue/equeue_posix.c b/events/equeue/equeue_posix.c new file mode 100644 index 0000000000..e13007a768 --- /dev/null +++ b/events/equeue/equeue_posix.c @@ -0,0 +1,106 @@ +/* + * Implementation for Posix compliant platforms + * + * Copyright (c) 2016 Christopher Haster + * + * 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. + */ +#include "equeue_platform.h" + +#if defined(EQUEUE_PLATFORM_POSIX) + +#include +#include +#include + + +// Tick operations +unsigned equeue_tick(void) { + struct timeval tv; + gettimeofday(&tv, 0); + return (unsigned)(tv.tv_sec*1000 + tv.tv_usec/1000); +} + + +// Mutex operations +int equeue_mutex_create(equeue_mutex_t *m) { + return pthread_mutex_init(m, 0); +} + +void equeue_mutex_destroy(equeue_mutex_t *m) { + pthread_mutex_destroy(m); +} + +void equeue_mutex_lock(equeue_mutex_t *m) { + pthread_mutex_lock(m); +} + +void equeue_mutex_unlock(equeue_mutex_t *m) { + pthread_mutex_unlock(m); +} + + +// Semaphore operations +int equeue_sema_create(equeue_sema_t *s) { + int err = pthread_mutex_init(&s->mutex, 0); + if (err) { + return err; + } + + err = pthread_cond_init(&s->cond, 0); + if (err) { + return err; + } + + s->signal = false; + return 0; +} + +void equeue_sema_destroy(equeue_sema_t *s) { + pthread_cond_destroy(&s->cond); + pthread_mutex_destroy(&s->mutex); +} + +void equeue_sema_signal(equeue_sema_t *s) { + pthread_mutex_lock(&s->mutex); + s->signal = true; + pthread_cond_signal(&s->cond); + pthread_mutex_unlock(&s->mutex); +} + +bool equeue_sema_wait(equeue_sema_t *s, int ms) { + pthread_mutex_lock(&s->mutex); + if (!s->signal) { + if (ms < 0) { + pthread_cond_wait(&s->cond, &s->mutex); + } else { + struct timeval tv; + gettimeofday(&tv, 0); + + struct timespec ts = { + .tv_sec = ms/1000 + tv.tv_sec, + .tv_nsec = ms*1000000 + tv.tv_usec*1000, + }; + + pthread_cond_timedwait(&s->cond, &s->mutex, &ts); + } + } + + bool signal = s->signal; + s->signal = false; + pthread_mutex_unlock(&s->mutex); + + return signal; +} + +#endif diff --git a/events/equeue/tests/prof.c b/events/equeue/tests/prof.c new file mode 100644 index 0000000000..20d5ac514b --- /dev/null +++ b/events/equeue/tests/prof.c @@ -0,0 +1,407 @@ +/* + * Profiling framework for the events library + * + * Copyright (c) 2016 Christopher Haster + * + * 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. + */ +#include "equeue.h" +#include +#include +#include +#include +#include +#include +#include + + +// Performance measurement utils +#define PROF_RUNS 5 +#define PROF_INTERVAL 100000000 + +#define prof_volatile(t) __attribute__((unused)) volatile t + +typedef uint64_t prof_cycle_t; + +static volatile prof_cycle_t prof_start_cycle; +static volatile prof_cycle_t prof_stop_cycle; +static prof_cycle_t prof_accum_cycle; +static prof_cycle_t prof_baseline_cycle; +static prof_cycle_t prof_iterations; +static const char *prof_units; + +#define prof_cycle() ({ \ + uint32_t a, b; \ + __asm__ volatile ("rdtsc" : "=a" (a), "=d" (b)); \ + ((uint64_t)b << 32) | (uint64_t)a; \ +}) + +#define prof_loop() \ + for (prof_iterations = 0; \ + prof_accum_cycle < PROF_INTERVAL; \ + prof_iterations++) + +#define prof_start() ({ \ + prof_start_cycle = prof_cycle(); \ +}) + +#define prof_stop() ({ \ + prof_stop_cycle = prof_cycle(); \ + prof_accum_cycle += prof_stop_cycle - prof_start_cycle; \ +}) + +#define prof_result(value, units) ({ \ + prof_accum_cycle = value+prof_baseline_cycle; \ + prof_iterations = 1; \ + prof_units = units; \ +}) + +#define prof_measure(func, ...) ({ \ + printf("%s: ...", #func); \ + fflush(stdout); \ + \ + prof_units = "cycles"; \ + prof_cycle_t runs[PROF_RUNS]; \ + for (int i = 0; i < PROF_RUNS; i++) { \ + prof_accum_cycle = 0; \ + prof_iterations = 0; \ + func(__VA_ARGS__); \ + runs[i] = prof_accum_cycle / prof_iterations; \ + } \ + \ + prof_cycle_t res = runs[0]; \ + for (int i = 0; i < PROF_RUNS; i++) { \ + if (runs[i] < res) { \ + res = runs[i]; \ + } \ + } \ + res -= prof_baseline_cycle; \ + printf("\r%s: %"PRIu64" %s", #func, res, prof_units); \ + \ + if (!isatty(0)) { \ + prof_cycle_t prev; \ + while (scanf("%*[^0-9]%"PRIu64, &prev) == 0); \ + int64_t perc = 100*((int64_t)prev - (int64_t)res) / (int64_t)prev; \ + \ + if (perc > 10) { \ + printf(" (\e[32m%+"PRId64"%%\e[0m)", perc); \ + } else if (perc < -10) { \ + printf(" (\e[31m%+"PRId64"%%\e[0m)", perc); \ + } else { \ + printf(" (%+"PRId64"%%)", perc); \ + } \ + } \ + \ + printf("\n"); \ + res; \ +}) + +#define prof_baseline(func, ...) ({ \ + prof_baseline_cycle = 0; \ + prof_baseline_cycle = prof_measure(func, __VA_ARGS__); \ +}) + + +// Various test functions +void no_func(void *eh) { +} + + +// Actual performance tests +void baseline_prof(void) { + prof_loop() { + prof_start(); + __asm__ volatile (""); + prof_stop(); + } +} + +void equeue_tick_prof(void) { + prof_volatile(unsigned) res; + prof_loop() { + prof_start(); + res = equeue_tick(); + prof_stop(); + } +} + +void equeue_alloc_prof(void) { + struct equeue q; + equeue_create(&q, 32*EQUEUE_EVENT_SIZE); + + prof_loop() { + prof_start(); + void *e = equeue_alloc(&q, 8 * sizeof(int)); + prof_stop(); + + equeue_dealloc(&q, e); + } + + equeue_destroy(&q); +} + +void equeue_alloc_many_prof(int count) { + struct equeue q; + equeue_create(&q, count*EQUEUE_EVENT_SIZE); + + void *es[count]; + + for (int i = 0; i < count; i++) { + es[i] = equeue_alloc(&q, (i % 4) * sizeof(int)); + } + + for (int i = 0; i < count; i++) { + equeue_dealloc(&q, es[i]); + } + + prof_loop() { + prof_start(); + void *e = equeue_alloc(&q, 8 * sizeof(int)); + prof_stop(); + + equeue_dealloc(&q, e); + } + + equeue_destroy(&q); +} + +void equeue_post_prof(void) { + struct equeue q; + equeue_create(&q, EQUEUE_EVENT_SIZE); + + prof_loop() { + void *e = equeue_alloc(&q, 0); + + prof_start(); + int id = equeue_post(&q, no_func, e); + prof_stop(); + + equeue_cancel(&q, id); + } + + equeue_destroy(&q); +} + +void equeue_post_many_prof(int count) { + struct equeue q; + equeue_create(&q, count*EQUEUE_EVENT_SIZE); + + for (int i = 0; i < count-1; i++) { + equeue_call(&q, no_func, 0); + } + + prof_loop() { + void *e = equeue_alloc(&q, 0); + + prof_start(); + int id = equeue_post(&q, no_func, e); + prof_stop(); + + equeue_cancel(&q, id); + } + + equeue_destroy(&q); +} + +void equeue_post_future_prof(void) { + struct equeue q; + equeue_create(&q, EQUEUE_EVENT_SIZE); + + prof_loop() { + void *e = equeue_alloc(&q, 0); + equeue_event_delay(e, 1000); + + prof_start(); + int id = equeue_post(&q, no_func, e); + prof_stop(); + + equeue_cancel(&q, id); + } + + equeue_destroy(&q); +} + +void equeue_post_future_many_prof(int count) { + struct equeue q; + equeue_create(&q, count*EQUEUE_EVENT_SIZE); + + for (int i = 0; i < count-1; i++) { + equeue_call(&q, no_func, 0); + } + + prof_loop() { + void *e = equeue_alloc(&q, 0); + equeue_event_delay(e, 1000); + + prof_start(); + int id = equeue_post(&q, no_func, e); + prof_stop(); + + equeue_cancel(&q, id); + } + + equeue_destroy(&q); +} + +void equeue_dispatch_prof(void) { + struct equeue q; + equeue_create(&q, EQUEUE_EVENT_SIZE); + + prof_loop() { + equeue_call(&q, no_func, 0); + + prof_start(); + equeue_dispatch(&q, 0); + prof_stop(); + } + + equeue_destroy(&q); +} + +void equeue_dispatch_many_prof(int count) { + struct equeue q; + equeue_create(&q, count*EQUEUE_EVENT_SIZE); + + prof_loop() { + for (int i = 0; i < count; i++) { + equeue_call(&q, no_func, 0); + } + + prof_start(); + equeue_dispatch(&q, 0); + prof_stop(); + } + + equeue_destroy(&q); +} + +void equeue_cancel_prof(void) { + struct equeue q; + equeue_create(&q, EQUEUE_EVENT_SIZE); + + prof_loop() { + int id = equeue_call(&q, no_func, 0); + + prof_start(); + equeue_cancel(&q, id); + prof_stop(); + } + + equeue_destroy(&q); +} + +void equeue_cancel_many_prof(int count) { + struct equeue q; + equeue_create(&q, count*EQUEUE_EVENT_SIZE); + + for (int i = 0; i < count-1; i++) { + equeue_call(&q, no_func, 0); + } + + prof_loop() { + int id = equeue_call(&q, no_func, 0); + + prof_start(); + equeue_cancel(&q, id); + prof_stop(); + } + + equeue_destroy(&q); +} + +void equeue_alloc_size_prof(void) { + size_t size = 32*EQUEUE_EVENT_SIZE; + + struct equeue q; + equeue_create(&q, size); + equeue_alloc(&q, 0); + + prof_result(size - q.slab.size, "bytes"); + + equeue_destroy(&q); +} + +void equeue_alloc_many_size_prof(int count) { + size_t size = count*EQUEUE_EVENT_SIZE; + + struct equeue q; + equeue_create(&q, size); + + for (int i = 0; i < count; i++) { + equeue_alloc(&q, (i % 4) * sizeof(int)); + } + + prof_result(size - q.slab.size, "bytes"); + + equeue_destroy(&q); +} + +void equeue_alloc_fragmented_size_prof(int count) { + size_t size = count*EQUEUE_EVENT_SIZE; + + struct equeue q; + equeue_create(&q, size); + + void *es[count]; + + for (int i = 0; i < count; i++) { + es[i] = equeue_alloc(&q, (i % 4) * sizeof(int)); + } + + for (int i = 0; i < count; i++) { + equeue_dealloc(&q, es[i]); + } + + for (int i = count-1; i >= 0; i--) { + es[i] = equeue_alloc(&q, (i % 4) * sizeof(int)); + } + + for (int i = count-1; i >= 0; i--) { + equeue_dealloc(&q, es[i]); + } + + for (int i = 0; i < count; i++) { + equeue_alloc(&q, (i % 4) * sizeof(int)); + } + + prof_result(size - q.slab.size, "bytes"); + + equeue_destroy(&q); +} + + +// Entry point +int main() { + printf("beginning profiling...\n"); + + prof_baseline(baseline_prof); + + prof_measure(equeue_tick_prof); + prof_measure(equeue_alloc_prof); + prof_measure(equeue_post_prof); + prof_measure(equeue_post_future_prof); + prof_measure(equeue_dispatch_prof); + prof_measure(equeue_cancel_prof); + + prof_measure(equeue_alloc_many_prof, 1000); + prof_measure(equeue_post_many_prof, 1000); + prof_measure(equeue_post_future_many_prof, 1000); + prof_measure(equeue_dispatch_many_prof, 100); + prof_measure(equeue_cancel_many_prof, 100); + + prof_measure(equeue_alloc_size_prof); + prof_measure(equeue_alloc_many_size_prof, 1000); + prof_measure(equeue_alloc_fragmented_size_prof, 1000); + + printf("done!\n"); +} diff --git a/events/equeue/tests/tests.c b/events/equeue/tests/tests.c new file mode 100644 index 0000000000..fc7ad81374 --- /dev/null +++ b/events/equeue/tests/tests.c @@ -0,0 +1,681 @@ +/* + * Testing framework for the events library + * + * Copyright (c) 2016 Christopher Haster + * + * 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. + */ +#include "equeue.h" +#include +#include +#include +#include +#include +#include + + +// Testing setup +static jmp_buf test_buf; +static int test_line; +static int test_failure; + +#define test_assert(test) ({ \ + if (!(test)) { \ + test_line = __LINE__; \ + longjmp(test_buf, 1); \ + } \ +}) + +#define test_run(func, ...) ({ \ + printf("%s: ...", #func); \ + fflush(stdout); \ + \ + if (!setjmp(test_buf)) { \ + func(__VA_ARGS__); \ + printf("\r%s: \e[32mpassed\e[0m\n", #func); \ + } else { \ + printf("\r%s: \e[31mfailed\e[0m at line %d\n", #func, test_line); \ + test_failure = true; \ + } \ +}) + + +// Test functions +void pass_func(void *eh) { +} + +void simple_func(void *p) { + (*(int *)p)++; +} + +void sloth_func(void *p) { + usleep(10000); + (*(int *)p)++; +} + +struct indirect { + int *touched; + uint8_t buffer[7]; +}; + +void indirect_func(void *p) { + struct indirect *i = (struct indirect*)p; + (*i->touched)++; +} + +struct timing { + unsigned tick; + unsigned delay; +}; + +void timing_func(void *p) { + struct timing *timing = (struct timing*)p; + unsigned tick = equeue_tick(); + + unsigned t1 = timing->delay; + unsigned t2 = tick - timing->tick; + test_assert(t1 > t2 - 10 && t1 < t2 + 10); + + timing->tick = tick; +} + +struct fragment { + equeue_t *q; + size_t size; + struct timing timing; +}; + +void fragment_func(void *p) { + struct fragment *fragment = (struct fragment*)p; + timing_func(&fragment->timing); + + struct fragment *nfragment = equeue_alloc(fragment->q, fragment->size); + test_assert(nfragment); + + *nfragment = *fragment; + equeue_event_delay(nfragment, fragment->timing.delay); + + int id = equeue_post(nfragment->q, fragment_func, nfragment); + test_assert(id); +} + +struct cancel { + equeue_t *q; + int id; +}; + +void cancel_func(void *p) { + struct cancel *cancel = (struct cancel *)p; + equeue_cancel(cancel->q, cancel->id); +} + +struct nest { + equeue_t *q; + void (*cb)(void *); + void *data; +}; + +void nest_func(void *p) { + struct nest *nest = (struct nest *)p; + equeue_call(nest->q, nest->cb, nest->data); + + usleep(10000); +} + + +// Simple call tests +void simple_call_test(void) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + bool touched = false; + equeue_call(&q, simple_func, &touched); + equeue_dispatch(&q, 0); + test_assert(touched); + + equeue_destroy(&q); +} + +void simple_call_in_test(void) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + bool touched = false; + int id = equeue_call_in(&q, 10, simple_func, &touched); + test_assert(id); + + equeue_dispatch(&q, 15); + test_assert(touched); + + equeue_destroy(&q); +} + +void simple_call_every_test(void) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + bool touched = false; + int id = equeue_call_every(&q, 10, simple_func, &touched); + test_assert(id); + + equeue_dispatch(&q, 15); + test_assert(touched); + + equeue_destroy(&q); +} + +void simple_post_test(void) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + int touched = false; + struct indirect *i = equeue_alloc(&q, sizeof(struct indirect)); + test_assert(i); + + i->touched = &touched; + int id = equeue_post(&q, indirect_func, i); + test_assert(id); + + equeue_dispatch(&q, 0); + test_assert(*i->touched); + + equeue_destroy(&q); +} + +// Misc tests +void destructor_test(void) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + int touched; + struct indirect *e; + int ids[3]; + + touched = 0; + for (int i = 0; i < 3; i++) { + e = equeue_alloc(&q, sizeof(struct indirect)); + test_assert(e); + + e->touched = &touched; + equeue_event_dtor(e, indirect_func); + int id = equeue_post(&q, pass_func, e); + test_assert(id); + } + + equeue_dispatch(&q, 0); + test_assert(touched == 3); + + touched = 0; + for (int i = 0; i < 3; i++) { + e = equeue_alloc(&q, sizeof(struct indirect)); + test_assert(e); + + e->touched = &touched; + equeue_event_dtor(e, indirect_func); + ids[i] = equeue_post(&q, pass_func, e); + test_assert(ids[i]); + } + + for (int i = 0; i < 3; i++) { + equeue_cancel(&q, ids[i]); + } + + equeue_dispatch(&q, 0); + test_assert(touched == 3); + + touched = 0; + for (int i = 0; i < 3; i++) { + e = equeue_alloc(&q, sizeof(struct indirect)); + test_assert(e); + + e->touched = &touched; + equeue_event_dtor(e, indirect_func); + int id = equeue_post(&q, pass_func, e); + test_assert(id); + } + + equeue_destroy(&q); + test_assert(touched == 3); +} + +void allocation_failure_test(void) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + void *p = equeue_alloc(&q, 4096); + test_assert(!p); + + for (int i = 0; i < 100; i++) { + p = equeue_alloc(&q, 0); + } + test_assert(!p); + + equeue_destroy(&q); +} + +void cancel_test(int N) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + bool touched = false; + int *ids = malloc(N*sizeof(int)); + + for (int i = 0; i < N; i++) { + ids[i] = equeue_call(&q, simple_func, &touched); + } + + for (int i = N-1; i >= 0; i--) { + equeue_cancel(&q, ids[i]); + } + + free(ids); + + equeue_dispatch(&q, 0); + test_assert(!touched); + + equeue_destroy(&q); +} + +void cancel_inflight_test(void) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + bool touched = false; + + int id = equeue_call(&q, simple_func, &touched); + equeue_cancel(&q, id); + + equeue_dispatch(&q, 0); + test_assert(!touched); + + id = equeue_call(&q, simple_func, &touched); + equeue_cancel(&q, id); + + equeue_dispatch(&q, 0); + test_assert(!touched); + + struct cancel *cancel = equeue_alloc(&q, sizeof(struct cancel)); + test_assert(cancel); + cancel->q = &q; + cancel->id = 0; + + id = equeue_post(&q, cancel_func, cancel); + test_assert(id); + + cancel->id = equeue_call(&q, simple_func, &touched); + + equeue_dispatch(&q, 0); + test_assert(!touched); + + equeue_destroy(&q); +} + +void cancel_unnecessarily_test(void) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + int id = equeue_call(&q, pass_func, 0); + for (int i = 0; i < 5; i++) { + equeue_cancel(&q, id); + } + + id = equeue_call(&q, pass_func, 0); + equeue_dispatch(&q, 0); + for (int i = 0; i < 5; i++) { + equeue_cancel(&q, id); + } + + bool touched = false; + equeue_call(&q, simple_func, &touched); + for (int i = 0; i < 5; i++) { + equeue_cancel(&q, id); + } + + equeue_dispatch(&q, 0); + test_assert(touched); + + equeue_destroy(&q); +} + +void loop_protect_test(void) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + bool touched = false; + equeue_call_every(&q, 0, simple_func, &touched); + + equeue_dispatch(&q, 0); + test_assert(touched); + + touched = false; + equeue_call_every(&q, 1, simple_func, &touched); + + equeue_dispatch(&q, 0); + test_assert(touched); + + equeue_destroy(&q); +} + +void break_test(void) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + bool touched = false; + equeue_call_every(&q, 0, simple_func, &touched); + + equeue_break(&q); + equeue_dispatch(&q, -1); + test_assert(touched); + + equeue_destroy(&q); +} + +void period_test(void) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + int count = 0; + equeue_call_every(&q, 10, simple_func, &count); + + equeue_dispatch(&q, 55); + test_assert(count == 5); + + equeue_destroy(&q); +} + +void nested_test(void) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + int touched = 0; + struct nest *nest = equeue_alloc(&q, sizeof(struct nest)); + test_assert(nest); + nest->q = &q; + nest->cb = simple_func; + nest->data = &touched; + + int id = equeue_post(&q, nest_func, nest); + test_assert(id); + + equeue_dispatch(&q, 5); + test_assert(touched == 0); + + equeue_dispatch(&q, 5); + test_assert(touched == 1); + + touched = 0; + nest = equeue_alloc(&q, sizeof(struct nest)); + test_assert(nest); + nest->q = &q; + nest->cb = simple_func; + nest->data = &touched; + + id = equeue_post(&q, nest_func, nest); + test_assert(id); + + equeue_dispatch(&q, 20); + test_assert(touched == 1); + + equeue_destroy(&q); +} + +void sloth_test(void) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + int touched = 0; + int id = equeue_call(&q, sloth_func, &touched); + test_assert(id); + + id = equeue_call_in(&q, 5, simple_func, &touched); + test_assert(id); + + id = equeue_call_in(&q, 15, simple_func, &touched); + test_assert(id); + + equeue_dispatch(&q, 20); + test_assert(touched == 3); + + equeue_destroy(&q); +} + +void *multithread_thread(void *p) { + equeue_t *q = (equeue_t *)p; + equeue_dispatch(q, -1); + return 0; +} + +void multithread_test(void) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + int touched = 0; + equeue_call_every(&q, 1, simple_func, &touched); + + pthread_t thread; + err = pthread_create(&thread, 0, multithread_thread, &q); + test_assert(!err); + + usleep(10000); + equeue_break(&q); + err = pthread_join(thread, 0); + test_assert(!err); + + test_assert(touched); + + equeue_destroy(&q); +} + +void background_func(void *p, int ms) { + *(unsigned *)p = ms; +} + +void background_test(void) { + equeue_t q; + int err = equeue_create(&q, 2048); + test_assert(!err); + + int id = equeue_call_in(&q, 20, pass_func, 0); + test_assert(id); + + unsigned ms; + equeue_background(&q, background_func, &ms); + test_assert(ms == 20); + + id = equeue_call_in(&q, 10, pass_func, 0); + test_assert(id); + test_assert(ms == 10); + + id = equeue_call(&q, pass_func, 0); + test_assert(id); + test_assert(ms == 0); + + equeue_dispatch(&q, 0); + test_assert(ms == 10); + + equeue_destroy(&q); + test_assert(ms == -1); +} + +void chain_test(void) { + equeue_t q1; + int err = equeue_create(&q1, 2048); + test_assert(!err); + + equeue_t q2; + err = equeue_create(&q2, 2048); + test_assert(!err); + + equeue_chain(&q2, &q1); + + int touched = 0; + + int id1 = equeue_call_in(&q1, 20, simple_func, &touched); + int id2 = equeue_call_in(&q2, 20, simple_func, &touched); + test_assert(id1 && id2); + + id1 = equeue_call(&q1, simple_func, &touched); + id2 = equeue_call(&q2, simple_func, &touched); + test_assert(id1 && id2); + + id1 = equeue_call_in(&q1, 5, simple_func, &touched); + id2 = equeue_call_in(&q2, 5, simple_func, &touched); + test_assert(id1 && id2); + + equeue_cancel(&q1, id1); + equeue_cancel(&q2, id2); + + id1 = equeue_call_in(&q1, 10, simple_func, &touched); + id2 = equeue_call_in(&q2, 10, simple_func, &touched); + test_assert(id1 && id2); + + equeue_dispatch(&q1, 30); + + test_assert(touched == 6); +} + +// Barrage tests +void simple_barrage_test(int N) { + equeue_t q; + int err = equeue_create(&q, N*(EQUEUE_EVENT_SIZE+sizeof(struct timing))); + test_assert(!err); + + for (int i = 0; i < N; i++) { + struct timing *timing = equeue_alloc(&q, sizeof(struct timing)); + test_assert(timing); + + timing->tick = equeue_tick(); + timing->delay = (i+1)*100; + equeue_event_delay(timing, timing->delay); + equeue_event_period(timing, timing->delay); + + int id = equeue_post(&q, timing_func, timing); + test_assert(id); + } + + equeue_dispatch(&q, N*100); + + equeue_destroy(&q); +} + +void fragmenting_barrage_test(int N) { + equeue_t q; + int err = equeue_create(&q, + 2*N*(EQUEUE_EVENT_SIZE+sizeof(struct fragment)+N*sizeof(int))); + test_assert(!err); + + for (int i = 0; i < N; i++) { + size_t size = sizeof(struct fragment) + i*sizeof(int); + struct fragment *fragment = equeue_alloc(&q, size); + test_assert(fragment); + + fragment->q = &q; + fragment->size = size; + fragment->timing.tick = equeue_tick(); + fragment->timing.delay = (i+1)*100; + equeue_event_delay(fragment, fragment->timing.delay); + + int id = equeue_post(&q, fragment_func, fragment); + test_assert(id); + } + + equeue_dispatch(&q, N*100); + + equeue_destroy(&q); +} + +struct ethread { + pthread_t thread; + equeue_t *q; + int ms; +}; + +static void *ethread_dispatch(void *p) { + struct ethread *t = (struct ethread*)p; + equeue_dispatch(t->q, t->ms); + return 0; +} + +void multithreaded_barrage_test(int N) { + equeue_t q; + int err = equeue_create(&q, N*(EQUEUE_EVENT_SIZE+sizeof(struct timing))); + test_assert(!err); + + struct ethread t; + t.q = &q; + t.ms = N*100; + err = pthread_create(&t.thread, 0, ethread_dispatch, &t); + test_assert(!err); + + for (int i = 0; i < N; i++) { + struct timing *timing = equeue_alloc(&q, sizeof(struct timing)); + test_assert(timing); + + timing->tick = equeue_tick(); + timing->delay = (i+1)*100; + equeue_event_delay(timing, timing->delay); + equeue_event_period(timing, timing->delay); + + int id = equeue_post(&q, timing_func, timing); + test_assert(id); + } + + err = pthread_join(t.thread, 0); + test_assert(!err); + + equeue_destroy(&q); +} + + +int main() { + printf("beginning tests...\n"); + + test_run(simple_call_test); + test_run(simple_call_in_test); + test_run(simple_call_every_test); + test_run(simple_post_test); + test_run(destructor_test); + test_run(allocation_failure_test); + test_run(cancel_test, 20); + test_run(cancel_inflight_test); + test_run(cancel_unnecessarily_test); + test_run(loop_protect_test); + test_run(break_test); + test_run(period_test); + test_run(nested_test); + test_run(sloth_test); + test_run(background_test); + test_run(chain_test); + test_run(multithread_test); + test_run(simple_barrage_test, 20); + test_run(fragmenting_barrage_test, 20); + test_run(multithreaded_barrage_test, 20); + + printf("done!\n"); + return test_failure; +} diff --git a/events/mbed_events.h b/events/mbed_events.h new file mode 100644 index 0000000000..a631723a1c --- /dev/null +++ b/events/mbed_events.h @@ -0,0 +1,33 @@ +/* events + * Copyright (c) 2016 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. + */ +#ifndef MBED_EVENTS_H +#define MBED_EVENTS_H + + +#include "equeue/equeue.h" + + +#ifdef __cplusplus + +#include "EventQueue.h" +#include "Event.h" + +using namespace events; + +#endif + + +#endif diff --git a/events/mbed_lib.json b/events/mbed_lib.json new file mode 100644 index 0000000000..7c6edcce89 --- /dev/null +++ b/events/mbed_lib.json @@ -0,0 +1,6 @@ +{ + "name": "events", + "config": { + "present": 1 + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/hal_patch/nordic_critical.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/hal_patch/nordic_critical.c new file mode 100644 index 0000000000..c8ebae99a7 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/hal_patch/nordic_critical.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2015-2016, 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. + */ + +#include // uint32_t, UINT32_MAX +#include // uint32_t, UINT32_MAX +#include "cmsis.h" +#include "nrf_soc.h" +#include "nrf_sdm.h" + +static union { + uint32_t _PRIMASK_state; + uint8_t _sd_state; +} _state = { 0 } ; +static volatile uint32_t _entry_count = 0; +static bool _use_softdevice_routine = false; + +void core_util_critical_section_enter() +{ + // if a critical section has already been entered, just update the counter + if (_entry_count) { + ++_entry_count; + return; + } + + // in this path, a critical section has never been entered + uint32_t primask = __get_PRIMASK(); + + // if interrupts are enabled, try to use the soft device + uint8_t sd_enabled; + if ((primask == 0) && (sd_softdevice_is_enabled(&sd_enabled) == NRF_SUCCESS) && sd_enabled == 1) { + // if the soft device can be use, use it + sd_nvic_critical_region_enter(&_state._sd_state); + _use_softdevice_routine = true; + } else { + // if interrupts where enabled, disable them + if(primask == 0) { + __disable_irq(); + } + + // store the PRIMASK state, it will be restored at the end of the critical section + _state._PRIMASK_state = primask; + _use_softdevice_routine = false; + } + + assert(_entry_count == 0); // entry count should always be equal to 0 at this point + ++_entry_count; +} + +void core_util_critical_section_exit() +{ + assert(_entry_count > 0); + --_entry_count; + + // If their is other segments which have entered the critical section, just leave + if (_entry_count) { + return; + } + + // This is the last segment of the critical section, state should be restored as before entering + // the critical section + if (_use_softdevice_routine) { + sd_nvic_critical_region_exit(_state._sd_state); + } else { + __set_PRIMASK(_state._PRIMASK_state); + } +} diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_C029/stm32f4_eth_init.c b/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_C029/stm32f4_eth_init.c index 34f13499ac..227d7d5843 100644 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_C029/stm32f4_eth_init.c +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_C029/stm32f4_eth_init.c @@ -119,7 +119,7 @@ void HAL_ETH_MspDeInit(ETH_HandleTypeDef* heth) } } -void mbed_mac_address(char *mac) +uint8_t mbed_otp_mac_address(char *mac) { C029_OTP_Header *pFound = NULL; C029_OTP_Header *pTemp = (C029_OTP_Header*)C029_OTP_START_ADDRESS; @@ -140,4 +140,6 @@ void mbed_mac_address(char *mac) } } memcpy(mac, _macAddr, 6); + + return 1; } diff --git a/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c b/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c index 9962e237ee..4e230228aa 100644 --- a/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c +++ b/features/net/FEATURE_IPV4/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c @@ -50,6 +50,8 @@ static err_t _eth_arch_netif_output_ipv6(struct netif *netif, struct pbuf *q, co static err_t _eth_arch_low_level_output(struct netif *netif, struct pbuf *p); static struct pbuf * _eth_arch_low_level_input(struct netif *netif); +__weak uint8_t mbed_otp_mac_address(char *mac); +void mbed_default_mac_address(char *mac); /** * Ethernet Rx Transfer completed callback @@ -468,3 +470,45 @@ void eth_arch_disable_interrupts(void) { NVIC_DisableIRQ(ETH_IRQn); } + +/** This returns a unique 6-byte MAC address, based on the device UID +* This function overrides hal/common/mbed_interface.c function +* @param mac A 6-byte array to write the MAC address +*/ + +void mbed_mac_address(char *mac) { + if (mbed_otp_mac_address(mac)) { + return; + } else { + mbed_default_mac_address(mac); + } + return; +} + +__weak uint8_t mbed_otp_mac_address(char *mac) { + return 0; +} + +void mbed_default_mac_address(char *mac) { + unsigned char ST_mac_addr[3] = {0x00, 0x80, 0xe1}; // default STMicro mac address + + // Read unic id +#if defined (TARGET_STM32F2) + uint32_t word0 = *(uint32_t *)0x1FFF7A10; +#elif defined (TARGET_STM32F4) + uint32_t word0 = *(uint32_t *)0x1FFF7A10; +#elif defined (TARGET_STM32F7) + uint32_t word0 = *(uint32_t *)0x1FF0F420; +#else + #error MAC address can not be derived from target unique Id +#endif + + mac[0] = ST_mac_addr[0]; + mac[1] = ST_mac_addr[1]; + mac[2] = ST_mac_addr[2]; + mac[3] = (word0 & 0x00ff0000) >> 16; + mac[4] = (word0 & 0x0000ff00) >> 8; + mac[5] = (word0 & 0x000000ff); + + return; +} diff --git a/features/net/FEATURE_IPV6/CONTRIBUTING.md b/features/net/FEATURE_IPV6/CONTRIBUTING.md deleted file mode 100644 index e1d3cf00a0..0000000000 --- a/features/net/FEATURE_IPV6/CONTRIBUTING.md +++ /dev/null @@ -1,83 +0,0 @@ -# How to contribute - -This directory structure is entirely generated or copied from other repositories. Do not send patches against it, they cannot be accepted because all code will be entirely overwritten on next release. - -Instead, follow these instructions to send and test your contributions against master repositories. - -## Directory structure - -This directory consists of following modules - -* [mbed-mesh-api](#mbed-mesh-api) -* [mbed-trace](#mbed-trace) -* [nanostack-hal-mbed-cmsis-rtos](#nanostack-hal-mbed-cmsis-rtos) -* [nanostack-libservice](#nanostack-libservice) -* [sal-stack-nanostack-eventloop](#sal-stack-nanostack-eventloop) -* [sal-stack-nanostack-private](#sal-stack-nanostack-private) - - -## mbed-mesh-api - -mbed Mesh API is copied from master repository https://github.com/ARMmbed/mbed-mesh-api - -To replace the copied version with the master repository, follow these steps: - -* Remove the mbed-mesh-api directory: `rm -rf mbed-mesh-api` -* Clone from the master: `git clone git@github.com:ARMmbed/mbed-mesh-api.git` - -Now you have the mbed-mesh-api directory replaced with the Git repository cloned from the original. You can build and test your changes against it and send patches normally to Github as a pull requests. - -## mbed-trace - -mbed-trace library is copied from master repository https://github.com/ARMmbed/mbed-trace - -To replace the copied version with the master repository, follow these steps: - -* Remove the mbed-mesh-api directory: `rm -rf mbed-trace` -* Clone from the master: `git clone git@github.com:ARMmbed/mbed-trace.git` - -## nanostack-hal-mbed-cmsis-rtos - -nanostack-hal-mbed-cmsis-rtos library is copied from master repository https://github.com/ARMmbed/nanostack-hal-mbed-cmsis-rtos - -To replace the copied version with the master repository, follow these steps: - -* Remove the mbed-mesh-api directory: `rm -rf nanostack-hal-mbed-cmsis-rtos` -* Clone from the master: `git clone git@github.com:ARMmbed/nanostack-hal-mbed-cmsis-rtos.git` - -## nanostack-libservice - -nanostack-libservice library is copied from master repository https://github.com/ARMmbed/nanostack-libservice - -To replace the copied version with the master repository, follow these steps: - -* Remove the mbed-mesh-api directory: `rm -rf nanostack-libservice` -* Clone from the master: `git clone git@github.com:ARMmbed/nanostack-libservice.git` - -## sal-stack-nanostack-eventloop - -sal-stack-nanostack-eventloop library is copied from master repository https://github.com/ARMmbed/sal-stack-nanostack-eventloop - -To replace the copied version with the master repository, follow these steps: - -* Remove the mbed-mesh-api directory: `rm -rf sal-stack-nanostack-eventloop` -* Clone from the master: `git clone git@github.com:ARMmbed/sal-stack-nanostack-eventloop.git` - -## sal-stack-nanostack-private - -This directory holds binary libraries generated from the Nanostack networking library. - -**Only mbed Partners have access to the source code.** - -If you have access, the source directory is available in https://github.com/ARMmbed/sal-stack-nanostack-private - -You can replace the binary libraries with the source tree as follows: - -* Remove the sal-stack-nanostack directory: `rm -rf sal-stack-nanostack` -* Clone the original source repository: `git@github.com:ARMmbed/sal-stack-nanostack-private.git` - -Now you can modify, build and test your changes with the mbed OS build. - -### Instructions for generating the binary modules - -Check `Releasing.md` from the Nanostack source repository. diff --git a/features/net/FEATURE_IPV6/coap-service/CHANGELOG.md b/features/net/FEATURE_IPV6/coap-service/CHANGELOG.md deleted file mode 100644 index ef43ec19c0..0000000000 --- a/features/net/FEATURE_IPV6/coap-service/CHANGELOG.md +++ /dev/null @@ -1,53 +0,0 @@ -# Change Log - -## [v4.0.3](https://github.com/ARMmbed/coap-service/releases/tag/v4.0.3) (15-Sep-2016) -[Full Changelog](https://github.com/ARMmbed/coap-service/compare/mbed-os-5.0-rc1...v4.0.3) - -** New feature ** - -- Updated coap-service to use new structure from mbed-client-c -- Set link layer security when opening socket. - - -**Merged pull requests:** - -commit 0fcd1d4254ca30c2d96ef51a5df513912b5fb133 (HEAD, tag: v4.0.3, origin/master, origin/HEAD, master) -Author: Antti Kauppila -Date: Thu Sep 15 15:21:03 2016 +0300 - - version v4.0.3 - -commit 4769b274ece0989cc43de614171bd20cca0b0a27 -Author: Antti Kauppila -Date: Thu Sep 15 15:18:55 2016 +0300 - - version v4.0.2 - -commit 078bd0db248955c7f09bc53fa1de3e1a2f2eac4e -Merge: 70447c3 bc636c0 -Author: Antti Kauppila -Date: Thu Sep 15 15:17:41 2016 +0300 - - Merge pull request #32 from ARMmbed/coap-option-tidy - - Coap option tidy - -commit bc636c0621f0a895e62b6dc23ecd7a261f18ed7e (origin/coap-option-tidy) -Author: Antti Kauppila -Date: Thu Sep 15 10:42:29 2016 +0300 - - mbed-client-c version updated - -commit 73d5163e4ef07ee10b494290761cf977ae6a6f28 -Author: Antti Kauppila -Date: Thu Sep 8 18:13:26 2016 +0300 - - New CoAP changes updated to this library - - Unittests updated also - -commit 70447c3e35426be19fb1885aaa85e645f2ee144d -Author: Tero Heinonen -Date: Wed Aug 17 14:30:36 2016 +0300 - - Set link layer security when opening socket. (#30) diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/DEPENDENCIES b/features/net/FEATURE_IPV6/sal-stack-nanostack/DEPENDENCIES deleted file mode 100644 index 5adb2eb96a..0000000000 --- a/features/net/FEATURE_IPV6/sal-stack-nanostack/DEPENDENCIES +++ /dev/null @@ -1,6 +0,0 @@ -Dependencies for sal-stack-nanostack library are: - * mbed-client-c > 0.1.6 - * nanostack-libservice > 3.0.0 - * sal-stack-nanostack-eventloop > 0.0.8 - * nanostack-randlib > 0.0.4 - diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_A/TARGET_A9/error_nanostack.c b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_A/TARGET_A9/error_nanostack.c deleted file mode 100644 index 755f6c7692..0000000000 --- a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_A/TARGET_A9/error_nanostack.c +++ /dev/null @@ -1 +0,0 @@ -#error "No binary build of IPV6/6LoWPAN/Thread stack available for this platform currently." diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_M/TARGET_M0/error_nanostack.c b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_M/TARGET_M0/error_nanostack.c deleted file mode 100644 index 755f6c7692..0000000000 --- a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_M/TARGET_M0/error_nanostack.c +++ /dev/null @@ -1 +0,0 @@ -#error "No binary build of IPV6/6LoWPAN/Thread stack available for this platform currently." diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_M/TARGET_M0P/error_nanostack.c b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_M/TARGET_M0P/error_nanostack.c deleted file mode 100644 index 755f6c7692..0000000000 --- a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_M/TARGET_M0P/error_nanostack.c +++ /dev/null @@ -1 +0,0 @@ -#error "No binary build of IPV6/6LoWPAN/Thread stack available for this platform currently." diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_M/TARGET_M3/libnanostack_armcc_Cortex-M3.ar b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_M/TARGET_M3/libnanostack_armcc_Cortex-M3.ar deleted file mode 100755 index b1d81f8ab7..0000000000 Binary files a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_M/TARGET_M3/libnanostack_armcc_Cortex-M3.ar and /dev/null differ diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_M/TARGET_M4/libnanostack_armcc_Cortex-M3.ar b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_M/TARGET_M4/libnanostack_armcc_Cortex-M3.ar deleted file mode 100755 index b1d81f8ab7..0000000000 Binary files a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_M/TARGET_M4/libnanostack_armcc_Cortex-M3.ar and /dev/null differ diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_M/TARGET_M7/libnanostack_armcc_Cortex-M7.ar b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_M/TARGET_M7/libnanostack_armcc_Cortex-M7.ar deleted file mode 100644 index b1d81f8ab7..0000000000 Binary files a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_ARM/TARGET_CORTEX_M/TARGET_M7/libnanostack_armcc_Cortex-M7.ar and /dev/null differ diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_A/TARGET_A9/error_nanostack.c b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_A/TARGET_A9/error_nanostack.c deleted file mode 100644 index 755f6c7692..0000000000 --- a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_A/TARGET_A9/error_nanostack.c +++ /dev/null @@ -1 +0,0 @@ -#error "No binary build of IPV6/6LoWPAN/Thread stack available for this platform currently." diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_M/TARGET_M0/error_nanostack.c b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_M/TARGET_M0/error_nanostack.c deleted file mode 100644 index 755f6c7692..0000000000 --- a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_M/TARGET_M0/error_nanostack.c +++ /dev/null @@ -1 +0,0 @@ -#error "No binary build of IPV6/6LoWPAN/Thread stack available for this platform currently." diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_M/TARGET_M0P/error_nanostack.c b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_M/TARGET_M0P/error_nanostack.c deleted file mode 100644 index 755f6c7692..0000000000 --- a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_M/TARGET_M0P/error_nanostack.c +++ /dev/null @@ -1 +0,0 @@ -#error "No binary build of IPV6/6LoWPAN/Thread stack available for this platform currently." diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_M/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3.a b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_M/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3.a deleted file mode 100644 index ae615e489d..0000000000 Binary files a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_M/TARGET_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3.a and /dev/null differ diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_M/TARGET_M4/libnanostack_arm-none-eabi-gcc_Cortex-M3.a b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_M/TARGET_M4/libnanostack_arm-none-eabi-gcc_Cortex-M3.a deleted file mode 100644 index ae615e489d..0000000000 Binary files a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_M/TARGET_M4/libnanostack_arm-none-eabi-gcc_Cortex-M3.a and /dev/null differ diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_M/TARGET_M7/libnanostack_arm-none-eabi-gcc_Cortex-M7.a b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_M/TARGET_M7/libnanostack_arm-none-eabi-gcc_Cortex-M7.a deleted file mode 100644 index ae615e489d..0000000000 Binary files a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_GCC/TARGET_CORTEX_M/TARGET_M7/libnanostack_arm-none-eabi-gcc_Cortex-M7.a and /dev/null differ diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_A/TARGET_A9/error_nanostack.c b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_A/TARGET_A9/error_nanostack.c deleted file mode 100644 index 755f6c7692..0000000000 --- a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_A/TARGET_A9/error_nanostack.c +++ /dev/null @@ -1 +0,0 @@ -#error "No binary build of IPV6/6LoWPAN/Thread stack available for this platform currently." diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_M/TARGET_M0/error_nanostack.c b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_M/TARGET_M0/error_nanostack.c deleted file mode 100644 index 755f6c7692..0000000000 --- a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_M/TARGET_M0/error_nanostack.c +++ /dev/null @@ -1 +0,0 @@ -#error "No binary build of IPV6/6LoWPAN/Thread stack available for this platform currently." diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_M/TARGET_M0P/error_nanostack.c b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_M/TARGET_M0P/error_nanostack.c deleted file mode 100644 index 755f6c7692..0000000000 --- a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_M/TARGET_M0P/error_nanostack.c +++ /dev/null @@ -1 +0,0 @@ -#error "No binary build of IPV6/6LoWPAN/Thread stack available for this platform currently." diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_M/TARGET_M3/libnanostack_iccarm_Cortex-M3.a b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_M/TARGET_M3/libnanostack_iccarm_Cortex-M3.a deleted file mode 100644 index f6ed9b6ff9..0000000000 Binary files a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_M/TARGET_M3/libnanostack_iccarm_Cortex-M3.a and /dev/null differ diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_M/TARGET_M4/libnanostack_iccarm_Cortex-M3.a b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_M/TARGET_M4/libnanostack_iccarm_Cortex-M3.a deleted file mode 100644 index f6ed9b6ff9..0000000000 Binary files a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_M/TARGET_M4/libnanostack_iccarm_Cortex-M3.a and /dev/null differ diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_M/TARGET_M7/libnanostack_iccarm_Cortex-M7.a b/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_M/TARGET_M7/libnanostack_iccarm_Cortex-M7.a deleted file mode 100644 index f6ed9b6ff9..0000000000 Binary files a/features/net/FEATURE_IPV6/sal-stack-nanostack/TOOLCHAIN_IAR/TARGET_CORTEX_M/TARGET_M7/libnanostack_iccarm_Cortex-M7.a and /dev/null differ diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/shalib.h b/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/shalib.h deleted file mode 100644 index 4b4fd520ee..0000000000 --- a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/shalib.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2014-2015 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 shalib.h - * \brief SHA256 Library API. - * - * \section sha256-api SHA256 Library API: - * There are two ways to calculate SHA256: - * 1. Calc by given 1 data and length pointer - * - SHALIB_SHA256_HASH(), A function to calculate SHA256 for given data. - * 2. Calc by different data pointer sequence given separately - * - SHALIB_init_sha256(), Init SHA registers - * - SHALIB_push_data_sha256(), Give data sectors(s) one by one - * - **** Give data - * - SHALIB_push_data_sha256(), Give last data sequence - * - SHALIB_finish_sha256(), Finish SHA256 by given data to given buffer - * - * \section sha256res-api SHA256 register resume and save library API: - * SHA256 Operation dataflow can come in many different timeslots or packets and between them, the application needs - * to calculated more SHA256 then SAVE and Resume operation SHA registers is usefully. - * -sha_resume_regs(), Load SHA registers from old HASH sessions - * -sha_save_regs(), Save SHA registers from current HASH sessions - * - * \section hmac256-inctuction HMAC256 process sequence: - * 1. SHALIB_init_HMAC(), Init HMAC IN process by given security signature material - * 2. SHALIB_push_data_sha256(), Give data sectors(s) one by one - * 3. SHALIB_finish_HMAC(), Finish HMAC and save SHA256 hash to given buffer - * - * \section prf256-inctuction PRF256 process sequence: - * 1. shalib_prf_param_get(), Init PRF and get configure structure - * 2. Set the following parameters to configure structure: - * - HMAC security signature pointer and length - * - Label text and length - * - Seed data and length - * - PRF result pointer - * 3. shalib_prf_calc(), Calc PRF256 HASH - * - */ - -#ifndef SHALIB_H_ -#define SHALIB_H_ - -#include "ns_types.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -/** Do Not change. */ -#define SHALIB_RING_BUFFER_SIZE 64 - -/*! - * \struct prf_sec_param_t - * \brief PRF 256 stucture - * This structure is used to configure PRF calc operation: secret, label, seed and buffer before call shalib_prf_calc(). - */ -typedef struct { - const uint8_t *secret; /**< HMAC security signature pointer. */ - uint8_t sec_len; /**< HMAC security signature length. */ - uint8_t label[25]; /**< Label text. */ - uint8_t lablen; /**< Label text length. */ - const uint8_t *seed; /**< Seed data. */ - uint8_t seedlen; /**< Seed data length. */ - uint8_t *buffer; /**< Buffer for saving 256-BIT hash. */ -} prf_sec_param_t; - -/*! - * \struct sha256_temp_t - * \brief SHA temporary buffer database for saving current hash operation or resume saved. - */ -typedef struct { - uint8_t m_Data[SHALIB_RING_BUFFER_SIZE]; /**< 64-bytes ring buffer for SHA256 operation. */ - uint8_t m_Read; /**< Read pointer to ring buffer. */ - uint8_t m_Write; /**< Write pointer to ring buffer. */ - uint32_t SHALIB_pushed_bytes; /**< Hash total byte coun. t*/ - uint8_t SHALIB_buffered_bytes; /**< Ring buffer data in. */ - uint32_t areg_temps[8]; /**< Shalib operation 8 HREG. */ -} sha256_temp_t; - -// Cumulative static version using a static ring buffer object -//============================================================================= -/** - * \brief Init SHA registers. - */ -void SHALIB_init_sha256(void); // Call this first... -/** - * \brief Push data SHALIB. - * - * \param data A pointer to data. - * \param len Length of data. - */ -void SHALIB_push_data_sha256(const uint8_t *data, uint16_t len); // ... add data ... -/** - * \brief Finish SHA-256 operation and get result to given buffer by given length. - * - * The first `len` words of the SHA-256 are output to buffer. - * - * \param buffer A pointer to result buffer. - * \param len Length of 32-bit register to save to buffer (8= 256 bit and 4= 128-bit). - */ -void SHALIB_finish_sha256(uint8_t *buffer, uint8_t len); // ... get the sha256 digest. -/** - * \brief Calc SHA-256 by 1 function call. - * - * \param data_ptr A pointer to data. - * \param data_len Length of data. - * \param buffer A pointer to 256-bit buffer!! - */ -void SHALIB_SHA256_HASH(const uint8_t *data_ptr, uint16_t data_len, uint8_t *buffer); // ... get the sha256 digest. - -/* Shalib registers resume and save API */ -/** - * \brief Resume old SHA-256 registers. - * - * \param ptr A pointer to saved session. - */ -void sha_resume_regs(const sha256_temp_t *ptr); -/** - * \brief Save SHA-256 registers. - * - * \param ptr A pointer to buffer. - */ -void sha_save_regs(sha256_temp_t *ptr); - -// Use these for cumulativec HMAC -/** - * \brief Init HMAC256 operation by given security material. - * - * \param secret A pointer to security material. - * \param sec_len Length of security material. - */ -void SHALIB_init_HMAC(const uint8_t *secret, uint8_t sec_len); // Call this first... -// ... add data ... by SHALIB_push_data_sha256() -/** - * \brief Finish HMAC256 operation and save result in given buffer. - * - * \param buffer A pointer to result buffer. - * \param len Length of 32-bit register to save to buffer (8= 256 bit and 4= 128-bit). - */ -void SHALIB_finish_HMAC(uint8_t *buffer, uint8_t len); // ... get the HMAC digest. - - -/** PRF API */ -/** - * \brief Init PRF library and SHA registers. - * This function returns configure structure where the user needs to set the following items: - * -Security material and length - * -Label text and length - * -Seed data and length - * -Buffer for 256 Result - * - * \return A pointer to PRF configure structure. - - */ -prf_sec_param_t *shalib_prf_param_get(void); // GET PRF structure -/* SET secret, label, seed & buffer to 256 PRF */ -/** - * \brief Finish PRF256 operation and save result in given buffer. - * - */ -void shalib_prf_calc(void);// GET 256 PRF -#ifdef __cplusplus -} -#endif -#endif /* SHALIB_H_ */ diff --git a/features/net/FEATURE_NANOSTACK/CONTRIBUTING.md b/features/net/FEATURE_NANOSTACK/CONTRIBUTING.md new file mode 100644 index 0000000000..16946661fd --- /dev/null +++ b/features/net/FEATURE_NANOSTACK/CONTRIBUTING.md @@ -0,0 +1,60 @@ +# How to contribute + +This directory structure contains some repositories that are copied from external sources. + +Please follow these instructions to send contributions to master repositories. + +## Directory structure + +This directory consists of following modules + +* [coap-service](#coap-service) +* [mbed-mesh-api](#mbed-mesh-api) +* [nanostack-interface](#nanostack-interface) +* [sal-stack-nanostack](#sal-stack-nanostack) + +## coap-service + +Master repository is located in the https://github.com/ARMmbed/coap-service + +Please send contributions against that repository. + +To test changes, remove the `coap-service` repository and replace with Git clone +of the master repository. + +``` +rm -rf coap-service +git clone git@github.com:ARMmbed/coap-service.git +``` + +## mbed-mesh-api + +This is the master source of mbed-mesh-api. +Send contributions directly to this repository. + +## nanostack-interface + +This is the master source of nanostack-interface. +Send contributions directly to this repository. + +## sal-stack-nanostack + +This directory holds binary libraries generated from the Nanostack networking library. + +**Only mbed Partners have access to the source code.** + +If you have access, the source directory is available in https://github.com/ARMmbed/sal-stack-nanostack-private + +You can replace the binary libraries with the source tree as follows: + +* Remove the sal-stack-nanostack directory: `rm -rf sal-stack-nanostack` +* Remove the binaries located one directory up: `rm -rf ../nanostack-binaries` +* Clone the original source repository to root folder of your application: `git@github.com:ARMmbed/sal-stack-nanostack-private.git` + +Now you can modify, build and test your changes with the mbed OS build. + +**NOTE:** You do not need to clone the Nanostack to exactly same location in the build tree. This may even cause build problems. + +### Instructions for generating the binary modules + +Check `Releasing.md` from the Nanostack source repository. diff --git a/features/net/FEATURE_NANOSTACK/clone_nanostack.sh b/features/net/FEATURE_NANOSTACK/clone_nanostack.sh new file mode 100755 index 0000000000..7e67195c6a --- /dev/null +++ b/features/net/FEATURE_NANOSTACK/clone_nanostack.sh @@ -0,0 +1,107 @@ +#!/bin/bash + +# +# Export FEATURE_NANOSTACK libraries into mbed OS +# +# Usage: +# +# To remove all repositories call: ./clone_client.sh clean +# To replace all with clone repositores: ./clone_client.sh clone +# To export from cloned repositories: ./clone_client.sh export +# +# For developers: +# Use "clone" functionality to get master repositories to work with. +# +# For maintainers: Creating a release +# Use "clone" to get master repositories. +# For every directory checkout the release branch. +# Now use "export" function to flatten the git repositories into bare directories +# Now you can "git add" each directory and do "git commit" +# +# Note "clone" does implicit "clean" so you lose all changes done into directories. + + +# REPOSITORIES and DIRECTORIES are array of repositories where to clone +# and directories where to clone +# these arrays MUST be in sync +# * Same number of elements +# * Same order. Each line should have maching pair in same index at other array +REPOSITORIES=( + git@github.com:ARMmbed/sal-stack-nanostack.git + git@github.com:ARMmbed/coap-service.git + ) + +DIRECTORIES=( + sal-stack-nanostack + coap-service + ) + +# Exit immediately on fail, thread unset variables as error +set -eu + +# Count number of repositories +N=0 +for repo in ${REPOSITORIES[*]}; do + let N=N+1 +done +let N=N-1 # Substract one, because indexes start from 0 + +print_usage() { + echo -e "Usage: $0 [clean | clone | export ]" + echo -e "\tclean : Remove all repositories" + echo -e "\tclone : Replace repositories with Git cone" + echo -e "\texport : Export cloned Git repositories" +} + +clean() { + for dir in ${DIRECTORIES[*]}; do + rm -rf $dir + done + clean_nanostack_binaries +} + +clone() { + for i in $(seq 0 $N); do + git clone ${REPOSITORIES[$i]} ${DIRECTORIES[$i]} + done +} + +export_repos() { + for i in $(seq 0 $N); do + echo "Exporting ${DIRECTORIES[$i]}" + cd ${DIRECTORIES[$i]} + git archive HEAD -o ../${DIRECTORIES[$i]}.tar.gz + cd .. + rm -rf ${DIRECTORIES[$i]} + mkdir ${DIRECTORIES[$i]} + tar xzf ${DIRECTORIES[$i]}.tar.gz -C ${DIRECTORIES[$i]} + rm ${DIRECTORIES[$i]}.tar.gz + done +} + +copy_nanostack_binaries() { + mkdir -p ../nanostack-binaries + mv sal-stack-nanostack/FEATURE_* ../nanostack-binaries/ +} + +clean_nanostack_binaries() { + rm -rf ../nanostack-binaries +} + +case "${1-}" in + clean) + clean + ;; + clone) + clean + clone + ;; + export) + export_repos + copy_nanostack_binaries + ;; + *) + print_usage + exit 1 + ;; +esac diff --git a/features/net/FEATURE_IPV6/coap-service/.gitignore b/features/net/FEATURE_NANOSTACK/coap-service/.gitignore similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/.gitignore rename to features/net/FEATURE_NANOSTACK/coap-service/.gitignore diff --git a/features/net/FEATURE_IPV6/coap-service/.mbedignore b/features/net/FEATURE_NANOSTACK/coap-service/.mbedignore similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/.mbedignore rename to features/net/FEATURE_NANOSTACK/coap-service/.mbedignore diff --git a/features/net/FEATURE_IPV6/coap-service/.yotta_ignore b/features/net/FEATURE_NANOSTACK/coap-service/.yotta_ignore similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/.yotta_ignore rename to features/net/FEATURE_NANOSTACK/coap-service/.yotta_ignore diff --git a/features/net/FEATURE_IPV6/coap-service/LICENSE b/features/net/FEATURE_NANOSTACK/coap-service/LICENSE similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/LICENSE rename to features/net/FEATURE_NANOSTACK/coap-service/LICENSE diff --git a/features/net/FEATURE_IPV6/coap-service/Makefile.test b/features/net/FEATURE_NANOSTACK/coap-service/Makefile.test similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/Makefile.test rename to features/net/FEATURE_NANOSTACK/coap-service/Makefile.test diff --git a/features/net/FEATURE_IPV6/coap-service/apache-2.0.txt b/features/net/FEATURE_NANOSTACK/coap-service/apache-2.0.txt similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/apache-2.0.txt rename to features/net/FEATURE_NANOSTACK/coap-service/apache-2.0.txt diff --git a/features/net/FEATURE_IPV6/coap-service/coap-service/coap_service_api.h b/features/net/FEATURE_NANOSTACK/coap-service/coap-service/coap_service_api.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/coap-service/coap_service_api.h rename to features/net/FEATURE_NANOSTACK/coap-service/coap-service/coap_service_api.h diff --git a/features/net/FEATURE_IPV6/coap-service/junit_xsl.xslt b/features/net/FEATURE_NANOSTACK/coap-service/junit_xsl.xslt similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/junit_xsl.xslt rename to features/net/FEATURE_NANOSTACK/coap-service/junit_xsl.xslt diff --git a/features/net/FEATURE_IPV6/coap-service/module.json b/features/net/FEATURE_NANOSTACK/coap-service/module.json similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/module.json rename to features/net/FEATURE_NANOSTACK/coap-service/module.json diff --git a/features/net/FEATURE_IPV6/coap-service/run_unit_tests.sh b/features/net/FEATURE_NANOSTACK/coap-service/run_unit_tests.sh similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/run_unit_tests.sh rename to features/net/FEATURE_NANOSTACK/coap-service/run_unit_tests.sh diff --git a/features/net/FEATURE_IPV6/coap-service/source/coap_connection_handler.c b/features/net/FEATURE_NANOSTACK/coap-service/source/coap_connection_handler.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/source/coap_connection_handler.c rename to features/net/FEATURE_NANOSTACK/coap-service/source/coap_connection_handler.c diff --git a/features/net/FEATURE_IPV6/coap-service/source/coap_message_handler.c b/features/net/FEATURE_NANOSTACK/coap-service/source/coap_message_handler.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/source/coap_message_handler.c rename to features/net/FEATURE_NANOSTACK/coap-service/source/coap_message_handler.c diff --git a/features/net/FEATURE_IPV6/coap-service/source/coap_security_handler.c b/features/net/FEATURE_NANOSTACK/coap-service/source/coap_security_handler.c similarity index 99% rename from features/net/FEATURE_IPV6/coap-service/source/coap_security_handler.c rename to features/net/FEATURE_NANOSTACK/coap-service/source/coap_security_handler.c index b235bea406..a33b50a5cc 100644 --- a/features/net/FEATURE_IPV6/coap-service/source/coap_security_handler.c +++ b/features/net/FEATURE_NANOSTACK/coap-service/source/coap_security_handler.c @@ -321,10 +321,11 @@ int coap_security_handler_connect(coap_security_t *sec, bool is_server, SecureSo return -1; } - //TODO: Only needed for server type? +#ifdef MBEDTLS_SSL_SRV_C mbedtls_ssl_conf_dtls_cookies(&sec->_conf, simple_cookie_write, simple_cookie_check, &sec->_cookie); +#endif sec->_is_started = true; @@ -416,10 +417,11 @@ int coap_security_handler_connect_non_blocking(coap_security_t *sec, bool is_ser return -1; } - //Only needed for server type? +#ifdef MBEDTLS_SSL_SRV_C mbedtls_ssl_conf_dtls_cookies(&sec->_conf, simple_cookie_write, simple_cookie_check, &sec->_cookie); +#endif mbedtls_ssl_conf_min_version(&sec->_conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MAJOR_VERSION_3); mbedtls_ssl_conf_max_version(&sec->_conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MAJOR_VERSION_3); diff --git a/features/net/FEATURE_IPV6/coap-service/source/coap_service_api.c b/features/net/FEATURE_NANOSTACK/coap-service/source/coap_service_api.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/source/coap_service_api.c rename to features/net/FEATURE_NANOSTACK/coap-service/source/coap_service_api.c diff --git a/features/net/FEATURE_IPV6/coap-service/source/include/coap_connection_handler.h b/features/net/FEATURE_NANOSTACK/coap-service/source/include/coap_connection_handler.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/source/include/coap_connection_handler.h rename to features/net/FEATURE_NANOSTACK/coap-service/source/include/coap_connection_handler.h diff --git a/features/net/FEATURE_IPV6/coap-service/source/include/coap_message_handler.h b/features/net/FEATURE_NANOSTACK/coap-service/source/include/coap_message_handler.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/source/include/coap_message_handler.h rename to features/net/FEATURE_NANOSTACK/coap-service/source/include/coap_message_handler.h diff --git a/features/net/FEATURE_IPV6/coap-service/source/include/coap_security_handler.h b/features/net/FEATURE_NANOSTACK/coap-service/source/include/coap_security_handler.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/source/include/coap_security_handler.h rename to features/net/FEATURE_NANOSTACK/coap-service/source/include/coap_security_handler.h diff --git a/features/net/FEATURE_IPV6/coap-service/source/include/coap_service_api_internal.h b/features/net/FEATURE_NANOSTACK/coap-service/source/include/coap_service_api_internal.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/source/include/coap_service_api_internal.h rename to features/net/FEATURE_NANOSTACK/coap-service/source/include/coap_service_api_internal.h diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/MakefileWorker.mk b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/MakefileWorker.mk similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/MakefileWorker.mk rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/MakefileWorker.mk diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_connection_handler/coap_connection_handlertest.cpp b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_connection_handler/coap_connection_handlertest.cpp similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_connection_handler/coap_connection_handlertest.cpp rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_connection_handler/coap_connection_handlertest.cpp diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_connection_handler/main.cpp b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_connection_handler/main.cpp similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_connection_handler/main.cpp rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_connection_handler/main.cpp diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_connection_handler/test_coap_connection_handler.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_connection_handler/test_coap_connection_handler.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_connection_handler/test_coap_connection_handler.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_connection_handler/test_coap_connection_handler.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_connection_handler/test_coap_connection_handler.h b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_connection_handler/test_coap_connection_handler.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_connection_handler/test_coap_connection_handler.h rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_connection_handler/test_coap_connection_handler.h diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_message_handler/coap_message_handlertest.cpp b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_message_handler/coap_message_handlertest.cpp similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_message_handler/coap_message_handlertest.cpp rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_message_handler/coap_message_handlertest.cpp diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_message_handler/main.cpp b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_message_handler/main.cpp similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_message_handler/main.cpp rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_message_handler/main.cpp diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_message_handler/test_coap_message_handler.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_message_handler/test_coap_message_handler.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_message_handler/test_coap_message_handler.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_message_handler/test_coap_message_handler.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_message_handler/test_coap_message_handler.h b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_message_handler/test_coap_message_handler.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_message_handler/test_coap_message_handler.h rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_message_handler/test_coap_message_handler.h diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_security_handler/coap_security_handlertest.cpp b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_security_handler/coap_security_handlertest.cpp similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_security_handler/coap_security_handlertest.cpp rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_security_handler/coap_security_handlertest.cpp diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_security_handler/main.cpp b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_security_handler/main.cpp similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_security_handler/main.cpp rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_security_handler/main.cpp diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_security_handler/test_coap_security_handler.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_security_handler/test_coap_security_handler.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_security_handler/test_coap_security_handler.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_security_handler/test_coap_security_handler.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_security_handler/test_coap_security_handler.h b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_security_handler/test_coap_security_handler.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_security_handler/test_coap_security_handler.h rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_security_handler/test_coap_security_handler.h diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_service_api/coap_service_apitest.cpp b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_service_api/coap_service_apitest.cpp similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_service_api/coap_service_apitest.cpp rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_service_api/coap_service_apitest.cpp diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_service_api/main.cpp b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_service_api/main.cpp similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_service_api/main.cpp rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_service_api/main.cpp diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_service_api/test_coap_service_api.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_service_api/test_coap_service_api.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_service_api/test_coap_service_api.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_service_api/test_coap_service_api.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_service_api/test_coap_service_api.h b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_service_api/test_coap_service_api.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/coap_service_api/test_coap_service_api.h rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/coap_service_api/test_coap_service_api.h diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/makefile_defines.txt b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/makefile_defines.txt similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/makefile_defines.txt rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/makefile_defines.txt diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/run_tests b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/run_tests old mode 100644 new mode 100755 similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/run_tests rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/run_tests diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/coap_connection_handler_stub.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/coap_connection_handler_stub.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/coap_connection_handler_stub.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/coap_connection_handler_stub.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/coap_connection_handler_stub.h b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/coap_connection_handler_stub.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/coap_connection_handler_stub.h rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/coap_connection_handler_stub.h diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/coap_message_handler_stub.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/coap_message_handler_stub.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/coap_message_handler_stub.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/coap_message_handler_stub.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/coap_message_handler_stub.h b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/coap_message_handler_stub.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/coap_message_handler_stub.h rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/coap_message_handler_stub.h diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/coap_security_handler_stub.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/coap_security_handler_stub.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/coap_security_handler_stub.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/coap_security_handler_stub.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/coap_security_handler_stub.h b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/coap_security_handler_stub.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/coap_security_handler_stub.h rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/coap_security_handler_stub.h diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/coap_service_api_stub.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/coap_service_api_stub.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/coap_service_api_stub.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/coap_service_api_stub.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/eventOS_event_stub.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/eventOS_event_stub.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/eventOS_event_stub.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/eventOS_event_stub.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/eventOS_event_stub.h b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/eventOS_event_stub.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/eventOS_event_stub.h rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/eventOS_event_stub.h diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/mbed_trace_stub.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/mbed_trace_stub.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/mbed_trace_stub.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/mbed_trace_stub.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/mbedtls_stub.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/mbedtls_stub.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/mbedtls_stub.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/mbedtls_stub.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/mbedtls_stub.h b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/mbedtls_stub.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/mbedtls_stub.h rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/mbedtls_stub.h diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/ns_list_stub.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/ns_list_stub.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/ns_list_stub.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/ns_list_stub.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/ns_timer_stub.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/ns_timer_stub.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/ns_timer_stub.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/ns_timer_stub.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/ns_timer_stub.h b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/ns_timer_stub.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/ns_timer_stub.h rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/ns_timer_stub.h diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/nsdynmemLIB_stub.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/nsdynmemLIB_stub.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/nsdynmemLIB_stub.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/nsdynmemLIB_stub.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/nsdynmemLIB_stub.h b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/nsdynmemLIB_stub.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/nsdynmemLIB_stub.h rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/nsdynmemLIB_stub.h diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/randLIB_stub.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/randLIB_stub.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/randLIB_stub.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/randLIB_stub.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/sn_coap_builder_stub.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/sn_coap_builder_stub.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/sn_coap_builder_stub.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/sn_coap_builder_stub.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/sn_coap_builder_stub.h b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/sn_coap_builder_stub.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/sn_coap_builder_stub.h rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/sn_coap_builder_stub.h diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/sn_coap_parser_stub.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/sn_coap_parser_stub.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/sn_coap_parser_stub.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/sn_coap_parser_stub.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/sn_coap_parser_stub.h b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/sn_coap_parser_stub.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/sn_coap_parser_stub.h rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/sn_coap_parser_stub.h diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/sn_coap_protocol_stub.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/sn_coap_protocol_stub.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/sn_coap_protocol_stub.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/sn_coap_protocol_stub.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/sn_coap_protocol_stub.h b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/sn_coap_protocol_stub.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/sn_coap_protocol_stub.h rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/sn_coap_protocol_stub.h diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/socket_api_stub.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/socket_api_stub.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/socket_api_stub.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/socket_api_stub.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/socket_api_stub.h b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/socket_api_stub.h similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/socket_api_stub.h rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/socket_api_stub.h diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/system_timer_stub.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/system_timer_stub.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/system_timer_stub.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/system_timer_stub.c diff --git a/features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/timeout_stub.c b/features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/timeout_stub.c similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/test/coap-service/unittest/stub/timeout_stub.c rename to features/net/FEATURE_NANOSTACK/coap-service/test/coap-service/unittest/stub/timeout_stub.c diff --git a/features/net/FEATURE_IPV6/coap-service/xsl_script.sh b/features/net/FEATURE_NANOSTACK/coap-service/xsl_script.sh old mode 100644 new mode 100755 similarity index 100% rename from features/net/FEATURE_IPV6/coap-service/xsl_script.sh rename to features/net/FEATURE_NANOSTACK/coap-service/xsl_script.sh diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/.gitignore b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/.gitignore similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/.gitignore rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/.gitignore diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/.mbedignore b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/.mbedignore similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/.mbedignore rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/.mbedignore diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/LICENSE b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/LICENSE similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/LICENSE rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/LICENSE diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/README.md b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/README.md similarity index 95% rename from features/net/FEATURE_IPV6/mbed-mesh-api/README.md rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/README.md index 71e3201319..920231b694 100644 --- a/features/net/FEATURE_IPV6/mbed-mesh-api/README.md +++ b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/README.md @@ -10,7 +10,7 @@ Currently, 6LoWPAN-ND (neighbour discovery) and Thread bootstrap modes are suppo ## Module Configuration -This module supports static configuration via **mbed configuration system** by using the `mbed_app.json` file. The application needs to create the configuration file if it wants to use other than default settings. +This module supports static configuration via **mbed configuration system** by using the `mbed_app.json` file. The application needs to create the configuration file if it wants to use other than default settings. An example of the configuration file: @@ -58,7 +58,7 @@ An example of the configuration file: | 6lowpan-nd-psk-key-id | number | PSK key id when PSK is enabled | | 6lowpan-nd-psk-key | byte array [16] | Pre shared network key | | 6lowpan-nd-sec-level | number [1-7] | Network security level. Use default `5` | - +| 6lowpan-nd-device-type | "NET_6LOWPAN_ROUTER" or "NET_6LOWPAN_HOST" | Device mode. Router is routing packets from other device, creating a mesh network. | ## Usage notes diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/apache-2.0.txt b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/apache-2.0.txt similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/apache-2.0.txt rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/apache-2.0.txt diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/mbed-mesh-api/AbstractMesh.h b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/mbed-mesh-api/AbstractMesh.h similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/mbed-mesh-api/AbstractMesh.h rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/mbed-mesh-api/AbstractMesh.h diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/mbed-mesh-api/AbstractNetworkInterface.h b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/mbed-mesh-api/AbstractNetworkInterface.h similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/mbed-mesh-api/AbstractNetworkInterface.h rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/mbed-mesh-api/AbstractNetworkInterface.h diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/mbed-mesh-api/Mesh6LoWPAN_ND.h b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/mbed-mesh-api/Mesh6LoWPAN_ND.h similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/mbed-mesh-api/Mesh6LoWPAN_ND.h rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/mbed-mesh-api/Mesh6LoWPAN_ND.h diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/mbed-mesh-api/MeshInterfaceFactory.h b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/mbed-mesh-api/MeshInterfaceFactory.h similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/mbed-mesh-api/MeshInterfaceFactory.h rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/mbed-mesh-api/MeshInterfaceFactory.h diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/mbed-mesh-api/MeshThread.h b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/mbed-mesh-api/MeshThread.h similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/mbed-mesh-api/MeshThread.h rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/mbed-mesh-api/MeshThread.h diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/mbed-mesh-api/mesh_interface_types.h b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/mbed-mesh-api/mesh_interface_types.h similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/mbed-mesh-api/mesh_interface_types.h rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/mbed-mesh-api/mesh_interface_types.h diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/mbed_lib.json b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/mbed_lib.json similarity index 95% rename from features/net/FEATURE_IPV6/mbed-mesh-api/mbed_lib.json rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/mbed_lib.json index 299807ae0f..4d21643598 100644 --- a/features/net/FEATURE_IPV6/mbed-mesh-api/mbed_lib.json +++ b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/mbed_lib.json @@ -9,6 +9,7 @@ "6lowpan-nd-psk-key-id": 1, "6lowpan-nd-psk-key": "{0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf}", "6lowpan-nd-sec-level": 5, + "6lowpan-nd-device-type": "NET_6LOWPAN_ROUTER", "thread-pskd": "\"Secret password\"", "thread-config-channel-mask": "0x7fff800", "thread-config-channel-page": 0, diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/module.json b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/module.json similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/module.json rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/module.json diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/source/AbstractMesh.cpp b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/AbstractMesh.cpp similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/source/AbstractMesh.cpp rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/AbstractMesh.cpp diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/source/AbstractNetworkInterface.cpp b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/AbstractNetworkInterface.cpp similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/source/AbstractNetworkInterface.cpp rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/AbstractNetworkInterface.cpp diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/source/CallbackHandler.cpp b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/CallbackHandler.cpp similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/source/CallbackHandler.cpp rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/CallbackHandler.cpp diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/source/Mesh6LoWPAN_ND.cpp b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/Mesh6LoWPAN_ND.cpp similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/source/Mesh6LoWPAN_ND.cpp rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/Mesh6LoWPAN_ND.cpp diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/source/MeshInterfaceFactory.cpp b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/MeshInterfaceFactory.cpp similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/source/MeshInterfaceFactory.cpp rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/MeshInterfaceFactory.cpp diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/source/MeshThread.cpp b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/MeshThread.cpp similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/source/MeshThread.cpp rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/MeshThread.cpp diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/source/include/callback_handler.h b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/include/callback_handler.h similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/source/include/callback_handler.h rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/include/callback_handler.h diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/source/include/mesh_system.h b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/include/mesh_system.h similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/source/include/mesh_system.h rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/include/mesh_system.h diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/source/include/nd_tasklet.h b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/include/nd_tasklet.h similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/source/include/nd_tasklet.h rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/include/nd_tasklet.h diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/source/include/static_config.h b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/include/static_config.h similarity index 99% rename from features/net/FEATURE_IPV6/mbed-mesh-api/source/include/static_config.h rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/include/static_config.h index db2f3dc275..cd2ff27149 100644 --- a/features/net/FEATURE_IPV6/mbed-mesh-api/source/include/static_config.h +++ b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/include/static_config.h @@ -73,7 +73,7 @@ extern "C" { #elif defined MBED_CONF_MBED_MESH_API_6LOWPAN_ND_SECURITY_MODE #define MBED_MESH_API_6LOWPAN_ND_SECURITY_MODE MBED_CONF_MBED_MESH_API_6LOWPAN_ND_SECURITY_MODE #else -#define YOTTA_CFG_MBED_MESH_API_6LOWPAN_ND_SECURITY_MODE NONE +#define MBED_MESH_API_6LOWPAN_ND_SECURITY_MODE NONE #endif #ifdef YOTTA_CFG_MBED_MESH_API_6LOWPAN_ND_PSK_KEY_ID diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/source/include/thread_tasklet.h b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/include/thread_tasklet.h similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/source/include/thread_tasklet.h rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/include/thread_tasklet.h diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/source/mesh_system.c b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/mesh_system.c similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/source/mesh_system.c rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/mesh_system.c diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/source/nd_tasklet.c b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/nd_tasklet.c similarity index 98% rename from features/net/FEATURE_IPV6/mbed-mesh-api/source/nd_tasklet.c rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/nd_tasklet.c index 153b90e6d1..3b74fe02bb 100644 --- a/features/net/FEATURE_IPV6/mbed-mesh-api/source/nd_tasklet.c +++ b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/nd_tasklet.c @@ -72,6 +72,7 @@ typedef struct { /* Tasklet data */ static tasklet_data_str_t *tasklet_data_ptr = NULL; +static mac_api_t *mac_api = NULL; /* private function prototypes */ void nd_tasklet_main(arm_event_s *event); @@ -369,8 +370,7 @@ int8_t nd_tasklet_connect(mesh_interface_cb callback, int8_t nwk_interface_id) tasklet_data_ptr->network_interface_id = nwk_interface_id; tasklet_data_ptr->tasklet_state = TASKLET_STATE_INITIALIZED; - //TODO: Fetch these values from device config api - tasklet_data_ptr->mode = NET_6LOWPAN_ROUTER; + tasklet_data_ptr->mode = MBED_CONF_MBED_MESH_API_6LOWPAN_ND_DEVICE_TYPE; tasklet_data_ptr->sec_mode = NET_SEC_MODE_NO_LINK_SECURITY; //tasklet_data_ptr->psk_sec_info.key_id = 0; @@ -427,7 +427,9 @@ int8_t nd_tasklet_network_init(int8_t device_id) storage_sizes.key_description_table_size = 3; storage_sizes.key_lookup_size = 1; storage_sizes.key_usage_size = 3; - mac_api_t *api = ns_sw_mac_create(device_id, &storage_sizes); - return arm_nwk_interface_lowpan_init(api, INTERFACE_NAME); + if (!mac_api) { + mac_api = ns_sw_mac_create(device_id, &storage_sizes); + } + return arm_nwk_interface_lowpan_init(mac_api, INTERFACE_NAME); } diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/source/thread_tasklet.c b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/thread_tasklet.c similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/source/thread_tasklet.c rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/thread_tasklet.c diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/source/to_be_ported.c b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/to_be_ported.c similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/source/to_be_ported.c rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/source/to_be_ported.c diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/test/6lowpan_nd/README.md b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/test/6lowpan_nd/README.md similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/test/6lowpan_nd/README.md rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/test/6lowpan_nd/README.md diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/test/6lowpan_nd/main.cpp b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/test/6lowpan_nd/main.cpp similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/test/6lowpan_nd/main.cpp rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/test/6lowpan_nd/main.cpp diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/test/system_test/main.cpp b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/test/system_test/main.cpp similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/test/system_test/main.cpp rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/test/system_test/main.cpp diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/test/system_test/test_cases.cpp b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/test/system_test/test_cases.cpp similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/test/system_test/test_cases.cpp rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/test/system_test/test_cases.cpp diff --git a/features/net/FEATURE_IPV6/mbed-mesh-api/test/system_test/test_cases.h b/features/net/FEATURE_NANOSTACK/mbed-mesh-api/test/system_test/test_cases.h similarity index 100% rename from features/net/FEATURE_IPV6/mbed-mesh-api/test/system_test/test_cases.h rename to features/net/FEATURE_NANOSTACK/mbed-mesh-api/test/system_test/test_cases.h diff --git a/features/net/FEATURE_IPV6/nanostack-interface/NanostackInterface.cpp b/features/net/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp similarity index 100% rename from features/net/FEATURE_IPV6/nanostack-interface/NanostackInterface.cpp rename to features/net/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.cpp diff --git a/features/net/FEATURE_IPV6/nanostack-interface/NanostackInterface.h b/features/net/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.h similarity index 100% rename from features/net/FEATURE_IPV6/nanostack-interface/NanostackInterface.h rename to features/net/FEATURE_NANOSTACK/nanostack-interface/NanostackInterface.h diff --git a/features/net/FEATURE_IPV6/nanostack-interface/NanostackRfPhy.h b/features/net/FEATURE_NANOSTACK/nanostack-interface/NanostackRfPhy.h similarity index 100% rename from features/net/FEATURE_IPV6/nanostack-interface/NanostackRfPhy.h rename to features/net/FEATURE_NANOSTACK/nanostack-interface/NanostackRfPhy.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/.gitignore b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/.gitignore similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/.gitignore rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/.gitignore diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/DOXYGEN_FRONTPAGE.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/DOXYGEN_FRONTPAGE.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/DOXYGEN_FRONTPAGE.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/DOXYGEN_FRONTPAGE.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/Doxyfile b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/Doxyfile similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/Doxyfile rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/Doxyfile diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/LICENSE b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/LICENSE similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/LICENSE rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/LICENSE diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/LICENSE-permissive-binary-license-1.0.txt b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/LICENSE-permissive-binary-license-1.0.txt similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/LICENSE-permissive-binary-license-1.0.txt rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/LICENSE-permissive-binary-license-1.0.txt diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/README.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/README.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/README.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/README.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/01_overview.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/01_overview.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/01_overview.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/01_overview.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/02_N_arch.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/02_N_arch.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/02_N_arch.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/02_N_arch.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/03_N_usage.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/03_N_usage.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/03_N_usage.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/03_N_usage.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/04_N_networking.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/04_N_networking.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/04_N_networking.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/04_N_networking.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/05_reference.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/05_reference.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/05_reference.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/05_reference.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/06_API_introduction.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/06_API_introduction.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/06_API_introduction.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/06_API_introduction.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/07_API_initialize.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/07_API_initialize.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/07_API_initialize.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/07_API_initialize.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/08_API_events.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/08_API_events.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/08_API_events.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/08_API_events.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/09_API_network_def.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/09_API_network_def.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/09_API_network_def.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/09_API_network_def.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/10_API_timer.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/10_API_timer.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/10_API_timer.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/10_API_timer.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/11_API_sockets.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/11_API_sockets.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/11_API_sockets.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/11_API_sockets.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/12_API_network.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/12_API_network.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/12_API_network.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/12_API_network.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/13_API_memory.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/13_API_memory.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/13_API_memory.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/13_API_memory.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/14_API_data.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/14_API_data.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/14_API_data.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/14_API_data.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/15_API_debug.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/15_API_debug.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/15_API_debug.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/15_API_debug.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/16_API_porting.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/16_API_porting.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/16_API_porting.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/16_API_porting.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/api_changes_to_v4_0_0.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/api_changes_to_v4_0_0.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/api_changes_to_v4_0_0.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/api_changes_to_v4_0_0.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/api_changes_to_v5_0_0.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/api_changes_to_v5_0_0.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/api_changes_to_v5_0_0.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/api_changes_to_v5_0_0.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/dev_stats.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/dev_stats.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/dev_stats.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/dev_stats.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/driver_api.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/driver_api.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/driver_api.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/driver_api.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/6lh.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/6lh.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/6lh.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/6lh.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/6lowpan_border_router_embedded_C_architecture.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/6lowpan_border_router_embedded_C_architecture.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/6lowpan_border_router_embedded_C_architecture.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/6lowpan_border_router_embedded_C_architecture.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/6lowpan_network_architecture.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/6lowpan_network_architecture.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/6lowpan_network_architecture.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/6lowpan_network_architecture.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/6lowpan_stack_architecture.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/6lowpan_stack_architecture.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/6lowpan_stack_architecture.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/6lowpan_stack_architecture.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/6lowpan_stack_networking_topologies.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/6lowpan_stack_networking_topologies.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/6lowpan_stack_networking_topologies.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/6lowpan_stack_networking_topologies.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/6lowpan_stack_osi_model.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/6lowpan_stack_osi_model.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/6lowpan_stack_osi_model.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/6lowpan_stack_osi_model.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/6lr.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/6lr.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/6lr.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/6lr.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/Thread_General.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/Thread_General.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/Thread_General.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/Thread_General.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/Thread_Prot_Arch2.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/Thread_Prot_Arch2.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/Thread_Prot_Arch2.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/Thread_Prot_Arch2.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/Thread_Prot_Arch_Comb.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/Thread_Prot_Arch_Comb.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/Thread_Prot_Arch_Comb.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/Thread_Prot_Arch_Comb.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/Thread_Proto_Arch.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/Thread_Proto_Arch.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/Thread_Proto_Arch.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/Thread_Proto_Arch.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/arch_general.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/arch_general.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/arch_general.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/arch_general.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/br.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/br.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/br.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/br.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/bw.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/bw.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/bw.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/bw.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/ed_scan_process.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/ed_scan_process.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/ed_scan_process.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/ed_scan_process.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/examples.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/examples.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/examples.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/examples.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/high_level_stack_API_interfaces.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/high_level_stack_API_interfaces.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/high_level_stack_API_interfaces.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/high_level_stack_API_interfaces.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/join_process_star_6lowpan_router.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/join_process_star_6lowpan_router.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/join_process_star_6lowpan_router.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/join_process_star_6lowpan_router.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/join_process_to_router_mesh_6lowpan.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/join_process_to_router_mesh_6lowpan.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/join_process_to_router_mesh_6lowpan.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/join_process_to_router_mesh_6lowpan.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/mbedOS_sockets.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/mbedOS_sockets.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/mbedOS_sockets.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/mbedOS_sockets.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/mesh.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/mesh.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/mesh.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/mesh.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/nanostack_in_mbed_OS.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/nanostack_in_mbed_OS.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/nanostack_in_mbed_OS.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/nanostack_in_mbed_OS.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/network_bootstrap_high_level_view.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/network_bootstrap_high_level_view.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/network_bootstrap_high_level_view.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/network_bootstrap_high_level_view.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/network_bootstrapping_process.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/network_bootstrapping_process.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/network_bootstrapping_process.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/network_bootstrapping_process.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/node_to_server.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/node_to_server.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/node_to_server.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/node_to_server.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/rpl_layer_reg_multiple_hops.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/rpl_layer_reg_multiple_hops.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/rpl_layer_reg_multiple_hops.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/rpl_layer_reg_multiple_hops.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/rpl_layer_reg_single_hop.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/rpl_layer_reg_single_hop.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/rpl_layer_reg_single_hop.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/rpl_layer_reg_single_hop.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/rpl_mesh_high_level_view.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/rpl_mesh_high_level_view.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/rpl_mesh_high_level_view.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/rpl_mesh_high_level_view.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/star_topology.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/star_topology.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/star_topology.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/star_topology.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/state_machine_6lowpan.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/state_machine_6lowpan.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/state_machine_6lowpan.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/state_machine_6lowpan.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/temp.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/temp.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/temp.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/temp.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_case1.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_case1.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_case1.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_case1.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_case2.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_case2.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_case2.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_case2.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_case3.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_case3.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_case3.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_case3.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_case4.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_case4.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_case4.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_case4.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_comm_ext.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_comm_ext.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_comm_ext.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_comm_ext.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_ext_pet_seq.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_ext_pet_seq.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_ext_pet_seq.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_ext_pet_seq.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_nat_pet_seq.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_nat_pet_seq.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_nat_pet_seq.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_nat_pet_seq.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_native_comm_pet.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_native_comm_pet.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_native_comm_pet.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_native_comm_pet.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_pet_auth_seq.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_pet_auth_seq.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/thread_pet_auth_seq.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/thread_pet_auth_seq.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/tx_process.png b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/tx_process.png similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/img/tx_process.png rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/img/tx_process.png diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/index.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/index.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/index.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/index.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/platform_API.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/platform_API.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/platform_API.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/platform_API.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/quick_start_build.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/quick_start_build.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/quick_start_build.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/quick_start_build.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/quick_start_config.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/quick_start_config.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/quick_start_config.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/quick_start_config.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/quick_start_hw.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/quick_start_hw.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/quick_start_hw.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/quick_start_hw.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/quick_start_intro.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/quick_start_intro.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/quick_start_intro.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/quick_start_intro.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/thread_APIs.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/thread_APIs.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/thread_APIs.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/thread_APIs.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/thread_comm.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/thread_comm.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/thread_comm.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/thread_comm.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/thread_dev_typ.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/thread_dev_typ.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/thread_dev_typ.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/thread_dev_typ.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/thread_overview.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/thread_overview.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/thread_overview.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/thread_overview.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/docs/thread_sec.md b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/thread_sec.md similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/docs/thread_sec.md rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/docs/thread_sec.md diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/doxygen/mainpage.dox b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/doxygen/mainpage.dox similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/doxygen/mainpage.dox rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/doxygen/mainpage.dox diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/mbed_lib.json b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/mbed_lib.json similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/mbed_lib.json rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/mbed_lib.json diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/mkdocs.yml b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/mkdocs.yml similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/mkdocs.yml rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/mkdocs.yml diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/cca_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/cca_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/cca_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/cca_api.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/ccmLIB.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ccmLIB.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/ccmLIB.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ccmLIB.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/dev_stat_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/dev_stat_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/dev_stat_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/dev_stat_api.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/dhcp_service_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/dhcp_service_api.h similarity index 93% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/dhcp_service_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/dhcp_service_api.h index 33df7f60fb..72c7345486 100644 --- a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/dhcp_service_api.h +++ b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/dhcp_service_api.h @@ -59,6 +59,12 @@ #define TX_OPT_MULTICAST_HOP_LIMIT_64 0x02 /**< Use multicast hop limit of 64. */ ///@} +typedef enum dhcp_instance_type +{ + DHCP_INSTANCE_CLIENT, + DHCP_INSTANCE_SERVER +} dhcp_instance_type_e; + /** * \brief DHCP Service receive callback. * @@ -96,14 +102,18 @@ typedef int (dhcp_service_receive_resp_cb)(uint16_t instance_id, void *ptr, uint /** - * \brief Initialize the server instance. + * \brief Initialize a new DHCP service instance. * * Creates and shares the socket for other DHCP services. * + * \param interface_id Interface for the new DHCP instance. + * \param instance_type The type of the new DHCP instance. + * \param A callback function to receive DHCP messages. + * * \return Instance ID that is used to identify the service. */ -uint16_t dhcp_service_init(int8_t interface_id, dhcp_service_receive_req_cb *receive_req_cb); +uint16_t dhcp_service_init(int8_t interface_id, dhcp_instance_type_e instance_type, dhcp_service_receive_req_cb *receive_req_cb); /** * \brief Deletes a server instance. diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/ethernet_mac_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ethernet_mac_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/ethernet_mac_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ethernet_mac_api.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/mac_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/mac_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/mac_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/mac_api.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/mac_common_defines.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/mac_common_defines.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/mac_common_defines.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/mac_common_defines.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/mac_filter_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/mac_filter_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/mac_filter_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/mac_filter_api.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/mac_mcps.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/mac_mcps.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/mac_mcps.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/mac_mcps.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/mlme.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/mlme.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/mlme.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/mlme.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/multicast_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/multicast_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/multicast_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/multicast_api.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_6lowpan_parameter_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_6lowpan_parameter_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_6lowpan_parameter_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_6lowpan_parameter_api.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_address_extension.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_address_extension.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_address_extension.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_address_extension.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_fhss.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_fhss.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_fhss.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_fhss.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_interface.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_interface.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_interface.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_interface.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_ipv6_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_ipv6_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_ipv6_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_ipv6_api.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_mle_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_mle_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_mle_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_mle_api.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_nvm_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_nvm_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_nvm_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_nvm_api.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_nwk_scan.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_nwk_scan.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_nwk_scan.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_nwk_scan.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_pana_parameters_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_pana_parameters_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_pana_parameters_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_pana_parameters_api.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_polling_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_polling_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_polling_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_polling_api.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_rpl.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_rpl.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_rpl.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_rpl.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_sleep.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_sleep.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_sleep.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_sleep.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_thread_test.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_thread_test.h similarity index 86% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_thread_test.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_thread_test.h index 33ec6303e7..309dacd4d3 100644 --- a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/net_thread_test.h +++ b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/net_thread_test.h @@ -30,7 +30,7 @@ extern "C" { #include "ns_types.h" - +#define thread_test_router_upgrade(iface) thread_test_router_id_request_send(iface, 2) // THREAD_COAP_STATUS_TLV_TOO_FEW_ROUTERS /** * \brief Add a static neighbour * @@ -174,15 +174,7 @@ int thread_test_set_context_id_reuse_timeout( * \return <0 Remove fail */ int thread_test_remove_router_by_id(int8_t interface_id, uint8_t routerId); -/** - * \brief Start router upgrade process. - * - * \param interface_id Network Interface - * - * \return 0, upgrade started - * \return <0 fail - */ -int thread_test_router_upgrade(int8_t interface_id); + /** * \brief Start router downgrade process. * @@ -367,7 +359,7 @@ int8_t thread_test_neighbour_info_get(int8_t interface_id, uint8_t index, uint16 typedef int (response_cb)(int8_t interface_id, uint8_t *response_ptr, uint16_t response_len); /** - * \brief Send diagnostic command + * \brief Send diagnostic command DEPRECATED * * \param interface_id Network Interface * \param address_ptr Address to which the command is sent @@ -380,6 +372,24 @@ typedef int (response_cb)(int8_t interface_id, uint8_t *response_ptr, uint16_t r */ int thread_test_diagnostic_command_send(int8_t interface_id, uint8_t *address_ptr,const char *uri_ptr, uint8_t request_length, uint8_t *request_ptr, response_cb *resp_cb); +typedef int (coap_response_cb)(int8_t interface_id, uint8_t message_code, uint8_t message_type, uint8_t *response_ptr, uint16_t response_len); + +/** + * \brief Send diagnostic request + * + * \param interface_id Network Interface + * \param address_ptr Address to which the command is sent + * \param msg_type Uri for the command + * \param msg_code Uri for the command + * \param uri_ptr Uri for the command + * \param request_length The length of the request + * \param request_ptr Pointer to the beginning of the request contents + * \param resp_cb Pointer to callback function that is called after the reply for the command is obtained + * + * \return 0, Command send OK + * \return <0 Command send Fail + */ +int thread_test_coap_request_send(int8_t interface_id, uint8_t *address_ptr, uint16_t port, uint8_t msg_type, uint8_t msg_code, uint16_t content_format, const char *uri_ptr, uint8_t *request_ptr, uint8_t request_length, coap_response_cb *resp_cb); /** * \brief Set initial SLAAC iid. @@ -391,6 +401,26 @@ int thread_test_diagnostic_command_send(int8_t interface_id, uint8_t *address_pt */ int8_t thread_test_initial_slaac_iid_set(int8_t interface_id, uint8_t *iid); +/** + * \brief Send router ID request. + * + * \param interface_id Network Interface + * \param status Value of router ID request status TLV + * \return 0, Command OK + * \return <0 Command Fail + */ +int8_t thread_test_router_id_request_send(int8_t interface_id, uint8_t status); + +/** + * \brief Set joiner port to joiner router device. + * If port == 0, then default port is used. + * + * \param iid Joiner port. + * \return 0, Command OK + * \return <0 Command Fail + */ +int8_t thread_test_joiner_router_joiner_port_set(uint16_t port); + #ifdef __cplusplus } #endif diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/ns_address.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ns_address.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/ns_address.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ns_address.h diff --git a/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ns_sha256.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ns_sha256.h new file mode 100644 index 0000000000..b32a29a748 --- /dev/null +++ b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ns_sha256.h @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2006-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 ns_sha256.h + * + * \brief SHA-256 cryptographic hash function + * + * This file is derived from sha256.h in mbed TLS 2.3.0. + * + * This file provides an API very similar to mbed TLS, either implemented + * locally, or by calling mbed TLS, depending on NS_USE_EXTERNAL_MBED_TLS. + * + * Differences from mbed TLS: + * + * a) ns_ prefix instead of mbedtls_; + * b) Pointers are void * instead of unsigned char * to avoid type clashes; + * c) SHA-224 not supported; + * d) Ability to output truncated hashes. + */ + + +#ifndef NS_SHA256_H_ +#define NS_SHA256_H_ + +#ifdef NS_USE_EXTERNAL_MBED_TLS + +#include +#include "mbedtls/sha256.h" + +typedef mbedtls_sha256_context ns_sha256_context; + +static inline void ns_sha256_init(ns_sha256_context *ctx) +{ + mbedtls_sha256_init(ctx); +} + +static inline void ns_sha256_free(ns_sha256_context *ctx) +{ + mbedtls_sha256_free(ctx); +} + +static inline void ns_sha256_clone(ns_sha256_context *dst, + const ns_sha256_context *src) +{ + mbedtls_sha256_clone(dst, src); +} + +static inline void ns_sha256_starts(ns_sha256_context *ctx) +{ + mbedtls_sha256_starts(ctx, 0); +} + +static inline void ns_sha256_update(ns_sha256_context *ctx, const void *input, + size_t ilen) +{ + mbedtls_sha256_update(ctx, input, ilen); +} + +static inline void ns_sha256_finish(ns_sha256_context *ctx, void *output) +{ + mbedtls_sha256_finish(ctx, output); +} + +static inline void ns_sha256(const void *input, size_t ilen, void *output) +{ + mbedtls_sha256(input, ilen, output, 0); +} + +/* Extensions to standard mbed TLS - output the first bits of a hash only */ +/* Number of bits must be a multiple of 32, and <=256 */ +static inline void ns_sha256_finish_nbits(ns_sha256_context *ctx, void *output, unsigned obits) +{ + if (obits == 256) { + mbedtls_sha256_finish(ctx, output); + } else { + uint8_t sha256[32]; + mbedtls_sha256_finish(ctx, sha256); + memcpy(output, sha256, obits / 8); + } +} + +static inline void ns_sha256_nbits(const void *input, size_t ilen, void *output, unsigned obits) +{ + if (obits == 256) { + mbedtls_sha256(input, ilen, output, 0); + } else { + uint8_t sha256[32]; + mbedtls_sha256(input, ilen, sha256, 0); + memcpy(output, sha256, obits / 8); + } +} + +#else /* NS_USE_EXTERNAL_MBED_TLS */ + +#include +#include + +/** + * \brief SHA-256 context structure + */ +typedef struct +{ + uint32_t total[2]; /*!< number of bytes processed */ + uint32_t state[8]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ +} +ns_sha256_context; + +/** + * \brief Initialize SHA-256 context + * + * \param ctx SHA-256 context to be initialized + */ +void ns_sha256_init( ns_sha256_context *ctx ); + +/** + * \brief Clear SHA-256 context + * + * \param ctx SHA-256 context to be cleared + */ +void ns_sha256_free( ns_sha256_context *ctx ); + +/** + * \brief Clone (the state of) a SHA-256 context + * + * \param dst The destination context + * \param src The context to be cloned + */ +void ns_sha256_clone( ns_sha256_context *dst, + const ns_sha256_context *src ); + +/** + * \brief SHA-256 context setup + * + * \param ctx context to be initialized + */ +void ns_sha256_starts( ns_sha256_context *ctx ); + +/** + * \brief SHA-256 process buffer + * + * \param ctx SHA-256 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void ns_sha256_update( ns_sha256_context *ctx, const void *input, + size_t ilen ); + +/** + * \brief SHA-256 final digest + * + * \param ctx SHA-256 context + * \param output SHA-256 checksum result + */ +void ns_sha256_finish( ns_sha256_context *ctx, void *output ); + +/** + * \brief SHA-256 final digest + * + * \param ctx SHA-256 context + * \param output SHA-256 checksum result + * \param obits Number of bits of to output - must be multiple of 32 + */ +void ns_sha256_finish_nbits( ns_sha256_context *ctx, + void *output, unsigned obits ); + +/** + * \brief Output = SHA-256( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output SHA-256 checksum result + */ +void ns_sha256( const void *input, size_t ilen, + void *output ); + +/** + * \brief Output = SHA-256( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output SHA-256 checksum result + * \param obits Number of bits of to output - must be multiple of 32 + */ +void ns_sha256_nbits( const void *input, size_t ilen, + void *output, unsigned obits ); + +#endif /* NS_USE_EXTERNAL_MBED_TLS */ + + +#endif /* NS_SHA256_H_ */ diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/ns_virtual_rf_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ns_virtual_rf_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/ns_virtual_rf_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/ns_virtual_rf_api.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/nwk_stats_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/nwk_stats_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/nwk_stats_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/nwk_stats_api.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/platform/arm_hal_aes.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/platform/arm_hal_aes.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/platform/arm_hal_aes.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/platform/arm_hal_aes.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/platform/arm_hal_phy.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/platform/arm_hal_phy.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/platform/arm_hal_phy.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/platform/arm_hal_phy.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/platform/os_whiteboard.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/platform/os_whiteboard.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/platform/os_whiteboard.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/platform/os_whiteboard.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/platform/topo_trace.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/platform/topo_trace.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/platform/topo_trace.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/platform/topo_trace.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/serial_mac_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/serial_mac_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/serial_mac_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/serial_mac_api.h diff --git a/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/shalib.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/shalib.h new file mode 100644 index 0000000000..4b70cc0f9d --- /dev/null +++ b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/shalib.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014-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 shalib.h + * \brief SHA256 Library API. + * + * \section hmac256-inctuction HMAC256 process sequence: + * 1. SHALIB_init_HMAC(), Init HMAC IN process by given security signature material + * 2. SHALIB_push_data_HMAC(), Give data sectors(s) one by one + * 3. SHALIB_finish_HMAC(), Finish HMAC and save SHA256 hash to given buffer + * + * \section prf256-inctuction PRF256 process sequence: + * 1. shalib_prf_param_get(), Init PRF and get configure structure + * 2. Set the following parameters to configure structure: + * - HMAC security signature pointer and length + * - Label text + * - Seed data and length + * 3. shalib_prf_calc(), Calc PRF256 HASH + * + */ + +#ifndef SHALIB_H_ +#define SHALIB_H_ + +#include "ns_types.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * \struct prf_sec_param_t + * \brief PRF 256 stucture + * This structure is used to configure PRF calc operation: secret, label, seed and buffer before call shalib_prf_calc(). + */ +typedef struct { + const uint8_t *secret; /**< HMAC security signature pointer. */ + uint8_t sec_len; /**< HMAC security signature length. */ + const char *label; /**< PRF label text. */ + const uint8_t *seed; /**< PRF Seed data. */ + uint8_t seedlen; /**< PRF Seed data length. */ +} prf_sec_param_t; + + +// Use these for cumulative HMAC +/** + * \brief Init HMAC256 operation by given security material. + * + * \param secret A pointer to security material. + * \param sec_len Length of security material. + */ +void SHALIB_init_HMAC(const uint8_t *secret, uint8_t sec_len); // Call this first... +/** + * \brief Push data for HMAC + * + * \param data A pointer to data. + * \param len Length of data. + */ +void SHALIB_push_data_HMAC(const void *data, uint16_t len); // ... add data ... +/** + * \brief Finish HMAC256 operation and save result in given buffer. + * + * \param buffer A pointer to result buffer. + * \param nwords Length of 32-bit register to save to buffer (8= 256 bit and 4= 128-bit). + */ +void SHALIB_finish_HMAC(void *buffer, uint8_t nwords); // ... get the HMAC digest. + + +/** PRF API */ +/** + * \brief Init PRF library and SHA registers. + * This function returns configure structure where the user needs to set the following items: + * -Security material and length + * -Label text and length + * -Seed data and length + * + * \return A pointer to PRF configure structure. + + */ +prf_sec_param_t *shalib_prf_param_get(void); // GET PRF structure +/* SET secret, label, seed & buffer to 256 PRF */ +/** + * \brief Finish PRF256 operation and save result in given buffer. + */ +void shalib_prf_calc(void *output, uint_fast16_t nwords);// GET 256 PRF +#ifdef __cplusplus +} +#endif +#endif /* SHALIB_H_ */ diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/socket_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/socket_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/socket_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/socket_api.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/sw_mac.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/sw_mac.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/sw_mac.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/sw_mac.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_border_router_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_border_router_api.h similarity index 78% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_border_router_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_border_router_api.h index 2ca7707340..b227958719 100644 --- a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_border_router_api.h +++ b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_border_router_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015 ARM Limited. All rights reserved. + * Copyright (c) 2014-2016 ARM Limited. All rights reserved. * * SPDX-License-Identifier: LicenseRef-PBL * @@ -27,10 +27,8 @@ #include "ns_types.h" - /** - * Structure specifying the prefix service. - * + * \brief Border router network data structure. */ typedef struct thread_border_router_info_t { unsigned Prf: 2; /**!< Prefix preference, 01 = High, 00 = Default, 11 = Low, 10 = Reserved. */ @@ -44,10 +42,6 @@ typedef struct thread_border_router_info_t { bool stableData: 1; /**!< This data is stable and expected to be available at least 48h. */ } thread_border_router_info_t; -/* Define flags for backwards compatibility. Remove once applications have been updated */ -#define P_slaac_preferred P_preferred -#define P_slaac_valid P_slaac - /** * \brief Create local service that is provided to the Thread network. * If a prefix exists it is updated. For example, when removing SLAAC (Stateless Address Autoconfiguration) you should modify the prefix @@ -158,4 +152,32 @@ int thread_border_router_publish(int8_t interface_id); */ int thread_border_router_delete_all(int8_t interface_id); +/** + * \brief Set Recursive DNS server (RDNSS) option that is encoded according to RFC6106. + * Setting a new RDNSS will overwrite previous RDNSS option. Set RNDDS will be used + * until it is cleared. + * + * \param interface_id Network interface ID. + * \param recursive_dns_server_option Recursive DNS server option encoded according to rfc6106, can be NULL to clear existing RDNSS. + * \param recursive_dns_server_option_len Length of the recursive_dns_server_option in bytes. + * + * \return 0, Option saved OK. + * \return <0 when error occurs during option processing. + */ +int thread_border_router_recursive_dns_server_option_set(int8_t interface_id, uint8_t *recursive_dns_server_option, uint16_t recursive_dns_server_option_len); + +/** + * \brief Set DNS server search list (DNSSL) option that is encoded according to RFC6106. + * Setting a new DNSSL will overwrite previous DNSSL option. Set DNSSL will be used + * until it is cleared. + * + * \param interface_id Network interface ID. + * \param dns_search_list_option DNS search list option encoded according to rfc6106, can be NULL to clear existing DNSSL. + * \param search_list_option_len Length of the dns_search_list_option in bytes. + * + * \return 0, Option saved OK. + * \return <0 when error occurs during option processing. + */ +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_ */ diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_commissioning_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_commissioning_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_commissioning_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_commissioning_api.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_dhcpv6_server.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_dhcpv6_server.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_dhcpv6_server.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_dhcpv6_server.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_diagcop_lib.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_diagcop_lib.h similarity index 99% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_diagcop_lib.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_diagcop_lib.h index b60c4618dc..80f59e8dd8 100644 --- a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_diagcop_lib.h +++ b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_diagcop_lib.h @@ -40,8 +40,7 @@ #define DIAGCOP_TLV_SUPPLY_VOLTAGE 15 /**< Can not reset*/ #define DIAGCOP_TLV_CHILD_TABLE 16 /**< Can not reset*/ #define DIAGCOP_TLV_CHANNEL_PAGES 17 /**< Can not reset*/ - -#define DIAGCOP_TLV_GET 13 +#define DIAGCOP_TLV_TYPE_LIST 18 /** * \brief Write array TLV. diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_management_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_management_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_management_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_management_api.h diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_management_if.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_management_if.h similarity index 91% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_management_if.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_management_if.h index 775f487638..4c10309f4c 100644 --- a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_management_if.h +++ b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_management_if.h @@ -121,6 +121,38 @@ int thread_management_node_init( device_configuration_s *device_configuration, link_configuration_s *static_configuration); +/** + * Thread device type. + * + * REED - Router enabled End device. Device can become router or end device depending on network conditions. + * FED - Full End Device. Device creates links and makes address queries but does not become router. + * MED - Minimal End Device. Device communicates through parent. With radio on + * SED - Sleepy End Device. Device communicates through parent. Uses data poll to sleep. +*/ +typedef enum { + THREAD_DEVICE_REED = 1, + THREAD_DEVICE_FED, + THREAD_DEVICE_MED, + THREAD_DEVICE_SED, +} thread_device_type_e; + +/** + * Change thread device type. + * + * This function modifies the thread device mode. Default values are given in + * function arm_nwk_interface_configure_6lowpan_bootstrap_set(). + * + * If this function is called when interface is up re-attach is made. + * + * \param interface_id Network interface ID. + * \param device_type Device type of current bootstrap. + * + * \return 0, Set OK. + * \return <0 Set fail. + */ + +int thread_management_device_type_set(int8_t interface_id, thread_device_type_e device_type); + /** * Get Thread network settings. * diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_meshcop_lib.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_meshcop_lib.h similarity index 94% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_meshcop_lib.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_meshcop_lib.h index 17c0f11168..91c7b72692 100644 --- a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/thread_meshcop_lib.h +++ b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_meshcop_lib.h @@ -52,6 +52,11 @@ #define MESHCOP_TLV_STATE 16 #define MESHCOP_TLV_JOINER_UDP_PORT 18 +/** + * Network management TLV specific bit defines + */ +#define MESHCOP_TLV_ACTIVE_TIME_STAMP_U_BIT 0x01 + /** * Relay message TLV */ @@ -158,6 +163,18 @@ uint8_t *thread_meshcop_tlv_data_write_uint32(uint8_t *ptr, const uint8_t type, */ uint8_t *thread_meshcop_tlv_data_write_uint64(uint8_t *ptr, const uint8_t type, const uint64_t data); +/** + * Check if TLV exists in the message. + * + * \param ptr Message buffer. + * \param length Length of the message buffer to validate message. + * \param type Type of TLV searched. + * + * \return true if TLV is found. + * \return false if TLV does not exist. + */ +bool thread_meshcop_tlv_exist(const uint8_t *ptr, const uint16_t length, const uint8_t type); + /** * Find TLV from message. * diff --git a/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_net_config_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_net_config_api.h new file mode 100644 index 0000000000..e66a404207 --- /dev/null +++ b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/thread_net_config_api.h @@ -0,0 +1,57 @@ +/* + * 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 thread_net_config_api.h + * \brief Public API to handle the Thread network services and configuration. + */ + +#ifndef _THREAD_NET_CONFIG_API_H_ +#define _THREAD_NET_CONFIG_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ns_types.h" + +/* + * \brief function callback type for nd_data_request. + * + * \param inteface_id Network interface ID where request was made. + * \param status 0 when response is received from destination, -1 otherwise. + * \param data_ptr ND_data options encoded according to RFC6106. Is NULL if destination was unreachable or didn't have the requested data. + * \param data_len Length of data in bytes. + */ +typedef void thread_net_config_nd_data_req_cb(int8_t interface_id, int8_t status, uint8_t *data_ptr, uint16_t data_len); + +/** + * \brief Request ND options (as in RFC6106) from given destination. + * Response data will be provided in callback function. + * + * \param interface_id network interface ID. + * \param destination IPv6 address where request is sent. + * \param options requested option type identifiers according to RFC6106. + * \param options_len number of options requested. + * \param callback Function that will be called once information is available. + * + * \return 0 on success. A callback will be called with/without response data. + * \return <0 in error cases. Callback will not be called. + */ +int thread_net_config_nd_data_request(int8_t interface_id, const uint8_t destination[16], const uint8_t *options, uint8_t options_len, thread_net_config_nd_data_req_cb *callback); + +#ifdef __cplusplus +} +#endif +#endif /* _THREAD_NET_CONFIG_API_H_ */ diff --git a/features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/whiteboard_api.h b/features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/whiteboard_api.h similarity index 100% rename from features/net/FEATURE_IPV6/sal-stack-nanostack/nanostack/whiteboard_api.h rename to features/net/FEATURE_NANOSTACK/sal-stack-nanostack/nanostack/whiteboard_api.h diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar new file mode 100644 index 0000000000..33811dddf7 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_border_router.ar b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_border_router.ar new file mode 100644 index 0000000000..e877b3d6a4 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_border_router.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar new file mode 100644 index 0000000000..33811dddf7 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_border_router.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_border_router.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_border_router.a new file mode 100644 index 0000000000..34467eba27 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_border_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_border_router.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_border_router.a new file mode 100644 index 0000000000..96663b6c68 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_border_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_border_router.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_border_router.a new file mode 100644 index 0000000000..34467eba27 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_border_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a new file mode 100644 index 0000000000..9aabc250e5 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_border_router.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_border_router.a new file mode 100644 index 0000000000..b0894e8200 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_border_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a new file mode 100644 index 0000000000..9aabc250e5 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_border_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_lowpan_host.ar b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_lowpan_host.ar new file mode 100644 index 0000000000..0553dec65e Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_lowpan_host.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_host.ar b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_host.ar new file mode 100644 index 0000000000..95e6798c1c Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_host.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_host.ar b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_host.ar new file mode 100644 index 0000000000..0553dec65e Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_host.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a new file mode 100644 index 0000000000..8b14a42de9 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_host.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_host.a new file mode 100644 index 0000000000..5e2510f12a Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_host.a differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a new file mode 100644 index 0000000000..8b14a42de9 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_host.a differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_lowpan_host.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_lowpan_host.a new file mode 100644 index 0000000000..d76a2dc63f Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_lowpan_host.a differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_host.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_host.a new file mode 100644 index 0000000000..ad21529689 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_host.a differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_host.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_host.a new file mode 100644 index 0000000000..d76a2dc63f Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_HOST/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_host.a differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_lowpan_router.ar b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_lowpan_router.ar new file mode 100644 index 0000000000..2987f2e585 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_lowpan_router.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_router.ar b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_router.ar new file mode 100644 index 0000000000..53b6b26378 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_lowpan_router.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_router.ar b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_router.ar new file mode 100644 index 0000000000..2987f2e585 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_lowpan_router.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a new file mode 100644 index 0000000000..e07bd65ab6 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_router.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_router.a new file mode 100644 index 0000000000..df5e8b5ba8 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_lowpan_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a new file mode 100644 index 0000000000..e07bd65ab6 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_lowpan_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_lowpan_router.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_lowpan_router.a new file mode 100644 index 0000000000..3861fee7e3 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_lowpan_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_router.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_router.a new file mode 100644 index 0000000000..666f387502 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_lowpan_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_router.a b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_router.a new file mode 100644 index 0000000000..3861fee7e3 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_LOWPAN_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_lowpan_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_nanostack_full.ar b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_nanostack_full.ar new file mode 100644 index 0000000000..be759128ce Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_nanostack_full.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_nanostack_full.ar b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_nanostack_full.ar new file mode 100644 index 0000000000..07a7897839 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_nanostack_full.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_nanostack_full.ar b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_nanostack_full.ar new file mode 100644 index 0000000000..be759128ce Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_nanostack_full.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a new file mode 100644 index 0000000000..200680b221 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a differ diff --git a/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_nanostack_full.a b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_nanostack_full.a new file mode 100644 index 0000000000..54283f8192 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_nanostack_full.a differ diff --git a/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a new file mode 100644 index 0000000000..200680b221 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_nanostack_full.a differ diff --git a/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_nanostack_full.a b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_nanostack_full.a new file mode 100644 index 0000000000..42368b4bc8 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_nanostack_full.a differ diff --git a/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_nanostack_full.a b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_nanostack_full.a new file mode 100644 index 0000000000..2f13dcdde3 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_nanostack_full.a differ diff --git a/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_nanostack_full.a b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_nanostack_full.a new file mode 100644 index 0000000000..42368b4bc8 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_NANOSTACK_FULL/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_nanostack_full.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_thread_border_router.ar b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_thread_border_router.ar new file mode 100644 index 0000000000..684d7e5a31 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_thread_border_router.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_border_router.ar b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_border_router.ar new file mode 100644 index 0000000000..5c5265fa4d Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_border_router.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_border_router.ar b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_border_router.ar new file mode 100644 index 0000000000..684d7e5a31 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_border_router.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_border_router.a b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_border_router.a new file mode 100644 index 0000000000..fa9804bff8 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_border_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_border_router.a b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_border_router.a new file mode 100644 index 0000000000..4b5f82206d Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_border_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_border_router.a b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_border_router.a new file mode 100644 index 0000000000..fa9804bff8 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_border_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_thread_border_router.a b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_thread_border_router.a new file mode 100644 index 0000000000..7377413813 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_thread_border_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_border_router.a b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_border_router.a new file mode 100644 index 0000000000..c2ed9e598e Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_border_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_border_router.a b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_border_router.a new file mode 100644 index 0000000000..7377413813 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_BORDER_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_border_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_thread_end_device.ar b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_thread_end_device.ar new file mode 100644 index 0000000000..10ec4f02a3 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_thread_end_device.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_end_device.ar b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_end_device.ar new file mode 100644 index 0000000000..34435487cd Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_end_device.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_end_device.ar b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_end_device.ar new file mode 100644 index 0000000000..10ec4f02a3 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_end_device.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_end_device.a b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_end_device.a new file mode 100644 index 0000000000..23827414a7 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_end_device.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_end_device.a b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_end_device.a new file mode 100644 index 0000000000..fdb0aaf34b Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_end_device.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_end_device.a b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_end_device.a new file mode 100644 index 0000000000..23827414a7 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_end_device.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_thread_end_device.a b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_thread_end_device.a new file mode 100644 index 0000000000..ee2f68c417 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_thread_end_device.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_end_device.a b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_end_device.a new file mode 100644 index 0000000000..6ff82578be Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_end_device.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_end_device.a b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_end_device.a new file mode 100644 index 0000000000..ee2f68c417 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_END_DEVICE/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_end_device.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_thread_router.ar b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_thread_router.ar new file mode 100644 index 0000000000..ce618c79b1 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_CORTEX_M3/libnanostack_armcc_Cortex-M3_thread_router.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_router.ar b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_router.ar new file mode 100644 index 0000000000..ac76d9cdfb Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_LIKE_CORTEX_M0/libnanostack_armcc_Cortex-M0_thread_router.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_router.ar b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_router.ar new file mode 100644 index 0000000000..ce618c79b1 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_ARM/TARGET_RTOS_M4_M7/libnanostack_armcc_Cortex-M3_thread_router.ar differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_router.a b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_router.a new file mode 100644 index 0000000000..1310780d01 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_CORTEX_M3/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_router.a b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_router.a new file mode 100644 index 0000000000..ddbb03c824 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_LIKE_CORTEX_M0/libnanostack_arm-none-eabi-gcc_Cortex-M0_thread_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_router.a b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_router.a new file mode 100644 index 0000000000..1310780d01 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_GCC/TARGET_RTOS_M4_M7/libnanostack_arm-none-eabi-gcc_Cortex-M3_thread_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_thread_router.a b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_thread_router.a new file mode 100644 index 0000000000..82a5da6cac Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_CORTEX_M3/libnanostack_iccarm_Cortex-M3_thread_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_router.a b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_router.a new file mode 100644 index 0000000000..39fe356a33 Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_LIKE_CORTEX_M0/libnanostack_iccarm_Cortex-M0_thread_router.a differ diff --git a/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_router.a b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_router.a new file mode 100644 index 0000000000..82a5da6cac Binary files /dev/null and b/features/net/nanostack-binaries/FEATURE_THREAD_ROUTER/TOOLCHAIN_IAR/TARGET_RTOS_M4_M7/libnanostack_iccarm_Cortex-M3_thread_router.a differ diff --git a/hal/api/Callback.h b/hal/api/Callback.h index a587b24b32..a6d63790e7 100644 --- a/hal/api/Callback.h +++ b/hal/api/Callback.h @@ -4436,54 +4436,6 @@ Callback callback(R (*func)(const volatile T*), const volatile T *arg) { return Callback(func, arg); } -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(const F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(volatile F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(const volatile F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function @@ -4757,54 +4709,6 @@ Callback callback(R (*func)(const volatile T*, A0), const volatile T *arg return Callback(func, arg); } -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(const F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(volatile F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(const volatile F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function @@ -5078,54 +4982,6 @@ Callback callback(R (*func)(const volatile T*, A0, A1), const volatil return Callback(func, arg); } -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(const F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(volatile F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(const volatile F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function @@ -5399,54 +5255,6 @@ Callback callback(R (*func)(const volatile T*, A0, A1, A2), const return Callback(func, arg); } -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(const F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(volatile F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(const volatile F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function @@ -5720,54 +5528,6 @@ Callback callback(R (*func)(const volatile T*, A0, A1, A2, A3 return Callback(func, arg); } -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(const F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(volatile F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(const volatile F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function @@ -6041,54 +5801,6 @@ Callback callback(R (*func)(const volatile T*, A0, A1, A2 return Callback(func, arg); } -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(const F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(volatile F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - -/** Create a callback class with type infered from the arguments - * @param func Function object to attach - * @note The function object is limited to a single word of storage - */ -template -Callback callback(const volatile F f, typename detail::enable_if< - detail::is_type::value && - sizeof(F) <= sizeof(uintptr_t) - >::type = detail::nil()) { - return Callback(f); -} - /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function diff --git a/hal/api/mbed.h b/hal/api/mbed.h index 472246ac9e..6acda136b7 100644 --- a/hal/api/mbed.h +++ b/hal/api/mbed.h @@ -26,6 +26,10 @@ #include "network-socket/nsapi.h" #endif +#if MBED_CONF_EVENTS_PRESENT +#include "events/mbed_events.h" +#endif + #include "toolchain.h" #include "platform.h" diff --git a/hal/common/mbed_critical.c b/hal/common/mbed_critical.c index f65f67a8b5..bc9d748ef3 100644 --- a/hal/common/mbed_critical.c +++ b/hal/common/mbed_critical.c @@ -19,6 +19,7 @@ #include "cmsis.h" #include "mbed_assert.h" +#include "toolchain.h" #define EXCLUSIVE_ACCESS (!defined (__CORTEX_M0) && !defined (__CORTEX_M0PLUS)) @@ -34,7 +35,7 @@ bool core_util_are_interrupts_enabled(void) #endif } -void core_util_critical_section_enter(void) +MBED_WEAK void core_util_critical_section_enter(void) { bool interrupts_disabled = !core_util_are_interrupts_enabled(); __disable_irq(); @@ -59,7 +60,7 @@ void core_util_critical_section_enter(void) interrupt_enable_counter++; } -void core_util_critical_section_exit(void) +MBED_WEAK void core_util_critical_section_exit(void) { /* If critical_section_enter has not previously been called, do nothing */ if (interrupt_enable_counter) { diff --git a/hal/targets.json b/hal/targets.json index dffaa479ba..fc03fb2c46 100644 --- a/hal/targets.json +++ b/hal/targets.json @@ -624,7 +624,7 @@ "core": "Cortex-M0", "default_toolchain": "uARM", "extra_labels": ["STM", "STM32F0", "STM32F031K6"], - "macros": ["DEVICE_RTC_LSI=1"], + "macros": ["RTC_LSI=1"], "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "inherits": ["Target"], "progen": {"target": "nucleo-f031k6"}, @@ -638,7 +638,7 @@ "core": "Cortex-M0", "default_toolchain": "uARM", "extra_labels": ["STM", "STM32F0", "STM32F042K6"], - "macros": ["DEVICE_RTC_LSI=1"], + "macros": ["RTC_LSI=1"], "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "inherits": ["Target"], "progen": {"target": "nucleo-f042k6"}, @@ -726,7 +726,7 @@ "core": "Cortex-M4F", "default_toolchain": "ARM", "extra_labels": ["STM", "STM32F3", "STM32F303K8"], - "macros": ["DEVICE_RTC_LSI=1"], + "macros": ["RTC_LSI=1"], "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "inherits": ["Target"], "progen": {"target": "nucleo-f303k8"}, @@ -832,8 +832,8 @@ "extra_labels": ["STM", "STM32F4", "STM32F429", "STM32F429ZI", "STM32F429xx"], "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"], "progen": {"target": "nucleo-f429zi"}, - "macros": ["DEVICE_RTC_LSI=1", "TRANSACTION_QUEUE_SIZE_SPI=2"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "RTC_LSI", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"], + "macros": ["RTC_LSI=1", "TRANSACTION_QUEUE_SIZE_SPI=2"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"], "detect_code": ["0796"], "features": ["IPV4"], "release_versions": ["2", "5"] @@ -1041,20 +1041,20 @@ "core": "Cortex-M4F", "default_toolchain": "ARM", "extra_labels": ["STM", "STM32F3", "STM32F303", "STM32F303VC"], - "macros": ["DEVICE_RTC_LSI=1"], + "macros": ["RTC_LSI=1"], "supported_toolchains": ["GCC_ARM"], - "device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "RTC_LSI", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"] + "device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"] }, "DISCO_F334C8": { "inherits": ["Target"], "core": "Cortex-M4F", "default_toolchain": "ARM", "extra_labels": ["STM", "STM32F3", "STM32F334C8"], - "macros": ["DEVICE_RTC_LSI=1"], + "macros": ["RTC_LSI=1"], "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "progen": {"target": "disco-f334c8"}, "detect_code": ["0810"], - "device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "RTC_LSI", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], + "device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], "default_lib": "small", "release_versions": ["2"] }, @@ -1072,7 +1072,7 @@ "core": "Cortex-M4F", "default_toolchain": "ARM", "extra_labels": ["STM", "STM32F4", "STM32F429", "STM32F429ZI", "STM32F429xx"], - "macros": ["DEVICE_RTC_LSI=1","TRANSACTION_QUEUE_SIZE_SPI=2"], + "macros": ["RTC_LSI=1","TRANSACTION_QUEUE_SIZE_SPI=2"], "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"], "progen": {"target": "disco-f429zi"}, "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "TRNG"], @@ -1192,7 +1192,7 @@ "core": "Cortex-M3", "default_toolchain": "uARM", "extra_labels": ["STM", "STM32L1", "STM32L152RC"], - "macros": ["DEVICE_RTC_LSI=1"], + "macros": ["RTC_LSI=1"], "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "progen": {"target": "stm32l151rc"}, "detect_code": ["4100"], @@ -1227,7 +1227,7 @@ "default_toolchain": "uARM", "program_cycle_s": 1.5, "extra_labels": ["STM", "STM32L1", "STM32L151RC"], - "macros": ["DEVICE_RTC_LSI=1"], + "macros": ["RTC_LSI=1"], "supported_toolchains": ["ARM", "uARM", "GCC_ARM"], "progen": {"target": "stm32l151rc"}, "device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"], diff --git a/hal/targets/cmsis/TARGET_STM/mbed_rtx.h b/hal/targets/cmsis/TARGET_STM/mbed_rtx.h index b0a18d335d..bc117b9923 100644 --- a/hal/targets/cmsis/TARGET_STM/mbed_rtx.h +++ b/hal/targets/cmsis/TARGET_STM/mbed_rtx.h @@ -317,36 +317,6 @@ #define OS_CLOCK 168000000 #endif -#elif defined(TARGET_STM32F411RE) - -#ifndef INITIAL_SP -#define INITIAL_SP (0x20020000UL) -#endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 100000000 -#endif - -#elif defined(TARGET_STM32F411RE) - -#ifndef INITIAL_SP -#define INITIAL_SP (0x20020000UL) -#endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 100000000 -#endif - #elif defined(TARGET_STM32F405RG) #ifndef INITIAL_SP @@ -362,21 +332,6 @@ #define OS_CLOCK 48000000 #endif -#elif defined(TARGET_STM32F411RE) - -#ifndef INITIAL_SP -#define INITIAL_SP (0x20020000UL) -#endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 96000000 -#endif - #elif defined(TARGET_STM32F401RE) #ifndef INITIAL_SP @@ -407,6 +362,21 @@ #define OS_CLOCK 100000000 #endif +#elif defined(TARGET_MTS_MDOT_F411RE) || defined (TARGET_MTS_DRAGONFLY_F411RE) + +#ifndef INITIAL_SP +#define INITIAL_SP (0x20020000UL) +#endif +#ifndef OS_TASKCNT +#define OS_TASKCNT 14 +#endif +#ifndef OS_MAINSTKSIZE +#define OS_MAINSTKSIZE 1024 +#endif +#ifndef OS_CLOCK +#define OS_CLOCK 96000000 +#endif + #elif defined(TARGET_STM32F411RE) #ifndef INITIAL_SP diff --git a/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/nordic_critical.c b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/nordic_critical.c new file mode 100644 index 0000000000..4f94263196 --- /dev/null +++ b/hal/targets/hal/TARGET_NORDIC/TARGET_NRF5/nordic_critical.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015-2016, 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. + */ + +#include // uint32_t, UINT32_MAX +#include // uint32_t, UINT32_MAX +#include "cmsis.h" +#include "nrf_soc.h" +#include "nrf_sdm.h" +#include "nrf_nvic.h" + +static uint8_t _sd_state = 0; +static volatile uint32_t _entry_count = 0; + +void core_util_critical_section_enter() +{ + // if a critical section has already been entered, just update the counter + if (_entry_count) { + ++_entry_count; + return; + } + + // in this path, a critical section has never been entered + // routine of SD V11 work even if the softdevice is not active + sd_nvic_critical_region_enter(&_sd_state); + + assert(_entry_count == 0); // entry count should always be equal to 0 at this point + ++_entry_count; +} + +void core_util_critical_section_exit() +{ + assert(_entry_count > 0); + --_entry_count; + + // If their is other segments which have entered the critical section, just leave + if (_entry_count) { + return; + } + + // This is the last segment of the critical section, state should be restored as before entering + // the critical section + sd_nvic_critical_region_exit(_sd_state); +} diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/rtc_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/rtc_api.c index bf0a38fca2..bf6724c297 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F0/rtc_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F0/rtc_api.c @@ -34,13 +34,13 @@ #include "mbed_error.h" -#if DEVICE_RTC_LSI +#if RTC_LSI static int rtc_inited = 0; #endif static RTC_HandleTypeDef RtcHandle; -#if DEVICE_RTC_LSI +#if RTC_LSI #define RTC_CLOCK LSI_VALUE #else #define RTC_CLOCK LSE_VALUE @@ -62,14 +62,14 @@ static RTC_HandleTypeDef RtcHandle; void rtc_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct; -#if DEVICE_RTC_LSI +#if RTC_LSI if (rtc_inited) return; rtc_inited = 1; #endif RtcHandle.Instance = RTC; -#if !DEVICE_RTC_LSI +#if !RTC_LSI // Enable LSE Oscillator RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured! @@ -119,7 +119,7 @@ void rtc_init(void) { } #if DEVICE_LOWPOWERTIMER -#if DEVICE_RTC_LSI +#if RTC_LSI rtc_write(0); #else if (!rtc_isenabled()) { @@ -134,7 +134,7 @@ void rtc_init(void) { } void rtc_free(void) { -#if DEVICE_RTC_LSI +#if RTC_LSI // Enable Power clock __PWR_CLK_ENABLE(); @@ -157,13 +157,13 @@ void rtc_free(void) { RCC_OscInitStruct.LSEState = RCC_LSE_OFF; HAL_RCC_OscConfig(&RCC_OscInitStruct); -#if DEVICE_RTC_LSI +#if RTC_LSI rtc_inited = 0; #endif } int rtc_isenabled(void) { -#if DEVICE_RTC_LSI +#if RTC_LSI return rtc_inited; #else if ((RTC->ISR & RTC_ISR_INITS) == RTC_ISR_INITS) { diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F1/rtc_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F1/rtc_api.c index b5594504b6..82c527a058 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F1/rtc_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F1/rtc_api.c @@ -46,7 +46,7 @@ void rtc_init(void) RtcHandle.Instance = RTC; -#if !DEVICE_RTC_LSI +#if !RTC_LSI // Enable LSE Oscillator RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured! @@ -94,7 +94,7 @@ void rtc_init(void) void rtc_free(void) { -#if DEVICE_RTC_LSI +#if RTC_LSI // Enable Power clock __PWR_CLK_ENABLE(); diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F2/rtc_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F2/rtc_api.c index fadcfd89c7..563d5391e8 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F2/rtc_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F2/rtc_api.c @@ -33,7 +33,7 @@ #include "mbed_error.h" -#if DEVICE_RTC_LSI +#if RTC_LSI static int rtc_inited = 0; #endif @@ -44,13 +44,13 @@ void rtc_init(void) RCC_OscInitTypeDef RCC_OscInitStruct; uint32_t rtc_freq = 0; -#if DEVICE_RTC_LSI +#if RTC_LSI rtc_inited = 1; #endif RtcHandle.Instance = RTC; -#if !DEVICE_RTC_LSI +#if !RTC_LSI // Enable LSE Oscillator RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; /* Mandatory, otherwise the PLL is reconfigured! */ @@ -106,7 +106,7 @@ void rtc_init(void) void rtc_free(void) { -#if DEVICE_RTC_LSI +#if RTC_LSI // Enable Power clock __PWR_CLK_ENABLE(); @@ -128,14 +128,14 @@ void rtc_free(void) RCC_OscInitStruct.LSIState = RCC_LSI_OFF; RCC_OscInitStruct.LSEState = RCC_LSE_OFF; HAL_RCC_OscConfig(&RCC_OscInitStruct); -#if DEVICE_RTC_LSI +#if RTC_LSI rtc_inited = 0; #endif } int rtc_isenabled(void) { -#if DEVICE_RTC_LSI +#if RTC_LSI return rtc_inited; #else if ((RTC->ISR & RTC_ISR_INITS) == RTC_ISR_INITS) { diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/rtc_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/rtc_api.c index 08f51f7a57..c82d6f1ec0 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/rtc_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/rtc_api.c @@ -34,13 +34,13 @@ #include "mbed_error.h" -#if DEVICE_RTC_LSI +#if RTC_LSI static int rtc_inited = 0; #endif static RTC_HandleTypeDef RtcHandle; -#if DEVICE_RTC_LSI +#if RTC_LSI #define RTC_CLOCK LSI_VALUE #else #define RTC_CLOCK LSE_VALUE @@ -63,14 +63,14 @@ void rtc_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct; -#if DEVICE_RTC_LSI +#if RTC_LSI if (rtc_inited) return; rtc_inited = 1; #endif RtcHandle.Instance = RTC; -#if !DEVICE_RTC_LSI +#if !RTC_LSI // Enable LSE Oscillator RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; /* Mandatory, otherwise the PLL is reconfigured! */ @@ -119,7 +119,7 @@ void rtc_init(void) } #if DEVICE_LOWPOWERTIMER -#if DEVICE_RTC_LSI +#if RTC_LSI rtc_write(0); #else if (!rtc_isenabled()) { @@ -135,7 +135,7 @@ void rtc_init(void) void rtc_free(void) { -#if DEVICE_RTC_LSI +#if RTC_LSI // Enable Power clock __PWR_CLK_ENABLE(); @@ -158,14 +158,14 @@ void rtc_free(void) RCC_OscInitStruct.LSEState = RCC_LSE_OFF; HAL_RCC_OscConfig(&RCC_OscInitStruct); -#if DEVICE_RTC_LSI +#if RTC_LSI rtc_inited = 0; #endif } int rtc_isenabled(void) { -#if DEVICE_RTC_LSI +#if RTC_LSI return rtc_inited; #else if ((RTC->ISR & RTC_ISR_INITS) == RTC_ISR_INITS) return 1; diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F4/rtc_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F4/rtc_api.c index 6770b78767..6e126d0ce2 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F4/rtc_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F4/rtc_api.c @@ -34,13 +34,13 @@ #include "mbed_error.h" -#if DEVICE_RTC_LSI +#if RTC_LSI static int rtc_inited = 0; #endif static RTC_HandleTypeDef RtcHandle; -#if DEVICE_RTC_LSI +#if RTC_LSI #define RTC_CLOCK LSI_VALUE #else #define RTC_CLOCK LSE_VALUE @@ -63,14 +63,14 @@ void rtc_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct; -#if DEVICE_RTC_LSI +#if RTC_LSI if (rtc_inited) return; rtc_inited = 1; #endif RtcHandle.Instance = RTC; -#if !DEVICE_RTC_LSI +#if !RTC_LSI // Enable LSE Oscillator RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; /* Mandatory, otherwise the PLL is reconfigured! */ @@ -121,7 +121,7 @@ void rtc_init(void) } #if DEVICE_LOWPOWERTIMER -#if DEVICE_RTC_LSI +#if RTC_LSI rtc_write(0); #else if (!rtc_isenabled()) { @@ -137,7 +137,7 @@ void rtc_init(void) void rtc_free(void) { -#if DEVICE_RTC_LSI +#if RTC_LSI // Enable Power clock __PWR_CLK_ENABLE(); @@ -160,14 +160,14 @@ void rtc_free(void) RCC_OscInitStruct.LSEState = RCC_LSE_OFF; HAL_RCC_OscConfig(&RCC_OscInitStruct); -#if DEVICE_RTC_LSI +#if RTC_LSI rtc_inited = 0; #endif } int rtc_isenabled(void) { -#if DEVICE_RTC_LSI +#if RTC_LSI return rtc_inited; #else if ((RTC->ISR & RTC_ISR_INITS) == RTC_ISR_INITS) return 1; diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F7/rtc_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F7/rtc_api.c index d4783aa750..40e7ede75f 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F7/rtc_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F7/rtc_api.c @@ -34,13 +34,13 @@ #include "mbed_error.h" -#if DEVICE_RTC_LSI +#if RTC_LSI static int rtc_inited = 0; #endif static RTC_HandleTypeDef RtcHandle; -#if DEVICE_RTC_LSI +#if RTC_LSI #define RTC_CLOCK LSI_VALUE #else #define RTC_CLOCK LSE_VALUE @@ -63,14 +63,14 @@ void rtc_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct; -#if DEVICE_RTC_LSI +#if RTC_LSI if (rtc_inited) return; rtc_inited = 1; #endif RtcHandle.Instance = RTC; -#if !DEVICE_RTC_LSI +#if !RTC_LSI // Enable LSE Oscillator RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured! @@ -122,7 +122,7 @@ void rtc_init(void) } #if DEVICE_LOWPOWERTIMER -#if DEVICE_RTC_LSI +#if RTC_LSI rtc_write(0); #else if (!rtc_isenabled()) { @@ -138,7 +138,7 @@ void rtc_init(void) void rtc_free(void) { -#if DEVICE_RTC_LSI +#if RTC_LSI // Enable Power clock __PWR_CLK_ENABLE(); @@ -161,14 +161,14 @@ void rtc_free(void) RCC_OscInitStruct.LSEState = RCC_LSE_OFF; HAL_RCC_OscConfig(&RCC_OscInitStruct); -#if DEVICE_RTC_LSI +#if RTC_LSI rtc_inited = 0; #endif } int rtc_isenabled(void) { -#if DEVICE_RTC_LSI +#if RTC_LSI return rtc_inited; #else if ((RTC->ISR & RTC_ISR_INITS) == RTC_ISR_INITS) { diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32L0/rtc_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32L0/rtc_api.c index b8f2f445a8..82f4c055e0 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32L0/rtc_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32L0/rtc_api.c @@ -34,13 +34,13 @@ #include "mbed_error.h" -#if DEVICE_RTC_LSI +#if RTC_LSI static int rtc_inited = 0; #endif static RTC_HandleTypeDef RtcHandle; -#if DEVICE_RTC_LSI +#if RTC_LSI #define RTC_CLOCK LSI_VALUE #else #define RTC_CLOCK LSE_VALUE @@ -64,7 +64,7 @@ void rtc_init(void) RCC_OscInitTypeDef RCC_OscInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; -#if DEVICE_RTC_LSI +#if RTC_LSI if (rtc_inited) return; rtc_inited = 1; #endif @@ -79,7 +79,7 @@ void rtc_init(void) // Enable access to Backup domain HAL_PWR_EnableBkUpAccess(); -#if !DEVICE_RTC_LSI +#if !RTC_LSI // Enable LSE Oscillator RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured! @@ -129,7 +129,7 @@ void rtc_init(void) } #if DEVICE_LOWPOWERTIMER -#if DEVICE_RTC_LSI +#if RTC_LSI rtc_write(0); #else if (!rtc_isenabled()) { @@ -145,7 +145,7 @@ void rtc_init(void) void rtc_free(void) { -#if DEVICE_RTC_LSI +#if RTC_LSI // Enable Power clock __PWR_CLK_ENABLE(); @@ -168,14 +168,14 @@ void rtc_free(void) RCC_OscInitStruct.LSEState = RCC_LSE_OFF; HAL_RCC_OscConfig(&RCC_OscInitStruct); -#if DEVICE_RTC_LSI +#if RTC_LSI rtc_inited = 0; #endif } int rtc_isenabled(void) { -#if DEVICE_RTC_LSI +#if RTC_LSI return rtc_inited; #else if ((RTC->ISR & RTC_ISR_INITS) == RTC_ISR_INITS) { diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32L1/rtc_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32L1/rtc_api.c index 3bcde9b584..612ff04c73 100755 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32L1/rtc_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32L1/rtc_api.c @@ -34,13 +34,13 @@ #include "mbed_error.h" -#if DEVICE_RTC_LSI +#if RTC_LSI static int rtc_inited = 0; #endif static RTC_HandleTypeDef RtcHandle; -#if DEVICE_RTC_LSI +#if RTC_LSI #define RTC_CLOCK LSI_VALUE #else #define RTC_CLOCK LSE_VALUE @@ -63,14 +63,14 @@ void rtc_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct; -#if DEVICE_RTC_LSI +#if RTC_LSI if (rtc_inited) return; rtc_inited = 1; #endif RtcHandle.Instance = RTC; -#if !DEVICE_RTC_LSI +#if !RTC_LSI // Enable LSE Oscillator RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured! @@ -128,7 +128,7 @@ void rtc_init(void) } #if DEVICE_LOWPOWERTIMER -#if DEVICE_RTC_LSI +#if RTC_LSI rtc_write(0); #else if (!rtc_isenabled()) { @@ -144,7 +144,7 @@ void rtc_init(void) void rtc_free(void) { -#if DEVICE_RTC_LSI +#if RTC_LSI // Enable Power clock __PWR_CLK_ENABLE(); @@ -167,14 +167,14 @@ void rtc_free(void) RCC_OscInitStruct.LSEState = RCC_LSE_OFF; HAL_RCC_OscConfig(&RCC_OscInitStruct); -#if DEVICE_RTC_LSI +#if RTC_LSI rtc_inited = 0; #endif } int rtc_isenabled(void) { -#if DEVICE_RTC_LSI +#if RTC_LSI return rtc_inited; #else if ((RTC->ISR & RTC_ISR_INITS) == RTC_ISR_INITS) { diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32L4/rtc_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32L4/rtc_api.c index 2581c236cd..c34d806f71 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32L4/rtc_api.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32L4/rtc_api.c @@ -34,13 +34,13 @@ #include "mbed_error.h" -#if DEVICE_RTC_LSI +#if RTC_LSI static int rtc_inited = 0; #endif static RTC_HandleTypeDef RtcHandle; -#if DEVICE_RTC_LSI +#if RTC_LSI #define RTC_CLOCK LSI_VALUE #else #define RTC_CLOCK LSE_VALUE @@ -64,14 +64,14 @@ void rtc_init(void) RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; -#if DEVICE_RTC_LSI +#if RTC_LSI if (rtc_inited) return; rtc_inited = 1; #endif RtcHandle.Instance = RTC; -#if !DEVICE_RTC_LSI +#if !RTC_LSI // Enable LSE Oscillator RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured! @@ -130,7 +130,7 @@ void rtc_init(void) } #if DEVICE_LOWPOWERTIMER -#if DEVICE_RTC_LSI +#if RTC_LSI rtc_write(0); #else if (!rtc_isenabled()) { @@ -146,7 +146,7 @@ void rtc_init(void) void rtc_free(void) { -#if DEVICE_RTC_LSI +#if RTC_LSI // Enable Power clock __HAL_RCC_PWR_CLK_ENABLE(); @@ -169,14 +169,14 @@ void rtc_free(void) RCC_OscInitStruct.LSEState = RCC_LSE_OFF; HAL_RCC_OscConfig(&RCC_OscInitStruct); -#if DEVICE_RTC_LSI +#if RTC_LSI rtc_inited = 0; #endif } int rtc_isenabled(void) { -#if DEVICE_RTC_LSI +#if RTC_LSI return rtc_inited; #else if ((RTC->ISR & RTC_ISR_INITS) == RTC_ISR_INITS) { diff --git a/libraries/tests/rtos/mbed/mutex/main.cpp b/libraries/tests/rtos/mbed/mutex/main.cpp index aff4ec7915..da10822b3b 100644 --- a/libraries/tests/rtos/mbed/mutex/main.cpp +++ b/libraries/tests/rtos/mbed/mutex/main.cpp @@ -22,6 +22,10 @@ #define STACK_SIZE DEFAULT_STACK_SIZE/2 #elif defined(TARGET_STM32F303K8) && defined(TOOLCHAIN_IAR) #define STACK_SIZE DEFAULT_STACK_SIZE/2 +#elif defined(TARGET_STM32F334C8) + #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) diff --git a/libraries/tests/rtos/mbed/semaphore/main.cpp b/libraries/tests/rtos/mbed/semaphore/main.cpp index 10a8a7e417..8873534d34 100644 --- a/libraries/tests/rtos/mbed/semaphore/main.cpp +++ b/libraries/tests/rtos/mbed/semaphore/main.cpp @@ -17,13 +17,17 @@ */ #if (defined(TARGET_STM32F072RB) || defined(TARGET_STM32F070RB)) #define STACK_SIZE DEFAULT_STACK_SIZE/2 -#elif defined(TARGET_STM32F334R8) && (defined(TOOLCHAIN_GCC) || defined(TOOLCHAIN_IAR)) +#elif defined(TARGET_STM32F334R8) #define STACK_SIZE DEFAULT_STACK_SIZE/4 #elif defined(TARGET_STM32F103RB) && defined(TOOLCHAIN_IAR) #define STACK_SIZE DEFAULT_STACK_SIZE/4 #elif defined(TARGET_STM32F302R8) && defined(TOOLCHAIN_IAR) #define STACK_SIZE DEFAULT_STACK_SIZE/2 -#elif defined(TARGET_STM32F303K8) && defined(TOOLCHAIN_IAR) +#elif defined(TARGET_STM32F303K8) + #define STACK_SIZE DEFAULT_STACK_SIZE/4 +#elif defined(TARGET_STM32F334C8) + #define STACK_SIZE DEFAULT_STACK_SIZE/4 +#elif defined(TARGET_STM32L073RZ) #define STACK_SIZE DEFAULT_STACK_SIZE/4 #elif (defined(TARGET_EFM32HG_STK3400)) && !defined(TOOLCHAIN_ARM_MICRO) #define STACK_SIZE 512 diff --git a/tools/build.py b/tools/build.py index 7915ed03a4..2749776a08 100644 --- a/tools/build.py +++ b/tools/build.py @@ -31,6 +31,7 @@ from tools.toolchains import TOOLCHAINS, TOOLCHAIN_CLASSES, TOOLCHAIN_PATHS from tools.toolchains import mbedToolchain from tools.targets import TARGET_NAMES, TARGET_MAP from tools.options import get_default_options_parser +from tools.options import extract_profile from tools.build_api import build_library, build_mbed_libs, build_lib from tools.build_api import mcu_toolchain_matrix from tools.build_api import static_analysis_scan, static_analysis_scan_lib, static_analysis_scan_library @@ -222,13 +223,20 @@ if __name__ == '__main__': try: mcu = TARGET_MAP[target] # CMSIS and MBED libs analysis - static_analysis_scan(mcu, toolchain, CPPCHECK_CMD, CPPCHECK_MSG_FORMAT, verbose=options.verbose, jobs=options.jobs) + profile = extract_profile(parser, options, toolchain) + static_analysis_scan( + mcu, toolchain, CPPCHECK_CMD, CPPCHECK_MSG_FORMAT, + verbose=options.verbose, jobs=options.jobs, + build_profile=profile) for lib_id in libraries: # Static check for library - static_analysis_scan_lib(lib_id, mcu, toolchain, CPPCHECK_CMD, CPPCHECK_MSG_FORMAT, - options=options.options, - extra_verbose=options.extra_verbose_notify, verbose=options.verbose, jobs=options.jobs, clean=options.clean, - macros=options.macros) + static_analysis_scan_lib( + lib_id, mcu, toolchain, CPPCHECK_CMD, + CPPCHECK_MSG_FORMAT, + extra_verbose=options.extra_verbose_notify, + verbose=options.verbose, jobs=options.jobs, + clean=options.clean, macros=options.macros, + build_profile=profile) pass except Exception, e: if options.verbose: @@ -248,9 +256,9 @@ if __name__ == '__main__': else: try: mcu = TARGET_MAP[target] + profile = extract_profile(parser, options, toolchain) if options.source_dir: lib_build_res = build_library(options.source_dir, options.build_dir, mcu, toolchain, - options=options.options, extra_verbose=options.extra_verbose_notify, verbose=options.verbose, silent=options.silent, @@ -258,26 +266,27 @@ if __name__ == '__main__': clean=options.clean, archive=(not options.no_archive), macros=options.macros, - name=options.artifact_name) + name=options.artifact_name, + build_profile=profile) else: lib_build_res = build_mbed_libs(mcu, toolchain, - options=options.options, extra_verbose=options.extra_verbose_notify, verbose=options.verbose, silent=options.silent, jobs=options.jobs, clean=options.clean, - macros=options.macros) + macros=options.macros, + build_profile=profile) for lib_id in libraries: build_lib(lib_id, mcu, toolchain, - options=options.options, extra_verbose=options.extra_verbose_notify, verbose=options.verbose, silent=options.silent, clean=options.clean, macros=options.macros, - jobs=options.jobs) + jobs=options.jobs, + build_profile=profile) if lib_build_res: successes.append(tt_id) else: diff --git a/tools/build_api.py b/tools/build_api.py index 4718e8da09..1e5048c26a 100644 --- a/tools/build_api.py +++ b/tools/build_api.py @@ -274,10 +274,10 @@ def get_mbed_official_release(version): def prepare_toolchain(src_paths, target, toolchain_name, - macros=None, options=None, clean=False, jobs=1, + macros=None, clean=False, jobs=1, notify=None, silent=False, verbose=False, extra_verbose=False, config=None, - app_config=None): + app_config=None, build_profile=None): """ Prepares resource related objects - toolchain, target, config Positional arguments: @@ -287,7 +287,6 @@ def prepare_toolchain(src_paths, target, toolchain_name, Keyword arguments: macros - additional macros - options - general compiler options like debug-symbols or small-build clean - Rebuild everything if True jobs - how many compilers we can run at once notify - Notify function for logs @@ -296,6 +295,7 @@ def prepare_toolchain(src_paths, target, toolchain_name, extra_verbose - even more output! config - a Config object to use instead of creating one app_config - location of a chosen mbed_app.json file + build_profile - a dict of flags that will be passed to the compiler """ # We need to remove all paths which are repeated to avoid @@ -303,14 +303,14 @@ def prepare_toolchain(src_paths, target, toolchain_name, src_paths = [src_paths[0]] + list(set(src_paths[1:])) # If the configuration object was not yet created, create it now - config = config or Config(target, src_paths) + config = config or Config(target, src_paths, app_config=app_config) target = config.target # Toolchain instance try: toolchain = TOOLCHAIN_CLASSES[toolchain_name]( - target, options, notify, macros, silent, - extra_verbose=extra_verbose) + target, notify, macros, silent, + extra_verbose=extra_verbose, build_profile=build_profile) except KeyError: raise KeyError("Toolchain %s not supported" % toolchain_name) @@ -361,12 +361,12 @@ def scan_resources(src_paths, toolchain, dependencies_paths=None, return resources def build_project(src_paths, build_path, target, toolchain_name, - libraries_paths=None, options=None, linker_script=None, + libraries_paths=None, linker_script=None, clean=False, notify=None, verbose=False, name=None, macros=None, inc_dirs=None, jobs=1, silent=False, report=None, properties=None, project_id=None, project_description=None, extra_verbose=False, config=None, - app_config=None): + app_config=None, build_profile=None): """ Build a project. A project may be a test or a user program. Positional arguments: @@ -378,7 +378,6 @@ def build_project(src_paths, build_path, target, toolchain_name, Keyword arguments: libraries_paths - The location of libraries to include when linking - options - general compiler options like debug-symbols or small-build linker_script - the file that drives the linker to do it's job clean - Rebuild everything if True notify - Notify function for logs @@ -395,6 +394,7 @@ def build_project(src_paths, build_path, target, toolchain_name, extra_verbose - even more output! config - a Config object to use instead of creating one app_config - location of a chosen mbed_app.json file + build_profile - a dict of flags that will be passed to the compiler """ # Convert src_path to a list if needed @@ -411,9 +411,10 @@ def build_project(src_paths, build_path, target, toolchain_name, # Pass all params to the unified prepare_toolchain() toolchain = prepare_toolchain( - src_paths, target, toolchain_name, macros=macros, options=options, - clean=clean, jobs=jobs, notify=notify, silent=silent, verbose=verbose, - extra_verbose=extra_verbose, config=config, app_config=app_config) + src_paths, target, toolchain_name, macros=macros, clean=clean, + jobs=jobs, notify=notify, silent=silent, verbose=verbose, + extra_verbose=extra_verbose, config=config, app_config=app_config, + build_profile=build_profile) # The first path will give the name to the library if name is None: @@ -451,6 +452,8 @@ def build_project(src_paths, build_path, target, toolchain_name, # Link Program res, _ = toolchain.link_program(resources, build_path, name) + resources.detect_duplicates(toolchain) + if report != None: end = time() cur_result["elapsed_time"] = end - start @@ -483,11 +486,12 @@ def build_project(src_paths, build_path, target, toolchain_name, raise def build_library(src_paths, build_path, target, toolchain_name, - dependencies_paths=None, options=None, name=None, clean=False, + dependencies_paths=None, name=None, clean=False, archive=True, notify=None, verbose=False, macros=None, inc_dirs=None, jobs=1, silent=False, report=None, properties=None, extra_verbose=False, project_id=None, - remove_config_header_file=False, app_config=None): + remove_config_header_file=False, app_config=None, + build_profile=None): """ Build a library Positional arguments: @@ -499,7 +503,6 @@ def build_library(src_paths, build_path, target, toolchain_name, Keyword arguments: dependencies_paths - The location of libraries to include when linking - options - general compiler options like debug-symbols or small-build name - the name of the library clean - Rebuild everything if True archive - whether the library will create an archive file @@ -515,6 +518,7 @@ def build_library(src_paths, build_path, target, toolchain_name, project_id - the name that goes in the report remove_config_header_file - delete config header file when done building app_config - location of a chosen mbed_app.json file + build_profile - a dict of flags that will be passed to the compiler """ # Convert src_path to a list if needed @@ -536,9 +540,10 @@ def build_library(src_paths, build_path, target, toolchain_name, # Pass all params to the unified prepare_toolchain() toolchain = prepare_toolchain( - src_paths, target, toolchain_name, macros=macros, options=options, - clean=clean, jobs=jobs, notify=notify, silent=silent, verbose=verbose, - extra_verbose=extra_verbose, app_config=app_config) + src_paths, target, toolchain_name, macros=macros, clean=clean, + jobs=jobs, notify=notify, silent=silent, verbose=verbose, + extra_verbose=extra_verbose, app_config=app_config, + build_profile=build_profile) # The first path will give the name to the library if name is None: @@ -639,9 +644,10 @@ def build_library(src_paths, build_path, target, toolchain_name, ### Legacy methods ### ###################### -def build_lib(lib_id, target, toolchain_name, options=None, verbose=False, +def build_lib(lib_id, target, toolchain_name, verbose=False, clean=False, macros=None, notify=None, jobs=1, silent=False, - report=None, properties=None, extra_verbose=False): + report=None, properties=None, extra_verbose=False, + build_profile=None): """ Legacy method for building mbed libraries Positional arguments: @@ -650,7 +656,6 @@ def build_lib(lib_id, target, toolchain_name, options=None, verbose=False, toolchain_name - the name of the build tools Keyword arguments: - options - general compiler options like debug-symbols or small-build clean - Rebuild everything if True verbose - Write the actual tools command lines used if True macros - additional macros @@ -660,6 +665,7 @@ def build_lib(lib_id, target, toolchain_name, options=None, verbose=False, report - a dict where a result may be appended properties - UUUUHHHHH beats me extra_verbose - even more output! + build_profile - a dict of flags that will be passed to the compiler """ lib = Library(lib_id) if not lib.is_supported(target, toolchain_name): @@ -715,8 +721,8 @@ def build_lib(lib_id, target, toolchain_name, options=None, verbose=False, try: # Toolchain instance toolchain = TOOLCHAIN_CLASSES[toolchain_name]( - target, options, macros=macros, notify=notify, silent=silent, - extra_verbose=extra_verbose) + target, macros=macros, notify=notify, silent=silent, + extra_verbose=extra_verbose, build_profile=build_profile) toolchain.VERBOSE = verbose toolchain.jobs = jobs toolchain.build_all = clean @@ -804,9 +810,10 @@ def build_lib(lib_id, target, toolchain_name, options=None, verbose=False, # We do have unique legacy conventions about how we build and package the mbed # library -def build_mbed_libs(target, toolchain_name, options=None, verbose=False, +def build_mbed_libs(target, toolchain_name, verbose=False, clean=False, macros=None, notify=None, jobs=1, silent=False, - report=None, properties=None, extra_verbose=False): + report=None, properties=None, extra_verbose=False, + build_profile=None): """ Function returns True is library was built and false if building was skipped @@ -815,7 +822,6 @@ def build_mbed_libs(target, toolchain_name, options=None, verbose=False, toolchain_name - the name of the build tools Keyword arguments: - options - general compiler options like debug-symbols or small-build verbose - Write the actual tools command lines used if True clean - Rebuild everything if True macros - additional macros @@ -825,6 +831,7 @@ def build_mbed_libs(target, toolchain_name, options=None, verbose=False, report - a dict where a result may be appended properties - UUUUHHHHH beats me extra_verbose - even more output! + build_profile - a dict of flags that will be passed to the compiler """ if report != None: @@ -859,8 +866,8 @@ def build_mbed_libs(target, toolchain_name, options=None, verbose=False, try: # Toolchain toolchain = TOOLCHAIN_CLASSES[toolchain_name]( - target, options, macros=macros, notify=notify, silent=silent, - extra_verbose=extra_verbose) + target, macros=macros, notify=notify, silent=silent, + extra_verbose=extra_verbose, build_profile=build_profile) toolchain.VERBOSE = verbose toolchain.jobs = jobs toolchain.build_all = clean @@ -907,7 +914,8 @@ def build_mbed_libs(target, toolchain_name, options=None, verbose=False, hal_implementation = toolchain.scan_resources(hal_src) toolchain.copy_files(hal_implementation.headers + hal_implementation.hex_files + - hal_implementation.libraries, + hal_implementation.libraries + + [MBED_CONFIG_FILE], build_target, resources=hal_implementation) incdirs = toolchain.scan_resources(build_target).inc_dirs objects = toolchain.compile_sources(hal_implementation, tmp_path, @@ -1096,9 +1104,9 @@ def get_target_supported_toolchains(target): def static_analysis_scan(target, toolchain_name, cppcheck_cmd, - cppcheck_msg_format, options=None, verbose=False, + cppcheck_msg_format, verbose=False, clean=False, macros=None, notify=None, jobs=1, - extra_verbose=False): + extra_verbose=False, build_profile=None): """Perform static analysis on a target and toolchain combination Positional arguments: @@ -1108,18 +1116,19 @@ def static_analysis_scan(target, toolchain_name, cppcheck_cmd, cppcheck_msg_format - the format of the check messages Keyword arguments: - options - things like debug-symbols, or small-build, etc. verbose - more printing! clean - start from a clean slate macros - extra macros to compile with notify - the notification event handling function jobs - number of commands to run at once extra_verbose - even moar printing + build_profile - a dict of flags that will be passed to the compiler """ # Toolchain - toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, - macros=macros, notify=notify, - extra_verbose=extra_verbose) + toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, macros=macros, + notify=notify, + extra_verbose=extra_verbose, + build_profile=build_profile) toolchain.VERBOSE = verbose toolchain.jobs = jobs toolchain.build_all = clean @@ -1241,9 +1250,9 @@ def static_analysis_scan(target, toolchain_name, cppcheck_cmd, def static_analysis_scan_lib(lib_id, target, toolchain, cppcheck_cmd, - cppcheck_msg_format, options=None, verbose=False, + cppcheck_msg_format, verbose=False, clean=False, macros=None, notify=None, jobs=1, - extra_verbose=False): + extra_verbose=False, build_profile=None): """Perform static analysis on a library as if it were to be compiled for a particular target and toolchain combination """ @@ -1251,9 +1260,9 @@ def static_analysis_scan_lib(lib_id, target, toolchain, cppcheck_cmd, if lib.is_supported(target, toolchain): static_analysis_scan_library( lib.source_dir, lib.build_dir, target, toolchain, cppcheck_cmd, - cppcheck_msg_format, lib.dependencies, options, verbose=verbose, + cppcheck_msg_format, lib.dependencies, verbose=verbose, clean=clean, macros=macros, notify=notify, jobs=jobs, - extra_verbose=extra_verbose) + extra_verbose=extra_verbose, build_profile=build_profile) else: print('Library "%s" is not yet supported on target %s with toolchain %s' % (lib_id, target.name, toolchain)) @@ -1261,10 +1270,10 @@ def static_analysis_scan_lib(lib_id, target, toolchain, cppcheck_cmd, def static_analysis_scan_library(src_paths, build_path, target, toolchain_name, cppcheck_cmd, cppcheck_msg_format, - dependencies_paths=None, options=None, + dependencies_paths=None, name=None, clean=False, notify=None, verbose=False, macros=None, jobs=1, - extra_verbose=False): + extra_verbose=False, build_profile=None): """ Function scans library for statically detectable defects Positional arguments: @@ -1277,7 +1286,6 @@ def static_analysis_scan_library(src_paths, build_path, target, toolchain_name, Keyword arguments: dependencies_paths - the paths to sources that this library depends on - options - things like debug-symbols, or small-build, etc. name - the name of this library clean - start from a clean slate notify - the notification event handling function @@ -1285,6 +1293,7 @@ def static_analysis_scan_library(src_paths, build_path, target, toolchain_name, macros - extra macros to compile with jobs - number of commands to run at once extra_verbose - even moar printing + build_profile - a dict of flags that will be passed to the compiler """ if type(src_paths) != ListType: src_paths = [src_paths] @@ -1295,9 +1304,10 @@ def static_analysis_scan_library(src_paths, build_path, target, toolchain_name, src_path) # Toolchain instance - toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, - macros=macros, notify=notify, - extra_verbose=extra_verbose) + toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, macros=macros, + notify=notify, + extra_verbose=extra_verbose, + build_profile=build_profile) toolchain.VERBOSE = verbose toolchain.jobs = jobs diff --git a/tools/build_release.py b/tools/build_release.py index ec46e32293..cdcfd4906b 100644 --- a/tools/build_release.py +++ b/tools/build_release.py @@ -29,6 +29,7 @@ sys.path.insert(0, ROOT) from tools.build_api import build_mbed_libs from tools.build_api import write_build_report from tools.build_api import get_mbed_official_release +from tools.options import extract_profile from tools.targets import TARGET_MAP, TARGET_NAMES from tools.test_exporters import ReportExporter, ResultExporterType from tools.test_api import SingleTestRunner @@ -48,6 +49,8 @@ if __name__ == '__main__': default=False, help="Verbose diagnostic output") parser.add_option("-t", "--toolchains", dest="toolchains", help="Use toolchains names separated by comma") + parser.add_option("--profile", dest="profile", action="append", default=[]) + parser.add_option("-p", "--platforms", dest="platforms", default="", help="Build only for the platform namesseparated by comma") parser.add_option("-L", "--list-config", action="store_true", dest="list_config", @@ -127,6 +130,8 @@ if __name__ == '__main__': test_spec["targets"][target_name] = toolchains single_test = SingleTestRunner(_muts=mut, + _parser=parser, + _opts=options, _opts_report_build_file_name=options.report_build_file_name, _test_spec=test_spec, _opts_test_by_names=",".join(test_names), @@ -162,8 +167,16 @@ if __name__ == '__main__': for toolchain in toolchains: id = "%s::%s" % (target_name, toolchain) + profile = extract_profile(parser, options, toolchain) + try: - built_mbed_lib = build_mbed_libs(TARGET_MAP[target_name], toolchain, verbose=options.verbose, jobs=options.jobs, report=build_report, properties=build_properties) + built_mbed_lib = build_mbed_libs(TARGET_MAP[target_name], + toolchain, + verbose=options.verbose, + jobs=options.jobs, + report=build_report, + properties=build_properties, + build_profile=profile) except Exception, e: print str(e) diff --git a/tools/config.py b/tools/config.py index 59cdab1417..2f411fb699 100644 --- a/tools/config.py +++ b/tools/config.py @@ -347,8 +347,10 @@ class Config(object): # Allowed features in configurations __allowed_features = [ - "UVISOR", "BLE", "CLIENT", "IPV4", "IPV6", "COMMON_PAL", "STORAGE" - ] + "UVISOR", "BLE", "CLIENT", "IPV4", "COMMON_PAL", "STORAGE", "NANOSTACK", + # Nanostack configurations + "LOWPAN_BORDER_ROUTER", "LOWPAN_HOST", "LOWPAN_ROUTER", "NANOSTACK_FULL", "THREAD_BORDER_ROUTER", "THREAD_END_DEVICE", "THREAD_ROUTER" + ] def __init__(self, tgt, top_level_dirs=None, app_config=None): """Construct a mbed configuration diff --git a/tools/export/__init__.py b/tools/export/__init__.py index 4b0a29471e..16e5d48563 100644 --- a/tools/export/__init__.py +++ b/tools/export/__init__.py @@ -21,7 +21,7 @@ import yaml from tools.export import uvision4, uvision5, codered, makefile, ds5_5, iar from tools.export import emblocks, coide, kds, simplicityv3, atmelstudio -from tools.export import sw4stm32, e2studio, zip +from tools.export import sw4stm32, e2studio, zip, cdt from tools.export.exporters import OldLibrariesException, FailedBuildException from tools.targets import TARGET_NAMES, EXPORT_MAP, TARGET_MAP @@ -45,7 +45,10 @@ EXPORTERS = { 'atmelstudio' : atmelstudio.AtmelStudio, 'sw4stm32' : sw4stm32.Sw4STM32, 'e2studio' : e2studio.E2Studio, - 'zip' : zip.ZIP, + 'eclipse_gcc_arm' : cdt.EclipseGcc, + 'eclipse_iar' : cdt.EclipseIAR, + 'eclipse_armc5' : cdt.EclipseArmc5, + 'zip' : zip.ZIP } ERROR_MESSAGE_UNSUPPORTED_TOOLCHAIN = """ diff --git a/tools/export/cdt/.cproject.tmpl b/tools/export/cdt/.cproject.tmpl new file mode 100644 index 0000000000..53cd29cfb3 --- /dev/null +++ b/tools/export/cdt/.cproject.tmpl @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/export/cdt/.project.tmpl b/tools/export/cdt/.project.tmpl new file mode 100644 index 0000000000..ce4e268083 --- /dev/null +++ b/tools/export/cdt/.project.tmpl @@ -0,0 +1,27 @@ + + + {{name}} + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/tools/export/cdt/__init__.py b/tools/export/cdt/__init__.py new file mode 100644 index 0000000000..d62d88773e --- /dev/null +++ b/tools/export/cdt/__init__.py @@ -0,0 +1,51 @@ +from os.path import join, exists, realpath, relpath, basename +from os import makedirs + +from tools.export.makefile import Makefile, GccArm, Armc5, IAR + +class Eclipse(Makefile): + """Generic Eclipse project. Intended to be subclassed by classes that + specify a type of Makefile. + """ + def generate(self): + """Generate Makefile, .cproject & .project Eclipse project file, + py_ocd_settings launch file, and software link .p2f file + """ + super(Eclipse, self).generate() + ctx = { + 'name': self.project_name, + 'elf_location': join('.build',self.project_name)+'.elf', + 'c_symbols': self.toolchain.get_symbols(), + 'asm_symbols': self.toolchain.get_symbols(True), + 'target': self.target, + 'include_paths': self.resources.inc_dirs, + 'load_exe': str(self.LOAD_EXE).lower() + } + + if not exists(join(self.export_dir,'eclipse-extras')): + makedirs(join(self.export_dir,'eclipse-extras')) + + + self.gen_file('cdt/pyocd_settings.tmpl', ctx, + join('eclipse-extras',self.target+'_pyocd_settings.launch')) + self.gen_file('cdt/necessary_software.tmpl', ctx, + join('eclipse-extras','necessary_software.p2f')) + + cproj = relpath('.cproject',self.export_dir) + self.gen_file('cdt/.cproject.tmpl', ctx, + cproj) + proj = relpath('.project',self.export_dir) + self.gen_file('cdt/.project.tmpl', ctx, + proj) + + +class EclipseGcc(Eclipse, GccArm): + LOAD_EXE = True + +class EclipseArmc5(Eclipse, Armc5): + LOAD_EXE = False + +class EclipseIAR(Eclipse, IAR): + LOAD_EXE = True + + diff --git a/tools/export/cdt/necessary_software.tmpl b/tools/export/cdt/necessary_software.tmpl new file mode 100644 index 0000000000..8807d07492 --- /dev/null +++ b/tools/export/cdt/necessary_software.tmpl @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/tools/export/cdt/pyocd_settings.tmpl b/tools/export/cdt/pyocd_settings.tmpl new file mode 100644 index 0000000000..a34c0dbbd4 --- /dev/null +++ b/tools/export/cdt/pyocd_settings.tmpl @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/git_hooks/__init__.py b/tools/git_hooks/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/git_hooks/find_duplicates.py b/tools/git_hooks/find_duplicates.py new file mode 100755 index 0000000000..40531994e2 --- /dev/null +++ b/tools/git_hooks/find_duplicates.py @@ -0,0 +1,26 @@ +from os import walk +from os.path import join, abspath, dirname, basename, splitext +import sys + +ROOT = abspath(join(dirname(__file__), "..", "..")) +sys.path.insert(0, ROOT) + +from tools.toolchains.gcc import GCC_ARM +from tools.targets import TARGET_MAP +from argparse import ArgumentParser + +if __name__ == "__main__": + parser = ArgumentParser("Find duplicate file names within a directory structure") + parser.add_argument("dirs", help="Directories to search for duplicate file names" + , nargs="*") + parser.add_argument("--silent", help="Supress printing of filenames, just return number of duplicates", action="store_true") + args = parser.parse_args() + + toolchain = GCC_ARM(TARGET_MAP["K64F"]) + + resources = sum([toolchain.scan_resources(d) for d in args.dirs], None) + + scanned_files = {} + + exit(resources.detect_duplicates(toolchain)) + diff --git a/tools/make.py b/tools/make.py index 4434931f8e..ea4da69b92 100644 --- a/tools/make.py +++ b/tools/make.py @@ -19,6 +19,7 @@ limitations under the License. TEST BUILD & RUN """ import sys +import json from time import sleep from shutil import copy from os.path import join, abspath, dirname @@ -41,6 +42,7 @@ from tools.tests import TEST_MBED_LIB from tools.tests import test_known, test_name_known from tools.targets import TARGET_MAP from tools.options import get_default_options_parser +from tools.options import extract_profile from tools.build_api import build_project from tools.build_api import mcu_toolchain_matrix from utils import argparse_filestring_type @@ -220,6 +222,7 @@ if __name__ == '__main__': if options.source_dir and not options.build_dir: args_error(parser, "argument --build is required when argument --source is provided") + if options.color: # This import happens late to prevent initializing colorization when we don't need it import colorize @@ -271,7 +274,8 @@ if __name__ == '__main__': build_dir = options.build_dir try: - bin_file = build_project(test.source_dir, build_dir, mcu, toolchain, test.dependencies, options.options, + bin_file = build_project(test.source_dir, build_dir, mcu, toolchain, + test.dependencies, linker_script=options.linker_script, clean=options.clean, verbose=options.verbose, @@ -280,7 +284,10 @@ if __name__ == '__main__': macros=options.macros, jobs=options.jobs, name=options.artifact_name, - app_config=options.app_config) + app_config=options.app_config, + build_profile=extract_profile(parser, + options, + toolchain)) print 'Image: %s'% bin_file if options.disk: diff --git a/tools/memap.py b/tools/memap.py index 669fc41a8b..abc3282a53 100644 --- a/tools/memap.py +++ b/tools/memap.py @@ -10,10 +10,11 @@ import json import argparse from prettytable import PrettyTable -from tools.utils import argparse_filestring_type, \ +from utils import argparse_filestring_type, \ argparse_lowercase_hyphen_type, argparse_uppercase_type DEBUG = False + RE_ARMCC = re.compile( r'^\s+0x(\w{8})\s+0x(\w{8})\s+(\w+)\s+(\w+)\s+(\d+)\s+[*]?.+\s+(.+)$') RE_IAR = re.compile( @@ -37,10 +38,12 @@ class MemapParser(object): # sections to print info (generic for all toolchains) sections = ('.text', '.data', '.bss', '.heap', '.stack') - def __init__(self): + def __init__(self, detailed_misc=False): """ General initialization """ - + # + self.detailed_misc = detailed_misc + # list of all modules and their sections self.modules = dict() @@ -51,9 +54,14 @@ class MemapParser(object): # list of all object files and mappting to module names self.object_to_module = dict() - # Memory usage summary structure + # Memory report (sections + summary) + self.mem_report = [] + + # Just the memory summary section self.mem_summary = dict() + self.subtotal = dict() + def module_add(self, module_name, size, section): """ Adds a module / section to the list @@ -90,8 +98,8 @@ class MemapParser(object): else: return False # everything else, means no change in section - @staticmethod - def path_object_to_module_name(txt): + + def path_object_to_module_name(self, txt): """ Parse a path to object file to extract it's module and object data Positional arguments: @@ -114,9 +122,17 @@ class MemapParser(object): module_name = data[0] + '/' + data[1] return [module_name, object_name] - else: + + elif self.detailed_misc: + rex_obj_name = r'^.+\/(.+\.o\)*)$' + test_rex_obj_name = re.match(rex_obj_name, txt) + if test_rex_obj_name: + object_name = test_rex_obj_name.group(1) + return ['Misc/' + object_name, ""] + + return ['Misc', ""] + else: return ['Misc', ""] - def parse_section_gcc(self, line): """ Parse data from a section of gcc map file @@ -399,68 +415,27 @@ class MemapParser(object): print "I/O error({0}): {1}".format(error.errno, error.strerror) return False - subtotal = dict() - for k in self.sections: - subtotal[k] = 0 - - # Calculate misc flash sections - misc_flash_mem = 0 - for i in self.modules: - for k in self.misc_flash_sections: - if self.modules[i][k]: - misc_flash_mem += self.modules[i][k] - - json_obj = [] - for i in sorted(self.modules): - - row = [] - - json_obj.append({ - "module":i, - "size":{ - k:self.modules[i][k] for k in self.print_sections - } - }) - - summary = { - 'summary':{ - 'static_ram': (subtotal['.data'] + subtotal['.bss']), - 'heap': (subtotal['.heap']), - 'stack': (subtotal['.stack']), - 'total_ram': (subtotal['.data'] + subtotal['.bss'] + - subtotal['.heap']+subtotal['.stack']), - 'total_flash': (subtotal['.text'] + subtotal['.data'] + - misc_flash_mem), - } - } - - self.mem_summary = json_obj + [summary] - to_call = {'json': self.generate_json, 'csv-ci': self.generate_csv, 'table': self.generate_table}[export_format] - to_call(subtotal, misc_flash_mem, file_desc) + to_call(file_desc) if file_desc is not sys.stdout: file_desc.close() - def generate_json(self, _, dummy, file_desc): + def generate_json(self, file_desc): """Generate a json file from a memory map Positional arguments: - subtotal - total sizes for each module - misc_flash_mem - size of misc flash sections file_desc - the file to write out the final report to """ - file_desc.write(json.dumps(self.mem_summary, indent=4)) + file_desc.write(json.dumps(self.mem_report, indent=4)) file_desc.write('\n') - def generate_csv(self, subtotal, misc_flash_mem, file_desc): + def generate_csv(self, file_desc): """Generate a CSV file from a memoy map Positional arguments: - subtotal - total sizes for each module - misc_flash_mem - size of misc flash sections file_desc - the file to write out the final report to """ csv_writer = csv.writer(file_desc, delimiter=',', @@ -474,36 +449,33 @@ class MemapParser(object): csv_sizes += [self.modules[i][k]] csv_module_section += ['static_ram'] - csv_sizes += [subtotal['.data']+subtotal['.bss']] + csv_sizes += [self.mem_summary['static_ram']] csv_module_section += ['heap'] - if subtotal['.heap'] == 0: + if self.mem_summary['heap'] == 0: csv_sizes += ['unknown'] else: - csv_sizes += [subtotal['.heap']] + csv_sizes += [self.mem_summary['heap']] csv_module_section += ['stack'] - if subtotal['.stack'] == 0: + if self.mem_summary['stack'] == 0: csv_sizes += ['unknown'] else: - csv_sizes += [subtotal['.stack']] + csv_sizes += [self.mem_summary['stack']] csv_module_section += ['total_ram'] - csv_sizes += [subtotal['.data'] + subtotal['.bss'] + - subtotal['.heap'] + subtotal['.stack']] + csv_sizes += [self.mem_summary['total_ram']] csv_module_section += ['total_flash'] - csv_sizes += [subtotal['.text']+subtotal['.data']+misc_flash_mem] + csv_sizes += [self.mem_summary['total_flash']] csv_writer.writerow(csv_module_section) csv_writer.writerow(csv_sizes) - def generate_table(self, subtotal, misc_flash_mem, file_desc): + def generate_table(self, file_desc): """Generate a table from a memoy map Positional arguments: - subtotal - total sizes for each module - misc_flash_mem - size of misc flash sections file_desc - the file to write out the final report to """ # Create table @@ -521,9 +493,6 @@ class MemapParser(object): for i in sorted(self.modules): row = [i] - for k in self.sections: - subtotal[k] += self.modules[i][k] - for k in self.print_sections: row.append(self.modules[i][k]) @@ -531,37 +500,73 @@ class MemapParser(object): subtotal_row = ['Subtotals'] for k in self.print_sections: - subtotal_row.append(subtotal[k]) + subtotal_row.append(self.subtotal[k]) table.add_row(subtotal_row) file_desc.write(table.get_string()) file_desc.write('\n') - if subtotal['.heap'] == 0: + if self.mem_summary['heap'] == 0: file_desc.write("Allocated Heap: unknown\n") else: file_desc.write("Allocated Heap: %s bytes\n" % - str(subtotal['.heap'])) + str(self.mem_summary['heap'])) - if subtotal['.stack'] == 0: + if self.mem_summary['stack'] == 0: file_desc.write("Allocated Stack: unknown\n") else: file_desc.write("Allocated Stack: %s bytes\n" % - str(subtotal['.stack'])) + str(self.mem_summary['stack'])) file_desc.write("Total Static RAM memory (data + bss): %s bytes\n" % - (str(subtotal['.data'] + subtotal['.bss']))) + (str(self.mem_summary['static_ram']))) file_desc.write( "Total RAM memory (data + bss + heap + stack): %s bytes\n" - % (str(subtotal['.data'] + subtotal['.bss'] + subtotal['.heap'] + - subtotal['.stack']))) + % (str(self.mem_summary['total_ram']))) file_desc.write("Total Flash memory (text + data + misc): %s bytes\n" % - (str(subtotal['.text'] + subtotal['.data'] + - misc_flash_mem))) + (str(self.mem_summary['total_flash']))) toolchains = ["ARM", "ARM_STD", "ARM_MICRO", "GCC_ARM", "IAR"] + def compute_report(self): + for k in self.sections: + self.subtotal[k] = 0 + + for i in sorted(self.modules): + for k in self.sections: + self.subtotal[k] += self.modules[i][k] + + # Calculate misc flash sections + self.misc_flash_mem = 0 + for i in self.modules: + for k in self.misc_flash_sections: + if self.modules[i][k]: + self.misc_flash_mem += self.modules[i][k] + + self.mem_summary = { + 'static_ram': (self.subtotal['.data'] + self.subtotal['.bss']), + 'heap': (self.subtotal['.heap']), + 'stack': (self.subtotal['.stack']), + 'total_ram': (self.subtotal['.data'] + self.subtotal['.bss'] + + self.subtotal['.heap']+self.subtotal['.stack']), + 'total_flash': (self.subtotal['.text'] + self.subtotal['.data'] + + self.misc_flash_mem), + } + + self.mem_report = [] + for i in sorted(self.modules): + self.mem_report.append({ + "module":i, + "size":{ + k:self.modules[i][k] for k in self.print_sections + } + }) + + self.mem_report.append({ + 'summary': self.mem_summary + }) + def parse(self, mapfile, toolchain): """ Parse and decode map file depending on the toolchain @@ -584,6 +589,9 @@ class MemapParser(object): self.parse_map_file_iar(file_input) else: result = False + + self.compute_report() + except IOError as error: print "I/O error({0}): {1}".format(error.errno, error.strerror) result = False @@ -620,6 +628,8 @@ def main(): ", ".join(MemapParser.export_formats)) parser.add_argument('-v', '--version', action='version', version=version) + + parser.add_argument('-d', '--detailed', action='store_true', help='Displays the elements in "Misc" in a detailed fashion', required=False) # Parse/run command if len(sys.argv) <= 1: @@ -630,7 +640,7 @@ def main(): args = parser.parse_args() # Create memap object - memap = MemapParser() + memap = MemapParser(detailed_misc=args.detailed) # Parse and decode a map file if args.file and args.toolchain: diff --git a/tools/options.py b/tools/options.py index 45f3cfb016..0c3b016d95 100644 --- a/tools/options.py +++ b/tools/options.py @@ -14,12 +14,14 @@ 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. """ +from json import load +from os.path import join, dirname from argparse import ArgumentParser from tools.toolchains import TOOLCHAINS from tools.targets import TARGET_NAMES from tools.utils import argparse_force_uppercase_type, \ argparse_lowercase_hyphen_type, argparse_many, \ - argparse_filestring_type + argparse_filestring_type, args_error def get_default_options_parser(add_clean=True, add_options=True, add_app_config=False): @@ -70,21 +72,35 @@ def get_default_options_parser(add_clean=True, add_options=True, help="clean the build directory") if add_options: - parser.add_argument("-o", "--options", action="append", - help=('Add a build argument ("save-asm": save the ' - 'asm generated by the compiler, "debug-info":' - ' generate debugging information, "analyze": ' - 'run Goanna static code analyzer")'), - type=argparse_lowercase_hyphen_type(['save-asm', - 'debug-info', - 'analyze', - 'small-lib', - 'std-lib'], - "build option")) - + parser.add_argument("--profile", dest="profile", action="append", + type=argparse_filestring_type, + default=[]) if add_app_config: parser.add_argument("--app-config", default=None, dest="app_config", type=argparse_filestring_type, help="Path of an app configuration file (Default is to look for 'mbed_app.json')") return parser + + +def extract_profile(parser, options, toolchain): + """Extract a Toolchain profile from parsed options + + Positional arguments: + parser - parser used to parse the command line arguments + options - The parsed command line arguments + toolchain - the toolchain that the profile should be extracted for + """ + profile = {'c': [], 'cxx': [], 'ld': [], 'common': [], 'asm': []} + filenames = options.profile or [join(dirname(__file__), "profiles", + "default.json")] + for filename in filenames: + contents = load(open(filename)) + try: + for key in profile.iterkeys(): + profile[key] += contents[toolchain][key] + except KeyError: + args_error(parser, ("argument --profile: toolchain {} is not" + " supported by profile {}").format(toolchain, + filename)) + return profile diff --git a/tools/profiles/all-warnings.json b/tools/profiles/all-warnings.json new file mode 100644 index 0000000000..a7e8cb71ed --- /dev/null +++ b/tools/profiles/all-warnings.json @@ -0,0 +1,9 @@ +{ + "GCC_ARM": { + "common": ["-pedantic"], + "asm": [], + "c": [], + "cxx": [], + "ld": [] + } +} diff --git a/tools/profiles/debug.json b/tools/profiles/debug.json new file mode 100644 index 0000000000..b463f0ab7c --- /dev/null +++ b/tools/profiles/debug.json @@ -0,0 +1,44 @@ +{ + "GCC_ARM": { + "common": ["-c", "-Wall", "-Wextra", + "-Wno-unused-parameter", "-Wno-missing-field-initializers", + "-fmessage-length=0", "-fno-exceptions", "-fno-builtin", + "-ffunction-sections", "-fdata-sections", "-funsigned-char", + "-MMD", "-fno-delete-null-pointer-checks", + "-fomit-frame-pointer", "-O0", "-g"], + "asm": ["-x", "assembler-with-cpp"], + "c": ["-std=gnu99"], + "cxx": ["-std=gnu++98", "-fno-rtti", "-Wvla"], + "ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r", + "-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", + "-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit"] + }, + "ARM": { + "common": ["-c", "--gnu", "-Otime", "--split_sections", + "--apcs=interwork", "--brief_diagnostics", "--restrict", + "--multibyte_chars", "-O0", "-g"], + "asm": [], + "c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"], + "cxx": ["--cpp", "--no_rtti", "--no_vla"], + "ld": [] + }, + "uARM": { + "common": ["-c", "--gnu", "-Otime", "--split_sections", + "--apcs=interwork", "--brief_diagnostics", "--restrict", + "--multibyte_chars", "-O0", "-D__MICROLIB", "-g" + "--library_type=microlib", "-DMBED_RTOS_SINGLE_THREAD"], + "asm": [], + "c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"], + "cxx": ["--cpp", "--no_rtti", "--no_vla"], + "ld": ["--library_type=microlib"] + }, + "IAR": { + "common": [ + "--no_wrap_diagnostics", "non-native end of line sequence", "-e", + "--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-On", "-r"], + "asm": [], + "c": ["--vla"], + "cxx": ["--guard_calls", "--no_static_destruction"], + "ld": ["--skip_dynamic_initialization", "--threaded_lib"] + } +} diff --git a/tools/profiles/default.json b/tools/profiles/default.json new file mode 100644 index 0000000000..d4755e9b81 --- /dev/null +++ b/tools/profiles/default.json @@ -0,0 +1,44 @@ +{ + "GCC_ARM": { + "common": ["-c", "-Wall", "-Wextra", + "-Wno-unused-parameter", "-Wno-missing-field-initializers", + "-fmessage-length=0", "-fno-exceptions", "-fno-builtin", + "-ffunction-sections", "-fdata-sections", "-funsigned-char", + "-MMD", "-fno-delete-null-pointer-checks", + "-fomit-frame-pointer", "-Os"], + "asm": ["-x", "assembler-with-cpp"], + "c": ["-std=gnu99"], + "cxx": ["-std=gnu++98", "-fno-rtti", "-Wvla"], + "ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r", + "-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", + "-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit"] + }, + "ARM": { + "common": ["-c", "--gnu", "-Otime", "--split_sections", + "--apcs=interwork", "--brief_diagnostics", "--restrict", + "--multibyte_chars", "-O3"], + "asm": [], + "c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"], + "cxx": ["--cpp", "--no_rtti", "--no_vla"], + "ld": [] + }, + "uARM": { + "common": ["-c", "--gnu", "-Otime", "--split_sections", + "--apcs=interwork", "--brief_diagnostics", "--restrict", + "--multibyte_chars", "-O3", "-D__MICROLIB", + "--library_type=microlib", "-DMBED_RTOS_SINGLE_THREAD"], + "asm": [], + "c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"], + "cxx": ["--cpp", "--no_rtti", "--no_vla"], + "ld": ["--library_type=microlib"] + }, + "IAR": { + "common": [ + "--no_wrap_diagnostics", "-e", + "--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-Oh"], + "asm": [], + "c": ["--vla"], + "cxx": ["--guard_calls", "--no_static_destruction"], + "ld": ["--skip_dynamic_initialization", "--threaded_lib"] + } +} diff --git a/tools/profiles/nanolib.json b/tools/profiles/nanolib.json new file mode 100644 index 0000000000..545120d0ac --- /dev/null +++ b/tools/profiles/nanolib.json @@ -0,0 +1,9 @@ +{ + "GCC_ARM": { + "common": [ "-DMBED_RTOS_SINGLE_THREAD"], + "asm": [], + "c": [], + "cxx": [], + "ld": [ "--specs=nano.specs"] + } +} diff --git a/tools/profiles/save-asm.json b/tools/profiles/save-asm.json new file mode 100644 index 0000000000..04128176d9 --- /dev/null +++ b/tools/profiles/save-asm.json @@ -0,0 +1,23 @@ +{ + "GCC_ARM": { + "common": ["-save-temps"], + "asm": [], + "c": [], + "cxx": [], + "ld": [] + }, + "ARM": { + "common": ["--asm", "--interleave"], + "asm": [], + "c": [], + "cxx": [], + "ld": [] + }, + "uARM": { + "common": ["--asm", "--interleave"], + "asm": [], + "c": [], + "cxx": [], + "ld": [] + } +} diff --git a/tools/project.py b/tools/project.py index 399faa7413..1b7cd885b8 100644 --- a/tools/project.py +++ b/tools/project.py @@ -19,6 +19,7 @@ from tools.utils import argparse_filestring_type, argparse_many, args_error from tools.utils import argparse_force_lowercase_type from tools.utils import argparse_force_uppercase_type from tools.project_api import export_project +from tools.options import extract_profile def setup_project(ide, target, program=None, source_dir=None, build=None, export_path=None): @@ -63,7 +64,8 @@ def setup_project(ide, target, program=None, source_dir=None, build=None, export def export(target, ide, build=None, src=None, macros=None, project_id=None, - clean=False, zip_proj=False, options=None, export_path=None, silent=False): + clean=False, zip_proj=False, build_profile=None, export_path=None, + silent=False): """Do an export of a project. Positional arguments: @@ -87,7 +89,7 @@ def export(target, ide, build=None, src=None, macros=None, project_id=None, return export_project(src, project_dir, target, ide, clean=clean, name=name, macros=macros, libraries_paths=lib, zip_proj=zip_name, - options=options, silent=silent) + build_profile=build_profile, silent=silent) def main(): @@ -167,11 +169,10 @@ def main(): dest="macros", help="Add a macro definition") - parser.add_argument("-o", - type=argparse_many(str), - dest="opts", - default=["debug-info"], - help="Toolchain options") + parser.add_argument("--profile", + type=argparse_filestring_type, + default=[], + help="Toolchain profile") options = parser.parse_args() @@ -220,10 +221,12 @@ def main(): if (options.program is None) and (not options.source_dir): args_error(parser, "one of -p, -n, or --source is required") # Export to selected toolchain + _, toolchain_name = get_exporter_toolchain(options.ide) + profile = extract_profile(parser, options, toolchain_name) export(options.mcu, options.ide, build=options.build, src=options.source_dir, macros=options.macros, project_id=options.program, clean=options.clean, - zip_proj=zip_proj, options=options.opts) + zip_proj=zip_proj, build_profile=profile) if __name__ == "__main__": diff --git a/tools/project_api.py b/tools/project_api.py index 0a64df0fc5..dc5871f217 100644 --- a/tools/project_api.py +++ b/tools/project_api.py @@ -135,10 +135,11 @@ def zip_export(file_name, prefix, resources, project_files, inc_repos): def export_project(src_paths, export_path, target, ide, - libraries_paths=None, options=None, linker_script=None, - clean=False, notify=None, verbose=False, name=None, - inc_dirs=None, jobs=1, silent=False, extra_verbose=False, - config=None, macros=None, zip_proj=None, inc_repos=False): + libraries_paths=None, linker_script=None, clean=False, + notify=None, verbose=False, name=None, inc_dirs=None, + jobs=1, silent=False, extra_verbose=False, config=None, + macros=None, zip_proj=None, inc_repos=False, + build_profile=None): """Generates a project file and creates a zip archive if specified Positional Arguments: @@ -149,7 +150,6 @@ def export_project(src_paths, export_path, target, ide, Keyword Arguments: libraries_paths - paths to additional libraries - options - build options passed by -o flag linker_script - path to the linker script for the specified target clean - removes the export_path if it exists notify - function is passed all events, and expected to handle notification @@ -192,10 +192,10 @@ def export_project(src_paths, export_path, target, ide, # Pass all params to the unified prepare_resources() toolchain = prepare_toolchain(paths, target, toolchain_name, - macros=macros, options=options, clean=clean, - jobs=jobs, notify=notify, silent=silent, - verbose=verbose, extra_verbose=extra_verbose, - config=config) + macros=macros, clean=clean, jobs=jobs, + notify=notify, silent=silent, verbose=verbose, + extra_verbose=extra_verbose, config=config, + build_profile=build_profile) # The first path will give the name to the library if name is None: name = basename(normpath(abspath(src_paths[0]))) diff --git a/tools/singletest.py b/tools/singletest.py index bde208c521..a07ecd4b23 100644 --- a/tools/singletest.py +++ b/tools/singletest.py @@ -225,6 +225,8 @@ if __name__ == '__main__': _test_loops_list=opts.test_loops_list, _muts=MUTs, _clean=opts.clean, + _parser=parser, + _opts=opts, _opts_db_url=opts.db_url, _opts_log_file_name=opts.log_file_name, _opts_report_html_file_name=opts.report_html_file_name, diff --git a/tools/test.py b/tools/test.py index 851cb05538..9e520d59b2 100644 --- a/tools/test.py +++ b/tools/test.py @@ -27,7 +27,7 @@ ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) sys.path.insert(0, ROOT) from tools.test_api import test_path_to_name, find_tests, print_tests, build_tests, test_spec_from_test_builds -from tools.options import get_default_options_parser +from tools.options import get_default_options_parser, extract_profile from tools.build_api import build_project, build_library from tools.build_api import print_build_memory_usage from tools.targets import TARGET_MAP @@ -132,7 +132,7 @@ if __name__ == '__main__': # Find all tests in the relevant paths for path in all_paths: - all_tests.update(find_tests(path, mcu, toolchain, options.options, + all_tests.update(find_tests(path, mcu, toolchain, app_config=options.app_config)) # Filter tests by name if specified @@ -180,10 +180,10 @@ if __name__ == '__main__': build_properties = {} library_build_success = False + profile = extract_profile(parser, options, toolchain) try: # Build sources build_library(base_source_paths, options.build_dir, mcu, toolchain, - options=options.options, jobs=options.jobs, clean=options.clean, report=build_report, @@ -193,7 +193,8 @@ if __name__ == '__main__': verbose=options.verbose, notify=notify, archive=False, - app_config=options.app_config) + app_config=options.app_config, + build_profile=profile) library_build_success = True except ToolException, e: @@ -212,7 +213,6 @@ if __name__ == '__main__': # Build all the tests test_build_success, test_build = build_tests(tests, [options.build_dir], options.build_dir, mcu, toolchain, - options=options.options, clean=options.clean, report=build_report, properties=build_properties, @@ -221,7 +221,8 @@ if __name__ == '__main__': notify=notify, jobs=options.jobs, continue_on_build_fail=options.continue_on_build_fail, - app_config=options.app_config) + app_config=options.app_config, + build_profile=profile) # If a path to a test spec is provided, write it to a file if options.test_spec: diff --git a/tools/test/build_api/build_api_test.py b/tools/test/build_api/build_api_test.py index 97c2f1cf21..a3353929ea 100644 --- a/tools/test/build_api/build_api_test.py +++ b/tools/test/build_api/build_api_test.py @@ -16,8 +16,10 @@ limitations under the License. """ import unittest -from mock import patch -from tools.build_api import prepare_toolchain, build_project, build_library +from collections import namedtuple +from mock import patch, MagicMock +from tools.build_api import prepare_toolchain, build_project, build_library,\ + scan_resources """ Tests for build_api.py @@ -47,7 +49,30 @@ class BuildApiTests(unittest.TestCase): """ pass - @patch('tools.config.Config.__init__') + @patch('tools.toolchains.arm.ARM_STD.parse_dependencies', + return_value=["foo"]) + @patch('tools.toolchains.mbedToolchain.need_update', + side_effect=[i % 2 for i in range(3000)]) + @patch('os.mkdir') + @patch('tools.toolchains.exists', return_value=True) + @patch('tools.utils.run_cmd', return_value=("", "", 0)) + def test_always_complete_build(self, *_): + with MagicMock() as notify: + toolchain = prepare_toolchain(self.src_paths, self.target, + self.toolchain_name, notify=notify) + + res = scan_resources(self.src_paths, toolchain) + + toolchain.RESPONSE_FILES=False + toolchain.config_processed = True + toolchain.config_file = "junk" + toolchain.compile_sources(res, self.build_path) + + assert any('percent' in msg[0] and msg[0]['percent'] == 100.0 + for _, msg, _ in notify.mock_calls if msg) + + + @patch('tools.build_api.Config') def test_prepare_toolchain_app_config(self, mock_config_init): """ Test that prepare_toolchain uses app_config correctly @@ -56,15 +81,18 @@ class BuildApiTests(unittest.TestCase): :return: """ app_config = "app_config" - mock_config_init.return_value = None + mock_config_init.return_value = namedtuple("Config", "target")( + namedtuple("Target", + "init_hooks name features core")(lambda _, __ : None, + "Junk", [], "Cortex-M3")) prepare_toolchain(self.src_paths, self.target, self.toolchain_name, app_config=app_config) - mock_config_init.assert_called_with(self.target, self.src_paths, - app_config=app_config) + mock_config_init.assert_called_once_with(self.target, self.src_paths, + app_config=app_config) - @patch('tools.config.Config.__init__') + @patch('tools.build_api.Config') def test_prepare_toolchain_no_app_config(self, mock_config_init): """ Test that prepare_toolchain correctly deals with no app_config @@ -72,12 +100,15 @@ class BuildApiTests(unittest.TestCase): :param mock_config_init: mock of Config __init__ :return: """ - mock_config_init.return_value = None + mock_config_init.return_value = namedtuple("Config", "target")( + namedtuple("Target", + "init_hooks name features core")(lambda _, __ : None, + "Junk", [], "Cortex-M3")) prepare_toolchain(self.src_paths, self.target, self.toolchain_name) - mock_config_init.assert_called_with(self.target, self.src_paths, - app_config=None) + mock_config_init.assert_called_once_with(self.target, self.src_paths, + app_config=None) @patch('tools.build_api.scan_resources') @patch('tools.build_api.mkdir') diff --git a/tools/test/config_test/test21/mbed_app.json b/tools/test/config_test/test21/mbed_app.json index d1a874a23d..3c809f7d65 100644 --- a/tools/test/config_test/test21/mbed_app.json +++ b/tools/test/config_test/test21/mbed_app.json @@ -1,7 +1,7 @@ { "target_overrides": { "*": { - "target.features": ["IPV4", "IPV6"] + "target.features": ["IPV4"] } } } diff --git a/tools/test/config_test/test21/test_data.py b/tools/test/config_test/test21/test_data.py index ca0a48907c..4f7ae443e9 100644 --- a/tools/test/config_test/test21/test_data.py +++ b/tools/test/config_test/test21/test_data.py @@ -3,6 +3,6 @@ expected_results = { "test_target": { "desc": "test basic features", - "expected_features": ["IPV4", "IPV6"] + "expected_features": ["IPV4"] } } diff --git a/tools/test/config_test/test22/mbed_app.json b/tools/test/config_test/test22/mbed_app.json index a070a2d556..9509bfecb9 100644 --- a/tools/test/config_test/test22/mbed_app.json +++ b/tools/test/config_test/test22/mbed_app.json @@ -1,7 +1,7 @@ { "target_overrides": { "*": { - "target.features_add": ["IPV6"] + "target.features_add": ["STORAGE"] } } } diff --git a/tools/test/config_test/test22/test_data.py b/tools/test/config_test/test22/test_data.py index 7610f4107c..5edfe17891 100644 --- a/tools/test/config_test/test22/test_data.py +++ b/tools/test/config_test/test22/test_data.py @@ -3,6 +3,6 @@ expected_results = { "test_target": { "desc": "test composing features", - "expected_features": ["IPV4", "IPV6"] + "expected_features": ["IPV4", "STORAGE"] } } diff --git a/tools/test/config_test/test23/mbed_app.json b/tools/test/config_test/test23/mbed_app.json index a070a2d556..9509bfecb9 100644 --- a/tools/test/config_test/test23/mbed_app.json +++ b/tools/test/config_test/test23/mbed_app.json @@ -1,7 +1,7 @@ { "target_overrides": { "*": { - "target.features_add": ["IPV6"] + "target.features_add": ["STORAGE"] } } } diff --git a/tools/test/config_test/test24/FEATURE_IPV4/lib1/mbed_lib.json b/tools/test/config_test/test24/FEATURE_IPV4/lib1/mbed_lib.json index 539d8ccc22..4ba03096c9 100644 --- a/tools/test/config_test/test24/FEATURE_IPV4/lib1/mbed_lib.json +++ b/tools/test/config_test/test24/FEATURE_IPV4/lib1/mbed_lib.json @@ -2,7 +2,7 @@ "name": "lib1", "target_overrides": { "*": { - "target.features_add": ["IPV6"] + "target.features_add": ["STORAGE"] } } } diff --git a/tools/test/config_test/test24/FEATURE_IPV6/lib2/mbed_lib.json b/tools/test/config_test/test24/FEATURE_STORAGE/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test24/FEATURE_IPV6/lib2/mbed_lib.json rename to tools/test/config_test/test24/FEATURE_STORAGE/lib2/mbed_lib.json diff --git a/tools/test/config_test/test24/test_data.py b/tools/test/config_test/test24/test_data.py index 00681ed475..a77f026758 100644 --- a/tools/test/config_test/test24/test_data.py +++ b/tools/test/config_test/test24/test_data.py @@ -3,6 +3,6 @@ expected_results = { "test_target": { "desc": "test recursive features", - "expected_features": ["IPV4", "IPV6", "UVISOR"] + "expected_features": ["IPV4", "STORAGE", "UVISOR"] } } diff --git a/tools/test/config_test/test25/FEATURE_IPV6/FEATURE_IPV4/lib1/mbed_lib.json b/tools/test/config_test/test25/FEATURE_STORAGE/FEATURE_IPV4/lib1/mbed_lib.json similarity index 63% rename from tools/test/config_test/test25/FEATURE_IPV6/FEATURE_IPV4/lib1/mbed_lib.json rename to tools/test/config_test/test25/FEATURE_STORAGE/FEATURE_IPV4/lib1/mbed_lib.json index 539d8ccc22..4ba03096c9 100644 --- a/tools/test/config_test/test25/FEATURE_IPV6/FEATURE_IPV4/lib1/mbed_lib.json +++ b/tools/test/config_test/test25/FEATURE_STORAGE/FEATURE_IPV4/lib1/mbed_lib.json @@ -2,7 +2,7 @@ "name": "lib1", "target_overrides": { "*": { - "target.features_add": ["IPV6"] + "target.features_add": ["STORAGE"] } } } diff --git a/tools/test/config_test/test25/FEATURE_IPV6/lib2/mbed_lib.json b/tools/test/config_test/test25/FEATURE_STORAGE/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test25/FEATURE_IPV6/lib2/mbed_lib.json rename to tools/test/config_test/test25/FEATURE_STORAGE/lib2/mbed_lib.json diff --git a/tools/test/config_test/test25/mbed_app.json b/tools/test/config_test/test25/mbed_app.json index d1a874a23d..b4ad5832fb 100644 --- a/tools/test/config_test/test25/mbed_app.json +++ b/tools/test/config_test/test25/mbed_app.json @@ -1,7 +1,7 @@ { "target_overrides": { "*": { - "target.features": ["IPV4", "IPV6"] + "target.features": ["IPV4", "STORAGE"] } } } diff --git a/tools/test/config_test/test26/FEATURE_IPV4/lib1/mbed_lib.json b/tools/test/config_test/test26/FEATURE_IPV4/lib1/mbed_lib.json index 539d8ccc22..4ba03096c9 100644 --- a/tools/test/config_test/test26/FEATURE_IPV4/lib1/mbed_lib.json +++ b/tools/test/config_test/test26/FEATURE_IPV4/lib1/mbed_lib.json @@ -2,7 +2,7 @@ "name": "lib1", "target_overrides": { "*": { - "target.features_add": ["IPV6"] + "target.features_add": ["STORAGE"] } } } diff --git a/tools/test/config_test/test26/FEATURE_IPV6/lib2/mbed_lib.json b/tools/test/config_test/test26/FEATURE_STORAGE/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test26/FEATURE_IPV6/lib2/mbed_lib.json rename to tools/test/config_test/test26/FEATURE_STORAGE/lib2/mbed_lib.json diff --git a/tools/test/examples/examples.json b/tools/test/examples/examples.json index c45d2feecb..0e7a99924e 100644 --- a/tools/test/examples/examples.json +++ b/tools/test/examples/examples.json @@ -1,9 +1,5 @@ { "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-blinky" : {}, - "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-Beacon" : - {"features": ["BLE"]}, - "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-HeartRate" : - {"features": ["BLE"]}, "https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-mesh-minimal" : {"features": ["IPV6"]}, "https://github.com/ARMmbed/mbed-os-example-client" : {"features": ["IPV6"]}, diff --git a/tools/test/memap/memap_test.py b/tools/test/memap/memap_test.py new file mode 100644 index 0000000000..4407347422 --- /dev/null +++ b/tools/test/memap/memap_test.py @@ -0,0 +1,168 @@ +""" +mbed SDK +Copyright (c) 2016 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. +""" +import sys +import os + +ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "..")) +sys.path.insert(0, ROOT) + +import unittest +from tools.memap import MemapParser +from copy import deepcopy + +""" +Tests for test_api.py +""" + +class MemapParserTests(unittest.TestCase): + """ + Test cases for Test Api + """ + + def setUp(self): + """ + Called before each test case + + :return: + """ + self.memap_parser = MemapParser() + + self.memap_parser.modules = { + "Misc": { + "unknown": 0, + ".ARM": 8, + ".ARM.extab": 0, + ".init": 12, + "OUTPUT": 0, + ".stack": 0, + ".eh_frame": 0, + ".fini_array": 4, + ".heap": 0, + ".stabstr": 0, + ".interrupts_ram": 0, + ".init_array": 0, + ".stab": 0, + ".ARM.attributes": 7347, + ".bss": 8517, + ".flash_config": 16, + ".interrupts": 1024, + ".data": 2325, + ".ARM.exidx": 0, + ".text": 59906, + ".jcr": 0 + }, + "Fill": { + "unknown": 12, + ".ARM": 0, + ".ARM.extab": 0, + ".init": 0, + "OUTPUT": 0, + ".stack": 0, + ".eh_frame": 0, + ".fini_array": 0, + ".heap": 65536, + ".stabstr": 0, + ".interrupts_ram": 1024, + ".init_array": 0, + ".stab": 0, + ".ARM.attributes": 0, + ".bss": 2235, + ".flash_config": 0, + ".interrupts": 0, + ".data": 3, + ".ARM.exidx": 0, + ".text": 136, + ".jcr": 0 + } + } + + self.memap_parser.compute_report() + + def tearDown(self): + """ + Called after each test case + + :return: + """ + pass + + def generate_test_helper(self, output_type, file_output=None): + """ + Helper that ensures that the member variables "modules", "mem_report", + and "mem_summary" are unchanged after calling "generate_output" + + :param output_type: type string that is passed to "generate_output" + :param file_output: path to output file that is passed to "generate_output" + :return: + """ + + old_modules = deepcopy(self.memap_parser.modules) + old_report = deepcopy(self.memap_parser.mem_report) + old_summary = deepcopy(self.memap_parser.mem_summary) + self.memap_parser.generate_output(output_type, file_output) + self.assertEqual(self.memap_parser.modules, old_modules, + "generate_output modified the 'modules' property") + self.assertEqual(self.memap_parser.mem_report, old_report, + "generate_output modified the 'mem_report' property") + self.assertEqual(self.memap_parser.mem_summary, old_summary, + "generate_output modified the 'mem_summary' property") + + def test_report_computed(self): + """ + Test ensures the report and summary are computed + + :return: + """ + self.assertTrue(self.memap_parser.mem_report) + self.assertTrue(self.memap_parser.mem_summary) + self.assertEqual(self.memap_parser.mem_report[-1]['summary'], + self.memap_parser.mem_summary, + "mem_report did not contain a correct copy of mem_summary") + + def test_generate_output_table(self): + """ + Test ensures that an output of type "table" can be generated correctly + + :return: + """ + self.generate_test_helper('table') + + def test_generate_output_json(self): + """ + Test ensures that an output of type "json" can be generated correctly + + :return: + """ + file_name = '.json_test_output.json' + self.generate_test_helper('json', file_output=file_name) + self.assertTrue(os.path.exists(file_name), "Failed to create json file") + os.remove(file_name) + + def test_generate_output_csv_ci(self): + """ + Test ensures that an output of type "csv-ci" can be generated correctly + + :return: + """ + file_name = '.csv_ci_test_output.csv' + self.generate_test_helper('csv-ci', file_output=file_name) + self.assertTrue(os.path.exists(file_name), "Failed to create csv-ci file") + os.remove(file_name) + + +if __name__ == '__main__': + unittest.main() diff --git a/tools/test/toolchains/api.py b/tools/test/toolchains/api.py index 1452f58c01..100d02d11d 100644 --- a/tools/test/toolchains/api.py +++ b/tools/test/toolchains/api.py @@ -1,13 +1,124 @@ +"""Tests for the toolchain sub-system""" import sys import os +from string import printable +from copy import deepcopy +from mock import MagicMock +from hypothesis import given +from hypothesis.strategies import text, lists, fixed_dictionaries -ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "..")) +ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", + "..")) sys.path.insert(0, ROOT) -from tools.toolchains import TOOLCHAIN_CLASSES, LEGACY_TOOLCHAIN_NAMES +from tools.toolchains import TOOLCHAIN_CLASSES, LEGACY_TOOLCHAIN_NAMES,\ + Resources from tools.targets import TARGET_MAP def test_instantiation(): + """Test that all exported toolchain may be instantiated""" + for name, tc_class in TOOLCHAIN_CLASSES.items(): + cls = tc_class(TARGET_MAP["K64F"]) + assert name == cls.name or\ + name == LEGACY_TOOLCHAIN_NAMES[cls.name] + +ALPHABET = [char for char in printable if char not in [u'.', u'/']] + +@given(fixed_dictionaries({ + 'common': lists(text()), + 'c': lists(text()), + 'cxx': lists(text()), + 'asm': lists(text()), + 'ld': lists(text())}), + lists(text(min_size=1, alphabet=ALPHABET), min_size=1)) +def test_toolchain_profile_c(profile, source_file): + """Test that the appropriate profile parameters are passed to the + C compiler""" + filename = deepcopy(source_file) + filename[-1] += ".c" + to_compile = os.path.join(*filename) + for _, tc_class in TOOLCHAIN_CLASSES.items(): + toolchain = tc_class(TARGET_MAP["K64F"], build_profile=profile) + toolchain.inc_md5 = "" + toolchain.build_dir = "" + compile_command = toolchain.compile_command(to_compile, + to_compile + ".o", []) + for parameter in profile['c'] + profile['common']: + assert any(parameter in cmd for cmd in compile_command), \ + "Toolchain %s did not propigate arg %s" % (toolchain.name, + parameter) + +@given(fixed_dictionaries({ + 'common': lists(text()), + 'c': lists(text()), + 'cxx': lists(text()), + 'asm': lists(text()), + 'ld': lists(text())}), + lists(text(min_size=1, alphabet=ALPHABET), min_size=1)) +def test_toolchain_profile_cpp(profile, source_file): + """Test that the appropriate profile parameters are passed to the + C++ compiler""" + filename = deepcopy(source_file) + filename[-1] += ".cpp" + to_compile = os.path.join(*filename) + for _, tc_class in TOOLCHAIN_CLASSES.items(): + toolchain = tc_class(TARGET_MAP["K64F"], build_profile=profile) + toolchain.inc_md5 = "" + toolchain.build_dir = "" + compile_command = toolchain.compile_command(to_compile, + to_compile + ".o", []) + for parameter in profile['cxx'] + profile['common']: + assert any(parameter in cmd for cmd in compile_command), \ + "Toolchain %s did not propigate arg %s" % (toolchain.name, + parameter) + +@given(fixed_dictionaries({ + 'common': lists(text()), + 'c': lists(text()), + 'cxx': lists(text()), + 'asm': lists(text()), + 'ld': lists(text())}), + lists(text(min_size=1, alphabet=ALPHABET), min_size=1)) +def test_toolchain_profile_asm(profile, source_file): + """Test that the appropriate profile parameters are passed to the + Assembler""" + filename = deepcopy(source_file) + filename[-1] += ".s" + to_compile = os.path.join(*filename) + for _, tc_class in TOOLCHAIN_CLASSES.items(): + toolchain = tc_class(TARGET_MAP["K64F"], build_profile=profile) + toolchain.inc_md5 = "" + toolchain.build_dir = "" + compile_command = toolchain.compile_command(to_compile, + to_compile + ".o", []) + if not compile_command: + assert compile_command, to_compile + for parameter in profile['asm']: + assert any(parameter in cmd for cmd in compile_command), \ + "Toolchain %s did not propigate arg %s" % (toolchain.name, + parameter) + for name, Class in TOOLCHAIN_CLASSES.items(): CLS = Class(TARGET_MAP["K64F"]) assert name == CLS.name or name == LEGACY_TOOLCHAIN_NAMES[CLS.name] + + +@given(lists(text(alphabet=ALPHABET, min_size=1), min_size=1)) +def test_detect_duplicates(filenames): + c_sources = [os.path.join(name, "dupe.c") for name in filenames] + s_sources = [os.path.join(name, "dupe.s") for name in filenames] + cpp_sources = [os.path.join(name, "dupe.cpp") for name in filenames] + with MagicMock() as notify: + toolchain = TOOLCHAIN_CLASSES["ARM"](TARGET_MAP["K64F"], notify=notify) + res = Resources() + res.c_sources = c_sources + res.s_sources = s_sources + res.cpp_sources = cpp_sources + assert res.detect_duplicates(toolchain) == 1,\ + "Not Enough duplicates found" + + _, (notification, _), _ = notify.mock_calls[1] + assert "dupe.o" in notification["message"] + assert "dupe.s" in notification["message"] + assert "dupe.c" in notification["message"] + assert "dupe.cpp" in notification["message"] diff --git a/tools/test_api.py b/tools/test_api.py index 3c05788e2b..126328f3ad 100644 --- a/tools/test_api.py +++ b/tools/test_api.py @@ -60,6 +60,7 @@ from tools.build_api import add_result_to_report from tools.build_api import prepare_toolchain from tools.build_api import scan_resources from tools.libraries import LIBRARIES, LIBRARY_MAP +from tools.options import extract_profile from tools.toolchains import TOOLCHAIN_PATHS from tools.toolchains import TOOLCHAINS from tools.test_exporters import ReportExporter, ResultExporterType @@ -170,6 +171,8 @@ class SingleTestRunner(object): _test_loops_list=None, _muts={}, _clean=False, + _parser=None, + _opts=None, _opts_db_url=None, _opts_log_file_name=None, _opts_report_html_file_name=None, @@ -258,6 +261,8 @@ class SingleTestRunner(object): self.opts_consolidate_waterfall_test = _opts_consolidate_waterfall_test self.opts_extend_test_timeout = _opts_extend_test_timeout self.opts_clean = _clean + self.opts_parser = _parser + self.opts = _opts self.opts_auto_detect = _opts_auto_detect self.opts_include_non_automated = _opts_include_non_automated @@ -355,19 +360,20 @@ class SingleTestRunner(object): print self.logger.log_line(self.logger.LogType.NOTIF, 'Skipped tests for %s target. Target platform not found'% (target)) continue - build_mbed_libs_options = ["analyze"] if self.opts_goanna_for_mbed_sdk else None clean_mbed_libs_options = True if self.opts_goanna_for_mbed_sdk or clean or self.opts_clean else None + profile = extract_profile(self.opts_parser, self.opts, toolchain) + try: build_mbed_libs_result = build_mbed_libs(T, toolchain, - options=build_mbed_libs_options, clean=clean_mbed_libs_options, verbose=self.opts_verbose, jobs=self.opts_jobs, report=build_report, - properties=build_properties) + properties=build_properties, + build_profile=profile) if not build_mbed_libs_result: print self.logger.log_line(self.logger.LogType.NOTIF, 'Skipped tests for %s target. Toolchain %s is not yet supported for this target'% (T.name, toolchain)) @@ -423,7 +429,6 @@ class SingleTestRunner(object): libraries.append(lib['id']) - build_project_options = ["analyze"] if self.opts_goanna_for_tests else None clean_project_options = True if self.opts_goanna_for_tests or clean or self.opts_clean else None # Build all required libraries @@ -432,12 +437,12 @@ class SingleTestRunner(object): build_lib(lib_id, T, toolchain, - options=build_project_options, verbose=self.opts_verbose, clean=clean_mbed_libs_options, jobs=self.opts_jobs, report=build_report, - properties=build_properties) + properties=build_properties, + build_profile=profile) except ToolException: print self.logger.log_line(self.logger.LogType.ERROR, 'There were errors while building library %s'% (lib_id)) @@ -479,7 +484,6 @@ class SingleTestRunner(object): T, toolchain, test.dependencies, - options=build_project_options, clean=clean_project_options, verbose=self.opts_verbose, name=project_name, @@ -489,7 +493,8 @@ class SingleTestRunner(object): report=build_report, properties=build_properties, project_id=test_id, - project_description=test.get_description()) + project_description=test.get_description(), + build_profile=profile) except Exception, e: project_name_str = project_name if project_name is not None else test_id @@ -1789,6 +1794,10 @@ def get_default_test_options_parser(): action="store_true", help='Test only peripheral declared for MUT and skip common tests') + parser.add_argument("--profile", dest="profile", action="append", + type=argparse_filestring_type, + default=[]) + parser.add_argument('-C', '--only-commons', dest='test_only_common', default=False, @@ -1990,7 +1999,7 @@ def test_path_to_name(path, base): return "-".join(name_parts).lower() -def find_tests(base_dir, target_name, toolchain_name, options=None, app_config=None): +def find_tests(base_dir, target_name, toolchain_name, app_config=None): """ Finds all tests in a directory recursively base_dir: path to the directory to scan for tests (ex. 'path/to/project') target_name: name of the target to use for scanning (ex. 'K64F') @@ -2002,7 +2011,7 @@ def find_tests(base_dir, target_name, toolchain_name, options=None, app_config=N tests = {} # Prepare the toolchain - toolchain = prepare_toolchain([base_dir], target_name, toolchain_name, options=options, + toolchain = prepare_toolchain([base_dir], target_name, toolchain_name, silent=True, app_config=app_config) # Scan the directory for paths to probe for 'TESTS' folders @@ -2060,9 +2069,10 @@ def norm_relative_path(path, start): return path def build_tests(tests, base_source_paths, build_path, target, toolchain_name, - options=None, clean=False, notify=None, verbose=False, jobs=1, - macros=None, silent=False, report=None, properties=None, - continue_on_build_fail=False, app_config=None): + clean=False, notify=None, verbose=False, jobs=1, macros=None, + silent=False, report=None, properties=None, + continue_on_build_fail=False, app_config=None, + build_profile=None): """Given the data structure from 'find_tests' and the typical build parameters, build all the tests @@ -2095,7 +2105,6 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name, try: bin_file = build_project(src_path, test_build_path, target, toolchain_name, - options=options, jobs=jobs, clean=clean, macros=macros, @@ -2104,16 +2113,17 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name, report=report, properties=properties, verbose=verbose, - app_config=app_config) + app_config=app_config, + build_profile=build_profile) - except Exception, e: - if not isinstance(e, NotSupportedException): - result = False - - if continue_on_build_fail: - continue - else: - break + except NotSupportedException: + pass + except ToolException: + result = False + if continue_on_build_fail: + continue + else: + break # If a clean build was carried out last time, disable it for the next build. # Otherwise the previously built test will be deleted. diff --git a/tools/toolchains/__init__.py b/tools/toolchains/__init__.py index 9b56649f9c..98def03191 100644 --- a/tools/toolchains/__init__.py +++ b/tools/toolchains/__init__.py @@ -31,7 +31,7 @@ from distutils.spawn import find_executable from multiprocessing import Pool, cpu_count from tools.utils import run_cmd, mkdir, rel_path, ToolException, NotSupportedException, split_path, compile_worker -from tools.settings import BUILD_OPTIONS, MBED_ORG_USER +from tools.settings import MBED_ORG_USER import tools.hooks as hooks from tools.memap import MemapParser from hashlib import md5 @@ -120,6 +120,43 @@ class Resources: return self + def _collect_duplicates(self, dupe_dict, dupe_headers): + for filename in self.s_sources + self.c_sources + self.cpp_sources: + objname, _ = splitext(basename(filename)) + dupe_dict.setdefault(objname, set()) + dupe_dict[objname] |= set([filename]) + for filename in self.headers: + headername = basename(filename) + dupe_headers.setdefault(headername, set()) + dupe_headers[headername] |= set([headername]) + for res in self.features.values(): + res._collect_duplicates(dupe_dict, dupe_headers) + return dupe_dict, dupe_headers + + def detect_duplicates(self, toolchain): + """Detect all potential ambiguities in filenames and report them with + a toolchain notification + + Positional Arguments: + toolchain - used for notifications + """ + count = 0 + dupe_dict, dupe_headers = self._collect_duplicates(dict(), dict()) + for objname, filenames in dupe_dict.iteritems(): + if len(filenames) > 1: + count+=1 + toolchain.tool_error( + "Object file %s.o is not unique! It could be made from: %s"\ + % (objname, " ".join(filenames))) + for headername, locations in dupe_headers.iteritems(): + if len(locations) > 1: + count+=1 + toolchain.tool_error( + "Header file %s is not unique! It could be: %s" %\ + (headername, " ".join(locations))) + return count + + def relative_to(self, base, dot=False): for field in ['inc_dirs', 'headers', 's_sources', 'c_sources', 'cpp_sources', 'lib_dirs', 'objects', 'libraries', @@ -217,7 +254,9 @@ class mbedToolchain: __metaclass__ = ABCMeta - def __init__(self, target, options=None, notify=None, macros=None, silent=False, extra_verbose=False): + profile_template = {'common':[], 'c':[], 'cxx':[], 'asm':[], 'ld':[]} + + def __init__(self, target, notify=None, macros=None, silent=False, extra_verbose=False, build_profile=None): self.target = target self.name = self.__class__.__name__ @@ -225,7 +264,7 @@ class mbedToolchain: self.hook = hooks.Hook(target, self) # Toolchain flags - self.flags = deepcopy(self.DEFAULT_FLAGS) + self.flags = deepcopy(build_profile or self.profile_template) # User-defined macros self.macros = macros or [] @@ -291,15 +330,6 @@ class mbedToolchain: self.output = str() self.map_outputs = list() # Place to store memmap scan results in JSON like data structures - # Build options passed by -o flag - self.options = options if options is not None else [] - - # Build options passed by settings.py or mbed_settings.py - self.options.extend(BUILD_OPTIONS) - - if self.options: - self.info("Build Options: %s" % (', '.join(self.options))) - # uVisor spepcific rules if 'UVISOR' in self.target.features and 'UVISOR_SUPPORTED' in self.target.extra_labels: self.target.core = re.sub(r"F$", '', self.target.core) @@ -434,10 +464,20 @@ class mbedToolchain: toolchain_labels = [c.__name__ for c in getmro(self.__class__)] toolchain_labels.remove('mbedToolchain') self.labels = { - 'TARGET': self.target.labels + ["DEBUG" if "debug-info" in self.options else "RELEASE"], + 'TARGET': self.target.labels, 'FEATURE': self.target.features, 'TOOLCHAIN': toolchain_labels } + + # This is a policy decision and it should /really/ be in the config system + # ATM it's here for backward compatibility + if (("-g" in self.flags['common'] and + "-O0") in self.flags['common'] or + ("-r" in self.flags['common'] and + "-On" in self.flags['common'])): + self.labels['TARGET'].append("DEBUG") + else: + self.labels['TARGET'].append("RELEASE") return self.labels @@ -757,6 +797,7 @@ class mbedToolchain: 'chroot': self.CHROOT }) else: + self.compiled += 1 objects.append(object) # Use queues/multiprocessing if cpu count is higher than setting @@ -1047,7 +1088,7 @@ class mbedToolchain: # Here we return memory statistics structure (constructed after # call to generate_output) which contains raw data in bytes # about sections + summary - return memap.mem_summary + return memap.mem_report # Set the configuration data def set_config_data(self, config_data): diff --git a/tools/toolchains/arm.py b/tools/toolchains/arm.py index f294edb5f5..5eb5387187 100644 --- a/tools/toolchains/arm.py +++ b/tools/toolchains/arm.py @@ -30,20 +30,6 @@ class ARM(mbedToolchain): INDEX_PATTERN = re.compile('(?P\s*)\^') DEP_PATTERN = re.compile('\S+:\s(?P.+)\n') - - # ANY changes to these default flags is backwards incompatible and require - # an update to the mbed-sdk-tools and website that introduces a profile - # for the previous version of these flags - DEFAULT_FLAGS = { - 'common': ["-c", "--gnu", - "-Otime", "--split_sections", "--apcs=interwork", - "--brief_diagnostics", "--restrict", "--multibyte_chars"], - 'asm': [], - 'c': ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"], - 'cxx': ["--cpp", "--no_rtti", "--no_vla"], - 'ld': [], - } - @staticmethod def check_executable(): """Returns True if the executable (armcc) location specified by the @@ -51,8 +37,11 @@ class ARM(mbedToolchain): Returns False otherwise.""" return mbedToolchain.generic_check_executable("ARM", 'armcc', 2, 'bin') - def __init__(self, target, options=None, notify=None, macros=None, silent=False, extra_verbose=False): - mbedToolchain.__init__(self, target, options, notify, macros, silent, extra_verbose=extra_verbose) + def __init__(self, target, notify=None, macros=None, + silent=False, extra_verbose=False, build_profile=None): + mbedToolchain.__init__(self, target, notify, macros, silent, + extra_verbose=extra_verbose, + build_profile=build_profile) if target.core == "Cortex-M0+": cpu = "Cortex-M0" @@ -71,14 +60,6 @@ class ARM(mbedToolchain): main_cc = join(ARM_BIN, "armcc") self.flags['common'] += ["--cpu=%s" % cpu] - if "save-asm" in self.options: - self.flags['common'].extend(["--asm", "--interleave"]) - - if "debug-info" in self.options: - self.flags['common'].append("-g") - self.flags['c'].append("-O0") - else: - self.flags['c'].append("-O3") self.asm = [main_cc] + self.flags['common'] + self.flags['asm'] + ["-I \""+ARM_INC+"\""] self.cc = [main_cc] + self.flags['common'] + self.flags['c'] + ["-I \""+ARM_INC+"\""] @@ -106,6 +87,7 @@ class ARM(mbedToolchain): if match is not None: if msg is not None: self.cc_info(msg) + msg = None msg = { 'severity': match.group('severity').lower(), 'file': match.group('file'), @@ -241,8 +223,10 @@ class ARM(mbedToolchain): class ARM_STD(ARM): - def __init__(self, target, options=None, notify=None, macros=None, silent=False, extra_verbose=False): - ARM.__init__(self, target, options, notify, macros, silent, extra_verbose=extra_verbose) + def __init__(self, target, notify=None, macros=None, + silent=False, extra_verbose=False, build_profile=None): + ARM.__init__(self, target, notify, macros, silent, + extra_verbose=extra_verbose, build_profile=build_profile) # Run-time values self.ld.extend(["--libpath", join(TOOLCHAIN_PATHS['ARM'], "lib")]) @@ -251,40 +235,10 @@ class ARM_STD(ARM): class ARM_MICRO(ARM): PATCHED_LIBRARY = False - def __init__(self, target, options=None, notify=None, macros=None, silent=False, extra_verbose=False): - ARM.__init__(self, target, options, notify, macros, silent, extra_verbose=extra_verbose) - - # Extend flags - self.flags['common'].extend(["-D__MICROLIB"]) - self.flags['c'].extend(["--library_type=microlib"]) - self.flags['ld'].extend(["--library_type=microlib"]) + def __init__(self, target, notify=None, macros=None, + silent=False, extra_verbose=False, build_profile=None): + ARM.__init__(self, target, notify, macros, silent, + extra_verbose=extra_verbose, build_profile=build_profile) # Run-time values - self.asm += ["-D__MICROLIB"] - self.cc += ["-D__MICROLIB", "--library_type=microlib"] - self.cppc += ["-D__MICROLIB", "--library_type=microlib"] - self.ld += ["--library_type=microlib"] - - # Only allow a single thread - self.cc += ["-DMBED_RTOS_SINGLE_THREAD"] - self.cppc += ["-DMBED_RTOS_SINGLE_THREAD"] - - # We had to patch microlib to add C++ support - # In later releases this patch should have entered mainline - if ARM_MICRO.PATCHED_LIBRARY: - # Run-time values - self.flags['ld'].extend(["--noscanlib"]) - # Run-time values - self.ld += ["--noscanlib"] - - # System Libraries - self.sys_libs.extend([join(TOOLCHAIN_PATHS['ARM'], "lib", "microlib", lib+".l") for lib in ["mc_p", "mf_p", "m_ps"]]) - - if target.core == "Cortex-M3": - self.sys_libs.extend([join(TOOLCHAIN_PATHS['ARM'], "lib", "cpplib", lib+".l") for lib in ["cpp_ws", "cpprt_w"]]) - - elif target.core in ["Cortex-M0", "Cortex-M0+"]: - self.sys_libs.extend([join(TOOLCHAIN_PATHS['ARM'], "lib", "cpplib", lib+".l") for lib in ["cpp_ps", "cpprt_p"]]) - else: - # Run-time values - self.ld.extend(["--libpath", join(TOOLCHAIN_PATHS['ARM'], "lib")]) + self.ld.extend(["--libpath", join(TOOLCHAIN_PATHS['ARM'], "lib")]) diff --git a/tools/toolchains/gcc.py b/tools/toolchains/gcc.py index dbbe2c62bc..190f7f9f74 100644 --- a/tools/toolchains/gcc.py +++ b/tools/toolchains/gcc.py @@ -28,26 +28,12 @@ class GCC(mbedToolchain): DIAGNOSTIC_PATTERN = re.compile('((?P[^:]+):(?P\d+):)(\d+:)? (?Pwarning|error): (?P.+)') INDEX_PATTERN = re.compile('(?P\s*)\^') - # ANY changes to these default flags is backwards incompatible and require - # an update to the mbed-sdk-tools and website that introduces a profile - # for the previous version of these flags - DEFAULT_FLAGS = { - 'common': ["-c", "-Wall", "-Wextra", - "-Wno-unused-parameter", "-Wno-missing-field-initializers", - "-fmessage-length=0", "-fno-exceptions", "-fno-builtin", - "-ffunction-sections", "-fdata-sections", "-funsigned-char", - "-MMD", "-fno-delete-null-pointer-checks", "-fomit-frame-pointer" - ], - 'asm': ["-x", "assembler-with-cpp"], - 'c': ["-std=gnu99"], - 'cxx': ["-std=gnu++98", "-fno-rtti", "-Wvla"], - 'ld': ["-Wl,--gc-sections", "-Wl,--wrap,main", - "-Wl,--wrap,_malloc_r", "-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", "-Wl,--wrap,_calloc_r", - "-Wl,--wrap,exit", "-Wl,--wrap,atexit"], - } - - def __init__(self, target, options=None, notify=None, macros=None, silent=False, tool_path="", extra_verbose=False): - mbedToolchain.__init__(self, target, options, notify, macros, silent, extra_verbose=extra_verbose) + def __init__(self, target, notify=None, macros=None, + silent=False, tool_path="", extra_verbose=False, + build_profile=None): + mbedToolchain.__init__(self, target, notify, macros, silent, + extra_verbose=extra_verbose, + build_profile=build_profile) if target.core == "Cortex-M0+": cpu = "cortex-m0plus" @@ -75,8 +61,6 @@ class GCC(mbedToolchain): self.cpu.append("-mfpu=fpv5-d16") self.cpu.append("-mfloat-abi=softfp") - - if target.core == "Cortex-A9": self.cpu.append("-mthumb-interwork") self.cpu.append("-marm") @@ -85,20 +69,8 @@ class GCC(mbedToolchain): self.cpu.append("-mfloat-abi=hard") self.cpu.append("-mno-unaligned-access") - - # Note: We are using "-O2" instead of "-Os" to avoid this known GCC bug: - # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46762 self.flags["common"] += self.cpu - if "save-asm" in self.options: - self.flags["common"].append("-save-temps") - - if "debug-info" in self.options: - self.flags["common"].append("-g") - self.flags["common"].append("-O0") - else: - self.flags["common"].append("-Os") - main_cc = join(tool_path, "arm-none-eabi-gcc") main_cppc = join(tool_path, "arm-none-eabi-g++") self.asm = [main_cc] + self.flags['asm'] + self.flags["common"] @@ -146,6 +118,7 @@ class GCC(mbedToolchain): if match is not None: if msg is not None: self.cc_info(msg) + msg = None msg = { 'severity': match.group('severity').lower(), 'file': match.group('file'), @@ -166,6 +139,9 @@ class GCC(mbedToolchain): else: msg['text'] += line+"\n" + if msg is not None: + self.cc_info(msg) + def get_dep_option(self, object): base, _ = splitext(object) dep_path = base + '.d' @@ -280,27 +256,12 @@ class GCC_ARM(GCC): Returns False otherwise.""" return mbedToolchain.generic_check_executable("GCC_ARM", 'arm-none-eabi-gcc', 1) - def __init__(self, target, options=None, notify=None, macros=None, silent=False, extra_verbose=False): - GCC.__init__(self, target, options, notify, macros, silent, TOOLCHAIN_PATHS['GCC_ARM'], extra_verbose=extra_verbose) + def __init__(self, target, notify=None, macros=None, + silent=False, extra_verbose=False, build_profile=None): + GCC.__init__(self, target, notify, macros, silent, + TOOLCHAIN_PATHS['GCC_ARM'], extra_verbose=extra_verbose, + build_profile=build_profile) - # Use latest gcc nanolib - if "std-lib" in self.options: - use_nano = False - elif "small-lib" in self.options: - use_nano = True - elif target.default_lib == "std": - use_nano = False - elif target.default_lib == "small": - use_nano = True - else: - use_nano = False - - if use_nano: - self.ld.append("--specs=nano.specs") - self.flags['ld'].append("--specs=nano.specs") - self.cc += ["-DMBED_RTOS_SINGLE_THREAD"] - self.cppc += ["-DMBED_RTOS_SINGLE_THREAD"] - self.macros.extend(["MBED_RTOS_SINGLE_THREAD"]) self.sys_libs.append("nosys") @@ -312,8 +273,11 @@ class GCC_CR(GCC): Returns False otherwise.""" return mbedToolchain.generic_check_executable("GCC_CR", 'arm-none-eabi-gcc', 1) - def __init__(self, target, options=None, notify=None, macros=None, silent=False, extra_verbose=False): - GCC.__init__(self, target, options, notify, macros, silent, TOOLCHAIN_PATHS['GCC_CR'], extra_verbose=extra_verbose) + def __init__(self, target, notify=None, macros=None, + silent=False, extra_verbose=False, build_profile=None): + GCC.__init__(self, target, notify, macros, silent, + TOOLCHAIN_PATHS['GCC_CR'], extra_verbose=extra_verbose, + build_profile=build_profile) additional_compiler_flags = [ "-D__NEWLIB__", "-D__CODE_RED", "-D__USE_CMSIS", "-DCPP_USE_HEAP", diff --git a/tools/toolchains/iar.py b/tools/toolchains/iar.py index b712c2a158..46ada3a703 100644 --- a/tools/toolchains/iar.py +++ b/tools/toolchains/iar.py @@ -29,24 +29,6 @@ class IAR(mbedToolchain): DIAGNOSTIC_PATTERN = re.compile('"(?P[^"]+)",(?P[\d]+)\s+(?PWarning|Error)(?P.+)') INDEX_PATTERN = re.compile('(?P\s*)\^') - # ANY changes to these default flags is backwards incompatible and require - # an update to the mbed-sdk-tools and website that introduces a profile - # for the previous version of these flags - DEFAULT_FLAGS = { - 'common': [ - "--no_wrap_diagnostics", - # Pa050: No need to be notified about "non-native end of line sequence" - # Pa084: Pointless integer comparison -> checks for the values of an enum, but we use values outside of the enum to notify errors (ie: NC). - # Pa093: Implicit conversion from float to integer (ie: wait_ms(85.4) -> wait_ms(85)) - # Pa082: Operation involving two values from two registers (ie: (float)(*obj->MR)/(float)(LPC_PWM1->MR0)) - "-e", # Enable IAR language extension - "--diag_suppress=Pa050,Pa084,Pa093,Pa082"], - 'asm': [], - 'c': ["--vla"], - 'cxx': ["--guard_calls", "--no_static_destruction"], - 'ld': ["--skip_dynamic_initialization", "--threaded_lib"], - } - @staticmethod def check_executable(): """Returns True if the executable (arm-none-eabi-gcc) location @@ -54,8 +36,11 @@ class IAR(mbedToolchain): Returns False otherwise.""" return mbedToolchain.generic_check_executable("IAR", 'iccarm', 2, "bin") - def __init__(self, target, options=None, notify=None, macros=None, silent=False, extra_verbose=False): - mbedToolchain.__init__(self, target, options, notify, macros, silent, extra_verbose=extra_verbose) + def __init__(self, target, notify=None, macros=None, + silent=False, extra_verbose=False, build_profile=None): + mbedToolchain.__init__(self, target, notify, macros, silent, + extra_verbose=extra_verbose, + build_profile=build_profile) if target.core == "Cortex-M7F" or target.core == "Cortex-M7FD": cpuchoice = "Cortex-M7" else: @@ -94,12 +79,6 @@ class IAR(mbedToolchain): asm_flags_cmd += ["--fpu", "VFPv5_sp"] c_flags_cmd.append("--fpu=VFPv5_sp") - if "debug-info" in self.options: - c_flags_cmd.append("-r") - c_flags_cmd.append("-On") - else: - c_flags_cmd.append("-Oh") - IAR_BIN = join(TOOLCHAIN_PATHS['IAR'], "bin") main_cc = join(IAR_BIN, "iccarm") @@ -123,6 +102,7 @@ class IAR(mbedToolchain): if match is not None: if msg is not None: self.cc_info(msg) + msg = None msg = { 'severity': match.group('severity').lower(), 'file': match.group('file'), @@ -143,6 +123,9 @@ class IAR(mbedToolchain): else: msg['text'] += line+"\n" + if msg is not None: + self.cc_info(msg) + def get_dep_option(self, object): base, _ = splitext(object) dep_path = base + '.d'