diff --git a/.travis.yml b/.travis.yml index 0738cdf0b56..0bd0e8a1855 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ python: - "2.7" - +group: deprecated-2017Q3 script: - mkdir BUILD # Assert that the Doxygen build produced no warnings. @@ -19,14 +19,13 @@ script: - | find -name "*.s" | tee BUILD/badasm | sed -e "s/^/Bad Assembler file name found: /" && [ ! -s BUILD/badasm ] - make -C events/equeue test clean - - PYTHONPATH=. python tools/test/config_test/config_test.py - - PYTHONPATH=. python tools/test/build_api/build_api_test.py - - PYTHONPATH=. python tools/test/targets/target_test.py - - python tools/test/pylint.py - - py.test tools/test/toolchains/api.py - - python tools/test/memap/memap_test.py - - python tools/project.py -S - - python tools/build_travis.py + - PYTHONPATH=. coverage run -a -m pytest tools/test + - python2 tools/test/pylint.py + - coverage run -a tools/project.py -S + - python2 tools/build_travis.py + - coverage html +after_success: + - coveralls before_install: - sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa - sudo add-apt-repository -y ppa:libreoffice/libreoffice-4-2 @@ -42,3 +41,5 @@ install: - pip install pylint - pip install hypothesis - pip install mock + - pip install coverage + - pip install coveralls diff --git a/README.md b/README.md index 3f1be0c06d0..ee51e5fd6e1 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ We run continuous integration on all of our branches and pull requests to verify - Master branch [![Master Branch CI Badge](https://travis-ci.org/ARMmbed/mbed-os.svg?branch=master)](https://travis-ci.org/ARMmbed/mbed-os) - Latest release [![Latest Tag CI Badge](https://travis-ci.org/ARMmbed/mbed-os.svg?branch=latest)](https://travis-ci.org/ARMmbed/mbed-os/branches) +Tools coverage [![Coverage Status](https://coveralls.io/repos/github/ARMmbed/mbed-os/badge.svg?branch=master)](https://coveralls.io/github/ARMmbed/mbed-os?branch=master) + ## Getting Started for Developers You need [mbed CLI](https://github.com/ARMmbed/mbed-cli) to build mbed OS. For more details, read the [mbed OS Handbook](https://docs.mbed.com/docs/mbed-os-handbook/en/latest/). diff --git a/TESTS/mbedmicro-rtos-mbed/mail/main.cpp b/TESTS/mbedmicro-rtos-mbed/mail/main.cpp index dada44f4960..3332de41e10 100644 --- a/TESTS/mbedmicro-rtos-mbed/mail/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/mail/main.cpp @@ -15,69 +15,472 @@ */ #include "mbed.h" #include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" #include "rtos.h" #if defined(MBED_RTOS_SINGLE_THREAD) #error [NOT_SUPPORTED] test not supported #endif +using namespace utest::v1; + +#define THREAD_STACK_SIZE 384 /* larger stack cause out of memory on some 16kB RAM boards in multi thread test*/ +#define QUEUE_SIZE 16 +#define THREAD_1_ID 1 +#define THREAD_2_ID 2 +#define THREAD_3_ID 3 +#define QUEUE_PUT_DELAY_1 5 +#define QUEUE_PUT_DELAY_2 50 +#define QUEUE_PUT_DELAY_3 100 +#define DATA_BASE 100 + + typedef struct { - float voltage; /* AD result of measured voltage */ - float current; /* AD result of measured current */ - uint32_t counter; /* A counter value */ + uint16_t data; + uint8_t thread_id; } mail_t; -#define CREATE_VOLTAGE(COUNTER) (COUNTER * 0.1) * 33 -#define CREATE_CURRENT(COUNTER) (COUNTER * 0.1) * 11 -#define QUEUE_SIZE 16 -#define QUEUE_PUT_DELAY 100 - -#define STACK_SIZE 1024 - -Mail mail_box; - -void send_thread () { - static uint32_t i = 10; - while (true) { - i++; // fake data update - mail_t *mail = mail_box.alloc(); - mail->voltage = CREATE_VOLTAGE(i); - mail->current = CREATE_CURRENT(i); - mail->counter = i; - mail_box.put(mail); - Thread::wait(QUEUE_PUT_DELAY); + +template +void send_thread(Mail *m) +{ + uint32_t data = thread_id * DATA_BASE; + + for (uint32_t i = 0; i < send_count; i++) { + mail_t *mail = m->alloc(); + mail->thread_id = thread_id; + mail->data = data++; + m->put(mail); + Thread::wait(wait_ms); } } -int main (void) { - GREENTEA_SETUP(20, "default_auto"); +template +void receive_thread(Mail *m) +{ + int result_counter = 0; + uint32_t data = thread_id * DATA_BASE; + + Thread::wait(wait_ms); + for (uint32_t i = 0; i < queue_size; i++) { + osEvent evt = m->get(); + if (evt.status == osEventMail) { + mail_t *mail = (mail_t*)evt.value.p; + const uint8_t id = mail->thread_id; - Thread thread(osPriorityNormal, STACK_SIZE); - thread.start(send_thread); - bool result = true; + // verify thread id + TEST_ASSERT_TRUE(id == thread_id); + // verify sent data + TEST_ASSERT_TRUE(mail->data == data++); + + m->free(mail); + result_counter++; + } + } + TEST_ASSERT_EQUAL(queue_size, result_counter); +} + +/** Test single thread Mail usage and order + + Given mailbox and one additional thread + When messages are put in to the Mail box by this thread + Then messages are received in main thread in the same order as was sent and the data sent is valid + */ +void test_single_thread_order(void) +{ + uint16_t data = DATA_BASE; int result_counter = 0; + Mail mail_box; + + // mail send thread creation + Thread thread(osPriorityNormal, THREAD_STACK_SIZE); + thread.start(callback(send_thread, &mail_box)); - while (true) { + // wait for some mail to be collected + Thread::wait(10); + + for (uint32_t i = 0; i < QUEUE_SIZE; i++) { + // mail receive (main thread) osEvent evt = mail_box.get(); if (evt.status == osEventMail) { mail_t *mail = (mail_t*)evt.value.p; - const float expected_voltage = CREATE_VOLTAGE(mail->counter); - const float expected_current = CREATE_CURRENT(mail->counter); - // Check using macros if received values correspond to values sent via queue - bool expected_values = (expected_voltage == mail->voltage) && - (expected_current == mail->current); - result = result && expected_values; - const char *result_msg = expected_values ? "OK" : "FAIL"; - printf("%3d %.2fV %.2fA ... [%s]\r\n", mail->counter, - mail->voltage, - mail->current, - result_msg); + const uint8_t id = mail->thread_id; + + // verify thread id + TEST_ASSERT_TRUE(id == THREAD_1_ID); + // verify sent data + TEST_ASSERT_TRUE(mail->data == data++); mail_box.free(mail); - if (result == false || ++result_counter == QUEUE_SIZE) { - break; - } + + result_counter++; } } - GREENTEA_TESTSUITE_RESULT(result); - return 0; + TEST_ASSERT_EQUAL(QUEUE_SIZE, result_counter); +} + +/** Test multi thread Mail usage and order + + Given mailbox and three additional threads + When messages are put in to the Mail box by these threads + Then messages are received in main thread in the same per thread order as was sent and the data sent is valid + */ +void test_multi_thread_order(void) +{ + uint16_t data[4] = { 0, DATA_BASE, DATA_BASE * 2, DATA_BASE * 3 }; + int result_counter = 0; + Mail mail_box; + + // mail send threads creation + Thread thread1(osPriorityNormal, THREAD_STACK_SIZE); + Thread thread2(osPriorityNormal, THREAD_STACK_SIZE); + Thread thread3(osPriorityNormal, THREAD_STACK_SIZE); + thread1.start(callback(send_thread, &mail_box)); + thread2.start(callback(send_thread, &mail_box)); + thread3.start(callback(send_thread, &mail_box)); + + // wait for some mail to be collected + Thread::wait(10); + + for (uint32_t i = 0; i < QUEUE_SIZE; i++) { + // mail receive (main thread) + osEvent evt = mail_box.get(); + if (evt.status == osEventMail) { + mail_t *mail = (mail_t*)evt.value.p; + const uint8_t id = mail->thread_id; + + // verify thread id + TEST_ASSERT_TRUE((id == THREAD_1_ID) || (id == THREAD_2_ID) || (id == THREAD_3_ID)); + // verify sent data + TEST_ASSERT_TRUE(mail->data == data[id]++); + mail_box.free(mail); + + result_counter++; + } + } + TEST_ASSERT_EQUAL(QUEUE_SIZE, result_counter); +} + +/** Test multi thread multi Mail usage and order + + Given 3 mailbox and three additional threads + When messages are put in to the mail boxes by main thread + Then messages are received by threads in the same per mail box order as was sent and the data sent is valid + */ +void test_multi_thread_multi_mail_order(void) +{ + Mail mail_box[4]; /* mail_box[0] not used */ + uint16_t data[4] = { 0, DATA_BASE, DATA_BASE * 2, DATA_BASE * 3 }; + mail_t *mail; + uint8_t id; + + // mail receive threads creation + Thread thread1(osPriorityNormal, THREAD_STACK_SIZE); + Thread thread2(osPriorityNormal, THREAD_STACK_SIZE); + Thread thread3(osPriorityNormal, THREAD_STACK_SIZE); + thread1.start(callback(receive_thread, mail_box + 1)); + thread2.start(callback(receive_thread, mail_box + 2)); + thread3.start(callback(receive_thread, mail_box + 3)); + + for (uint32_t i = 0; i < 4; i++) { + id = THREAD_1_ID; + mail = mail_box[id].alloc(); + mail->thread_id = id; + mail->data = data[id]++; + mail_box[id].put(mail); + + id = THREAD_2_ID; + mail = mail_box[id].alloc(); + mail->thread_id = id; + mail->data = data[id]++; + mail_box[id].put(mail); + + id = THREAD_3_ID; + mail = mail_box[id].alloc(); + mail->thread_id = id; + mail->data = data[id]++; + mail_box[id].put(mail); + + Thread::wait(i * 10); + } + + thread1.join(); + thread2.join(); + thread3.join(); +} + +/** Test message memory deallocation with block out of the scope + + Given an empty mailbox + When try to free out of the scope memory block + Then it return appropriate error code + */ +void test_free_wrong() +{ + osStatus status; + Mail mail_box; + uint32_t *mail, data; + + mail = &data; + status = mail_box.free(mail); + TEST_ASSERT_EQUAL(osErrorParameter, status); + + mail = mail_box.alloc(); + TEST_ASSERT_NOT_EQUAL(NULL, mail); + + mail = &data; + status = mail_box.free(mail); + TEST_ASSERT_EQUAL(osErrorParameter, status); +} + +/** Test message memory deallocation with null block + + Given an empty mailbox + When try to free null ptr + Then it return appropriate error code + */ +void test_free_null() +{ + osStatus status; + Mail mail_box; + uint32_t *mail; + + mail = NULL; + status = mail_box.free(mail); + TEST_ASSERT_EQUAL(osErrorParameter, status); + + mail = mail_box.alloc(); + TEST_ASSERT_NOT_EQUAL(NULL, mail); + + mail = NULL; + status = mail_box.free(mail); + TEST_ASSERT_EQUAL(osErrorParameter, status); +} + +/** Test same message memory deallocation twice + + Given an empty mailbox + Then allocate message memory + When try to free it second time + Then it return appropriate error code + */ +void test_free_twice() +{ + osStatus status; + Mail mail_box; + + uint32_t *mail = mail_box.alloc(); + TEST_ASSERT_NOT_EQUAL(NULL, mail); + + status = mail_box.free(mail); + TEST_ASSERT_EQUAL(osOK, status); + + status = mail_box.free(mail); + TEST_ASSERT_EQUAL(osErrorResource, status); +} + +/** Test get from empty mailbox with timeout set + + Given an empty mailbox + When @a get is called on the mailbox with timeout of 50 + Then mailbox returns status of osOK, but no data after specified amount of time + */ +void test_get_empty_timeout() +{ + Mail mail_box; + Timer timer; + + timer.start(); + osEvent evt = mail_box.get(50); + TEST_ASSERT_UINT32_WITHIN(5000, 50000, timer.read_us()); + TEST_ASSERT_EQUAL(osEventTimeout, evt.status); +} + +/** Test get from empty mailbox with 0 timeout + + Given an empty mailbox + When @a get is called on the mailbox with timeout of 0 + Then mailbox returns status of osOK, but no data + */ +void test_get_empty_no_timeout() +{ + Mail mail_box; + + osEvent evt = mail_box.get(0); + TEST_ASSERT_EQUAL(osOK, evt.status); +} + +/** Test mail order + + Given an mailbox for uint32_t values + Then allocate two mails and put them in to mailbox + When call @a get it returns previously put mails + Then mails should be in the same order as put + */ +void test_order(void) +{ + osStatus status; + osEvent evt; + Mail mail_box; + const int32_t TEST_VAL1 = 123; + const int32_t TEST_VAL2 = 456; + + int32_t *mail1 = mail_box.alloc(); + TEST_ASSERT_NOT_EQUAL(NULL, mail1); + + *mail1 = TEST_VAL1; + status = mail_box.put(mail1); + TEST_ASSERT_EQUAL(osOK, status); + + int32_t *mail2 = mail_box.alloc(); + TEST_ASSERT_NOT_EQUAL(NULL, mail2); + + *mail2 = TEST_VAL2; + status = mail_box.put(mail2); + TEST_ASSERT_EQUAL(osOK, status); + + + evt = mail_box.get(); + TEST_ASSERT_EQUAL(evt.status, osEventMail); + + mail1 = (int32_t*)evt.value.p; + TEST_ASSERT_EQUAL(TEST_VAL1, *mail1); + + evt = mail_box.get(); + TEST_ASSERT_EQUAL(evt.status, osEventMail); + + mail2 = (int32_t*)evt.value.p; + TEST_ASSERT_EQUAL(TEST_VAL2, *mail2); + + + status = mail_box.free(mail1); + TEST_ASSERT_EQUAL(osOK, status); + + status = mail_box.free(mail2); + TEST_ASSERT_EQUAL(osOK, status); +} + +/** Test Mail box max size limit + + Given an Mail box with max size of 4 elements + When call @a alloc four times it returns memory blocks + Then the memory blocks should be valid + When call @a alloc one more time it returns memory blocks + Then the memory blocks should be not valid (NULL - no memory available) + */ +void test_max_size() +{ + osStatus status; + Mail mail_box; + const uint32_t TEST_VAL = 123; + + // 1 OK + uint32_t *mail1 = mail_box.alloc(); + TEST_ASSERT_NOT_EQUAL(NULL, mail1); + + // 2 OK + uint32_t *mail2 = mail_box.alloc(); + TEST_ASSERT_NOT_EQUAL(NULL, mail2); + + // 3 OK + uint32_t *mail3 = mail_box.alloc(); + TEST_ASSERT_NOT_EQUAL(NULL, mail3); + + // 4 OK + uint32_t *mail4 = mail_box.alloc(); + TEST_ASSERT_NOT_EQUAL(NULL, mail4); + + // 5 KO + uint32_t *mail5 = mail_box.alloc(); + TEST_ASSERT_EQUAL(NULL, mail5); + + + status = mail_box.free(mail1); + TEST_ASSERT_EQUAL(osOK, status); + + status = mail_box.free(mail2); + TEST_ASSERT_EQUAL(osOK, status); + + status = mail_box.free(mail3); + TEST_ASSERT_EQUAL(osOK, status); + + status = mail_box.free(mail4); + TEST_ASSERT_EQUAL(osOK, status); +} + +/** Test mailbox of T type data + + Given an mailbox with T memory block type + When allocate/put/get/free memory block + Then all operations should succeed + */ +template +void test_data_type(void) +{ + osStatus status; + Mail mail_box; + const T TEST_VAL = 123; + + T *mail = mail_box.alloc(); + TEST_ASSERT_NOT_EQUAL(NULL, mail); + + *mail = TEST_VAL; + status = mail_box.put(mail); + TEST_ASSERT_EQUAL(osOK, status); + + osEvent evt = mail_box.get(); + TEST_ASSERT_EQUAL(evt.status, osEventMail); + + mail = (T*)evt.value.p; + TEST_ASSERT_EQUAL(TEST_VAL, *mail); + + + status = mail_box.free(mail); + TEST_ASSERT_EQUAL(osOK, status); +} + +/** Test calloc - memory block allocation with resetting + + Given an empty Mail box + When call @a calloc it returns allocated memory block + Then the memory block should be valid and filled with zeros + */ +void test_calloc() +{ + Mail mail_box; + + uint32_t *mail = mail_box.calloc(); + TEST_ASSERT_NOT_EQUAL(NULL, mail); + TEST_ASSERT_EQUAL(0, *mail); +} + + +utest::v1::status_t test_setup(const size_t number_of_cases) +{ + GREENTEA_SETUP(10, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +Case cases[] = { + Case("Test calloc", test_calloc), + Case("Test message type uint8", test_data_type), + Case("Test message type uint16", test_data_type), + Case("Test message type uint32", test_data_type), + Case("Test mailbox max size", test_max_size), + Case("Test message send order", test_order), + Case("Test get with timeout on empty mailbox", test_get_empty_timeout), + Case("Test get without timeout on empty mailbox", test_get_empty_no_timeout), + Case("Test message free twice", test_free_twice), + Case("Test null message free", test_free_null), + Case("Test invalid message free", test_free_wrong), + Case("Test message send/receive single thread and order", test_single_thread_order), + Case("Test message send/receive multi-thread and per thread order", test_multi_thread_order), + Case("Test message send/receive multi-thread, multi-Mail and per thread order", test_multi_thread_multi_mail_order) +}; + +Specification specification(test_setup, cases); + +int main() +{ + return !Harness::run(specification); } diff --git a/events/equeue/equeue_platform.h b/events/equeue/equeue_platform.h index 5a16e07e197..9c5bec289d3 100644 --- a/events/equeue/equeue_platform.h +++ b/events/equeue/equeue_platform.h @@ -51,7 +51,7 @@ extern "C" { #include #elif defined(EQUEUE_PLATFORM_MBED) #include "cmsis_os2.h" -#include "rtx_lib.h" +#include "mbed_rtos_storage.h" #endif @@ -117,7 +117,7 @@ typedef struct equeue_sema { #elif defined(EQUEUE_PLATFORM_MBED) && defined(MBED_CONF_RTOS_PRESENT) typedef struct equeue_sema { osEventFlagsId_t id; - os_event_flags_t mem; + mbed_rtos_storage_event_flags_t mem; } equeue_sema_t; #elif defined(EQUEUE_PLATFORM_MBED) typedef volatile int equeue_sema_t; diff --git a/features/FEATURE_BLE/ble/BLE.h b/features/FEATURE_BLE/ble/BLE.h index c4471ed0802..9cd27f58ef6 100644 --- a/features/FEATURE_BLE/ble/BLE.h +++ b/features/FEATURE_BLE/ble/BLE.h @@ -798,7 +798,7 @@ class BLE * @param connectionParams * Connection parameters. * @param scanParams - * Paramters to use while scanning for the peer. + * Parameters to use while scanning for the peer. * @return BLE_ERROR_NONE if connection establishment procedure is started * successfully. The onConnection callback (if set) is invoked upon * a connection event. diff --git a/features/FEATURE_BLE/ble/BLEProtocol.h b/features/FEATURE_BLE/ble/BLEProtocol.h index 83e33403ae7..bcfb08765a5 100644 --- a/features/FEATURE_BLE/ble/BLEProtocol.h +++ b/features/FEATURE_BLE/ble/BLEProtocol.h @@ -25,7 +25,7 @@ * A common namespace for types and constants used everywhere in BLE API. */ namespace BLEProtocol { - /**< + /** * A simple container for the enumeration of address-types for Protocol addresses. * * Adding a struct to encapsulate the contained enumeration prevents @@ -37,7 +37,7 @@ namespace BLEProtocol { * would allow the use of AliasedType::PUBLIC in code. */ struct AddressType { - /**< Address-types for Protocol addresses. */ + /** Address-types for Protocol addresses. */ enum Type { PUBLIC = 0, RANDOM_STATIC, diff --git a/features/FEATURE_BLE/ble/Gap.h b/features/FEATURE_BLE/ble/Gap.h index 6da37773d4a..5a01e4e9a4b 100644 --- a/features/FEATURE_BLE/ble/Gap.h +++ b/features/FEATURE_BLE/ble/Gap.h @@ -56,7 +56,7 @@ class Gap { * * @deprecated Use BLEProtocol::AddressType_t instead. The following * constants have been left in their deprecated state to - * transparenly support existing applications which may have + * transparently support existing applications which may have * used Gap::ADDR_TYPE_*. */ enum DeprecatedAddressType_t { @@ -320,7 +320,7 @@ class Gap { /** * Type for the registered callbacks added to the disconnection event - * callchain. Refer to Gap::onDisconnetion(). + * callchain. Refer to Gap::onDisconnection(). */ typedef FunctionPointerWithContext DisconnectionEventCallback_t; /** @@ -447,7 +447,7 @@ class Gap { * @param[in] connectionParams * Connection parameters. * @param[in] scanParams - * Paramters to be used while scanning for the peer. + * Parameters to be used while scanning for the peer. * * @return BLE_ERROR_NONE if connection establishment procedure is started * successfully. The connectionCallChain (if set) will be invoked upon @@ -516,7 +516,7 @@ class Gap { * * @deprecated This version of disconnect() doesn't take a connection handle. It * works reliably only for stacks that are limited to a single - * connection. Use instead Gap::disconnect(Handle_t connectionHandle, + * connection. Use Gap::disconnect(Handle_t connectionHandle, * DisconnectionReason_t reason) instead. */ virtual ble_error_t disconnect(DisconnectionReason_t reason) { diff --git a/features/FEATURE_BLE/ble/GapAdvertisingParams.h b/features/FEATURE_BLE/ble/GapAdvertisingParams.h index c212dd35f18..a1938268183 100644 --- a/features/FEATURE_BLE/ble/GapAdvertisingParams.h +++ b/features/FEATURE_BLE/ble/GapAdvertisingParams.h @@ -160,7 +160,7 @@ class GapAdvertisingParams { } /** - * Get The advertising timeout. + * Get the advertising timeout. * * @return The advertising timeout (in seconds). */ diff --git a/features/FEATURE_BLE/ble/GattCallbackParamTypes.h b/features/FEATURE_BLE/ble/GattCallbackParamTypes.h index 07eab8d8c94..40c1e61dd67 100644 --- a/features/FEATURE_BLE/ble/GattCallbackParamTypes.h +++ b/features/FEATURE_BLE/ble/GattCallbackParamTypes.h @@ -31,7 +31,7 @@ struct GattWriteCallbackParams { OP_EXEC_WRITE_REQ_NOW = 0x06, /**< Execute write request: immediately execute all prepared writes. */ }; - Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event */ + Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event. */ GattAttribute::Handle_t handle; /**< Attribute Handle to which the write operation applies. */ WriteOp_t writeOp; /**< Type of write operation. */ uint16_t offset; /**< Offset for the write operation. */ @@ -46,7 +46,7 @@ struct GattWriteCallbackParams { }; struct GattReadCallbackParams { - Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event */ + Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event. */ GattAttribute::Handle_t handle; /**< Attribute Handle to which the read operation applies. */ uint16_t offset; /**< Offset for the read operation. */ uint16_t len; /**< Length (in bytes) of the data to read. */ @@ -75,7 +75,7 @@ enum GattAuthCallbackReply_t { }; struct GattWriteAuthCallbackParams { - Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event */ + Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event. */ GattAttribute::Handle_t handle; /**< Attribute Handle to which the write operation applies. */ uint16_t offset; /**< Offset for the write operation. */ uint16_t len; /**< Length of the incoming data. */ @@ -88,7 +88,7 @@ struct GattWriteAuthCallbackParams { }; struct GattReadAuthCallbackParams { - Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event */ + Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event. */ GattAttribute::Handle_t handle; /**< Attribute Handle to which the read operation applies. */ uint16_t offset; /**< Offset for the read operation. */ uint16_t len; /**< Optional: new length of the outgoing data. */ @@ -105,7 +105,7 @@ struct GattReadAuthCallbackParams { * generated at the remote server. */ struct GattHVXCallbackParams { - Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event */ + Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event. */ GattAttribute::Handle_t handle; /**< Attribute Handle to which the HVx operation applies. */ HVXType_t type; /**< Indication or Notification, see HVXType_t. */ uint16_t len; /**< Attribute data length. */ diff --git a/features/FEATURE_BLE/ble/GattCharacteristic.h b/features/FEATURE_BLE/ble/GattCharacteristic.h index f5f3c460f59..c21d99111b7 100644 --- a/features/FEATURE_BLE/ble/GattCharacteristic.h +++ b/features/FEATURE_BLE/ble/GattCharacteristic.h @@ -395,7 +395,7 @@ class GattCharacteristic { /** * Set up callback that will be triggered before the GATT Client is allowed * to read this characteristic. The handler will determine the - * authorizaion reply for the read. + * authorization reply for the read. * * @param[in] callback * Event handler being registered. @@ -457,7 +457,8 @@ class GattCharacteristic { * is granted. * * @note To authorize or deny the read the params->authorizationReply field - * should be set to true (authorize) or false (deny). + * should be set to AUTH_CALLBACK_REPLY_SUCCESS (authorize) or any + * of the AUTH_CALLBACK_REPLY_ATTERR_* values (deny). * * @note If the read is approved and params->data is unchanged (NULL), * the current characteristic value will be used. @@ -507,7 +508,7 @@ class GattCharacteristic { } /** - * Get the characteristic's propertied. Refer to + * Get the characteristic's properties. Refer to * GattCharacteristic::Properties_t. * * @return The characteristic's properties. @@ -548,7 +549,7 @@ class GattCharacteristic { /** * Check whether write authorization is enabled i.e. check whether a * write authorization callback was previously registered. Refer to - * GattCharacteristic::setReadAuthorizationCallback(). + * GattCharacteristic::setWriteAuthorizationCallback(). * * @return true if write authorization is enabled, false otherwise. */ @@ -590,7 +591,7 @@ class GattCharacteristic { /** * The characteristic's descriptor attributes. * This contains only CCCDs that has neither the notify nor the indicate - * flag set, as thoses are handled by the underlying BLE stack. + * flag set, as those are handled by the underlying BLE stack. */ GattAttribute **_descriptors; /** @@ -635,9 +636,9 @@ class ReadOnlyGattCharacteristic : public GattCharacteristic { * @param[in] uuid * The characteristic's UUID. * @param[in] valuePtr - * Pointer to the characterisitic's initial value. + * Pointer to the characteristic's initial value. * @param[in] additionalProperties - * Additional characterisitic properties. By default, the + * Additional characteristic properties. By default, the * properties are set to * Properties_t::BLE_GATT_CHAR_PROPERTIES_READ. * @param[in] descriptors @@ -673,9 +674,9 @@ class WriteOnlyGattCharacteristic : public GattCharacteristic { * @param[in] uuid * The characteristic's UUID. * @param[in] valuePtr - * Pointer to the characterisitic's initial value. + * Pointer to the characteristic's initial value. * @param[in] additionalProperties - * Additional characterisitic properties. By default, the + * Additional characteristic properties. By default, the * properties are set to * Properties_t::BLE_GATT_CHAR_PROPERTIES_WRITE. * @param[in] descriptors @@ -711,9 +712,9 @@ class ReadWriteGattCharacteristic : public GattCharacteristic { * @param[in] uuid * The characteristic's UUID. * @param[in] valuePtr - * Pointer to the characterisitic's initial value. + * Pointer to the characteristic's initial value. * @param[in] additionalProperties - * Additional characterisitic properties. By default, the + * Additional characteristic properties. By default, the * properties are set to * Properties_t::BLE_GATT_CHAR_PROPERTIES_WRITE | * Properties_t::BLE_GATT_CHAR_PROPERTIES_READ. @@ -754,7 +755,7 @@ class WriteOnlyArrayGattCharacteristic : public GattCharacteristic { * Pointer to an array of length NUM_ELEMENTS containing the * characteristic's intitial value. * @param[in] additionalProperties - * Additional characterisitic properties. By default, the + * Additional characteristic properties. By default, the * properties are set to * Properties_t::BLE_GATT_CHAR_PROPERTIES_WRITE. * @param[in] descriptors @@ -794,7 +795,7 @@ class ReadOnlyArrayGattCharacteristic : public GattCharacteristic { * Pointer to an array of length NUM_ELEMENTS containing the * characteristic's intitial value. * @param[in] additionalProperties - * Additional characterisitic properties. By default, the + * Additional characteristic properties. By default, the * properties are set to * Properties_t::BLE_GATT_CHAR_PROPERTIES_READ. * @param[in] descriptors @@ -834,7 +835,7 @@ class ReadWriteArrayGattCharacteristic : public GattCharacteristic { * Pointer to an array of length NUM_ELEMENTS containing the * characteristic's intitial value. * @param[in] additionalProperties - * Additional characterisitic properties. By default, the + * Additional characteristic properties. By default, the * properties are set to * Properties_t::BLE_GATT_CHAR_PROPERTIES_WRITE | * Properties_t::BLE_GATT_CHAR_PROPERTIES_READ. diff --git a/features/FEATURE_BLE/ble/GattService.h b/features/FEATURE_BLE/ble/GattService.h index 52aa63215fc..d638b3c9167 100644 --- a/features/FEATURE_BLE/ble/GattService.h +++ b/features/FEATURE_BLE/ble/GattService.h @@ -109,7 +109,7 @@ class GattService { * @param[in] index * The index of the characteristic. * - * @return A pointer to the characterisitic at index @p index. + * @return A pointer to the characteristic at index @p index. */ GattCharacteristic *getCharacteristic(uint8_t index) { if (index >= _characteristicCount) { diff --git a/features/FEATURE_BLE/ble/services/DFUService.h b/features/FEATURE_BLE/ble/services/DFUService.h index 69a070218d2..1614a3cfd99 100644 --- a/features/FEATURE_BLE/ble/services/DFUService.h +++ b/features/FEATURE_BLE/ble/services/DFUService.h @@ -96,7 +96,7 @@ class DFUService { * chance to clean up. * * @param[in] params - * Information about the characterisitc being updated. + * Information about the characteristic being updated. */ virtual void onDataWritten(const GattWriteCallbackParams *params) { if (params->handle == controlPoint.getValueHandle()) { @@ -124,16 +124,16 @@ class DFUService { protected: BLE &ble; - /**< Writing to the control characteristic triggers the handover to DFU - * bootloader. At present, writing anything will do the trick - this needs - * to be improved. */ + /** Writing to the control characteristic triggers the handover to DFU + * bootloader. At present, writing anything will do the trick - this needs + * to be improved. */ WriteOnlyArrayGattCharacteristic controlPoint; - /**< The packet characteristic in this service doesn't do anything meaningful; - * it is only a placeholder to mimic the corresponding characteristic in the - * actual DFU service implemented by the bootloader. Without this, some - * FOTA clients might get confused, because service definitions change after - * handing control over to the bootloader. */ + /** The packet characteristic in this service doesn't do anything meaningful; + * it is only a placeholder to mimic the corresponding characteristic in the + * actual DFU service implemented by the bootloader. Without this, some + * FOTA clients might get confused, because service definitions change after + * handing control over to the bootloader. */ GattCharacteristic packet; uint8_t controlBytes[SIZEOF_CONTROL_BYTES]; diff --git a/features/FEATURE_BLE/ble/services/HeartRateService.h b/features/FEATURE_BLE/ble/services/HeartRateService.h index 1d8796a43a1..6b802bb83f0 100644 --- a/features/FEATURE_BLE/ble/services/HeartRateService.h +++ b/features/FEATURE_BLE/ble/services/HeartRateService.h @@ -112,7 +112,7 @@ class HeartRateService { * controlPoint characteristic. * * @param[in] params - * Information about the characterisitc being updated. + * Information about the characteristic being updated. */ virtual void onDataWritten(const GattWriteCallbackParams *params) { if (params->handle == controlPoint.getValueAttribute().getHandle()) { diff --git a/features/FEATURE_BLE/ble/services/LinkLossService.h b/features/FEATURE_BLE/ble/services/LinkLossService.h index e18220dec54..beb44c20525 100644 --- a/features/FEATURE_BLE/ble/services/LinkLossService.h +++ b/features/FEATURE_BLE/ble/services/LinkLossService.h @@ -78,7 +78,7 @@ class LinkLossService { * This callback allows receiving updates to the AlertLevel characteristic. * * @param[in] params - * Information about the characterisitc being updated. + * Information about the characteristic being updated. */ virtual void onDataWritten(const GattWriteCallbackParams *params) { if (params->handle == alertLevelChar.getValueHandle()) { diff --git a/features/FEATURE_BLE/ble/services/UARTService.h b/features/FEATURE_BLE/ble/services/UARTService.h index 519ef591da9..1043ddbf465 100644 --- a/features/FEATURE_BLE/ble/services/UARTService.h +++ b/features/FEATURE_BLE/ble/services/UARTService.h @@ -45,7 +45,7 @@ extern const uint8_t UARTServiceRXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID] */ class UARTService { public: - /**< Maximum length of data (in bytes) that the UART service module can transmit to the peer. */ + /** Maximum length of data (in bytes) that the UART service module can transmit to the peer. */ static const unsigned BLE_UART_SERVICE_MAX_DATA_LEN = (BLE_GATT_MTU_SIZE_DEFAULT - 3); public: diff --git a/features/FEATURE_COMMON_PAL/mbed-coap/CHANGELOG.md b/features/FEATURE_COMMON_PAL/mbed-coap/CHANGELOG.md index 15d9feb4ffb..15bd3813d1b 100644 --- a/features/FEATURE_COMMON_PAL/mbed-coap/CHANGELOG.md +++ b/features/FEATURE_COMMON_PAL/mbed-coap/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## [v4.0.10](https://github.com/ARMmbed/mbed-coap/releases/tag/v4.0.10) + +-[Full Changelog](https://github.com/ARMmbed/mbed-coap/compare/v4.0.9...v4.0.10) + + **Closed issues:** + - IOTMAC-615 Node mDS registration failure during OTA transfer + ## [v4.0.9](https://github.com/ARMmbed/mbed-coap/releases/tag/v4.0.9) -[Full Changelog](https://github.com/ARMmbed/mbed-coap/compare/v4.0.8...v4.0.9) diff --git a/features/FEATURE_COMMON_PAL/mbed-coap/module.json b/features/FEATURE_COMMON_PAL/mbed-coap/module.json index ec1ee8fb243..265a343e7a6 100644 --- a/features/FEATURE_COMMON_PAL/mbed-coap/module.json +++ b/features/FEATURE_COMMON_PAL/mbed-coap/module.json @@ -1,6 +1,6 @@ { "name": "mbed-coap", - "version": "4.0.9", + "version": "4.0.10", "description": "COAP library", "keywords": [ "coap", diff --git a/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_builder.c b/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_builder.c index 0901fd00861..4aac0d11424 100644 --- a/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_builder.c +++ b/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_builder.c @@ -59,6 +59,7 @@ sn_coap_hdr_s *sn_coap_build_response(struct coap_s *handle, sn_coap_hdr_s *coap coap_res_ptr = sn_coap_parser_alloc_message(handle); if (!coap_res_ptr) { + tr_error("sn_coap_build_response - failed to allocate message!"); return NULL; } @@ -83,6 +84,7 @@ sn_coap_hdr_s *sn_coap_build_response(struct coap_s *handle, sn_coap_hdr_s *coap coap_res_ptr->token_len = coap_packet_ptr->token_len; coap_res_ptr->token_ptr = handle->sn_coap_protocol_malloc(coap_res_ptr->token_len); if (!coap_res_ptr->token_ptr) { + tr_error("sn_coap_build_response - failed to allocate token!"); handle->sn_coap_protocol_free(coap_res_ptr); return NULL; } @@ -98,7 +100,6 @@ int16_t sn_coap_builder(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_ms int16_t sn_coap_builder_2(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_payload_size) { - tr_debug("sn_coap_builder_2"); uint8_t *base_packet_data_ptr = NULL; /* * * * Check given pointers * * * */ @@ -108,8 +109,8 @@ int16_t sn_coap_builder_2(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_ /* Initialize given Packet data memory area with zero values */ uint16_t dst_byte_count_to_be_built = sn_coap_builder_calc_needed_packet_data_size_2(src_coap_msg_ptr, blockwise_payload_size); - tr_debug("sn_coap_builder_2 - message len: [%d]", dst_byte_count_to_be_built); if (!dst_byte_count_to_be_built) { + tr_error("sn_coap_builder_2 - failed to allocate message!"); return -1; } @@ -123,6 +124,7 @@ int16_t sn_coap_builder_2(uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_ /* * * * * * * * * * * * * * * * * * */ if (sn_coap_builder_header_build(&dst_packet_data_ptr, src_coap_msg_ptr) != 0) { /* Header building failed */ + tr_error("sn_coap_builder_2 - header building failed!"); return -1; } @@ -149,7 +151,6 @@ uint16_t sn_coap_builder_calc_needed_packet_data_size(sn_coap_hdr_s *src_coap_ms uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_payload_size) { (void)blockwise_payload_size; - tr_debug("sn_coap_builder_calc_needed_packet_data_size_2"); uint16_t returned_byte_count = 0; if (!src_coap_msg_ptr) { @@ -168,6 +169,7 @@ uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_ /* TOKEN - Length is 1-8 bytes */ if (src_coap_msg_ptr->token_ptr != NULL) { if (src_coap_msg_ptr->token_len > 8 || src_coap_msg_ptr->token_len < 1) { /* Check that option is not longer than defined */ + tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - token too large!"); return 0; } @@ -180,6 +182,7 @@ uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_ if (repeatable_option_size) { returned_byte_count += repeatable_option_size; } else { + tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - uri path size failed!"); return 0; } } @@ -188,6 +191,7 @@ uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_ /* CONTENT FORMAT - An integer option, up to 2 bytes */ if (src_coap_msg_ptr->content_format != COAP_CT_NONE) { if ((uint32_t) src_coap_msg_ptr->content_format > 0xffff) { + tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - content format too large!"); return 0; } @@ -198,6 +202,7 @@ uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_ /* ACCEPT - An integer option, up to 2 bytes */ if (src_coap_msg_ptr->options_list_ptr->accept != COAP_CT_NONE) { if ((uint32_t) src_coap_msg_ptr->options_list_ptr->accept > 0xffff) { + tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - accept too large!"); return 0; } @@ -222,6 +227,7 @@ uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_ } else { + tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - proxy uri too large!"); return 0; } @@ -235,6 +241,7 @@ uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_ if (repeatable_option_size) { returned_byte_count += repeatable_option_size; } else { + tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - etag too large!"); return 0; } } @@ -249,6 +256,7 @@ uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_ } else { + tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - uri host too large!"); return 0; } @@ -261,12 +269,14 @@ uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_ if (repeatable_option_size) { returned_byte_count += repeatable_option_size; } else { + tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - location path too large!"); return 0; } } /* URI PORT - An integer option, up to 2 bytes */ if (src_coap_msg_ptr->options_list_ptr->uri_port != COAP_OPTION_URI_PORT_NONE) { if ((uint32_t) src_coap_msg_ptr->options_list_ptr->uri_port > 0xffff) { + tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - uri port too large!"); return 0; } returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->uri_port, COAP_OPTION_URI_PORT, &tempInt); @@ -278,6 +288,7 @@ uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_ if (repeatable_option_size) { returned_byte_count += repeatable_option_size; } else { + tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - location query too large!"); return 0; } } @@ -295,6 +306,7 @@ uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_ if (repeatable_option_size) { returned_byte_count += repeatable_option_size; } else { + tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - observe too large!"); return 0; } } @@ -302,6 +314,7 @@ uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_ /* BLOCK 1 - An integer option, up to 3 bytes */ if (src_coap_msg_ptr->options_list_ptr->block1 != COAP_OPTION_BLOCK_NONE) { if ((uint32_t) src_coap_msg_ptr->options_list_ptr->block1 > 0xffffff) { + tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - block1 too large!"); return 0; } returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->block1, COAP_OPTION_BLOCK1, &tempInt); @@ -313,6 +326,7 @@ uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_ /* BLOCK 2 - An integer option, up to 3 bytes */ if (src_coap_msg_ptr->options_list_ptr->block2 != COAP_OPTION_BLOCK_NONE) { if ((uint32_t) src_coap_msg_ptr->options_list_ptr->block2 > 0xffffff) { + tr_error("sn_coap_builder_calc_needed_packet_data_size_2 - block2 too large!"); return 0; } returned_byte_count += sn_coap_builder_options_build_add_uint_option(NULL, src_coap_msg_ptr->options_list_ptr->block2, COAP_OPTION_BLOCK2, &tempInt); @@ -483,6 +497,7 @@ static int8_t sn_coap_builder_header_build(uint8_t **dst_packet_data_pptr, sn_co { /* * * * Check validity of Header values * * * */ if (sn_coap_header_validity_check(src_coap_msg_ptr, COAP_VERSION) != 0) { + tr_error("sn_coap_builder_header_build - header build failed!"); return -1; } @@ -526,6 +541,7 @@ static int8_t sn_coap_builder_options_build(uint8_t **dst_packet_data_pptr, sn_c /* * * * Check if Options are used at all * * * */ if (src_coap_msg_ptr->uri_path_ptr == NULL && src_coap_msg_ptr->token_ptr == NULL && src_coap_msg_ptr->content_format == COAP_CT_NONE && src_coap_msg_ptr->options_list_ptr == NULL) { + tr_error("sn_coap_builder_options_build - options not used!"); return 0; } diff --git a/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_header_check.c b/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_header_check.c index 0b48553af79..0d06e83910e 100644 --- a/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_header_check.c +++ b/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_header_check.c @@ -29,6 +29,9 @@ #include "mbed-coap/sn_coap_protocol.h" #include "sn_coap_header_internal.h" #include "sn_coap_protocol_internal.h" +#include "mbed-trace/mbed_trace.h" + +#define TRACE_GROUP "coap" /** * \fn int8_t sn_coap_header_validity_check(sn_coap_hdr_s *src_coap_msg_ptr, coap_version_e coap_version) @@ -56,6 +59,7 @@ int8_t sn_coap_header_validity_check(sn_coap_hdr_s *src_coap_msg_ptr, coap_versi case COAP_MSG_TYPE_RESET: break; /* Ok cases */ default: + tr_error("sn_coap_header_validity_check - unknown message type!"); return -1; /* Failed case */ } @@ -91,6 +95,7 @@ int8_t sn_coap_header_validity_check(sn_coap_hdr_s *src_coap_msg_ptr, coap_versi case COAP_MSG_CODE_RESPONSE_CONTINUE: break; /* Ok cases */ default: + tr_error("sn_coap_header_validity_check - unknown message code!"); return -1; /* Failed case */ } diff --git a/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_parser.c b/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_parser.c index 52a0c59355b..a8e30697abc 100644 --- a/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_parser.c +++ b/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_parser.c @@ -35,6 +35,9 @@ #include "mbed-coap/sn_coap_protocol.h" #include "sn_coap_header_internal.h" #include "sn_coap_protocol_internal.h" +#include "mbed-trace/mbed_trace.h" + +#define TRACE_GROUP "coap" /* * * * * * * * * * * * * * * * * * * * */ /* * * * LOCAL FUNCTION PROTOTYPES * * * */ /* * * * * * * * * * * * * * * * * * * * */ @@ -49,6 +52,7 @@ sn_coap_hdr_s *sn_coap_parser_init_message(sn_coap_hdr_s *coap_msg_ptr) { /* * * * Check given pointer * * * */ if (coap_msg_ptr == NULL) { + tr_error("sn_coap_parser_init_message - message null!"); return NULL; } @@ -91,6 +95,7 @@ sn_coap_options_list_s *sn_coap_parser_alloc_options(struct coap_s *handle, sn_c coap_msg_ptr->options_list_ptr = handle->sn_coap_protocol_malloc(sizeof(sn_coap_options_list_s)); if (coap_msg_ptr->options_list_ptr == NULL) { + tr_error("sn_coap_parser_alloc_options - failed to allocate options list!"); return NULL; } @@ -121,6 +126,7 @@ sn_coap_hdr_s *sn_coap_parser(struct coap_s *handle, uint16_t packet_data_len, u parsed_and_returned_coap_msg_ptr = sn_coap_parser_alloc_message(handle); if (parsed_and_returned_coap_msg_ptr == NULL) { + tr_error("sn_coap_parser - failed to allocate message!"); return NULL; } @@ -259,12 +265,14 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack if (dst_coap_msg_ptr->token_len) { if ((dst_coap_msg_ptr->token_len > 8) || dst_coap_msg_ptr->token_ptr) { + tr_error("sn_coap_parser_options_parse - token not valid!"); return -1; } dst_coap_msg_ptr->token_ptr = handle->sn_coap_protocol_malloc(dst_coap_msg_ptr->token_len); if (dst_coap_msg_ptr->token_ptr == NULL) { + tr_error("sn_coap_parser_options_parse - failed to allocate token!"); return -1; } @@ -293,6 +301,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack } /* Option number 15 reserved for payload marker. This is handled as a error! */ else if (option_number == 15) { + tr_error("sn_coap_parser_options_parse - invalid option number(15)!"); return -1; } @@ -310,6 +319,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack } /* Option number length 15 is reserved for the future use - ERROR */ else if (option_len == 15) { + tr_error("sn_coap_parser_options_parse - invalid option len(15)!"); return -1; } @@ -335,6 +345,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack case COAP_OPTION_SIZE1: case COAP_OPTION_SIZE2: if (sn_coap_parser_alloc_options(handle, dst_coap_msg_ptr) == NULL) { + tr_error("sn_coap_parser_options_parse - failed to allocate options!"); return -1; } break; @@ -344,6 +355,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack switch (option_number) { case COAP_OPTION_CONTENT_FORMAT: if ((option_len > 2) || (dst_coap_msg_ptr->content_format != COAP_CT_NONE)) { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_CONTENT_FORMAT not valid!"); return -1; } (*packet_data_pptr)++; @@ -352,6 +364,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack case COAP_OPTION_MAX_AGE: if (option_len > 4) { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_MAX_AGE not valid!"); return -1; } (*packet_data_pptr)++; @@ -360,6 +373,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack case COAP_OPTION_PROXY_URI: if ((option_len > 1034) || (option_len < 1) || dst_coap_msg_ptr->options_list_ptr->proxy_uri_ptr) { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_PROXY_URI not valid!"); return -1; } dst_coap_msg_ptr->options_list_ptr->proxy_uri_len = option_len; @@ -368,8 +382,10 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack dst_coap_msg_ptr->options_list_ptr->proxy_uri_ptr = handle->sn_coap_protocol_malloc(option_len); if (dst_coap_msg_ptr->options_list_ptr->proxy_uri_ptr == NULL) { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_PROXY_URI allocation failed!"); return -1; } + memcpy(dst_coap_msg_ptr->options_list_ptr->proxy_uri_ptr, *packet_data_pptr, option_len); (*packet_data_pptr) += option_len; @@ -386,12 +402,14 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack if (ret_status >= 0) { i += (ret_status - 1); /* i += is because possible several Options are handled by sn_coap_parser_options_parse_multiple_options() */ } else { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_ETAG not valid!"); return -1; } break; case COAP_OPTION_URI_HOST: if ((option_len > 255) || (option_len < 1) || dst_coap_msg_ptr->options_list_ptr->uri_host_ptr) { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_URI_HOST not valid!"); return -1; } dst_coap_msg_ptr->options_list_ptr->uri_host_len = option_len; @@ -400,6 +418,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack dst_coap_msg_ptr->options_list_ptr->uri_host_ptr = handle->sn_coap_protocol_malloc(option_len); if (dst_coap_msg_ptr->options_list_ptr->uri_host_ptr == NULL) { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_URI_HOST allocation failed!"); return -1; } memcpy(dst_coap_msg_ptr->options_list_ptr->uri_host_ptr, *packet_data_pptr, option_len); @@ -409,6 +428,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack case COAP_OPTION_LOCATION_PATH: if (dst_coap_msg_ptr->options_list_ptr->location_path_ptr) { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_LOCATION_PATH exists!"); return -1; } /* This is managed independently because User gives this option in one character table */ @@ -418,6 +438,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack if (ret_status >= 0) { i += (ret_status - 1); /* i += is because possible several Options are handled by sn_coap_parser_options_parse_multiple_options() */ } else { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_LOCATION_PATH not valid!"); return -1; } @@ -426,6 +447,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack case COAP_OPTION_URI_PORT: if ((option_len > 2) || dst_coap_msg_ptr->options_list_ptr->uri_port != COAP_OPTION_URI_PORT_NONE) { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_URI_PORT not valid!"); return -1; } (*packet_data_pptr)++; @@ -440,6 +462,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack if (ret_status >= 0) { i += (ret_status - 1); /* i += is because possible several Options are handled by sn_coap_parser_options_parse_multiple_options() */ } else { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_LOCATION_QUERY not valid!"); return -1; } @@ -452,6 +475,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack if (ret_status >= 0) { i += (ret_status - 1); /* i += is because possible several Options are handled by sn_coap_parser_options_parse_multiple_options() */ } else { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_URI_PATH not valid!"); return -1; } @@ -459,6 +483,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack case COAP_OPTION_OBSERVE: if ((option_len > 2) || dst_coap_msg_ptr->options_list_ptr->observe != COAP_OBSERVE_NONE) { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_OBSERVE not valid!"); return -1; } @@ -475,6 +500,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack if (ret_status >= 0) { i += (ret_status - 1); /* i += is because possible several Options are handled by sn_coap_parser_options_parse_multiple_options() */ } else { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_URI_QUERY not valid!"); return -1; } @@ -482,6 +508,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack case COAP_OPTION_BLOCK2: if ((option_len > 3) || dst_coap_msg_ptr->options_list_ptr->block2 != COAP_OPTION_BLOCK_NONE) { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_BLOCK2 not valid!"); return -1; } (*packet_data_pptr)++; @@ -492,6 +519,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack case COAP_OPTION_BLOCK1: if ((option_len > 3) || dst_coap_msg_ptr->options_list_ptr->block1 != COAP_OPTION_BLOCK_NONE) { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_BLOCK1 not valid!"); return -1; } (*packet_data_pptr)++; @@ -502,6 +530,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack case COAP_OPTION_ACCEPT: if ((option_len > 2) || (dst_coap_msg_ptr->options_list_ptr->accept != COAP_CT_NONE)) { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_ACCEPT not valid!"); return -1; } @@ -512,6 +541,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack case COAP_OPTION_SIZE1: if ((option_len > 4) || dst_coap_msg_ptr->options_list_ptr->use_size1) { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_SIZE1 not valid!"); return -1; } dst_coap_msg_ptr->options_list_ptr->use_size1 = true; @@ -521,6 +551,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack case COAP_OPTION_SIZE2: if ((option_len > 4) || dst_coap_msg_ptr->options_list_ptr->use_size2) { + tr_error("sn_coap_parser_options_parse - COAP_OPTION_SIZE2 not valid!"); return -1; } dst_coap_msg_ptr->options_list_ptr->use_size2 = true; @@ -529,6 +560,7 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack break; default: + tr_error("sn_coap_parser_options_parse - unknown option!"); return -1; } @@ -539,7 +571,6 @@ static int8_t sn_coap_parser_options_parse(struct coap_s *handle, uint8_t **pack message_left = packet_len - (*packet_data_pptr - packet_data_start_ptr); - } return 0; @@ -576,6 +607,7 @@ static int8_t sn_coap_parser_options_parse_multiple_options(struct coap_s *handl *dst_pptr = (uint8_t *) handle->sn_coap_protocol_malloc(uri_query_needed_heap); if (*dst_pptr == NULL) { + tr_error("sn_coap_parser_options_parse_multiple_options - failed to allocate options!"); return -1; } } @@ -753,6 +785,7 @@ static int8_t sn_coap_parser_payload_parse(uint16_t packet_data_len, uint8_t *pa } /* No payload marker.. */ else { + tr_error("sn_coap_parser_payload_parse - payload marker not found!"); return -1; } } diff --git a/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_protocol.c b/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_protocol.c index a0660e6ee42..1e14055faf9 100644 --- a/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_protocol.c +++ b/features/FEATURE_COMMON_PAL/mbed-coap/source/sn_coap_protocol.c @@ -216,8 +216,6 @@ struct coap_s *sn_coap_protocol_init(void *(*used_malloc_func_ptr)(uint16_t), vo if (message_id == 0) { message_id = 1; } - tr_debug("Coap random msg ID: %d", message_id); - tr_debug("Coap BLOCKWISE_MAX_TIME_DATA_STORED: %d", SN_COAP_BLOCKWISE_MAX_TIME_DATA_STORED); return handle; } @@ -350,24 +348,22 @@ int8_t prepare_blockwise_message(struct coap_s *handle, sn_coap_hdr_s *src_coap_ /* Allocate memory for less used options */ if (sn_coap_parser_alloc_options(handle, src_coap_msg_ptr) == NULL) { + tr_error("prepare_blockwise_message - failed to allocate options!"); return -2; } /* Check if Request message */ if (src_coap_msg_ptr->msg_code < COAP_MSG_CODE_RESPONSE_CREATED) { - tr_debug("prepare_blockwise_message - block1 request"); /* Add Blockwise option, use Block1 because Request payload */ src_coap_msg_ptr->options_list_ptr->block1 = 0x08; /* First block (BLOCK NUMBER, 4 MSB bits) + More to come (MORE, 1 bit) */ src_coap_msg_ptr->options_list_ptr->block1 |= sn_coap_convert_block_size(handle->sn_coap_block_data_size); /* Add size1 parameter */ - tr_debug("prepare_blockwise_message block1 request - payload len %d", src_coap_msg_ptr->payload_len); src_coap_msg_ptr->options_list_ptr->use_size1 = true; src_coap_msg_ptr->options_list_ptr->use_size2 = false; src_coap_msg_ptr->options_list_ptr->size1 = src_coap_msg_ptr->payload_len; } else { /* Response message */ - tr_debug("prepare_blockwise_message - block2 response"); /* Add Blockwise option, use Block2 because Response payload */ src_coap_msg_ptr->options_list_ptr->block2 = 0x08; /* First block (BLOCK NUMBER, 4 MSB bits) + More to come (MORE, 1 bit) */ src_coap_msg_ptr->options_list_ptr->block2 |= sn_coap_convert_block_size(handle->sn_coap_block_data_size); @@ -384,7 +380,6 @@ int8_t prepare_blockwise_message(struct coap_s *handle, sn_coap_hdr_s *src_coap_ int16_t sn_coap_protocol_build(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_ptr, uint8_t *dst_packet_data_ptr, sn_coap_hdr_s *src_coap_msg_ptr, void *param) { - tr_debug("sn_coap_protocol_build - payload len %d", src_coap_msg_ptr->payload_len); int16_t byte_count_built = 0; #if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not used at all, this part of code will not be compiled */ uint16_t original_payload_len = 0; @@ -429,6 +424,7 @@ int16_t sn_coap_protocol_build(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_p byte_count_built = sn_coap_builder_2(dst_packet_data_ptr, src_coap_msg_ptr, handle->sn_coap_block_data_size); if (byte_count_built < 0) { + tr_error("sn_coap_protocol_build - failed to build message!"); return byte_count_built; } @@ -460,6 +456,7 @@ int16_t sn_coap_protocol_build(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_p memcpy(info->packet_ptr, dst_packet_data_ptr, byte_count_built); info->packet_len = byte_count_built; } else { + tr_error("sn_coap_protocol_build - failed to allocate duplication info!"); return -4; } } @@ -480,6 +477,7 @@ int16_t sn_coap_protocol_build(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_p stored_blockwise_msg_ptr = handle->sn_coap_protocol_malloc(sizeof(coap_blockwise_msg_s)); if (!stored_blockwise_msg_ptr) { //block paylaod save failed, only first block can be build. Perhaps we should return error. + tr_error("sn_coap_protocol_build - blockwise message allocation failed!"); return byte_count_built; } memset(stored_blockwise_msg_ptr, 0, sizeof(coap_blockwise_msg_s)); @@ -491,6 +489,7 @@ int16_t sn_coap_protocol_build(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_p if( stored_blockwise_msg_ptr->coap_msg_ptr == NULL ){ handle->sn_coap_protocol_free(stored_blockwise_msg_ptr); stored_blockwise_msg_ptr = 0; + tr_error("sn_coap_protocol_build - block header copy failed!"); return -2; } @@ -502,6 +501,7 @@ int16_t sn_coap_protocol_build(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_p sn_coap_parser_release_allocated_coap_msg_mem(handle, stored_blockwise_msg_ptr->coap_msg_ptr); handle->sn_coap_protocol_free(stored_blockwise_msg_ptr); stored_blockwise_msg_ptr = 0; + tr_error("sn_coap_protocol_build - block payload allocation failed!"); return byte_count_built; } memcpy(stored_blockwise_msg_ptr->coap_msg_ptr->payload_ptr, src_coap_msg_ptr->payload_ptr, stored_blockwise_msg_ptr->coap_msg_ptr->payload_len); @@ -516,6 +516,7 @@ int16_t sn_coap_protocol_build(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_p stored_blockwise_msg_ptr = handle->sn_coap_protocol_malloc(sizeof(coap_blockwise_msg_s)); if (!stored_blockwise_msg_ptr) { + tr_error("sn_coap_protocol_build - blockwise (GET) allocation failed!"); return byte_count_built; } memset(stored_blockwise_msg_ptr, 0, sizeof(coap_blockwise_msg_s)); @@ -527,6 +528,7 @@ int16_t sn_coap_protocol_build(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_p if( stored_blockwise_msg_ptr->coap_msg_ptr == NULL ){ handle->sn_coap_protocol_free(stored_blockwise_msg_ptr); stored_blockwise_msg_ptr = 0; + tr_error("sn_coap_protocol_build - blockwise (GET) copy header failed!"); return -2; } @@ -536,15 +538,12 @@ int16_t sn_coap_protocol_build(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_p #endif /* SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE */ - tr_debug("sn_coap_protocol_build - msg id: [%d], bytes: [%d]", src_coap_msg_ptr->msg_id, byte_count_built); - /* * * * Return built CoAP message Packet data length * * * */ return byte_count_built; } sn_coap_hdr_s *sn_coap_protocol_parse(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint16_t packet_data_len, uint8_t *packet_data_ptr, void *param) { - tr_debug("sn_coap_protocol_parse"); sn_coap_hdr_s *returned_dst_coap_msg_ptr = NULL; coap_version_e coap_version = COAP_VERSION_UNKNOWN; @@ -560,12 +559,14 @@ sn_coap_hdr_s *sn_coap_protocol_parse(struct coap_s *handle, sn_nsdl_addr_s *src /* Check status of returned pointer */ if (returned_dst_coap_msg_ptr == NULL) { /* Memory allocation error in parser */ + tr_error("sn_coap_protocol_parse - allocation fail in parser!"); return NULL; } /* * * * Send bad request response if parsing fails * * * */ if (returned_dst_coap_msg_ptr->coap_status == COAP_STATUS_PARSER_ERROR_IN_HEADER) { sn_coap_protocol_send_rst(handle, returned_dst_coap_msg_ptr->msg_id, src_addr_ptr, param); sn_coap_parser_release_allocated_coap_msg_mem(handle, returned_dst_coap_msg_ptr); + tr_error("sn_coap_protocol_parse - COAP_STATUS_PARSER_ERROR_IN_HEADER"); return NULL; } @@ -575,6 +576,7 @@ sn_coap_hdr_s *sn_coap_protocol_parse(struct coap_s *handle, sn_nsdl_addr_s *src if (((returned_dst_coap_msg_ptr->msg_code >> 5) == 1) || // if class == 1 ((returned_dst_coap_msg_ptr->msg_code >> 5) == 6) || // if class == 6 ((returned_dst_coap_msg_ptr->msg_code >> 5) == 7)) { // if class == 7 + tr_error("sn_coap_protocol_parse - message code not valid!"); sn_coap_protocol_send_rst(handle, returned_dst_coap_msg_ptr->msg_id, src_addr_ptr, param); } @@ -613,6 +615,7 @@ sn_coap_hdr_s *sn_coap_protocol_parse(struct coap_s *handle, sn_nsdl_addr_s *src returned_dst_coap_msg_ptr->options_list_ptr->block2 != COAP_OPTION_BLOCK_NONE)) { /* Set returned status to User */ returned_dst_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_BLOCKWISE_MSG_REJECTED; + tr_error("sn_coap_protocol_parse - COAP_STATUS_PARSER_BLOCKWISE_MSG_REJECTED!"); //todo: send response -> not implemented return returned_dst_coap_msg_ptr; } @@ -714,6 +717,7 @@ sn_coap_hdr_s *sn_coap_protocol_parse(struct coap_s *handle, sn_nsdl_addr_s *src } if (!returned_dst_coap_msg_ptr) { + tr_error("sn_coap_protocol_parse - returned_dst_coap_msg_ptr null!"); return NULL; } @@ -770,7 +774,9 @@ int8_t sn_coap_protocol_exec(struct coap_s *handle, uint32_t current_time) #if ENABLE_RESENDINGS /* Check if there is ongoing active message sendings */ - ns_list_foreach_safe(coap_send_msg_s, stored_msg_ptr, &handle->linked_list_resent_msgs) { + /* foreach_safe isn't sufficient because callback routine could cancel messages. */ +rescan: + ns_list_foreach(coap_send_msg_s, stored_msg_ptr, &handle->linked_list_resent_msgs) { // First check that msg belongs to handle if( stored_msg_ptr->coap == handle ){ /* Check if it is time to send this message */ @@ -816,7 +822,9 @@ int8_t sn_coap_protocol_exec(struct coap_s *handle, uint32_t current_time) handle->sn_coap_resending_intervall, stored_msg_ptr->resending_counter); } - + /* Callback routine could have wiped the list (eg as a response to sending failed) */ + /* Be super cautious and rescan from the start */ + goto rescan; } } } @@ -859,6 +867,7 @@ static uint8_t sn_coap_protocol_linked_list_send_msg_store(struct coap_s *handle if (handle->sn_coap_resending_queue_msgs > 0) { if (handle->count_resent_msgs >= handle->sn_coap_resending_queue_msgs) { + tr_error("sn_coap_protocol_linked_list_send_msg_store - resend queue full!"); return 0; } } @@ -866,6 +875,7 @@ static uint8_t sn_coap_protocol_linked_list_send_msg_store(struct coap_s *handle /* Count resending queue size, if buffer size is defined */ if (handle->sn_coap_resending_queue_bytes > 0) { if ((sn_coap_count_linked_list_size(&handle->linked_list_resent_msgs) + send_packet_data_len) > handle->sn_coap_resending_queue_bytes) { + tr_error("sn_coap_protocol_linked_list_send_msg_store - resend buffer size reached!"); return 0; } } @@ -874,6 +884,7 @@ static uint8_t sn_coap_protocol_linked_list_send_msg_store(struct coap_s *handle stored_msg_ptr = sn_coap_protocol_allocate_mem_for_msg(handle, dst_addr_ptr, send_packet_data_len); if (stored_msg_ptr == 0) { + tr_error("sn_coap_protocol_linked_list_send_msg_store - failed to allocate message!"); return 0; } @@ -1028,6 +1039,7 @@ static void sn_coap_protocol_linked_list_duplication_info_store(struct coap_s *h stored_duplication_info_ptr = handle->sn_coap_protocol_malloc(sizeof(coap_duplication_info_s)); if (stored_duplication_info_ptr == NULL) { + tr_error("sn_coap_protocol_linked_list_duplication_info_store - failed to allocate duplication info!"); return; } memset(stored_duplication_info_ptr, 0, sizeof(coap_duplication_info_s)); @@ -1035,6 +1047,7 @@ static void sn_coap_protocol_linked_list_duplication_info_store(struct coap_s *h /* Allocate memory for stored Duplication info's address */ stored_duplication_info_ptr->address = handle->sn_coap_protocol_malloc(sizeof(sn_nsdl_addr_s)); if (stored_duplication_info_ptr->address == NULL) { + tr_error("sn_coap_protocol_linked_list_duplication_info_store - failed to allocate address!"); handle->sn_coap_protocol_free(stored_duplication_info_ptr); stored_duplication_info_ptr = 0; return; @@ -1044,6 +1057,7 @@ static void sn_coap_protocol_linked_list_duplication_info_store(struct coap_s *h stored_duplication_info_ptr->address->addr_ptr = handle->sn_coap_protocol_malloc(addr_ptr->addr_len); if (stored_duplication_info_ptr->address->addr_ptr == NULL) { + tr_error("sn_coap_protocol_linked_list_duplication_info_store - failed to allocate address pointer!"); handle->sn_coap_protocol_free(stored_duplication_info_ptr->address); stored_duplication_info_ptr->address = 0; handle->sn_coap_protocol_free(stored_duplication_info_ptr); @@ -1227,6 +1241,7 @@ static void sn_coap_protocol_linked_list_blockwise_payload_store(struct coap_s * stored_blockwise_payload_ptr = handle->sn_coap_protocol_malloc(sizeof(coap_blockwise_payload_s)); if (stored_blockwise_payload_ptr == NULL) { + tr_error("sn_coap_protocol_linked_list_blockwise_payload_store - failed to allocate blockwise!"); return; } @@ -1235,6 +1250,7 @@ static void sn_coap_protocol_linked_list_blockwise_payload_store(struct coap_s * stored_blockwise_payload_ptr->payload_ptr = handle->sn_coap_protocol_malloc(stored_payload_len); if (stored_blockwise_payload_ptr->payload_ptr == NULL) { + tr_error("sn_coap_protocol_linked_list_blockwise_payload_store - failed to allocate payload!"); handle->sn_coap_protocol_free(stored_blockwise_payload_ptr); stored_blockwise_payload_ptr = 0; return; @@ -1244,6 +1260,7 @@ static void sn_coap_protocol_linked_list_blockwise_payload_store(struct coap_s * stored_blockwise_payload_ptr->addr_ptr = handle->sn_coap_protocol_malloc(addr_ptr->addr_len); if (stored_blockwise_payload_ptr->addr_ptr == NULL) { + tr_error("sn_coap_protocol_linked_list_blockwise_payload_store - failed to allocate address pointer!"); handle->sn_coap_protocol_free(stored_blockwise_payload_ptr->payload_ptr); stored_blockwise_payload_ptr->payload_ptr = 0; handle->sn_coap_protocol_free(stored_blockwise_payload_ptr); @@ -1313,7 +1330,6 @@ static bool sn_coap_protocol_linked_list_blockwise_payload_compare_block_number( if (stored_payload_info_ptr->port == src_addr_ptr->port) { // Check that incoming block number matches to last received one if (block_number - 1 == stored_payload_info_ptr->block_number) { - tr_debug("sn_coap_protocol_linked_list_blockwise_payload_search_block_number - found %d", stored_payload_info_ptr->block_number); return true; } } @@ -1569,7 +1585,6 @@ void sn_coap_protocol_block_remove(struct coap_s *handle, sn_nsdl_addr_s *source static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, sn_coap_hdr_s *received_coap_msg_ptr, void *param) { - tr_debug("sn_coap_handle_blockwise_message"); sn_coap_hdr_s *src_coap_blockwise_ack_msg_ptr = NULL; uint16_t dst_packed_data_needed_mem = 0; uint8_t *dst_ack_packet_data_ptr = NULL; @@ -1581,9 +1596,7 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn /* Block1 Option in a request (e.g., PUT or POST) */ // Blocked request sending, received ACK, sending next block.. if (received_coap_msg_ptr->options_list_ptr->block1 != COAP_OPTION_BLOCK_NONE) { - tr_debug("sn_coap_handle_blockwise_message - block1, message code: [%d]", received_coap_msg_ptr->msg_code); if (received_coap_msg_ptr->msg_code > COAP_MSG_CODE_REQUEST_DELETE) { - tr_debug("sn_coap_handle_blockwise_message - send block1 request"); if (received_coap_msg_ptr->options_list_ptr->block1 & 0x08) { coap_blockwise_msg_s *stored_blockwise_msg_temp_ptr = NULL; @@ -1614,6 +1627,7 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2 = COAP_OPTION_BLOCK_NONE; } else { if (!sn_coap_parser_alloc_options(handle, src_coap_blockwise_ack_msg_ptr)) { + tr_error("sn_coap_handle_blockwise_message - (send block1) failed to allocate ack message!"); sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr); return 0; } @@ -1642,6 +1656,7 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn dst_ack_packet_data_ptr = handle->sn_coap_protocol_malloc(dst_packed_data_needed_mem); if (!dst_ack_packet_data_ptr) { + tr_error("sn_coap_handle_blockwise_message - (send block1) failed to allocate ack message!"); handle->sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr); src_coap_blockwise_ack_msg_ptr->options_list_ptr = 0; handle->sn_coap_protocol_free(original_payload_ptr); @@ -1658,7 +1673,6 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn } sn_coap_builder_2(dst_ack_packet_data_ptr, src_coap_blockwise_ack_msg_ptr, handle->sn_coap_block_data_size); - tr_debug("sn_coap_handle_blockwise_message - block1 request, send block msg id: [%d]", src_coap_blockwise_ack_msg_ptr->msg_id); handle->sn_coap_tx_callback(dst_ack_packet_data_ptr, dst_packed_data_needed_mem, src_addr_ptr, param); handle->sn_coap_protocol_free(dst_ack_packet_data_ptr); @@ -1671,7 +1685,6 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn } } else { // XXX what was this trying to free? - tr_debug("sn_coap_handle_blockwise_message - block1 request - last block sent"); received_coap_msg_ptr->coap_status = COAP_STATUS_OK; } @@ -1679,7 +1692,6 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn // Blocked request receiving else { - tr_debug("sn_coap_handle_blockwise_message - block1 received"); if (received_coap_msg_ptr->payload_len > handle->sn_coap_block_data_size) { received_coap_msg_ptr->payload_len = handle->sn_coap_block_data_size; } @@ -1703,14 +1715,15 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn /* If not last block (more value is set) */ /* Block option length can be 1-3 bytes. First 4-20 bits are for block number. Last 4 bits are ALWAYS more bit + block size. */ if (received_coap_msg_ptr->options_list_ptr->block1 & 0x08) { - tr_debug("sn_coap_handle_blockwise_message - block1 received, send ack"); src_coap_blockwise_ack_msg_ptr = sn_coap_parser_alloc_message(handle); if (src_coap_blockwise_ack_msg_ptr == NULL) { + tr_error("sn_coap_handle_blockwise_message - (recv block1) failed to allocate ack message!"); sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr); return NULL; } if (sn_coap_parser_alloc_options(handle, src_coap_blockwise_ack_msg_ptr) == NULL) { + tr_error("sn_coap_handle_blockwise_message - (recv block1) failed to allocate options!"); handle->sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr); src_coap_blockwise_ack_msg_ptr = 0; sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr); @@ -1718,13 +1731,14 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn } // Response with COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE if the payload size is more than we can handle - tr_debug("sn_coap_handle_blockwise_message - block1 received - incoming size: [%d]", received_coap_msg_ptr->options_list_ptr->size1); uint32_t max_size = SN_COAP_MAX_INCOMING_BLOCK_MESSAGE_SIZE; if (!blocks_in_order) { + tr_error("sn_coap_handle_blockwise_message - (recv block1) COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_INCOMPLETE!"); src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_INCOMPLETE; } else if (received_coap_msg_ptr->options_list_ptr->size1 > max_size) { // Include maximum size that stack can handle into response + tr_error("sn_coap_handle_blockwise_message - (recv block1) COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE!"); src_coap_blockwise_ack_msg_ptr->msg_code = COAP_MSG_CODE_RESPONSE_REQUEST_ENTITY_TOO_LARGE; src_coap_blockwise_ack_msg_ptr->options_list_ptr->size1 = max_size; } else if (received_coap_msg_ptr->msg_code == COAP_MSG_CODE_REQUEST_GET) { @@ -1760,6 +1774,7 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn dst_ack_packet_data_ptr = handle->sn_coap_protocol_malloc(dst_packed_data_needed_mem); if (!dst_ack_packet_data_ptr) { + tr_error("sn_coap_handle_blockwise_message - (recv block1) message allocation failed!"); sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr); handle->sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr); src_coap_blockwise_ack_msg_ptr->options_list_ptr = 0; @@ -1769,7 +1784,6 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn } sn_coap_builder_2(dst_ack_packet_data_ptr, src_coap_blockwise_ack_msg_ptr, handle->sn_coap_block_data_size); - tr_debug("sn_coap_handle_blockwise_message - block1 received - send msg id [%d]", src_coap_blockwise_ack_msg_ptr->msg_id); handle->sn_coap_tx_callback(dst_ack_packet_data_ptr, dst_packed_data_needed_mem, src_addr_ptr, param); sn_coap_parser_release_allocated_coap_msg_mem(handle, src_coap_blockwise_ack_msg_ptr); @@ -1779,7 +1793,6 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn received_coap_msg_ptr->coap_status = COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVING; } else { - tr_debug("sn_coap_handle_blockwise_message - block1 received, last block received"); /* * * This is the last block when whole Blockwise payload from received * * */ /* * * blockwise messages is gathered and returned to User * * */ @@ -1789,10 +1802,9 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn uint32_t whole_payload_len = sn_coap_protocol_linked_list_blockwise_payloads_get_len(handle, src_addr_ptr); uint8_t *temp_whole_payload_ptr = NULL; - tr_debug("sn_coap_handle_blockwise_message - block1 received, whole_payload_len %d", whole_payload_len); temp_whole_payload_ptr = handle->sn_coap_protocol_malloc(whole_payload_len); if (temp_whole_payload_ptr == NULL || whole_payload_len > UINT16_MAX) { - tr_debug("sn_coap_handle_blockwise_message - block1 received, last block received alloc fails"); + tr_error("sn_coap_handle_blockwise_message - (recv block1) failed to allocate all blocks!"); sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr); handle->sn_coap_protocol_free(temp_whole_payload_ptr); return 0; @@ -1818,10 +1830,8 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn /* Block2 Option in a response (e.g., a 2.05 response for GET) */ /* Message ID must be same than in received message */ else { - tr_debug("sn_coap_handle_blockwise_message - block2 - message code: [%d]", received_coap_msg_ptr->msg_code); //This is response to request we made if (received_coap_msg_ptr->msg_code > COAP_MSG_CODE_REQUEST_DELETE) { - tr_debug("sn_coap_handle_blockwise_message - send block2 request"); uint32_t block_number = 0; /* Store blockwise payload to Linked list */ @@ -1846,12 +1856,14 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn } if (!previous_blockwise_msg_ptr || !previous_blockwise_msg_ptr->coap_msg_ptr) { + tr_error("sn_coap_handle_blockwise_message - (send block2) previous message null!"); sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr); return 0; } src_coap_blockwise_ack_msg_ptr = sn_coap_parser_alloc_message(handle); if (src_coap_blockwise_ack_msg_ptr == NULL) { + tr_error("sn_coap_handle_blockwise_message - (send block2) failed to allocate message!"); return 0; } @@ -1870,6 +1882,7 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn /* * * Then build CoAP Acknowledgement message * * */ if (sn_coap_parser_alloc_options(handle, src_coap_blockwise_ack_msg_ptr) == NULL) { + tr_error("sn_coap_handle_blockwise_message - (send block2) failed to allocate options!"); handle->sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr); src_coap_blockwise_ack_msg_ptr = 0; sn_coap_parser_release_allocated_coap_msg_mem(handle, received_coap_msg_ptr); @@ -1896,6 +1909,7 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn dst_ack_packet_data_ptr = handle->sn_coap_protocol_malloc(dst_packed_data_needed_mem); if (dst_ack_packet_data_ptr == NULL) { + tr_error("sn_coap_handle_blockwise_message - (send block2) failed to allocate packet!"); handle->sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr); src_coap_blockwise_ack_msg_ptr->options_list_ptr = 0; handle->sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr); @@ -1907,6 +1921,7 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn /* * * Then build Acknowledgement message to Packed data * * */ if ((sn_coap_builder_2(dst_ack_packet_data_ptr, src_coap_blockwise_ack_msg_ptr, handle->sn_coap_block_data_size)) < 0) { + tr_error("sn_coap_handle_blockwise_message - (send block2) builder failed!"); handle->sn_coap_protocol_free(dst_ack_packet_data_ptr); dst_ack_packet_data_ptr = 0; handle->sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr); @@ -1922,6 +1937,7 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn stored_blockwise_msg_ptr = handle->sn_coap_protocol_malloc(sizeof(coap_blockwise_msg_s)); if (!stored_blockwise_msg_ptr) { + tr_error("sn_coap_handle_blockwise_message - (send block2) failed to allocate blockwise message!"); handle->sn_coap_protocol_free(dst_ack_packet_data_ptr); dst_ack_packet_data_ptr = 0; handle->sn_coap_protocol_free(src_coap_blockwise_ack_msg_ptr->options_list_ptr); @@ -1967,6 +1983,7 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn temp_whole_payload_ptr = handle->sn_coap_protocol_malloc(whole_payload_len); if (!temp_whole_payload_ptr) { + tr_error("sn_coap_handle_blockwise_message - (send block2) failed to allocate whole payload!"); return 0; } @@ -1991,7 +2008,6 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn //Now we send data to request else { - tr_debug("sn_coap_handle_blockwise_message - block2 received"); //Get message by using block number //NOTE: Getting the first from list might not be correct one coap_blockwise_msg_s *stored_blockwise_msg_temp_ptr = ns_list_get_first(&handle->linked_list_blockwise_sent_msgs); @@ -2012,6 +2028,7 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn src_coap_blockwise_ack_msg_ptr->options_list_ptr->block2 = COAP_OPTION_BLOCK_NONE; } else { if (sn_coap_parser_alloc_options(handle, src_coap_blockwise_ack_msg_ptr) == NULL) { + tr_error("sn_coap_handle_blockwise_message - (recv block2) failed to allocate options!"); return 0; } } @@ -2059,6 +2076,7 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn dst_ack_packet_data_ptr = handle->sn_coap_protocol_malloc(dst_packed_data_needed_mem); if (!dst_ack_packet_data_ptr) { + tr_error("sn_coap_handle_blockwise_message - (recv block2) failed to allocate packet!"); if(original_payload_ptr){ handle->sn_coap_protocol_free(original_payload_ptr); original_payload_ptr = NULL; @@ -2071,7 +2089,6 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn } sn_coap_builder_2(dst_ack_packet_data_ptr, src_coap_blockwise_ack_msg_ptr, handle->sn_coap_block_data_size); - tr_debug("sn_coap_handle_blockwise_message - block2 received, send message: [%d]", src_coap_blockwise_ack_msg_ptr->msg_id); handle->sn_coap_tx_callback(dst_ack_packet_data_ptr, dst_packed_data_needed_mem, src_addr_ptr, param); handle->sn_coap_protocol_free(dst_ack_packet_data_ptr); @@ -2118,6 +2135,7 @@ static sn_coap_hdr_s *sn_coap_protocol_copy_header(struct coap_s *handle, sn_coa destination_header_ptr = sn_coap_parser_alloc_message(handle); if (!destination_header_ptr) { + tr_error("sn_coap_protocol_copy_header - failed to allocate message!"); return 0; } @@ -2130,6 +2148,7 @@ static sn_coap_hdr_s *sn_coap_protocol_copy_header(struct coap_s *handle, sn_coa destination_header_ptr->uri_path_len = source_header_ptr->uri_path_len; destination_header_ptr->uri_path_ptr = handle->sn_coap_protocol_malloc(source_header_ptr->uri_path_len); if (!destination_header_ptr->uri_path_ptr) { + tr_error("sn_coap_protocol_copy_header - failed to allocate uri path!"); sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr); return 0; } @@ -2141,6 +2160,7 @@ static sn_coap_hdr_s *sn_coap_protocol_copy_header(struct coap_s *handle, sn_coa destination_header_ptr->token_ptr = handle->sn_coap_protocol_malloc(source_header_ptr->token_len); if (!destination_header_ptr->token_ptr) { sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr); + tr_error("sn_coap_protocol_copy_header - failed to allocate token!"); return 0; } memcpy(destination_header_ptr->token_ptr, source_header_ptr->token_ptr, source_header_ptr->token_len); @@ -2152,6 +2172,7 @@ static sn_coap_hdr_s *sn_coap_protocol_copy_header(struct coap_s *handle, sn_coa if (source_header_ptr->options_list_ptr) { if (sn_coap_parser_alloc_options(handle, destination_header_ptr) == NULL) { sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr); + tr_error("sn_coap_protocol_copy_header - failed to allocate options!"); return 0; } @@ -2162,6 +2183,7 @@ static sn_coap_hdr_s *sn_coap_protocol_copy_header(struct coap_s *handle, sn_coa destination_header_ptr->options_list_ptr->proxy_uri_ptr = handle->sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->proxy_uri_len); if (!destination_header_ptr->options_list_ptr->proxy_uri_ptr) { sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr); + tr_error("sn_coap_protocol_copy_header - failed to allocate proxy uri!"); return 0; } memcpy(destination_header_ptr->options_list_ptr->proxy_uri_ptr, source_header_ptr->options_list_ptr->proxy_uri_ptr, source_header_ptr->options_list_ptr->proxy_uri_len); @@ -2172,6 +2194,7 @@ static sn_coap_hdr_s *sn_coap_protocol_copy_header(struct coap_s *handle, sn_coa destination_header_ptr->options_list_ptr->etag_ptr = handle->sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->etag_len); if (!destination_header_ptr->options_list_ptr->etag_ptr) { sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr); + tr_error("sn_coap_protocol_copy_header - failed to allocate etag!"); return 0; } memcpy(destination_header_ptr->options_list_ptr->etag_ptr, source_header_ptr->options_list_ptr->etag_ptr, source_header_ptr->options_list_ptr->etag_len); @@ -2182,6 +2205,7 @@ static sn_coap_hdr_s *sn_coap_protocol_copy_header(struct coap_s *handle, sn_coa destination_header_ptr->options_list_ptr->uri_host_ptr = handle->sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->uri_host_len); if (!destination_header_ptr->options_list_ptr->uri_host_ptr) { sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr); + tr_error("sn_coap_protocol_copy_header - failed to allocate uri host!"); return 0; } memcpy(destination_header_ptr->options_list_ptr->uri_host_ptr, source_header_ptr->options_list_ptr->uri_host_ptr, source_header_ptr->options_list_ptr->uri_host_len); @@ -2191,6 +2215,7 @@ static sn_coap_hdr_s *sn_coap_protocol_copy_header(struct coap_s *handle, sn_coa destination_header_ptr->options_list_ptr->location_path_len = source_header_ptr->options_list_ptr->location_path_len; destination_header_ptr->options_list_ptr->location_path_ptr = handle->sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->location_path_len); if (!destination_header_ptr->options_list_ptr->location_path_ptr) { + tr_error("sn_coap_protocol_copy_header - failed to allocate location path!"); sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr); return 0; } @@ -2204,6 +2229,7 @@ static sn_coap_hdr_s *sn_coap_protocol_copy_header(struct coap_s *handle, sn_coa destination_header_ptr->options_list_ptr->location_query_ptr = handle->sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->location_query_len); if (!destination_header_ptr->options_list_ptr->location_query_ptr) { sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr); + tr_error("sn_coap_protocol_copy_header - failed to allocate location query!"); return 0; } memcpy(destination_header_ptr->options_list_ptr->location_query_ptr, source_header_ptr->options_list_ptr->location_query_ptr, source_header_ptr->options_list_ptr->location_query_len); @@ -2217,6 +2243,7 @@ static sn_coap_hdr_s *sn_coap_protocol_copy_header(struct coap_s *handle, sn_coa destination_header_ptr->options_list_ptr->uri_query_ptr = handle->sn_coap_protocol_malloc(source_header_ptr->options_list_ptr->uri_query_len); if (!destination_header_ptr->options_list_ptr->uri_query_ptr) { sn_coap_parser_release_allocated_coap_msg_mem(handle, destination_header_ptr); + tr_error("sn_coap_protocol_copy_header - failed to allocate uri query!"); return 0; } memcpy(destination_header_ptr->options_list_ptr->uri_query_ptr, source_header_ptr->options_list_ptr->uri_query_ptr, source_header_ptr->options_list_ptr->uri_query_len); diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c index b4c9d1e8221..4b3c003eb9d 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c @@ -52,8 +52,7 @@ extern void k66f_init_eth_hardware(void); /* K64F EMAC driver data structure */ struct k64f_enetdata { struct netif *netif; /**< Reference back to LWIP parent netif */ - sys_sem_t RxReadySem; /**< RX packet ready semaphore */ - sys_sem_t TxCleanSem; /**< TX cleanup thread wakeup semaphore */ + osThreadId_t thread; /**< Processing thread */ sys_mutex_t TXLockMutex; /**< TX critical section mutex */ sys_sem_t xTXDCountSem; /**< TX free buffer counting semaphore */ uint8_t tx_consume_index, tx_produce_index; /**< TX buffers ring */ @@ -61,15 +60,24 @@ struct k64f_enetdata { static struct k64f_enetdata k64f_enetdata; -/** \brief Driver transmit and receive thread priorities - * - * Thread priorities for receive thread and TX cleanup thread. Alter - * to prioritize receive or transmit bandwidth. In a heavily loaded - * system or with LEIP_DEBUG enabled, the priorities might be better - * the same. */ -#define RX_PRIORITY (osPriorityNormal) -#define TX_PRIORITY (osPriorityNormal) -#define PHY_PRIORITY (osPriorityNormal) +/* \brief Flags for worker thread */ +#define FLAG_TX 1 +#define FLAG_RX 2 + +/** \brief Driver thread priority */ +#define THREAD_PRIORITY (osPriorityNormal) + +#ifdef LWIP_DEBUG +#define THREAD_STACKSIZE (DEFAULT_THREAD_STACKSIZE * 5) +#else +#define THREAD_STACKSIZE DEFAULT_THREAD_STACKSIZE +#endif + +static void k64f_phy_task(void *data); +static void packet_rx(struct k64f_enetdata *k64f_enet); +static void packet_tx(struct k64f_enetdata *k64f_enet); + +#define PHY_TASK_PERIOD_MS 200 /******************************************************************************** * Buffer management @@ -132,12 +140,12 @@ static void k64f_tx_reclaim(struct k64f_enetdata *k64f_enet) */ void enet_mac_rx_isr() { - sys_sem_signal(&k64f_enetdata.RxReadySem); + osThreadFlagsSet(k64f_enetdata.thread, FLAG_RX); } void enet_mac_tx_isr() { - sys_sem_signal(&k64f_enetdata.TxCleanSem); + osThreadFlagsSet(k64f_enetdata.thread, FLAG_TX); } void ethernet_callback(ENET_Type *base, enet_handle_t *handle, enet_event_t event, void *param) @@ -461,26 +469,56 @@ void k64f_enetif_input(struct netif *netif, int idx) } } +/** \brief Worker thread. + * + * Woken by thread flags to receive packets or clean up transmit + * + * \param[in] pvParameters pointer to the interface data + */ +static void emac_thread(void* pvParameters) +{ + struct k64f_enetdata *k64f_enet = pvParameters; + + for (;;) { + uint32_t flags = osThreadFlagsWait(FLAG_RX|FLAG_TX, osFlagsWaitAny, PHY_TASK_PERIOD_MS); + if (flags == osFlagsErrorTimeout) { + // Rather than calling strictly every period, we call when idle + // for that period - hopefully good enough. We run this task + // from lwIP's thread rather than our RX/TX thread, as PHY reads can + // be slow, and we don't want them to interfere with data pumping. + // This is analogous to the way the PHY polling works in the Nanostack + // version of the driver + tcpip_callback_with_block(k64f_phy_task, k64f_enet->netif, 0); + continue; + } + + LWIP_ASSERT("osThreadFlagsWait error", !(flags & osFlagsError)); + + if (flags & FLAG_RX) { + packet_rx(k64f_enet); + } + + if (flags & FLAG_TX) { + packet_tx(k64f_enet); + } + } +} + /** \brief Packet reception task * * This task is called when a packet is received. It will * pass the packet to the LWIP core. * - * \param[in] pvParameters pointer to the interface data + * \param[in] k64f_enet pointer to the interface data */ -static void packet_rx(void* pvParameters) { - struct k64f_enetdata *k64f_enet = pvParameters; - int idx = 0; - - while (1) { - /* Wait for receive task to wakeup */ - sys_arch_sem_wait(&k64f_enet->RxReadySem, 0); +static void packet_rx(struct k64f_enetdata *k64f_enet) +{ + static int idx = 0; while ((g_handle.rxBdCurrent->control & ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK) == 0) { - k64f_enetif_input(k64f_enet->netif, idx); - idx = (idx + 1) % ENET_RX_RING_LEN; + k64f_enetif_input(k64f_enet->netif, idx); + idx = (idx + 1) % ENET_RX_RING_LEN; } - } } /** \brief Transmit cleanup task @@ -489,16 +527,11 @@ static void packet_rx(void* pvParameters) { * reclaims the pbuf and descriptor used for the packet once * the packet has been transferred. * - * \param[in] pvParameters pointer to the interface data + * \param[in] k64f_enet pointer to the interface data */ -static void packet_tx(void* pvParameters) { - struct k64f_enetdata *k64f_enet = pvParameters; - - while (1) { - /* Wait for transmit cleanup task to wakeup */ - sys_arch_sem_wait(&k64f_enet->TxCleanSem, 0); +static void packet_tx(struct k64f_enetdata *k64f_enet) +{ k64f_tx_reclaim(k64f_enet); - } } /** \brief Low level output of a packet. Never call this from an @@ -569,7 +602,6 @@ static err_t k64f_low_level_output(struct netif *netif, struct pbuf *p) * PHY task: monitor link *******************************************************************************/ -#define PHY_TASK_PERIOD_MS 200 #define STATE_UNKNOWN (-1) typedef struct { @@ -578,7 +610,7 @@ typedef struct { phy_duplex_t duplex; } PHY_STATE; -int phy_link_status() { +int phy_link_status(void) { bool connection_status; uint32_t phyAddr = 0; @@ -586,40 +618,40 @@ int phy_link_status() { return (int)connection_status; } -static void k64f_phy_task(void *data) { - struct netif *netif = (struct netif*)data; - bool connection_status; - PHY_STATE crt_state = {STATE_UNKNOWN, (phy_speed_t)STATE_UNKNOWN, (phy_duplex_t)STATE_UNKNOWN}; - PHY_STATE prev_state; - uint32_t phyAddr = 0; - uint32_t rcr = 0; +static void k64f_phy_task(void *data) +{ + struct netif *netif = data; + + static PHY_STATE prev_state = {STATE_UNKNOWN, (phy_speed_t)STATE_UNKNOWN, (phy_duplex_t)STATE_UNKNOWN}; + + uint32_t phyAddr = 0; - prev_state = crt_state; - while (true) { // Get current status + PHY_STATE crt_state; + bool connection_status; PHY_GetLinkStatus(ENET, phyAddr, &connection_status); - crt_state.connected = connection_status ? 1 : 0; + crt_state.connected = connection_status; // Get the actual PHY link speed PHY_GetLinkSpeedDuplex(ENET, phyAddr, &crt_state.speed, &crt_state.duplex); // Compare with previous state if (crt_state.connected != prev_state.connected) { - if (crt_state.connected) - tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_up, (void*) netif, 1); - else - tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_down, (void*) netif, 1); + // We're called from lwIP's tcpip thread, so can call link functions directly + if (crt_state.connected) { + netif_set_link_up(netif); + } else { + netif_set_link_down(netif); + } } if (crt_state.speed != prev_state.speed) { - rcr = ENET->RCR; + uint32_t rcr = ENET->RCR; rcr &= ~ENET_RCR_RMII_10T_MASK; rcr |= ENET_RCR_RMII_10T(!crt_state.speed); ENET->RCR = rcr; } prev_state = crt_state; - osDelay(PHY_TASK_PERIOD_MS); - } } /** @@ -707,27 +739,13 @@ err_t eth_arch_enetif_init(struct netif *netif) err = sys_mutex_new(&k64f_enetdata.TXLockMutex); LWIP_ASSERT("TXLockMutex creation error", (err == ERR_OK)); - /* Packet receive task */ - err = sys_sem_new(&k64f_enetdata.RxReadySem, 0); - LWIP_ASSERT("RxReadySem creation error", (err == ERR_OK)); - -#ifdef LWIP_DEBUG - sys_thread_new("k64f_emac_rx_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE*5, RX_PRIORITY); -#else - sys_thread_new("k64f_emac_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE, RX_PRIORITY); -#endif - - /* Transmit cleanup task */ - err = sys_sem_new(&k64f_enetdata.TxCleanSem, 0); - LWIP_ASSERT("TxCleanSem creation error", (err == ERR_OK)); - sys_thread_new("k64f_emac_txclean_thread", packet_tx, netif->state, DEFAULT_THREAD_STACKSIZE, TX_PRIORITY); - - /* PHY monitoring task */ - sys_thread_new("k64f_emac_phy_thread", k64f_phy_task, netif, DEFAULT_THREAD_STACKSIZE, PHY_PRIORITY); - /* Allow the PHY task to detect the initial link state and set up the proper flags */ + tcpip_callback_with_block(k64f_phy_task, netif, 1); osDelay(10); + /* Worker thread */ + k64f_enetdata.thread = sys_thread_new("k64f_emac_thread", emac_thread, netif->state, THREAD_STACKSIZE, THREAD_PRIORITY)->id; + return ERR_OK; } diff --git a/features/FEATURE_LWIP/lwip-interface/lwipopts.h b/features/FEATURE_LWIP/lwip-interface/lwipopts.h index ebd3b612747..37f62618a3d 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwipopts.h +++ b/features/FEATURE_LWIP/lwip-interface/lwipopts.h @@ -69,10 +69,9 @@ #error "Either IPv4 or IPv6 must be preferred." #endif -#if defined(MBED_CONF_LWIP_DEBUG_ENABLED) -#define LWIP_DEBUG MBED_CONF_LWIP_DEBUG_ENABLED -#else -#define LWIP_DEBUG 0 +#undef LWIP_DEBUG +#if MBED_CONF_LWIP_DEBUG_ENABLED +#define LWIP_DEBUG 1 #endif #if NO_SYS == 0 @@ -93,7 +92,7 @@ #define MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE 1200 #endif -#if LWIP_DEBUG +#ifdef LWIP_DEBUG #define TCPIP_THREAD_STACKSIZE MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE*2 #else #define TCPIP_THREAD_STACKSIZE MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE @@ -111,7 +110,7 @@ #define MBED_CONF_LWIP_PPP_THREAD_STACKSIZE 768 #endif -#if LWIP_DEBUG +#ifdef LWIP_DEBUG #define DEFAULT_THREAD_STACKSIZE MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2 #define PPP_THREAD_STACK_SIZE MBED_CONF_LWIP_PPP_THREAD_STACKSIZE*2 #else @@ -250,7 +249,7 @@ #define ETHARP_DEBUG LWIP_DBG_OFF #define UDP_LPC_EMAC LWIP_DBG_OFF -#if LWIP_DEBUG +#ifdef LWIP_DEBUG #define MEMP_OVERFLOW_CHECK 1 #define MEMP_SANITY_CHECK 1 #define LWIP_DBG_TYPES_ON LWIP_DBG_ON diff --git a/features/mbedtls/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/mbedtls_device.h b/features/mbedtls/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/mbedtls_device.h index dfbc82055ef..90213bea118 100644 --- a/features/mbedtls/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/mbedtls_device.h +++ b/features/mbedtls/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/mbedtls_device.h @@ -20,7 +20,9 @@ #ifndef MBEDTLS_DEVICE_H #define MBEDTLS_DEVICE_H -#define MBEDTLS_AES_ALT +/* FIXME: Don't enable AES hardware acceleration until issue #4928 is fixed. + * (https://github.com/ARMmbed/mbed-os/issues/4928) */ +/* #define MBEDTLS_AES_ALT */ #define MBEDTLS_SHA256_ALT diff --git a/features/unsupported/USBDevice/USBDevice/USBEndpoints.h b/features/unsupported/USBDevice/USBDevice/USBEndpoints.h index b9de9cd7bc3..2e78516d2d5 100644 --- a/features/unsupported/USBDevice/USBDevice/USBEndpoints.h +++ b/features/unsupported/USBDevice/USBDevice/USBEndpoints.h @@ -53,10 +53,12 @@ typedef enum { #include "USBEndpoints_Maxim.h" #elif defined(TARGET_EFM32GG_STK3700) || defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32HG_STK3400) #include "USBEndpoints_EFM32.h" -#elif defined(TARGET_NUMAKER_PFM_NUC472) +#elif defined(TARGET_NUC472) #include "USBEndpoints_NUC472.h" -#elif defined(TARGET_NUMAKER_PFM_M453) +#elif defined(TARGET_M451) #include "USBEndpoints_M453.h" +#elif defined(TARGET_M480) +#include "USBEndpoints_M480.h" #else #error "Unknown target type" #endif diff --git a/features/unsupported/USBDevice/USBDevice/USBHAL.h b/features/unsupported/USBDevice/USBDevice/USBHAL.h index 86f0786d9c5..55ae2e64608 100644 --- a/features/unsupported/USBDevice/USBDevice/USBHAL.h +++ b/features/unsupported/USBDevice/USBDevice/USBHAL.h @@ -68,15 +68,15 @@ class USBHAL { virtual void suspendStateChanged(unsigned int suspended){}; virtual void SOF(int frameNumber){}; -#if defined(TARGET_NUMAKER_PFM_NUC472) || defined(TARGET_NUMAKER_PFM_M453) - // NUC472/M453 USB doesn't support configuration of the same EP number for IN/OUT simultaneously. +#if defined(TARGET_NUC472) || defined(TARGET_M451) + // NUC472/M451 USB doesn't support configuration of the same EP number for IN/OUT simultaneously. virtual bool EP1_OUT_callback(){return false;}; virtual bool EP2_IN_callback(){return false;}; virtual bool EP3_OUT_callback(){return false;}; virtual bool EP4_IN_callback(){return false;}; virtual bool EP5_OUT_callback(){return false;}; virtual bool EP6_IN_callback(){return false;}; -#if ! (defined(TARGET_NUMAKER_PFM_M453)) +#if ! (defined(TARGET_M451)) virtual bool EP7_OUT_callback(){return false;}; virtual bool EP8_IN_callback(){return false;}; virtual bool EP9_OUT_callback(){return false;}; @@ -128,11 +128,11 @@ class USBHAL { #if defined(TARGET_LPC11UXX) || defined(TARGET_LPC11U6X) || defined(TARGET_LPC1347) || defined(TARGET_LPC1549) bool (USBHAL::*epCallback[10 - 2])(void); -#elif (defined(TARGET_STM32F4) && !defined(USB_STM_HAL)) || defined(TARGET_NUMAKER_PFM_M453) +#elif (defined(TARGET_STM32F4) && !defined(USB_STM_HAL)) || defined(TARGET_M451) bool (USBHAL::*epCallback[8 - 2])(void); #elif defined(TARGET_STM) PCD_HandleTypeDef hpcd; -#elif defined(TARGET_NUMAKER_PFM_NUC472) +#elif defined(TARGET_NUC472) || defined(TARGET_M480) bool (USBHAL::*epCallback[14 - 2])(void); #else bool (USBHAL::*epCallback[32 - 2])(void); diff --git a/features/unsupported/USBDevice/USBDevice/USBHAL_M453.cpp b/features/unsupported/USBDevice/USBDevice/USBHAL_M453.cpp index fb933170267..832fdea952f 100644 --- a/features/unsupported/USBDevice/USBDevice/USBHAL_M453.cpp +++ b/features/unsupported/USBDevice/USBDevice/USBHAL_M453.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#if defined(TARGET_NUMAKER_PFM_M453) +#if defined(TARGET_M451) #include "USBHAL.h" #include "M451Series.h" diff --git a/features/unsupported/USBDevice/USBDevice/USBHAL_NUC472.cpp b/features/unsupported/USBDevice/USBDevice/USBHAL_NUC472.cpp index 7a81554c984..09191e99b20 100644 --- a/features/unsupported/USBDevice/USBDevice/USBHAL_NUC472.cpp +++ b/features/unsupported/USBDevice/USBDevice/USBHAL_NUC472.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#if defined(TARGET_NUMAKER_PFM_NUC472) +#if defined(TARGET_NUC472) #include "USBHAL.h" #include "NUC472_442.h" diff --git a/features/unsupported/USBDevice/targets/TARGET_NUVOTON/TARGET_M480/USBEndpoints_M480.h b/features/unsupported/USBDevice/targets/TARGET_NUVOTON/TARGET_M480/USBEndpoints_M480.h new file mode 100644 index 00000000000..221c229de38 --- /dev/null +++ b/features/unsupported/USBDevice/targets/TARGET_NUVOTON/TARGET_M480/USBEndpoints_M480.h @@ -0,0 +1,93 @@ + +#if (MBED_CONF_TARGET_USB_DEVICE_HSUSBD == 0) +#define NU_MAX_EPX_BUFSIZE 4096 +#else +#define NU_MAX_EPX_BUFSIZE 4096 +#endif + +#define NU_EP2EPL(ep) ((ep) >> 1) + +#if (MBED_CONF_TARGET_USB_DEVICE_HSUSBD == 0) +#define NU_EP2EPH(ep) (((ep) >> 1) + 1) +#define NU_EPL2EPH(ep) ((ep) + 1) +#define NU_EPH2EPL(ep) ((ep) - 1) +#define NUMBER_OF_PHYSICAL_ENDPOINTS 8 +#else +#define NU_EP2EPH(ep) (((ep) >> 1) - 1) +#define NU_EPX2EP(ep) ((ep == CEP) ? EP0OUT : ((ep) - EPA + EP1OUT)) +#define NU_EPL2EPH(ep) ((ep) - 1) +#define NU_EPH2EPL(ep) ((ep) + 1) +#define NUMBER_OF_PHYSICAL_ENDPOINTS 12 +#endif + +#define NU_EP_DIR_Pos 0 +#define NU_EP_DIR_Msk (1 << NU_EP_DIR_Pos) +#define NU_EP_DIR_OUT 0 +#define NU_EP_DIR_IN 1 + +#define NU_EP_TYPE(ep) (((ep) & NU_EP_TYPE_Msk) >> NU_EP_TYPE_Pos) +#define NU_EP_NUM(ep) (((ep) & NU_EP_NUM_Msk) >> NU_EP_NUM_Pos) +#define NU_EP_DIR(ep) (((ep) & NU_EP_DIR_Msk) >> NU_EP_DIR_Pos) +#define NU_EP_NUM_DIR(ep) ((NU_EP_NUM(ep) << 1) | NU_EP_DIR(ep)) + +#define EP0OUT (0) +#define EP0IN (1) +#define EP1OUT (2) +#define EP1IN (3) +#define EP2OUT (4) +#define EP2IN (5) +#define EP3OUT (6) +#define EP3IN (7) +#define EP4OUT (8) +#define EP4IN (9) +#define EP5OUT (10) +#define EP5IN (11) +#define EP6OUT (12) +#define EP6IN (13) + +/* Maximum Packet sizes */ +#define MAX_PACKET_SIZE_EP0 64 +#define MAX_PACKET_SIZE_EP1 64 +#define MAX_PACKET_SIZE_EP2 64 +#define MAX_PACKET_SIZE_EP3 0x60 +#define MAX_PACKET_SIZE_EP4 64 +#define MAX_PACKET_SIZE_EP5 64 +#define MAX_PACKET_SIZE_EP6 64 +#define MAX_PACKET_SIZE_EP7 64 + +#if (MBED_CONF_TARGET_USB_DEVICE_HSUSBD == 1) +#define MAX_PACKET_SIZE_EP8 64 +#define MAX_PACKET_SIZE_EP9 64 +#define MAX_PACKET_SIZE_EP10 64 +#define MAX_PACKET_SIZE_EP11 64 +#endif + +/* Generic endpoints - intended to be portable accross devices */ +/* and be suitable for simple USB devices. */ + +/* Bulk endpoints */ +#define EPBULK_OUT EP5OUT +#define EPBULK_IN EP6IN +#define EPBULK_OUT_callback EP5_OUT_callback +#define EPBULK_IN_callback EP6_IN_callback +/* Interrupt endpoints */ +#define EPINT_OUT EP1OUT +#define EPINT_IN EP2IN +#define EPINT_OUT_callback EP1_OUT_callback +#define EPINT_IN_callback EP2_IN_callback +/* Isochronous endpoints */ +#define EPISO_OUT EP3OUT +#define EPISO_IN EP4IN +#define EPISO_OUT_callback EP3_OUT_callback +#define EPISO_IN_callback EP4_IN_callback + +#define MAX_PACKET_SIZE_EPBULK 64 +#define MAX_PACKET_SIZE_EPINT 64 +#define MAX_PACKET_SIZE_EPISO 1023 + +#if (MBED_CONF_TARGET_USB_DEVICE_HSUSBD == 1) +#define HSUSBD_GET_EP_MAX_PAYLOAD(ep) HSUSBD->EP[ep].EPMPS +#define HSUSBD_GET_EP_DATA_COUNT(ep) (HSUSBD->EP[ep].EPDATCNT & 0xFFFFF) +#define HSUSBD_SET_EP_SHORT_PACKET(ep) HSUSBD->EP[ep].EPRSPCTL = ((HSUSBD->EP[ep].EPRSPCTL & 0x10) | 0x40) +#define HSUSBD_GET_EP_INT_EN(ep) HSUSBD->EP[ep].EPINTEN +#endif diff --git a/features/unsupported/USBDevice/targets/TARGET_NUVOTON/TARGET_M480/USBHAL_M480.cpp b/features/unsupported/USBDevice/targets/TARGET_NUVOTON/TARGET_M480/USBHAL_M480.cpp new file mode 100644 index 00000000000..364d195db85 --- /dev/null +++ b/features/unsupported/USBDevice/targets/TARGET_NUVOTON/TARGET_M480/USBHAL_M480.cpp @@ -0,0 +1,1093 @@ +/* mbed Microcontroller Library + * Copyright (c) 2015-2016 Nuvoton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined(TARGET_M480) + +#include "USBHAL.h" +#include "M480.h" +#include "pinmap.h" + +/** + * EP: mbed USBD defined endpoint, e.g. EP0OUT/IN, EP1OUT/IN, EP2OUT/IN. + * EPX: BSP defined endpoint, e.g. CEP, EPA, EPB, EPC. + */ + +USBHAL * USBHAL::instance; + +#if (MBED_CONF_TARGET_USB_DEVICE_HSUSBD == 0) + +/* Global variables for Control Pipe */ +extern uint8_t g_usbd_SetupPacket[]; /*!< Setup packet buffer */ + +static volatile uint32_t s_ep_compl = 0; +static volatile uint32_t s_ep_buf_ind = 8; +static volatile uint8_t s_usb_addr = 0; +static volatile uint8_t s_ep_data_bit[NUMBER_OF_PHYSICAL_ENDPOINTS] = {1}; +static volatile uint8_t s_ep_mxp[NUMBER_OF_PHYSICAL_ENDPOINTS] = {0}; + +extern volatile uint8_t *g_usbd_CtrlInPointer; +extern volatile uint32_t g_usbd_CtrlInSize; +extern volatile uint8_t *g_usbd_CtrlOutPointer; +extern volatile uint32_t g_usbd_CtrlOutSize; +extern volatile uint32_t g_usbd_CtrlOutSizeLimit; +extern volatile uint32_t g_usbd_UsbConfig; +extern volatile uint32_t g_usbd_CtrlMaxPktSize; +extern volatile uint32_t g_usbd_UsbAltInterface; +volatile uint32_t g_usbd_CepTransferLen = 0; +volatile uint32_t frame_cnt = 0; + +USBHAL::USBHAL(void) +{ + SYS_UnlockReg(); + + s_ep_buf_ind = 8; + + memset(epCallback, 0x00, sizeof (epCallback)); + epCallback[0] = &USBHAL::EP1_OUT_callback; + epCallback[1] = &USBHAL::EP2_IN_callback; + epCallback[2] = &USBHAL::EP3_OUT_callback; + epCallback[3] = &USBHAL::EP4_IN_callback; + epCallback[4] = &USBHAL::EP5_OUT_callback; + epCallback[5] = &USBHAL::EP6_IN_callback; + epCallback[6] = &USBHAL::EP7_OUT_callback; + epCallback[7] = &USBHAL::EP8_IN_callback; + epCallback[8] = &USBHAL::EP9_OUT_callback; + epCallback[9] = &USBHAL::EP10_IN_callback; + epCallback[10] = &USBHAL::EP11_OUT_callback; + epCallback[11] = &USBHAL::EP12_IN_callback; + + instance = this; + + /* Configure USB to Device mode */ + SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | SYS_USBPHY_USBROLE_STD_USBD; + + /* Enable USB PHY */ + SYS->USBPHY |= SYS_USBPHY_USBEN_Msk | SYS_USBPHY_SBO_Msk; + + /* Select IP clock source */ + CLK->CLKDIV0 = (CLK->CLKDIV0 & ~CLK_CLKDIV0_USBDIV_Msk) | CLK_CLKDIV0_USB(4); + + /* Enable IP clock */ + CLK_EnableModuleClock(USBD_MODULE); + + /* Configure pins for USB 1.1 port: VBUS/D+/D-/ID */ + pin_function(PA_12, SYS_GPA_MFPH_PA12MFP_USB_VBUS); + pin_function(PA_13, SYS_GPA_MFPH_PA13MFP_USB_D_N); + pin_function(PA_14, SYS_GPA_MFPH_PA14MFP_USB_D_P); + pin_function(PA_15, (int) SYS_GPA_MFPH_PA15MFP_USB_OTG_ID); + + /* Initial USB engine */ + USBD->ATTR = 0x7D0; + + /* Set SE0 (disconnect) */ + USBD_SET_SE0(); + + //NVIC_SetVector(OTG_FS_IRQn, (uint32_t) &_usbisr); + NVIC_SetVector(USBD_IRQn, (uint32_t) &_usbisr); + NVIC_EnableIRQ(USBD_IRQn); +} + +USBHAL::~USBHAL(void) +{ + NVIC_DisableIRQ(USBD_IRQn); + USBD_SET_SE0(); + USBD_DISABLE_PHY(); +} + +void USBHAL::connect(void) +{ + USBD->STBUFSEG = 0; + frame_cnt = 0; + /* EP0 ==> control IN endpoint, address 0 */ + USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | 0); + /* Buffer range for EP0 */ + USBD_SET_EP_BUF_ADDR(EP0, s_ep_buf_ind); + + /* EP1 ==> control OUT endpoint, address 0 */ + USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | 0); + /* Buffer range for EP1 */ + USBD_SET_EP_BUF_ADDR(EP1, s_ep_buf_ind); + + s_ep_buf_ind += MAX_PACKET_SIZE_EP0; + + /* Disable software-disconnect function */ + USBD_CLR_SE0(); + + /* Clear USB-related interrupts before enable interrupt */ + USBD_CLR_INT_FLAG(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP); + + /* Enable USB-related interrupts. */ + USBD_ENABLE_INT(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP); +} + +void USBHAL::disconnect(void) +{ + /* Set SE0 (disconnect) */ + USBD_SET_SE0(); +} + +void USBHAL::configureDevice(void) +{ + /** + * In USBDevice.cpp > USBDevice::requestSetConfiguration, configureDevice() is called after realiseEndpoint() (in USBCallback_setConfiguration()). + * So we have the following USB buffer management policy: + * 1. Allocate for CEP on connect(). + * 2. Allocate for EPX in realiseEndpoint(). + * 3. Deallocate all except for CEP in unconfigureDevice(). + */ +} + +void USBHAL::unconfigureDevice(void) +{ + s_ep_buf_ind = 8; +} + +void USBHAL::setAddress(uint8_t address) +{ + // NOTE: Delay address setting; otherwise, USB controller won't ack. + s_usb_addr = address; +} + +void USBHAL::remoteWakeup(void) +{ +#if 0 + USBD->OPER |= USBD_OPER_RESUMEEN_Msk; +#endif +} + +bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options) +{ + uint32_t ep_type = 0; + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + uint32_t ep_logic_index = NU_EP2EPL(endpoint); + uint32_t ep_dir = (NU_EP_DIR(endpoint) == NU_EP_DIR_IN) ? USBD_CFG_EPMODE_IN : USBD_CFG_EPMODE_OUT; + + if(ep_logic_index == 3 || ep_logic_index == 4) + ep_type = USBD_CFG_TYPE_ISO; + + USBD_CONFIG_EP(ep_hw_index, ep_dir | ep_type | ep_logic_index); + /* Buffer range */ + USBD_SET_EP_BUF_ADDR(ep_hw_index, s_ep_buf_ind); + + if(ep_dir == USBD_CFG_EPMODE_OUT) + USBD_SET_PAYLOAD_LEN(ep_hw_index, maxPacket); + + s_ep_mxp[ep_logic_index] = maxPacket; + + s_ep_buf_ind += maxPacket; + + return true; +} + +void USBHAL::EP0setup(uint8_t *buffer) +{ + uint32_t sz; + endpointReadResult(EP0OUT, buffer, &sz); +} + +void USBHAL::EP0read(void) +{ + + +} + +void USBHAL::EP0readStage(void) +{ + // N/A + + USBD_PrepareCtrlOut(0,0); +} + +uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) +{ + uint32_t i; + uint8_t *buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP1)); + uint32_t ceprxcnt = USBD_GET_PAYLOAD_LEN(EP1); + for (i = 0; i < ceprxcnt; i ++) + buffer[i] = buf[i]; + USBD_SET_PAYLOAD_LEN(EP1, MAX_PACKET_SIZE_EP0); + return ceprxcnt; +} + +void USBHAL::EP0write(uint8_t *buffer, uint32_t size) +{ + if (buffer && size) { + if(s_ep_data_bit[0] & 1) + USBD_SET_DATA1(EP0); + else + USBD_SET_DATA0(EP0); + s_ep_data_bit[0]++; + + USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), buffer, size); + USBD_SET_PAYLOAD_LEN(EP0, size); + if(size < MAX_PACKET_SIZE_EP0) + s_ep_data_bit[0] = 1; + + } else { + if(g_usbd_SetupPacket[0] & 0x80) { //Device to Host + // Status stage + // USBD_PrepareCtrlOut(0,0); + } else { + USBD_SET_DATA1(EP0); + USBD_SET_PAYLOAD_LEN(EP0, 0); + } + } +} + +void USBHAL::EP0getWriteResult(void) +{ + // N/A +} + +void USBHAL::EP0stall(void) +{ + stallEndpoint(EP0OUT); +} + +EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) +{ + return EP_PENDING; +} + +EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) //spcheng +{ + if(endpoint == EP0OUT) { + USBD_MemCopy(g_usbd_SetupPacket, (uint8_t *)USBD_BUF_BASE, 8); + if (buffer) { + USBD_MemCopy(buffer, g_usbd_SetupPacket, 8); + } + USBD_SET_PAYLOAD_LEN(EP1, MAX_PACKET_SIZE_EP0); + } else { + uint32_t i; + uint8_t *buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(NU_EP2EPH(endpoint))); + uint32_t eprxcnt = USBD_GET_PAYLOAD_LEN(NU_EP2EPH(endpoint)); + for (i = 0; i < eprxcnt; i ++) + buffer[i] = buf[i]; + + *bytesRead = eprxcnt; + + USBD_SET_PAYLOAD_LEN(NU_EP2EPH(endpoint),s_ep_mxp[NU_EPH2EPL(NU_EP2EPL(endpoint))]); + } + return EP_COMPLETED; +} + + +uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) +{ + return 0; +} + +EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) +{ + uint32_t ep_logic_index = NU_EP2EPL(endpoint); + if(ep_logic_index == 0) + return EP_INVALID; + else { + uint8_t *buf; + uint32_t i=0; + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + s_ep_compl |= (1 << ep_logic_index); + buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(ep_hw_index)); + for(i=0; i= NUMBER_OF_PHYSICAL_ENDPOINTS) + return; + + USBD_SetStall(NU_EPH2EPL(ep_hw_index)); + +} + +void USBHAL::unstallEndpoint(uint8_t endpoint) +{ + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS) + return; + USBD_ClearStall(NU_EPH2EPL(ep_hw_index)); +} + +bool USBHAL::getEndpointStallState(uint8_t endpoint) +{ + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS) + return false; + + return USBD_GetStall(NU_EPH2EPL(ep_hw_index)) ? 1 : 0; +} + +void USBHAL::_usbisr(void) +{ + MBED_ASSERT(instance); + instance->usbisr(); +} + +void USBHAL::usbisr(void) +{ + uint32_t u32IntSts = USBD_GET_INT_FLAG(); + uint32_t u32State = USBD_GET_BUS_STATE(); + +//------------------------------------------------------------------ + if(u32IntSts & USBD_INTSTS_VBDETIF_Msk) { + // Floating detect + USBD_CLR_INT_FLAG(USBD_INTSTS_VBDETIF_Msk); + + if(USBD_IS_ATTACHED()) { + /* USB Plug In */ + USBD_ENABLE_USB(); + } else { + /* USB Un-plug */ + USBD_DISABLE_USB(); + } + } + +//------------------------------------------------------------------ + if(u32IntSts & USBD_INTSTS_BUSIF_Msk) { + /* Clear event flag */ + USBD_CLR_INT_FLAG(USBD_INTSTS_BUSIF_Msk); + + if(u32State & USBD_ATTR_USBRST_Msk) { + /* Bus reset */ + USBD_ENABLE_USB(); + USBD_SwReset(); + } + if(u32State & USBD_ATTR_SUSPEND_Msk) { + /* Enable USB but disable PHY */ + USBD_DISABLE_PHY(); + } + if(u32State & USBD_ATTR_RESUME_Msk) { + /* Enable USB and enable PHY */ + USBD_ENABLE_USB(); + } + } + + if(u32IntSts & USBD_INTSTS_USBIF_Msk) { + // USB event + if(u32IntSts & USBD_INTSTS_SETUP_Msk) { + // Setup packet + /* Clear event flag */ + USBD_CLR_INT_FLAG(USBD_INTSTS_SETUP_Msk); + + /* Clear the data IN/OUT ready flag of control end-points */ + USBD_STOP_TRANSACTION(EP0); + USBD_STOP_TRANSACTION(EP1); + EP0setupCallback(); + } + + // EP events + if(u32IntSts & USBD_INTSTS_EP0) { + /* Clear event flag */ + USBD_CLR_INT_FLAG(USBD_INTSTS_EP0); + // control IN + EP0in(); + + // In ACK for Set address + if((g_usbd_SetupPacket[0] == REQ_STANDARD) && (g_usbd_SetupPacket[1] == USBD_SET_ADDRESS)) { + if((USBD_GET_ADDR() != s_usb_addr) && (USBD_GET_ADDR() == 0)) { + USBD_SET_ADDR(s_usb_addr); + } + } + } + if(u32IntSts & USBD_INTSTS_EP1) { + /* Clear event flag */ + USBD_CLR_INT_FLAG(USBD_INTSTS_EP1); + + // control OUT + EP0out(); + } + + uint32_t gintsts_epx = (u32IntSts >> 18) & 0x3F; + uint32_t ep_hw_index = 2; + while (gintsts_epx) { + if(gintsts_epx & 0x01) { + uint32_t ep_status = (USBD_GET_EP_FLAG() >> (ep_hw_index * 3 + 8)) & 0x7; + /* Clear event flag */ + USBD_CLR_INT_FLAG(1 << (ep_hw_index + 16)); + + if(ep_status == 0x02 || ep_status == 0x06 || (ep_status == 0x07 && NU_EPH2EPL(ep_hw_index) == 3)) { //RX + if(ep_status == 0x07) + SOF(frame_cnt++); + if ((instance->*(epCallback[ep_hw_index-2]))()) { + + } + USBD_SET_PAYLOAD_LEN(ep_hw_index,s_ep_mxp[NU_EPH2EPL(ep_hw_index)]); + } else if(ep_status == 0x00 || ep_status == 0x07) { //TX + s_ep_compl &= ~(1 << (NU_EPH2EPL(ep_hw_index))); + if ((instance->*(epCallback[ep_hw_index-2]))()) { + } + } + } + + gintsts_epx = gintsts_epx >> 1; + ep_hw_index++; + } + } +} +#else + +static volatile uint32_t s_ep_compl = 0; +static volatile uint32_t s_ep_buf_ind = 0; +static volatile uint8_t s_usb_addr = 0; +static volatile S_HSUSBD_CMD_T s_setup; +static volatile uint16_t s_ctrlin_packetsize; +static uint8_t *g_usbd_CtrlInPointer = 0; +static uint32_t g_usbd_CtrlMaxPktSize = 64; +static volatile uint32_t g_usbd_CtrlInSize; +static uint32_t g_usbd_ShortPacket = 0; +//static uint32_t gEpRead = 0; +static uint32_t gEpReadCnt = 0; + +void HSUSBD_CtrlInput(void) +{ + unsigned volatile i; + uint32_t volatile count; + + // Process remained data + if(g_usbd_CtrlInSize >= g_usbd_CtrlMaxPktSize) { + // Data size > MXPLD + for (i=0; i<(g_usbd_CtrlMaxPktSize >> 2); i++, g_usbd_CtrlInPointer+=4) + HSUSBD->CEPDAT = *(uint32_t *)g_usbd_CtrlInPointer; + HSUSBD_START_CEP_IN(g_usbd_CtrlMaxPktSize); + g_usbd_CtrlInSize -= g_usbd_CtrlMaxPktSize; + } else { + // Data size <= MXPLD + for (i=0; i<(g_usbd_CtrlInSize >> 2); i++, g_usbd_CtrlInPointer+=4) + HSUSBD->CEPDAT = *(uint32_t *)g_usbd_CtrlInPointer; + + count = g_usbd_CtrlInSize % 4; + for (i=0; iCEPDAT_BYTE = *(uint8_t *)(g_usbd_CtrlInPointer + i); + + HSUSBD_START_CEP_IN(g_usbd_CtrlInSize); + g_usbd_CtrlInPointer = 0; + g_usbd_CtrlInSize = 0; + } +} + +USBHAL::USBHAL(void) +{ + SYS_UnlockReg(); + + s_ep_buf_ind = 0; + + memset(epCallback, 0x00, sizeof (epCallback)); + epCallback[0] = &USBHAL::EP1_OUT_callback; + epCallback[1] = &USBHAL::EP2_IN_callback; + epCallback[2] = &USBHAL::EP3_OUT_callback; + epCallback[3] = &USBHAL::EP4_IN_callback; + epCallback[4] = &USBHAL::EP5_OUT_callback; + epCallback[5] = &USBHAL::EP6_IN_callback; + epCallback[6] = &USBHAL::EP7_OUT_callback; + epCallback[7] = &USBHAL::EP8_IN_callback; + epCallback[8] = &USBHAL::EP9_OUT_callback; + epCallback[9] = &USBHAL::EP10_IN_callback; + epCallback[10] = &USBHAL::EP11_OUT_callback; + epCallback[11] = &USBHAL::EP12_IN_callback; + + instance = this; + + /* Configure HSUSB to Device mode */ + SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_HSUSBROLE_Msk) | SYS_USBPHY_HSUSBROLE_STD_USBD; + /* Enable HSUSB PHY */ + SYS->USBPHY = (SYS->USBPHY & ~(SYS_USBPHY_HSUSBEN_Msk | SYS_USBPHY_HSUSBACT_Msk)) | SYS_USBPHY_HSUSBEN_Msk; + /* Delay >10 us and then switch HSUSB PHY from reset state to active state */ + wait_us(10); + SYS->USBPHY |= SYS_USBPHY_HSUSBACT_Msk; + + /* Enable USBD module clock */ + CLK_EnableModuleClock(HSUSBD_MODULE); + + /* Enable USB PHY and wait for it ready */ + HSUSBD_ENABLE_PHY(); + while (1) { + HSUSBD->EP[0].EPMPS = 0x20; + if (HSUSBD->EP[0].EPMPS == 0x20) + break; + } + + /* Force to full-speed */ + HSUSBD->OPER = 0;//USBD_OPER_HISPDEN_Msk; + + /* Set SE0 (disconnect) */ + HSUSBD_SET_SE0(); + + NVIC_SetVector(USBD20_IRQn, (uint32_t) &_usbisr); + NVIC_EnableIRQ(USBD20_IRQn); +} + +USBHAL::~USBHAL(void) +{ + NVIC_DisableIRQ(USBD20_IRQn); + HSUSBD_SET_SE0(); + HSUSBD_DISABLE_PHY(); +} + +void USBHAL::connect(void) +{ + HSUSBD_ResetDMA(); + HSUSBD_SET_ADDR(0); + + /** + * Control Transfer Packet Size Constraints + * low-speed: 8 + * full-speed: 8, 16, 32, 64 + * high-speed: 64 + */ + /* Control endpoint */ + HSUSBD_SetEpBufAddr(CEP, s_ep_buf_ind, MAX_PACKET_SIZE_EP0); + s_ep_buf_ind = MAX_PACKET_SIZE_EP0; + + /* Enable USB/CEP interrupt */ + HSUSBD_ENABLE_USB_INT(HSUSBD_GINTEN_USBIEN_Msk | HSUSBD_GINTEN_CEPIEN_Msk); + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk|HSUSBD_CEPINTEN_STSDONEIEN_Msk); + + /* Enable BUS interrupt */ + HSUSBD_ENABLE_BUS_INT( + HSUSBD_BUSINTEN_DMADONEIEN_Msk | + HSUSBD_BUSINTEN_RESUMEIEN_Msk | + HSUSBD_BUSINTEN_RSTIEN_Msk | + HSUSBD_BUSINTEN_VBUSDETIEN_Msk | + HSUSBD_BUSINTEN_SOFIEN_Msk + ); + + /* Clear SE0 (connect) */ + HSUSBD_CLR_SE0(); +} + +void USBHAL::disconnect(void) +{ + /* Set SE0 (disconnect) */ + HSUSBD_SET_SE0(); +} + +void USBHAL::configureDevice(void) +{ + /** + * In USBDevice.cpp > USBDevice::requestSetConfiguration, configureDevice() is called after realiseEndpoint() (in USBCallback_setConfiguration()). + * So we have the following USB buffer management policy: + * 1. Allocate for CEP on connect(). + * 2. Allocate for EPX in realiseEndpoint(). + * 3. Deallocate all except for CEP in unconfigureDevice(). + */ +} + +void USBHAL::unconfigureDevice(void) +{ + s_ep_buf_ind = MAX_PACKET_SIZE_EP0; +} + +void USBHAL::setAddress(uint8_t address) +{ + // NOTE: Delay address setting; otherwise, USB controller won't ack. + s_usb_addr = address; +} + +void USBHAL::remoteWakeup(void) +{ + HSUSBD->OPER |= HSUSBD_OPER_RESUMEEN_Msk; +} + +bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options) +{ + uint32_t ep_type; + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + + HSUSBD_SetEpBufAddr(ep_hw_index, s_ep_buf_ind, maxPacket); + s_ep_buf_ind += maxPacket; + HSUSBD_SET_MAX_PAYLOAD(ep_hw_index, maxPacket); + + switch (NU_EP2EPL(endpoint)) { + case 1: + case 2: + ep_type = HSUSBD_EP_CFG_TYPE_INT; + break; + + case 3: + case 4: + ep_type = HSUSBD_EP_CFG_TYPE_ISO; + break; + + default: + ep_type = HSUSBD_EP_CFG_TYPE_BULK; + } + uint32_t ep_dir = (NU_EP_DIR(endpoint) == NU_EP_DIR_IN) ? HSUSBD_EP_CFG_DIR_IN : HSUSBD_EP_CFG_DIR_OUT; + HSUSBD_ConfigEp(ep_hw_index, NU_EP2EPL(endpoint), ep_type, ep_dir); + + /* Enable USB/EPX interrupt */ + // NOTE: Require USBD_GINTEN_EPAIE_Pos, USBD_GINTEN_EPBIE_Pos, ... USBD_GINTEN_EPLIE_Pos to be consecutive. + HSUSBD_ENABLE_USB_INT(HSUSBD->GINTEN | HSUSBD_GINTEN_USBIEN_Msk | + HSUSBD_GINTEN_CEPIEN_Msk | + 1 << (ep_hw_index + HSUSBD_GINTEN_EPAIEN_Pos)); // Added USB/EPX interrupt + + if (ep_dir == 0) + HSUSBD_ENABLE_EP_INT(ep_hw_index, HSUSBD_EPINTEN_RXPKIEN_Msk); + else + HSUSBD_ENABLE_EP_INT(ep_hw_index, HSUSBD_EPINTEN_TXPKIEN_Msk); + return true; +} + +void USBHAL::EP0setup(uint8_t *buffer) +{ + uint32_t sz; + endpointReadResult(EP0OUT, buffer, &sz); +} + +void USBHAL::EP0read(void) +{ + if (s_setup.wLength && ! (s_setup.bmRequestType & 0x80)) { + // Control OUT + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk | HSUSBD_CEPINTEN_RXPKIEN_Msk); + } else { + // Status stage + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STSDONEIF_Msk); + HSUSBD_SET_CEP_STATE(HSUSBD_CEPCTL_NAKCLR); + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk); + } +} + +void USBHAL::EP0readStage(void) +{ + // N/A +} + +uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) +{ + uint32_t i; + uint32_t ceprxcnt = HSUSBD->CEPRXCNT; + for (i = 0; i < ceprxcnt; i ++) + *buffer ++ = HSUSBD->CEPDAT_BYTE; + return ceprxcnt; +} + +void USBHAL::EP0write(uint8_t *buffer, uint32_t size) +{ + if (buffer && size) { + g_usbd_CtrlInPointer = buffer; + g_usbd_CtrlInSize = size; + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_INTKIF_Msk); + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_INTKIEN_Msk); + } else { + /* Status stage */ + s_ctrlin_packetsize = 0; + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STSDONEIF_Msk); + HSUSBD_SET_CEP_STATE(HSUSBD_CEPCTL_NAKCLR); + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk); + } +} + +void USBHAL::EP0getWriteResult(void) +{ + // N/A +} + +void USBHAL::EP0stall(void) +{ + stallEndpoint(EP0OUT); +} + +EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) +{ + return EP_PENDING; +} + +EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) //spcheng +{ + if(endpoint == EP0OUT) { + if (buffer) { + *((uint16_t *) (buffer + 0)) = (uint16_t) HSUSBD->SETUP1_0; + *((uint16_t *) (buffer + 2)) = (uint16_t) HSUSBD->SETUP3_2; + *((uint16_t *) (buffer + 4)) = (uint16_t) HSUSBD->SETUP5_4; + *((uint16_t *) (buffer + 6)) = (uint16_t) HSUSBD->SETUP7_6; + } + + s_setup.bmRequestType = (uint8_t) (HSUSBD->SETUP1_0 & 0xff); + s_setup.bRequest = (int8_t) (HSUSBD->SETUP1_0 >> 8) & 0xff; + s_setup.wValue = (uint16_t) HSUSBD->SETUP3_2; + s_setup.wIndex = (uint16_t) HSUSBD->SETUP5_4; + s_setup.wLength = (uint16_t) HSUSBD->SETUP7_6; + } else { + if (!(s_ep_compl & (1 << NU_EP2EPL(endpoint)))) { + while(1) { + if (!(HSUSBD->DMACTL & HSUSBD_DMACTL_DMAEN_Msk)) + break; + else if (!HSUSBD_IS_ATTACHED()) + break; + } + gEpReadCnt = HSUSBD_GET_EP_DATA_COUNT(NU_EP2EPH(endpoint)); + if(gEpReadCnt == 0) { + *bytesRead = 0; + return EP_COMPLETED; + } + s_ep_compl |= (1 << NU_EP2EPL(endpoint)); + HSUSBD_SET_DMA_LEN(gEpReadCnt); + HSUSBD_SET_DMA_ADDR((uint32_t)buffer); + HSUSBD_SET_DMA_WRITE(NU_EP2EPL(endpoint)); + HSUSBD_ENABLE_DMA(); + return EP_PENDING;; + + } else { + if ((HSUSBD->DMACTL & HSUSBD_DMACTL_DMAEN_Msk)) + return EP_PENDING;; + + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_DMADONEIF_Msk); + s_ep_compl &= ~(1 << NU_EP2EPL(endpoint)); + *bytesRead = gEpReadCnt; + } + } + return EP_COMPLETED; +} + + +uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) +{ + return 0; +} + +EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) +{ + uint32_t ep_logic_index = NU_EP2EPL(endpoint); + if(ep_logic_index == 0) + return EP_INVALID; + else { + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + uint32_t mps = HSUSBD_GET_EP_MAX_PAYLOAD(ep_hw_index); + if (size > mps) { + return EP_INVALID; + } + if(size < mps) + g_usbd_ShortPacket = 1; + if (!(s_ep_compl & (1 << NU_EP2EPL(endpoint)))) { + s_ep_compl |= (1 << ep_logic_index); + + while(1) { + if (!(HSUSBD->DMACTL & HSUSBD_DMACTL_DMAEN_Msk)) + break; + else if (!HSUSBD_IS_ATTACHED()) + break; + } + HSUSBD_SET_DMA_LEN(size); + HSUSBD_SET_DMA_ADDR((uint32_t)data); + HSUSBD_SET_DMA_READ(ep_logic_index); + HSUSBD_ENABLE_DMA(); + } + } + return EP_PENDING; +} + +EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) +{ + if (!(s_ep_compl & (1 << NU_EP2EPL(endpoint)))) + return EP_COMPLETED; + else { + if((HSUSBD_GET_EP_DATA_COUNT(NU_EP2EPH(endpoint))) == 0 && !(HSUSBD->DMACTL & HSUSBD_DMACTL_DMAEN_Msk)) { + s_ep_compl &= ~(s_ep_compl & (1 << NU_EP2EPL(endpoint))); + return EP_COMPLETED; + } + } + return EP_PENDING; +} + +void USBHAL::stallEndpoint(uint8_t endpoint) +{ + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS) + return; + HSUSBD_SetStall(ep_hw_index); +} + +void USBHAL::unstallEndpoint(uint8_t endpoint) +{ + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS) + return; + HSUSBD_ClearStall(ep_hw_index); +} + +bool USBHAL::getEndpointStallState(uint8_t endpoint) +{ + uint32_t ep_hw_index = NU_EP2EPH(endpoint); + if (ep_hw_index >= NUMBER_OF_PHYSICAL_ENDPOINTS) + return false; + return HSUSBD_GetStall(ep_hw_index) ? 1 : 0; +} + +void USBHAL::_usbisr(void) +{ + MBED_ASSERT(instance); + instance->usbisr(); +} + +void USBHAL::usbisr(void) +{ + uint32_t gintsts = HSUSBD->GINTSTS & HSUSBD->GINTEN; + if (! gintsts) + return; + + if (gintsts & HSUSBD_GINTSTS_USBIF_Msk) { + uint32_t busintsts = HSUSBD->BUSINTSTS & HSUSBD->BUSINTEN; + + /* SOF */ + if (busintsts & HSUSBD_BUSINTSTS_SOFIF_Msk) { + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_SOFIF_Msk); + // TODO + SOF(HSUSBD->FRAMECNT >> 3); + } + + /* Reset */ + if (busintsts & HSUSBD_BUSINTSTS_RSTIF_Msk) { + connect(); + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_RSTIF_Msk); + HSUSBD_CLR_CEP_INT_FLAG(0x1ffc); + } + + /* Resume */ + if (busintsts & HSUSBD_BUSINTSTS_RESUMEIF_Msk) { + HSUSBD_ENABLE_BUS_INT(HSUSBD_BUSINTEN_RSTIEN_Msk|HSUSBD_BUSINTEN_SUSPENDIEN_Msk | HSUSBD_BUSINTEN_SOFIEN_Msk | HSUSBD_BUSINTEN_SOFIEN_Msk); + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_RESUMEIF_Msk); + } + + /* Suspend */ + if (busintsts & HSUSBD_BUSINTSTS_SUSPENDIF_Msk) { + HSUSBD_ENABLE_BUS_INT(HSUSBD_BUSINTEN_RSTIEN_Msk | HSUSBD_BUSINTEN_RESUMEIEN_Msk |HSUSBD_BUSINTEN_SOFIEN_Msk); + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_SUSPENDIF_Msk); + } + + /* High-speed */ + if (busintsts & HSUSBD_BUSINTSTS_HISPDIF_Msk) { + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk); + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_HISPDIF_Msk); + } + + /* DMA */ + if (busintsts & HSUSBD_BUSINTSTS_DMADONEIF_Msk) { + if(HSUSBD->DMACTL & 0x10) { /* IN - Read */ + if(g_usbd_ShortPacket) { + uint32_t ep_hw_index = NU_EPL2EPH((HSUSBD->DMACTL & 0xF)); + HSUSBD_SET_EP_SHORT_PACKET(ep_hw_index); + g_usbd_ShortPacket = 0; + } + } + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_DMADONEIF_Msk); + } + + /* PHY clock available */ + if (busintsts & HSUSBD_BUSINTSTS_PHYCLKVLDIF_Msk) { + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_PHYCLKVLDIF_Msk); + } + + /* VBUS plug-in */ + if (busintsts & HSUSBD_BUSINTSTS_VBUSDETIF_Msk) { + if (HSUSBD_IS_ATTACHED()) { + // USB plug-in + HSUSBD_ENABLE_USB(); + } else { + // USB unplug-out + HSUSBD_DISABLE_USB(); + } + HSUSBD_CLR_BUS_INT_FLAG(HSUSBD_BUSINTSTS_VBUSDETIF_Msk); + } + } + + /* CEP interrupts */ + if (gintsts & HSUSBD_GINTSTS_CEPIF_Msk) { + uint32_t cepintsts = HSUSBD->CEPINTSTS & HSUSBD->CEPINTEN; + + /* SETUP token packet */ + if (cepintsts & HSUSBD_CEPINTSTS_SETUPTKIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_SETUPTKIF_Msk); + return; + } + + /* SETUP transaction */ + if (cepintsts & HSUSBD_CEPINTSTS_SETUPPKIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_SETUPPKIF_Msk); + EP0setupCallback(); + return; + } + + /* OUT token packet */ + if (cepintsts & HSUSBD_CEPINTSTS_OUTTKIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_OUTTKIF_Msk); + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk); + return; + } + + /* IN token packet */ + if (cepintsts & HSUSBD_CEPINTSTS_INTKIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_INTKIF_Msk); + if (!(cepintsts & HSUSBD_CEPINTSTS_STSDONEIF_Msk)) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_TXPKIF_Msk); + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_TXPKIEN_Msk); + HSUSBD_CtrlInput(); + } else { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_TXPKIF_Msk); + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_TXPKIEN_Msk|HSUSBD_CEPINTEN_STSDONEIEN_Msk); + } + return; + } + + /* PING packet */ + if (cepintsts & HSUSBD_CEPINTSTS_PINGIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_PINGIF_Msk); + return; + } + + /* IN transaction */ + if (cepintsts & HSUSBD_CEPINTSTS_TXPKIF_Msk) { + EP0in(); + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_TXPKIF_Msk); + return; + } + + /* OUT transaction */ + if (cepintsts & HSUSBD_CEPINTSTS_RXPKIF_Msk) { + EP0out(); + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_RXPKIF_Msk); + return; + } + + /* NAK handshake packet */ + if (cepintsts & HSUSBD_CEPINTSTS_NAKIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_NAKIF_Msk); + return; + } + + /* STALL handshake packet */ + if (cepintsts & HSUSBD_CEPINTSTS_STALLIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STALLIF_Msk); + return; + } + + /* ERR special packet */ + if (cepintsts & HSUSBD_CEPINTSTS_ERRIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_ERRIF_Msk); + return; + } + + /* Status stage transaction */ + if (cepintsts & HSUSBD_CEPINTSTS_STSDONEIF_Msk) { + if (s_usb_addr) { + HSUSBD_SET_ADDR(s_usb_addr); + s_usb_addr = 0; + } + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STSDONEIF_Msk); + HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_SETUPPKIEN_Msk); + return; + } + + /* Buffer Full */ + if (cepintsts & HSUSBD_CEPINTSTS_BUFFULLIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_BUFFULLIF_Msk); + return; + } + + /* Buffer Empty */ + if (cepintsts & HSUSBD_CEPINTSTS_BUFEMPTYIF_Msk) { + HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_BUFEMPTYIF_Msk); + return; + } + } + /* EPA, EPB, EPC, ... EPL interrupts */ + uint32_t gintsts_epx = gintsts >> 2; + uint32_t ep_hw_index = 0; + while (gintsts_epx) { + if(gintsts_epx & 0x01) { + uint32_t epxintsts = HSUSBD_GET_EP_INT_FLAG(ep_hw_index) & HSUSBD_GET_EP_INT_EN(ep_hw_index); + + HSUSBD_CLR_EP_INT_FLAG(ep_hw_index, epxintsts); + + /* Buffer Full */ + if (epxintsts & HSUSBD_EPINTSTS_BUFFULLIF_Msk) { + } + + /* Buffer Empty */ + if (epxintsts & HSUSBD_EPINTSTS_BUFEMPTYIF_Msk) { + } + + /* Short Packet Transferred */ + if (epxintsts & HSUSBD_EPINTSTS_SHORTTXIF_Msk) { + } + + /* Data Packet Transmitted */ + if (epxintsts & HSUSBD_EPINTSTS_TXPKIF_Msk) { + s_ep_compl &= ~(1 << (NU_EPH2EPL(ep_hw_index))); + if ((instance->*(epCallback[ep_hw_index]))()) { + } + } + + /* Data Packet Received */ + if (epxintsts & HSUSBD_EPINTSTS_RXPKIF_Msk) { + if ((instance->*(epCallback[ep_hw_index]))()) { + + } + } + + /* OUT token packet */ + if (epxintsts & HSUSBD_EPINTSTS_OUTTKIF_Msk) { + } + + /* IN token packet */ + if (epxintsts & HSUSBD_EPINTSTS_INTKIF_Msk) { + } + + /* PING packet */ + if (epxintsts & HSUSBD_EPINTSTS_PINGIF_Msk) { + } + + /* NAK handshake packet sent to Host */ + if (epxintsts & HSUSBD_EPINTSTS_NAKIF_Msk) { + } + + /* STALL handshake packet sent to Host */ + if (epxintsts & HSUSBD_EPINTSTS_STALLIF_Msk) { + } + + /* NYET handshake packet sent to Host */ + if (epxintsts & HSUSBD_EPINTSTS_NYETIF_Msk) { + } + + /* ERR packet sent to Host */ + if (epxintsts & HSUSBD_EPINTSTS_ERRIF_Msk) { + } + + /* Bulk Out Short Packet Received */ + if (epxintsts & HSUSBD_EPINTSTS_SHORTRXIF_Msk) { + } + } + gintsts_epx = gintsts_epx >> 1; + ep_hw_index++; + } +} +#endif + +#endif + diff --git a/features/unsupported/USBHost/targets/TARGET_NUVOTON/TARGET_M480/USBHALHost_M480.cpp b/features/unsupported/USBHost/targets/TARGET_NUVOTON/TARGET_M480/USBHALHost_M480.cpp new file mode 100644 index 00000000000..37ecdafda60 --- /dev/null +++ b/features/unsupported/USBHost/targets/TARGET_NUVOTON/TARGET_M480/USBHALHost_M480.cpp @@ -0,0 +1,427 @@ +/* mbed Microcontroller Library + * Copyright (c) 2015-2016 Nuvoton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined(TARGET_M480) + +#include "mbed.h" +#include "USBHALHost.h" +#include "dbg.h" +#include "pinmap.h" + +#define HCCA_SIZE sizeof(HCCA) +#define ED_SIZE sizeof(HCED) +#define TD_SIZE sizeof(HCTD) + +#define TOTAL_SIZE (HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE) + (MAX_TD*TD_SIZE)) +#ifndef USBH_HcRhDescriptorA_POTPGT_Pos +#define USBH_HcRhDescriptorA_POTPGT_Pos (24) +#endif +#ifndef USBH_HcRhDescriptorA_POTPGT_Msk +#define USBH_HcRhDescriptorA_POTPGT_Msk (0xfful << USBH_HcRhDescriptorA_POTPGT_Pos) +#endif + +static volatile MBED_ALIGN(256) uint8_t usb_buf[TOTAL_SIZE]; // 256 bytes aligned! + +USBHALHost * USBHALHost::instHost; + +USBHALHost::USBHALHost() +{ + instHost = this; + memInit(); + memset((void*)usb_hcca, 0, HCCA_SIZE); + for (int i = 0; i < MAX_ENDPOINT; i++) { + edBufAlloc[i] = false; + } + for (int i = 0; i < MAX_TD; i++) { + tdBufAlloc[i] = false; + } +} + +void USBHALHost::init() +{ + // Unlock protected registers + SYS_UnlockReg(); + + /* Enable IP clock */ + CLK->AHBCLK |= CLK_AHBCLK_USBHCKEN_Msk | (1 << 4) | CLK_AHBCLK_HSUSBDCKEN_Msk; + + + /* USB Host desired input clock is 48 MHz. Set as PLL divided by 4 (192/4 = 48) */ + CLK->CLKDIV0 = (CLK->CLKDIV0 & ~CLK_CLKDIV0_USBDIV_Msk) | (3 << CLK_CLKDIV0_USBDIV_Pos); + + /* Enable USBD and OTG clock */ + CLK->APBCLK0 |= CLK_APBCLK0_USBDCKEN_Msk | CLK_APBCLK0_OTGCKEN_Msk; + + /* Configure USB to USB Host role */ + SYS->USBPHY = SYS_USBPHY_HSUSBEN_Msk | SYS_USBPHY_HSUSBROLE_STD_USBH | SYS_USBPHY_USBEN_Msk | SYS_USBPHY_SBO_Msk | SYS_USBPHY_USBROLE_STD_USBH; + + wait_us(20); + + SYS->USBPHY |= SYS_USBPHY_HSUSBACT_Msk; + + /*---------------------------------------------------------------------------------------------------------*/ + /* Init I/O Multi-function */ + /*---------------------------------------------------------------------------------------------------------*/ + + + /* USB_VBUS_EN (USB 1.1 VBUS power enable pin) multi-function pin - PB.15 */ + pin_function(PB_15, SYS_GPB_MFPH_PB15MFP_USB_VBUS_EN); + + /* USB_VBUS_ST (USB 1.1 over-current detect pin) multi-function pin - PC.14 */ + pin_function(PC_14, SYS_GPC_MFPH_PC14MFP_USB_VBUS_ST); + + /* HSUSB_VBUS_EN (USB 2.0 VBUS power enable pin) multi-function pin - PB.10 */ + pin_function(PB_10, SYS_GPB_MFPH_PB10MFP_HSUSB_VBUS_EN); + + /* HSUSB_VBUS_ST (USB 2.0 over-current detect pin) multi-function pin - PB.11 */ + pin_function(PB_11, SYS_GPB_MFPH_PB11MFP_HSUSB_VBUS_ST); + + /* Configure pins for USB 1.1 port: VBUS/D+/D-/ID */ + pin_function(PA_12, SYS_GPA_MFPH_PA12MFP_USB_VBUS); + pin_function(PA_13, SYS_GPA_MFPH_PA13MFP_USB_D_N); + pin_function(PA_14, SYS_GPA_MFPH_PA14MFP_USB_D_P); + pin_function(PA_15, (int) SYS_GPA_MFPH_PA15MFP_USB_OTG_ID); + + SYS_LockReg(); + HSUSBH->USBPCR0 = 0x160; /* enable PHY 0 */ + HSUSBH->USBPCR1 = 0x520; /* enable PHY 1 */ + + // Overcurrent flag is low active + USBH->HcMiscControl |= USBH_HcMiscControl_OCAL_Msk; + + // Disable HC interrupts + USBH->HcInterruptDisable = OR_INTR_ENABLE_MIE; + + // Needed by some controllers + USBH->HcControl = 0; + + // Software reset + USBH->HcCommandStatus = OR_CMD_STATUS_HCR; + while (USBH->HcCommandStatus & OR_CMD_STATUS_HCR); + + // Put HC in reset state + USBH->HcControl = (USBH->HcControl & ~OR_CONTROL_HCFS) | OR_CONTROL_HC_RSET; + // HCD must wait 10ms for HC reset complete + wait_ms(100); + + USBH->HcControlHeadED = 0; // Initialize Control ED list head to 0 + USBH->HcBulkHeadED = 0; // Initialize Bulk ED list head to 0 + USBH->HcHCCA = (uint32_t) usb_hcca; + + USBH->HcFmInterval = DEFAULT_FMINTERVAL; // Frame interval = 12000 - 1 + // MPS = 10,104 + USBH->HcPeriodicStart = FI * 90 / 100; // 90% of frame interval + USBH->HcLSThreshold = 0x628; // Low speed threshold + + // Put HC in operational state + USBH->HcControl = (USBH->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER; + + // FIXME + USBH->HcRhDescriptorA = USBH->HcRhDescriptorA & ~(USBH_HcRhDescriptorA_NOCP_Msk | USBH_HcRhDescriptorA_OCPM_Msk | USBH_HcRhDescriptorA_PSM_Msk); + // Issue SetGlobalPower command + USBH->HcRhStatus = USBH_HcRhStatus_LPSC_Msk; + // Power On To Power Good Time, in 2 ms units + wait_ms(((USBH->HcRhDescriptorA & USBH_HcRhDescriptorA_POTPGT_Msk) >> USBH_HcRhDescriptorA_POTPGT_Pos) * 2); + + // Clear Interrrupt Status + USBH->HcInterruptStatus |= USBH->HcInterruptStatus; + // Enable interrupts we care about + USBH->HcInterruptEnable = OR_INTR_ENABLE_MIE | OR_INTR_ENABLE_WDH | OR_INTR_ENABLE_RHSC; + + NVIC_SetVector(USBH_IRQn, (uint32_t)(_usbisr)); + NVIC_EnableIRQ(USBH_IRQn); + + + // Check for any connected devices + if (USBH->HcRhPortStatus[0] & OR_RH_PORT_CCS) { + // Device connected + wait_ms(150); + deviceConnected(0, 1, USBH->HcRhPortStatus[0] & OR_RH_PORT_LSDA); + } + + // Check for any connected devices + if (USBH->HcRhPortStatus[1] & OR_RH_PORT_CCS) { + // Device connected + wait_ms(150); + deviceConnected(0, 2, USBH->HcRhPortStatus[1] & OR_RH_PORT_LSDA); + } +} + +uint32_t USBHALHost::controlHeadED() +{ + return USBH->HcControlHeadED; +} + +uint32_t USBHALHost::bulkHeadED() +{ + return USBH->HcBulkHeadED; +} + +uint32_t USBHALHost::interruptHeadED() +{ + // FIXME: Only support one INT ED? + return usb_hcca->IntTable[0]; +} + +void USBHALHost::updateBulkHeadED(uint32_t addr) +{ + USBH->HcBulkHeadED = addr; +} + + +void USBHALHost::updateControlHeadED(uint32_t addr) +{ + USBH->HcControlHeadED = addr; +} + +void USBHALHost::updateInterruptHeadED(uint32_t addr) +{ + // FIXME: Only support one INT ED? + usb_hcca->IntTable[0] = addr; +} + + +void USBHALHost::enableList(ENDPOINT_TYPE type) +{ + switch(type) { + case CONTROL_ENDPOINT: + USBH->HcCommandStatus = OR_CMD_STATUS_CLF; + USBH->HcControl |= OR_CONTROL_CLE; + break; + case ISOCHRONOUS_ENDPOINT: + // FIXME + break; + case BULK_ENDPOINT: + USBH->HcCommandStatus = OR_CMD_STATUS_BLF; + USBH->HcControl |= OR_CONTROL_BLE; + break; + case INTERRUPT_ENDPOINT: + USBH->HcControl |= OR_CONTROL_PLE; + break; + } +} + + +bool USBHALHost::disableList(ENDPOINT_TYPE type) +{ + switch(type) { + case CONTROL_ENDPOINT: + if(USBH->HcControl & OR_CONTROL_CLE) { + USBH->HcControl &= ~OR_CONTROL_CLE; + return true; + } + return false; + case ISOCHRONOUS_ENDPOINT: + // FIXME + return false; + case BULK_ENDPOINT: + if(USBH->HcControl & OR_CONTROL_BLE) { + USBH->HcControl &= ~OR_CONTROL_BLE; + return true; + } + return false; + case INTERRUPT_ENDPOINT: + if(USBH->HcControl & OR_CONTROL_PLE) { + USBH->HcControl &= ~OR_CONTROL_PLE; + return true; + } + return false; + } + return false; +} + + +void USBHALHost::memInit() +{ + usb_hcca = (volatile HCCA *)usb_buf; + usb_edBuf = usb_buf + HCCA_SIZE; + usb_tdBuf = usb_buf + HCCA_SIZE + (MAX_ENDPOINT*ED_SIZE); +} + +volatile uint8_t * USBHALHost::getED() +{ + for (int i = 0; i < MAX_ENDPOINT; i++) { + if ( !edBufAlloc[i] ) { + edBufAlloc[i] = true; + return (volatile uint8_t *)(usb_edBuf + i*ED_SIZE); + } + } + perror("Could not allocate ED\r\n"); + return NULL; //Could not alloc ED +} + +volatile uint8_t * USBHALHost::getTD() +{ + int i; + for (i = 0; i < MAX_TD; i++) { + if ( !tdBufAlloc[i] ) { + tdBufAlloc[i] = true; + return (volatile uint8_t *)(usb_tdBuf + i*TD_SIZE); + } + } + perror("Could not allocate TD\r\n"); + return NULL; //Could not alloc TD +} + + +void USBHALHost::freeED(volatile uint8_t * ed) +{ + int i; + i = (ed - usb_edBuf) / ED_SIZE; + edBufAlloc[i] = false; +} + +void USBHALHost::freeTD(volatile uint8_t * td) +{ + int i; + i = (td - usb_tdBuf) / TD_SIZE; + tdBufAlloc[i] = false; +} + + +void USBHALHost::resetRootHub() +{ + // Reset port1 + USBH->HcRhPortStatus[0] = OR_RH_PORT_PRS; + while (USBH->HcRhPortStatus[0] & OR_RH_PORT_PRS); + USBH->HcRhPortStatus[0] = OR_RH_PORT_PRSC; + + USBH->HcRhPortStatus[1] = OR_RH_PORT_PRS; + while (USBH->HcRhPortStatus[1] & OR_RH_PORT_PRS); + USBH->HcRhPortStatus[1] = OR_RH_PORT_PRSC; +} + + +void USBHALHost::_usbisr(void) +{ + if (instHost) { + instHost->UsbIrqhandler(); + } +} + +void USBHALHost::UsbIrqhandler() +{ + uint32_t ints = USBH->HcInterruptStatus; + + // Root hub status change interrupt + if (ints & OR_INTR_STATUS_RHSC) { + uint32_t ints_roothub = USBH->HcRhStatus; + uint32_t ints_port1 = USBH->HcRhPortStatus[0]; + uint32_t ints_port2 = USBH->HcRhPortStatus[1]; + + // Port1: ConnectStatusChange + if (ints_port1 & OR_RH_PORT_CSC) { + if (ints_roothub & OR_RH_STATUS_DRWE) { + // When DRWE is on, Connect Status Change means a remote wakeup event. + } else { + if (ints_port1 & OR_RH_PORT_CCS) { + // Root device connected + + // wait 150ms to avoid bounce + wait_ms(150); + + //Hub 0 (root hub), Port 1 (count starts at 1), Low or High speed + deviceConnected(0, 1, ints_port1 & OR_RH_PORT_LSDA); + } else { + // Root device disconnected + + if (!(ints & OR_INTR_STATUS_WDH)) { + usb_hcca->DoneHead = 0; + } + + // wait 200ms to avoid bounce + wait_ms(200); + + deviceDisconnected(0, 1, NULL, usb_hcca->DoneHead & 0xFFFFFFFE); + + if (ints & OR_INTR_STATUS_WDH) { + usb_hcca->DoneHead = 0; + USBH->HcInterruptStatus = OR_INTR_STATUS_WDH; + } + } + } + USBH->HcRhPortStatus[0] = OR_RH_PORT_CSC; + } + + // Port1: ConnectStatusChange + if (ints_port2 & OR_RH_PORT_CSC) { + if (ints_roothub & OR_RH_STATUS_DRWE) { + // When DRWE is on, Connect Status Change means a remote wakeup event. + } else { + if (ints_port2 & OR_RH_PORT_CCS) { + // Root device connected + + // wait 150ms to avoid bounce + wait_ms(150); + + //Hub 0 (root hub), Port 2 (count starts at 2), Low or High speed + deviceConnected(0, 2, ints_port2 & OR_RH_PORT_LSDA); + } else { + // Root device disconnected + + if (!(ints & OR_INTR_STATUS_WDH)) { + usb_hcca->DoneHead = 0; + } + + // wait 200ms to avoid bounce + wait_ms(200); + + deviceDisconnected(0, 2, NULL, usb_hcca->DoneHead & 0xFFFFFFFE); + + if (ints & OR_INTR_STATUS_WDH) { + usb_hcca->DoneHead = 0; + USBH->HcInterruptStatus = OR_INTR_STATUS_WDH; + } + } + } + USBH->HcRhPortStatus[1] = OR_RH_PORT_CSC; + } + + + // Port1: Reset completed + if (ints_port1 & OR_RH_PORT_PRSC) { + USBH->HcRhPortStatus[0] = OR_RH_PORT_PRSC; + } + // Port1: PortEnableStatusChange + if (ints_port1 & OR_RH_PORT_PESC) { + USBH->HcRhPortStatus[0] = OR_RH_PORT_PESC; + } + + // Port2: PortOverCurrentIndicatorChange + if (ints_port2 & OR_RH_PORT_OCIC) { + USBH->HcRhPortStatus[1] = OR_RH_PORT_OCIC; + } + + // Port2: Reset completed + if (ints_port2 & OR_RH_PORT_PRSC) { + USBH->HcRhPortStatus[1] = OR_RH_PORT_PRSC; + } + // Port2: PortEnableStatusChange + if (ints_port2 & OR_RH_PORT_PESC) { + USBH->HcRhPortStatus[1] = OR_RH_PORT_PESC; + } + USBH->HcInterruptStatus = OR_INTR_STATUS_RHSC; + } + + // Writeback Done Head interrupt + if (ints & OR_INTR_STATUS_WDH) { + transferCompleted(usb_hcca->DoneHead & 0xFFFFFFFE); + USBH->HcInterruptStatus = OR_INTR_STATUS_WDH; + } + + +} +#endif diff --git a/features/unsupported/tests/rtos/mbed/file/main.cpp b/features/unsupported/tests/rtos/mbed/file/main.cpp index 3d07d9c9dbd..be92ac70d3b 100644 --- a/features/unsupported/tests/rtos/mbed/file/main.cpp +++ b/features/unsupported/tests/rtos/mbed/file/main.cpp @@ -39,6 +39,9 @@ void sd_thread(void const *argument) #elif defined(TARGET_NUMAKER_PFM_M453) SDFileSystem sd(PD_13, PD_14, PD_15, PD_12, "sd"); +#elif defined(TARGET_NUMAKER_PFM_M487) + SDFileSystem sd(D11, D12, D13, D10, "sd"); + #else SDFileSystem sd(p11, p12, p13, p14, "sd"); #endif diff --git a/mbed.h b/mbed.h index 879939dc13c..88be01a3b1c 100644 --- a/mbed.h +++ b/mbed.h @@ -16,13 +16,13 @@ #ifndef MBED_H #define MBED_H -#define MBED_LIBRARY_VERSION 150 +#define MBED_LIBRARY_VERSION 151 #if MBED_CONF_RTOS_PRESENT // RTOS present, this is valid only for mbed OS 5 #define MBED_MAJOR_VERSION 5 #define MBED_MINOR_VERSION 5 -#define MBED_PATCH_VERSION 6 +#define MBED_PATCH_VERSION 7 #else // mbed 2 diff --git a/platform/mbed_application.c b/platform/mbed_application.c index ff3e2db3f55..75657f69e7f 100644 --- a/platform/mbed_application.c +++ b/platform/mbed_application.c @@ -44,12 +44,12 @@ void mbed_start_application(uintptr_t address) static void powerdown_nvic() { - int isr_count; + int isr_groups_32; int i; int j; - isr_count = (SCnSCB->ICTR & SCnSCB_ICTR_INTLINESNUM_Msk) >> SCnSCB_ICTR_INTLINESNUM_Pos; - for (i = 0; i < isr_count; i++) { + isr_groups_32 = ((SCnSCB->ICTR & SCnSCB_ICTR_INTLINESNUM_Msk) >> SCnSCB_ICTR_INTLINESNUM_Pos) + 1; + for (i = 0; i < isr_groups_32; i++) { NVIC->ICER[i] = 0xFFFFFFFF; NVIC->ICPR[i] = 0xFFFFFFFF; for (j = 0; j < 8; j++) { diff --git a/rtos/Mail.h b/rtos/Mail.h index b4a0289862d..602907e34e3 100644 --- a/rtos/Mail.h +++ b/rtos/Mail.h @@ -28,7 +28,7 @@ #include "Queue.h" #include "MemoryPool.h" #include "cmsis_os2.h" -#include "rtx_lib.h" +#include "mbed_rtos_storage.h" #include "mbed_rtos1_types.h" #include "platform/NonCopyable.h" diff --git a/rtos/RtosTimer.h b/rtos/RtosTimer.h index b490fd351ae..3abef47c942 100644 --- a/rtos/RtosTimer.h +++ b/rtos/RtosTimer.h @@ -24,7 +24,7 @@ #include #include "cmsis_os2.h" -#include "rtx_lib.h" +#include "mbed_rtos_storage.h" #include "platform/Callback.h" #include "platform/NonCopyable.h" #include "platform/mbed_toolchain.h" @@ -150,7 +150,7 @@ class RtosTimer : private mbed::NonCopyable { osTimerId_t _id; osTimerAttr_t _attr; - os_timer_t _obj_mem; + mbed_rtos_storage_timer_t _obj_mem; mbed::Callback _function; }; diff --git a/rtos/Thread.cpp b/rtos/Thread.cpp index 2db5eccb54d..f01f1b1502d 100644 --- a/rtos/Thread.cpp +++ b/rtos/Thread.cpp @@ -168,7 +168,11 @@ Thread::State Thread::get_state() { _mutex.lock(); if (_tid != NULL) { +#if defined(MBED_OS_BACKEND_RTX5) state = _obj_mem.state; +#else + state = osThreadGetState(_tid); +#endif } _mutex.unlock(); @@ -185,6 +189,7 @@ Thread::State Thread::get_state() { case osThreadRunning: user_state = Running; break; +#if defined(MBED_OS_BACKEND_RTX5) case osRtxThreadWaitingDelay: user_state = WaitingDelay; break; @@ -212,6 +217,7 @@ Thread::State Thread::get_state() { case osRtxThreadWaitingMessagePut: user_state = WaitingMessagePut; break; +#endif case osThreadTerminated: default: user_state = Deleted; @@ -226,8 +232,7 @@ uint32_t Thread::stack_size() { _mutex.lock(); if (_tid != NULL) { - os_thread_t *thread = (os_thread_t *)_tid; - size = thread->stack_size; + size = osThreadGetStackSize(_tid); } _mutex.unlock(); @@ -238,10 +243,12 @@ uint32_t Thread::free_stack() { uint32_t size = 0; _mutex.lock(); +#if defined(MBED_OS_BACKEND_RTX5) if (_tid != NULL) { os_thread_t *thread = (os_thread_t *)_tid; size = (uint32_t)thread->sp - (uint32_t)thread->stack_mem; } +#endif _mutex.unlock(); return size; @@ -251,10 +258,12 @@ uint32_t Thread::used_stack() { uint32_t size = 0; _mutex.lock(); +#if defined(MBED_OS_BACKEND_RTX5) if (_tid != NULL) { os_thread_t *thread = (os_thread_t *)_tid; size = ((uint32_t)thread->stack_mem + thread->stack_size) - thread->sp; } +#endif _mutex.unlock(); return size; @@ -265,11 +274,15 @@ uint32_t Thread::max_stack() { _mutex.lock(); if (_tid != NULL) { +#if defined(MBED_OS_BACKEND_RTX5) os_thread_t *thread = (os_thread_t *)_tid; uint32_t high_mark = 0; while (((uint32_t *)(thread->stack_mem))[high_mark] == 0xE25A2EA5) high_mark++; size = thread->stack_size - (high_mark * sizeof(uint32_t)); +#else + size = osThreadGetStackSize(_tid) - osThreadGetStackSpace(_tid); +#endif } _mutex.unlock(); diff --git a/rtos/Thread.h b/rtos/Thread.h index 3d921bdb2e1..7aa4faa2762 100644 --- a/rtos/Thread.h +++ b/rtos/Thread.h @@ -26,7 +26,6 @@ #include "cmsis_os2.h" #include "mbed_rtos1_types.h" #include "mbed_rtos_storage.h" -#include "mbed_rtx_conf.h" #include "platform/Callback.h" #include "platform/mbed_toolchain.h" #include "platform/NonCopyable.h" diff --git a/rtos/mbed_rtos_storage.h b/rtos/mbed_rtos_storage.h index 50e92273701..11ebc43453f 100644 --- a/rtos/mbed_rtos_storage.h +++ b/rtos/mbed_rtos_storage.h @@ -41,6 +41,7 @@ extern "C" { */ #include "rtx_lib.h" +#include "mbed_rtx_conf.h" typedef os_mutex_t mbed_rtos_storage_mutex_t; typedef os_semaphore_t mbed_rtos_storage_semaphore_t; diff --git a/rtos/rtos.h b/rtos/rtos.h index 968ca78dd40..af0c08ccb63 100644 --- a/rtos/rtos.h +++ b/rtos/rtos.h @@ -25,8 +25,6 @@ #ifndef RTOS_H #define RTOS_H -#include "mbed_rtx.h" -#include "mbed_rtx_conf.h" #include "mbed_rtos_storage.h" #include "rtos/Thread.h" #include "rtos/Mutex.h" diff --git a/rtos/rtx5/mbed_rtx_conf.h b/rtos/rtx5/mbed_rtx_conf.h index b4fe1d4f224..304c2a11d61 100644 --- a/rtos/rtx5/mbed_rtx_conf.h +++ b/rtos/rtx5/mbed_rtx_conf.h @@ -24,6 +24,9 @@ #include "mbed_rtx.h" +/** Any access to RTX5 specific data structures used in common code should be wrapped in ifdef MBED_OS_BACKEND_RTX5 */ +#define MBED_OS_BACKEND_RTX5 + /** The thread's stack size can be configured by the application, if not explicitly specified it'll default to 4K */ #ifndef MBED_CONF_APP_THREAD_STACK_SIZE #define MBED_CONF_APP_THREAD_STACK_SIZE 4096 diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/cmsis_nvic.h index 93a590e880f..e58d148155b 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/cmsis_nvic.h @@ -39,7 +39,7 @@ extern uint32_t __VECTOR_RAM[]; #endif /* Symbols defined by the linker script */ -#define NVIC_NUM_VECTORS (16 + 240) // CORE + MCU Peripherals +#define NVIC_NUM_VECTORS (16 + 100) // CORE + MCU Peripherals #define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/device/cmsis_nvic.h index 93a590e880f..84ad93b14fa 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/device/cmsis_nvic.h @@ -39,7 +39,7 @@ extern uint32_t __VECTOR_RAM[]; #endif /* Symbols defined by the linker script */ -#define NVIC_NUM_VECTORS (16 + 240) // CORE + MCU Peripherals +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals #define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/device/cmsis_nvic.h index 93a590e880f..84ad93b14fa 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/device/cmsis_nvic.h @@ -39,7 +39,7 @@ extern uint32_t __VECTOR_RAM[]; #endif /* Symbols defined by the linker script */ -#define NVIC_NUM_VECTORS (16 + 240) // CORE + MCU Peripherals +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals #define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/device/cmsis_nvic.h index 93a590e880f..84ad93b14fa 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/device/cmsis_nvic.h @@ -39,7 +39,7 @@ extern uint32_t __VECTOR_RAM[]; #endif /* Symbols defined by the linker script */ -#define NVIC_NUM_VECTORS (16 + 240) // CORE + MCU Peripherals +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals #define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/device/cmsis_nvic.h index 93a590e880f..3fa5aa46682 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/device/cmsis_nvic.h @@ -39,7 +39,7 @@ extern uint32_t __VECTOR_RAM[]; #endif /* Symbols defined by the linker script */ -#define NVIC_NUM_VECTORS (16 + 240) // CORE + MCU Peripherals +#define NVIC_NUM_VECTORS (16 + 65) // CORE + MCU Peripherals #define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis_nvic.h index 490274f50d7..ded7a23f14a 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis_nvic.h @@ -39,7 +39,7 @@ extern uint32_t __VECTOR_RAM[]; #endif /* defined(__CC_ARM) */ /* Symbols defined by the linker script */ -#define NVIC_NUM_VECTORS (16 + 240) // CORE + MCU Peripherals +#define NVIC_NUM_VECTORS (16 + 74) // CORE + MCU Peripherals #define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/cmsis_nvic.h index 490274f50d7..e79f5ab471b 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/cmsis_nvic.h @@ -39,7 +39,7 @@ extern uint32_t __VECTOR_RAM[]; #endif /* defined(__CC_ARM) */ /* Symbols defined by the linker script */ -#define NVIC_NUM_VECTORS (16 + 240) // CORE + MCU Peripherals +#define NVIC_NUM_VECTORS (16 + 86) // CORE + MCU Peripherals #define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_hsusbd.c b/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_hsusbd.c index c31aa258e36..44cfe327fd0 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_hsusbd.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_hsusbd.c @@ -294,7 +294,7 @@ void HSUSBD_StandardRequest(void) if ((gUsbCmd.bmRequestType & 0x80ul) == 0x80ul) { /* request data transfer direction */ /* Device to host */ switch (gUsbCmd.bRequest) { - case GET_CONFIGURATION: { + case USBD_GET_CONFIGURATION: { /* Return current configuration setting */ HSUSBD_PrepareCtrlIn((uint8_t *)&g_hsusbd_UsbConfig, 1ul); @@ -302,14 +302,14 @@ void HSUSBD_StandardRequest(void) HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_INTKIEN_Msk); break; } - case GET_DESCRIPTOR: { + case USBD_GET_DESCRIPTOR: { if (!HSUSBD_GetDescriptor()) { HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_INTKIF_Msk); HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_INTKIEN_Msk); } break; } - case GET_INTERFACE: { + case USBD_GET_INTERFACE: { /* Return current interface setting */ HSUSBD_PrepareCtrlIn((uint8_t *)&g_hsusbd_UsbAltInterface, 1ul); @@ -317,7 +317,7 @@ void HSUSBD_StandardRequest(void) HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_INTKIEN_Msk); break; } - case GET_STATUS: { + case USBD_GET_STATUS: { /* Device */ if (gUsbCmd.bmRequestType == 0x80ul) { if ((g_hsusbd_sInfo->gu8ConfigDesc[7] & 0x40ul) == 0x40ul) { @@ -350,7 +350,7 @@ void HSUSBD_StandardRequest(void) } else { /* Host to device */ switch (gUsbCmd.bRequest) { - case CLEAR_FEATURE: { + case USBD_CLEAR_FEATURE: { if((gUsbCmd.wValue & 0xfful) == FEATURE_ENDPOINT_HALT) { uint32_t epNum, i; @@ -370,7 +370,7 @@ void HSUSBD_StandardRequest(void) HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk); break; } - case SET_ADDRESS: { + case USBD_SET_ADDRESS: { g_hsusbd_UsbAddr = (uint8_t)gUsbCmd.wValue; /* Status Stage */ HSUSBD_CLR_CEP_INT_FLAG(HSUSBD_CEPINTSTS_STSDONEIF_Msk); @@ -378,7 +378,7 @@ void HSUSBD_StandardRequest(void) HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk); break; } - case SET_CONFIGURATION: { + case USBD_SET_CONFIGURATION: { g_hsusbd_UsbConfig = (uint8_t)gUsbCmd.wValue; g_hsusbd_Configured = (uint8_t)1ul; /* Status stage */ @@ -387,7 +387,7 @@ void HSUSBD_StandardRequest(void) HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk); break; } - case SET_FEATURE: { + case USBD_SET_FEATURE: { if ((gUsbCmd.wValue & 0x3ul) == 2ul) { /* TEST_MODE */ g_hsusbd_EnableTestMode = (uint8_t)1ul; g_hsusbd_TestSelector = (uint8_t)(gUsbCmd.wIndex >> 8); @@ -402,7 +402,7 @@ void HSUSBD_StandardRequest(void) HSUSBD_ENABLE_CEP_INT(HSUSBD_CEPINTEN_STSDONEIEN_Msk); break; } - case SET_INTERFACE: { + case USBD_SET_INTERFACE: { g_hsusbd_UsbAltInterface = (uint8_t)gUsbCmd.wValue; if (g_hsusbd_pfnSetInterface != NULL) { g_hsusbd_pfnSetInterface((uint32_t)g_hsusbd_UsbAltInterface); @@ -442,11 +442,11 @@ void HSUSBD_StandardRequest(void) void HSUSBD_UpdateDeviceState(void) { switch (gUsbCmd.bRequest) { - case SET_ADDRESS: { + case USBD_SET_ADDRESS: { HSUSBD_SET_ADDR(g_hsusbd_UsbAddr); break; } - case SET_CONFIGURATION: { + case USBD_SET_CONFIGURATION: { if (g_hsusbd_UsbConfig == 0ul) { uint32_t volatile i; /* Reset PID DATA0 */ @@ -458,7 +458,7 @@ void HSUSBD_UpdateDeviceState(void) } break; } - case SET_FEATURE: { + case USBD_SET_FEATURE: { if(gUsbCmd.wValue == FEATURE_ENDPOINT_HALT) { uint32_t idx; idx = (uint32_t)(gUsbCmd.wIndex & 0xFul); @@ -479,7 +479,7 @@ void HSUSBD_UpdateDeviceState(void) } break; } - case CLEAR_FEATURE: { + case USBD_CLEAR_FEATURE: { if(gUsbCmd.wValue == FEATURE_ENDPOINT_HALT) { uint32_t idx; idx = (uint32_t)(gUsbCmd.wIndex & 0xFul); diff --git a/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_sys.h b/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_sys.h index b37faf22a2b..c24614bb603 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_sys.h +++ b/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_sys.h @@ -117,7 +117,10 @@ extern "C" #define SYS_USBPHY_USBROLE_STD_USBH (0x1UL << SYS_USBPHY_USBROLE_Pos) /*!< Standard USB host \hideinitializer */ #define SYS_USBPHY_USBROLE_ID_DEPH (0x2UL << SYS_USBPHY_USBROLE_Pos) /*!< ID dependent device \hideinitializer */ #define SYS_USBPHY_USBROLE_ON_THE_GO (0x3UL << SYS_USBPHY_USBROLE_Pos) /*!< On-The-Go device \hideinitializer */ - +#define SYS_USBPHY_HSUSBROLE_STD_USBD (0x0UL << SYS_USBPHY_HSUSBROLE_Pos) /*!< Standard USB device \hideinitializer */ +#define SYS_USBPHY_HSUSBROLE_STD_USBH (0x1UL << SYS_USBPHY_HSUSBROLE_Pos) /*!< Standard USB host \hideinitializer */ +#define SYS_USBPHY_HSUSBROLE_ID_DEPH (0x2UL << SYS_USBPHY_HSUSBROLE_Pos) /*!< ID dependent device \hideinitializer */ +#define SYS_USBPHY_HSUSBROLE_ON_THE_GO (0x3UL << SYS_USBPHY_HSUSBROLE_Pos) /*!< On-The-Go device \hideinitializer */ /*---------------------------------------------------------------------------------------------------------*/ /* Multi-Function constant definitions. */ diff --git a/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_usbd.c b/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_usbd.c index b2ae74e40f8..cf0919ae436 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_usbd.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_usbd.c @@ -267,7 +267,7 @@ void USBD_StandardRequest(void) if((g_usbd_SetupPacket[0] & 0x80ul) == 0x80ul) { /* request data transfer direction */ /* Device to host */ switch(g_usbd_SetupPacket[1]) { - case GET_CONFIGURATION: { + case USBD_GET_CONFIGURATION: { /* Return current configuration setting */ /* Data stage */ addr = USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0); @@ -278,12 +278,12 @@ void USBD_StandardRequest(void) USBD_PrepareCtrlOut(0, 0ul); break; } - case GET_DESCRIPTOR: { + case USBD_GET_DESCRIPTOR: { USBD_GetDescriptor(); USBD_PrepareCtrlOut(0, 0ul); /* For status stage */ break; } - case GET_INTERFACE: { + case USBD_GET_INTERFACE: { /* Return current interface setting */ /* Data stage */ addr = USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0); @@ -294,7 +294,7 @@ void USBD_StandardRequest(void) USBD_PrepareCtrlOut(0, 0ul); break; } - case GET_STATUS: { + case USBD_GET_STATUS: { /* Device */ if(g_usbd_SetupPacket[0] == 0x80ul) { uint8_t u8Tmp; @@ -342,7 +342,7 @@ void USBD_StandardRequest(void) } else { /* Host to device */ switch(g_usbd_SetupPacket[1]) { - case CLEAR_FEATURE: { + case USBD_CLEAR_FEATURE: { if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT) { uint32_t epNum, i; @@ -363,7 +363,7 @@ void USBD_StandardRequest(void) USBD_SET_PAYLOAD_LEN(EP0, 0ul); break; } - case SET_ADDRESS: { + case USBD_SET_ADDRESS: { g_usbd_UsbAddr = g_usbd_SetupPacket[2]; /* Status Stage */ USBD_SET_DATA1(EP0); @@ -371,7 +371,7 @@ void USBD_StandardRequest(void) break; } - case SET_CONFIGURATION: { + case USBD_SET_CONFIGURATION: { g_usbd_UsbConfig = g_usbd_SetupPacket[2]; if(g_usbd_pfnSetConfigCallback) { @@ -383,7 +383,7 @@ void USBD_StandardRequest(void) USBD_SET_PAYLOAD_LEN(EP0, 0ul); break; } - case SET_FEATURE: { + case USBD_SET_FEATURE: { if( (g_usbd_SetupPacket[0] & 0xFul) == 0ul ) { /* 0: device */ if((g_usbd_SetupPacket[2] == 3ul) && (g_usbd_SetupPacket[3] == 0ul)) { /* 3: HNP enable */ OTG->CTL |= (OTG_CTL_HNPREQEN_Msk | OTG_CTL_BUSREQ_Msk); @@ -401,7 +401,7 @@ void USBD_StandardRequest(void) break; } - case SET_INTERFACE: { + case USBD_SET_INTERFACE: { g_usbd_UsbAltInterface = g_usbd_SetupPacket[2]; if(g_usbd_pfnSetInterface != NULL) { g_usbd_pfnSetInterface(g_usbd_UsbAltInterface); @@ -491,7 +491,7 @@ void USBD_CtrlIn(void) } } else { /* In ACK for Set address */ - if((g_usbd_SetupPacket[0] == REQ_STANDARD) && (g_usbd_SetupPacket[1] == SET_ADDRESS)) { + if((g_usbd_SetupPacket[0] == REQ_STANDARD) && (g_usbd_SetupPacket[1] == USBD_SET_ADDRESS)) { addr = USBD_GET_ADDR(); if((addr != g_usbd_UsbAddr) && (addr == 0ul)) { USBD_SET_ADDR(g_usbd_UsbAddr); diff --git a/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_usbd.h b/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_usbd.h index 53ec8005351..05813f72a2a 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_usbd.h +++ b/targets/TARGET_NUVOTON/TARGET_M480/device/StdDriver/m480_usbd.h @@ -69,17 +69,17 @@ extern const S_USBD_INFO_T gsInfo; #define REQ_VENDOR 0x40ul /* USB Standard Request */ -#define GET_STATUS 0x00ul -#define CLEAR_FEATURE 0x01ul -#define SET_FEATURE 0x03ul -#define SET_ADDRESS 0x05ul -#define GET_DESCRIPTOR 0x06ul -#define SET_DESCRIPTOR 0x07ul -#define GET_CONFIGURATION 0x08ul -#define SET_CONFIGURATION 0x09ul -#define GET_INTERFACE 0x0Aul -#define SET_INTERFACE 0x0Bul -#define SYNC_FRAME 0x0Cul +#define USBD_GET_STATUS 0x00ul +#define USBD_CLEAR_FEATURE 0x01ul +#define USBD_SET_FEATURE 0x03ul +#define USBD_SET_ADDRESS 0x05ul +#define USBD_GET_DESCRIPTOR 0x06ul +#define USBD_SET_DESCRIPTOR 0x07ul +#define USBD_GET_CONFIGURATION 0x08ul +#define USBD_SET_CONFIGURATION 0x09ul +#define USBD_GET_INTERFACE 0x0Aul +#define USBD_SET_INTERFACE 0x0Bul +#define USBD_SYNC_FRAME 0x0Cul /* USB Descriptor Type */ #define DESC_DEVICE 0x01ul diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_ARM_STD/lib_peripheral_mbed_arm.ar b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_ARM_STD/lib_peripheral_mbed_arm.ar index 805b4991054..9ab2e81f22a 100644 Binary files a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_ARM_STD/lib_peripheral_mbed_arm.ar and b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_ARM_STD/lib_peripheral_mbed_arm.ar differ diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_ARM_STD/rtl8195a.sct b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_ARM_STD/rtl8195a.sct index 90b5a52b03a..e76cc189fe8 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_ARM_STD/rtl8195a.sct +++ b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_ARM_STD/rtl8195a.sct @@ -1,51 +1,78 @@ -; ************************************************************* -; *** Scatter-Loading Description File for RTL8195A *** -; ************************************************************* -LR_ROM 0x00000000 0x00030000{ - _ROM_CODE 0x00000000 0x00030000 { - ;*.o (RESET, +First) - ;*(InRoot$$Sections) - } -} +; Realtek Semiconductor Corp. +; +; RTL8195A ARMCC Scatter File +; +; MEMORY +; { +; SROM (rx) : ORIGIN = 0x10000000, LENGTH = 0x00007000 +; SRAM (rwx) : ORIGIN = 0x10007000, LENGTH = 0x00070000 - 0x00007000 +; TCM (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x00010000 +; DRAM (rwx) : ORIGIN = 0x30000000, LENGTH = 2M +; } -LR_RAM 0x10006000 0x6FFFF { -;LR_RAM 0x10000000 0x6FFFF { - ;ROM_BSS 0x10000000 0x0005FFF{ - ;rtl_console.o(.mon.ram.bss*) - ;} - - .image2.table 0x10006000 FIXED { - rtl8195a_init.o(.image2.ram.data*) - rtl8195a_init.o(.image2.validate.rodata*) - } - - .text +0 FIXED{ - rtl8195a_init.o(.infra.ram.start) - ;*.o(.mon.ram.text*) - ;*.o(.hal.flash.text*) - ;*.o(.hal.sdrc.text*) - ;*.o(.hal.gpio.text*) - ;*.o(.text*) - ;*.o(.rodata*) - .ANY (+RO) +LR_IRAM 0x10007000 (0x70000 - 0x7000) { + + IMAGE2_TABLE 0x10007000 FIXED { + *rtl8195a_init.o(.image2.ram.data*, +FIRST) + *rtl8195a_init.o(.image2.validate.rodata*) } - .data +0 FIXED{ - .ANY (+RW) + ER_IRAM +0 FIXED { + *rtl8195a_crypto.o (+RO) + * (i.mbedtls*) + *libc.a (+RO) + + *rtx_*.o (+RO) + *Ticker.o (+RO) + *Timeout.o (+RO) + *rtx_timer.o (+RO) + *TimerEvent.o (+RO) + *mbed_ticker_api.o (+RO) + *mbed_critical.o (+RO) + *us_ticker.o (+RO) + + *lib_peripheral_mbed_arm.ar (+RO) } RW_IRAM1 +0 UNINIT FIXED { - .ANY (+ZI) + *rtl8195a_crypto.o(+RW) + ;*mbedtls*.o(+RW) + *libc.a (+RW) + *(.sdram.data*) + *lib_peripheral_mbed_arm.ar (+RW) } - TCM_OVERLAY 0x1FFF0000 0x10000{ - lwip_mem.o(.bss*) - lwip_memp.o(.bss*) - *.o(.tcm.heap*) + RW_IRAM2 +0 UNINIT FIXED { + *rtl8195a_crypto.o(+ZI, COMMON) + ;*mbedtls*.o(+ZI, COMMON) + *libc.a (+ZI, COMMON) + *(.bss.thread_stack_main) + *lib_peripheral_mbed_arm.ar (+ZI, COMMON) } + + ARM_LIB_STACK (0x10070000 - 0x1000) EMPTY 0x1000 { + } +} + +LR_TCM 0x1FFF0000 0x10000 { + TCM_OVERLAY 0x1FFF0000 0x10000 { + *lwip_mem.o(.bss*) + *lwip_memp.o(.bss*) + *.o(.tcm.heap*) + } } -LR_DRAM 0x30000000 0x1FFFFF{ - _DRAM_CODE 0x30000000 0x1FFFFF{ - } -} \ No newline at end of file +LR_DRAM 0x30000000 0x200000 { + + ER_DRAM +0 FIXED { + .ANY (+RO) + } + + RW_DRAM1 +0 UNINIT FIXED { + .ANY (+RW) + } + + RW_DRAM2 +0 UNINIT FIXED { + .ANY (+ZI) + } +} diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_ARM_STD/sys.cpp b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_ARM_STD/sys.cpp index 7eb3026e3c5..13433246b46 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_ARM_STD/sys.cpp +++ b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_ARM_STD/sys.cpp @@ -1,46 +1,24 @@ -/****************************************************************************** - * Copyright (c) 2013-2016 Realtek Semiconductor Corp. +/* mbed Microcontroller Library - stackheap + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. * - * 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. - * - ****************************************************************************** - * mbed Microcontroller Library - stackheap - * Setup a fixed single stack/heap memory model, - * between the top of the RW/ZI region and the stackpointer - ******************************************************************************/ - + * Setup a fixed single stack/heap memory model, + * between the top of the RW/ZI region and the stackpointer + */ #ifdef __cplusplus extern "C" { -#endif +#endif #include #include -extern char Image$$RW_IRAM1$$ZI$$Limit[]; +extern char Image$$RW_IRAM2$$ZI$$Limit[]; + extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { - uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit; + uint32_t zi_limit = (uint32_t)Image$$RW_IRAM2$$ZI$$Limit; uint32_t sp_limit = __current_sp(); zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned - //push down stack pointer to recycle some of the stack space that are not use in future - __asm volatile - ( - "MRS IP, MSP \n" - "ADD IP, #64 \n" - "BIC IP, IP, #7 \n" - "MSR MSP, IP \n" - ); struct __initial_stackheap r; r.heap_base = zi_limit; r.heap_limit = sp_limit; @@ -49,4 +27,4 @@ extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_ #ifdef __cplusplus } -#endif +#endif diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_GCC_ARM/lib_peripheral_mbed_gcc.a b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_GCC_ARM/lib_peripheral_mbed_gcc.a index 9a6780af319..352cdf86f64 100644 Binary files a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_GCC_ARM/lib_peripheral_mbed_gcc.a and b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_GCC_ARM/lib_peripheral_mbed_gcc.a differ diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_GCC_ARM/rtl8195a.ld b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_GCC_ARM/rtl8195a.ld new file mode 100644 index 00000000000..4c05ef96414 --- /dev/null +++ b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_GCC_ARM/rtl8195a.ld @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2013-2016 Realtek Semiconductor Corp. + * + * 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 "rtl8195a_rom.h" +/* DATA_RAM: We cannot put Code(.text) in DATA_RAM, this region is reserved for Image1(boot loader). + But we can put .data/.bss of Image2 in this region */ +MEMORY +{ + TCM (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x00010000 + DATA_RAM (rwx) : ORIGIN = 0x10002100, LENGTH = 0x10007000 - 0x10002100 + SRAM1 (rwx) : ORIGIN = 0x10007000, LENGTH = 0x10070000 - 0x10007000 + SRAM2 (rwx) : ORIGIN = 0x30000000, LENGTH = 2M +} + +/* Stack sizes: */ +StackSize = 0x1000; + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * _reset_init : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .image2.table : + { + KEEP(*(SORT(.image2.ram.data*))) + KEEP(*(.image2.validate.rodata*)) + } > SRAM2 + + .text.sram1 : + { + . = ALIGN(4); + *rtl8195a_crypto.o (.text* .rodata*) + *mbedtls*.o (.text* .rodata*) + *libc.a: (.text* .rodata*) + *Ticker.o (.text*) + *Timeout.o (.text*) + *TimerEvent.o (.text*) + *mbed_ticker_api.o (.text*) + *mbed_critical.o (.text*) + *us_ticker.o (.text*) + + *lib_peripheral_mbed_gcc.a: (.text*) + + } > SRAM1 + + .text.sram2 : + { + . = ALIGN(4); + *(.mon.ram.text*) + *(.hal.flash.text*) + *(.hal.sdrc.text*) + *(.hal.gpio.text*) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > SRAM2 + __etext = .; + + __data_start__ = .; + + .data.sram1 : + { + . = ALIGN(4); + __sram_data_start__ = .; + *rtl8195a_crypto*.o (.data*) + *mbedtls*.o (.data*) + __sram_data_end__ = .; + } > SRAM1 + + .data.sram2 : + { + __sdram_data_start__ = .; + *(vtable) + *(.data*) + *(.sdram.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE (__fini_array_end = .); + + . = ALIGN(4); + + __sdram_data_end__ = .; + /* All data end */ + } > SRAM2 + __data_end__ = .; + __image2_end__ = .; + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > SRAM2 + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > SRAM2 + __exidx_end = .; + + .bss.sram1 (NOLOAD) : + { + __bss_sram_start__ = .; + *rtl8195a_crypto.o (.bss* COMMON) + *mbedtls*.o (.bss* COMMON) + *(.bss.thread_stack_main) + __bss_sram_end__ = .; + } > SRAM1 + + .bss.sram2 (NOLOAD) : + { + __bss_start__ = .; + __bss_dram_start__ = .; + *(.bss*) + *(COMMON) + *(.bdsram.data*) + __bss_dram_end__ = .; + __bss_end__ = .; + } > SRAM2 + + .bf_data : + { + __buffer_data_start__ = .; + *(.bfsram.data*) + __buffer_data_end__ = .; + } > SRAM2 + + .heap (NOLOAD): + { + __end__ = .; + end = __end__; + *(.heap*) + . = ORIGIN(SRAM1) + LENGTH(SRAM1) - StackSize; + __HeapLimit = .; + } > SRAM1 + + .TCM_overlay : + { + __bss_dtcm_start__ = .; + *lwip_mem.o (.bss*) + *lwip_memp.o (.bss*) + *(.tcm.heap*) + __bss_dtcm_end__ = .; + } > TCM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (NOLOAD): + { + __StackLimit = .; + *(.stack) + . += StackSize - (. - __StackLimit); + } > SRAM1 + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(SRAM1) + LENGTH(SRAM1); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM exceeds ram limit") +} diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_GCC_ARM/rlx8195A-symbol-v02-img2.ld b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_GCC_ARM/rtl8195a_rom.h similarity index 82% rename from targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_GCC_ARM/rlx8195A-symbol-v02-img2.ld rename to targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_GCC_ARM/rtl8195a_rom.h index 512f4460fe7..e9a2754ff8e 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_GCC_ARM/rlx8195A-symbol-v02-img2.ld +++ b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_GCC_ARM/rtl8195a_rom.h @@ -13,11 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - - -ENTRY(Reset_Handler) - -/*INCLUDE "mbed-os/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_GCC_ARM/export-rom_v02.txt"*/ SECTIONS { __vectors_table = 0x0; @@ -28,6 +23,7 @@ SECTIONS BusFault_Handler = 0x125; UsageFault_Handler = 0x129; HalLogUartInit = 0x201; + HalSerialPutcRtl8195a = 0x2d9; HalSerialGetcRtl8195a = 0x309; HalSerialGetIsrEnRegRtl8195a = 0x329; HalSerialSetIrqEnRegRtl8195a = 0x335; @@ -171,7 +167,7 @@ SECTIONS HalGdmaChDisRtl8195a = 0x5e6d; HalGdamChInitRtl8195a = 0x5e91; HalGdmaChSetingRtl8195a = 0x5ebd; - HalGdmaChBlockSetingRtl8195a = 0x000060dd; + HalGdmaChBlockSetingRtl8195a = 0x60dd; HalGdmaChIsrCleanRtl8195a = 0x6419; HalGdmaChCleanAutoSrcRtl8195a = 0x64a1; HalGdmaChCleanAutoDstRtl8195a = 0x6501; @@ -337,20 +333,30 @@ SECTIONS _memcmp = 0xf429; _memcpy = 0xf465; _memset = 0xf511; + __memcmp = 0xf429; + __memcpy = 0xf465; + __memset = 0xf511; Rand = 0xf585; _strncpy = 0xf60d; _strcpy = 0xf629; + __strncpy = 0xf60d; + __strcpy = 0xf629; prvStrCpy = 0xf639; _strlen = 0xf651; _strnlen = 0xf669; + __strlen = 0xf651; + __strnlen = 0xf669; prvStrLen = 0xf699; _strcmp = 0xf6b1; _strncmp = 0xf6d1; + __strcmp = 0xf6b1; + __strncmp = 0xf6d1; prvStrCmp = 0xf719; StrUpr = 0xf749; prvAtoi = 0xf769; prvStrStr = 0xf7bd; _strsep = 0xf7d5; + __strsep = 0xf7d5; skip_spaces = 0xf815; skip_atoi = 0xf831; _parse_integer_fixup_radix = 0xf869; @@ -365,8 +371,8 @@ SECTIONS div_s64 = 0xff99; div_u64_rem = 0xffa1; div_s64_rem = 0xffb1; - _strpbrk = 0xffc1; - _strchr = 0xffed; + __strpbrk = 0xffc1; + __strchr = 0xffed; aes_set_key = 0x10005; aes_encrypt = 0x103d1; aes_decrypt = 0x114a5; @@ -613,6 +619,11 @@ SECTIONS __AES_rcon = 0x30e78; __AES_Te4 = 0x30ea0; I2CDmaChNo = 0x312a0; + _GPIO_PinMap_Chip2IP_8195a = 0x312b4; + _GPIO_PinMap_PullCtrl_8195a = 0x3136c; + _GPIO_SWPORT_DDR_TBL = 0x31594; + _GPIO_EXT_PORT_TBL = 0x31598; + _GPIO_SWPORT_DR_TBL = 0x3159c; UartLogRomCmdTable = 0x316a0; _HalRuartOp = 0x31700; _HalGdmaOp = 0x31760; @@ -634,6 +645,90 @@ SECTIONS rom_wps_rcons = 0x35d88; rom_wps_Td4s = 0x35d94; rom_wps_Td0 = 0x35e94; + __rom_b_cut_end__ = 0x4467c; + __rom_c_cut_text_start__ = 0x4467c; + HalInitPlatformLogUartV02 = 0x4467d; + HalReInitPlatformLogUartV02 = 0x4471d; + HalInitPlatformTimerV02 = 0x44755; + HalShowBuildInfoV02 = 0x447cd; + SpicReleaseDeepPowerDownFlashRtl8195A = 0x44831; + HalSpiInitV02 = 0x4488d; + HalBootFlowV02 = 0x44a29; + HalInitialROMCodeGlobalVarV02 = 0x44ae5; + HalResetVsrV02 = 0x44b41; + HalI2CSendRtl8195aV02 = 0x44ce1; + HalI2CSetCLKRtl8195aV02 = 0x44d59; + RtkI2CSendV02 = 0x4508d; + RtkI2CReceiveV02 = 0x459a1; + HalI2COpInitV02 = 0x461ed; + I2CISRHandleV02 = 0x463e9; + RtkSalI2COpInitV02 = 0x46be1; + SpicLoadInitParaFromClockRtl8195AV02 = 0x46c25; + SpiFlashAppV02 = 0x46c85; + SpicInitRtl8195AV02 = 0x46dc5; + SpicEraseFlashRtl8195AV02 = 0x46ea1; + HalTimerIrq2To7HandleV02 = 0x46f5d; + HalTimerIrqRegisterRtl8195aV02 = 0x46fe1; + HalTimerInitRtl8195aV02 = 0x4706d; + HalTimerReadCountRtl8195aV02 = 0x471b5; + HalTimerReLoadRtl8195aV02 = 0x471d1; + HalTimerIrqUnRegisterRtl8195aV02 = 0x4722d; + HalTimerDeInitRtl8195aV02 = 0x472c1; + HalTimerOpInitV02 = 0x472f9; + GPIO_LockV02 = 0x47345; + GPIO_UnLockV02 = 0x47379; + GPIO_Int_Clear_8195aV02 = 0x473a5; + HAL_GPIO_IntCtrl_8195aV02 = 0x473b5; + FindElementIndexV02 = 0x47541; + HalRuartInitRtl8195aV02 = 0x4756d; + DramInit_rom = 0x47619; + ChangeRandSeed_rom = 0x47979; + Sdr_Rand2_rom = 0x47985; + MemTest_rom = 0x479dd; + SdrCalibration_rom = 0x47a45; + SdrControllerInit_rom = 0x47d99; + SDIO_EnterCritical = 0x47e39; + SDIO_ExitCritical = 0x47e85; + SDIO_IRQ_Handler_Rom = 0x47ec5; + SDIO_Interrupt_Init_Rom = 0x47f31; + SDIO_Device_Init_Rom = 0x47f81; + SDIO_Interrupt_DeInit_Rom = 0x48215; + SDIO_Device_DeInit_Rom = 0x48255; + SDIO_Enable_Interrupt_Rom = 0x48281; + SDIO_Disable_Interrupt_Rom = 0x482a1; + SDIO_Clear_ISR_Rom = 0x482c1; + SDIO_Alloc_Rx_Pkt_Rom = 0x482d9; + SDIO_Free_Rx_Pkt_Rom = 0x48331; + SDIO_Recycle_Rx_BD_Rom = 0x48355; + SDIO_RX_IRQ_Handler_BH_Rom = 0x484f1; + SDIO_RxTask_Rom = 0x4851d; + SDIO_Process_H2C_IOMsg_Rom = 0x4856d; + SDIO_Send_C2H_IOMsg_Rom = 0x4859d; + SDIO_Process_RPWM_Rom = 0x485b5; + SDIO_Reset_Cmd_Rom = 0x485e9; + SDIO_Rx_Data_Transaction_Rom = 0x48611; + SDIO_Send_C2H_PktMsg_Rom = 0x48829; + SDIO_Register_Tx_Callback_Rom = 0x488f5; + SDIO_ReadMem_Rom = 0x488fd; + SDIO_WriteMem_Rom = 0x489a9; + SDIO_SetMem_Rom = 0x48a69; + SDIO_TX_Pkt_Handle_Rom = 0x48b29; + SDIO_TX_FIFO_DataReady_Rom = 0x48c69; + SDIO_IRQ_Handler_BH_Rom = 0x48d95; + SDIO_TxTask_Rom = 0x48e9d; + SDIO_TaskUp_Rom = 0x48eed; + SDIO_Boot_Up = 0x48f55; + __rom_c_cut_text_end__ = 0x49070; + __rom_c_cut_rodata_start__ = 0x49070; + BAUDRATE_v02 = 0x49070; + OVSR_v02 = 0x490fc; + DIV_v02 = 0x49188; + OVSR_ADJ_v02 = 0x49214; + SdrDramInfo_rom = 0x492a0; + SdrDramTiming_rom = 0x492b4; + SdrDramModeReg_rom = 0x492e8; + SdrDramDev_rom = 0x49304; + __rom_c_cut_rodata_end__ = 0x49314; NewVectorTable = 0x10000000; UserIrqFunTable = 0x10000100; UserIrqDataTable = 0x10000200; @@ -661,193 +756,4 @@ SECTIONS DM_CfoTrack = 0x10000738; rom_libgloss_ram_map = 0x10000760; __rtl_errno = 0x10000bc4; - _rtl_impure_ptr = 0x10001c60; } - -/* DATA_RAM: We cannot put Code(.text) in DATA_RAM, this region is reserved for Image1(boot loader). - But we can put .data/.bss of Image2 in this region */ -MEMORY -{ - TCM (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x00010000 - ROM_USED_RAM (rwx) : ORIGIN = 0x10000bc8, LENGTH = 0x10006000-0x10000bc8 - DATA_RAM (rwx) : ORIGIN = 0x10002100, LENGTH = 0x10006000 - 0x10002100 - BD_RAM (rwx) : ORIGIN = 0x10006000, LENGTH = 0x10070000 - 0x10006000 - SD_RAM (rwx) : ORIGIN = 0x30000000, LENGTH = 2M -} - -/* Linker script to place sections and symbol values. Should be used together - * with other linker script that defines memory regions FLASH and RAM. - * It references following symbols, which must be defined in code: - * _reset_init : Entry of reset handler - * - * It defines following symbols, which code can use without definition: - * __exidx_start - * __exidx_end - * __etext - * __data_start__ - * __preinit_array_start - * __preinit_array_end - * __init_array_start - * __init_array_end - * __fini_array_start - * __fini_array_end - * __data_end__ - * __bss_start__ - * __bss_end__ - * __end__ - * end - * __HeapLimit - * __StackLimit - * __StackTop - * __stack - */ -ENTRY(Reset_Handler) - -SECTIONS -{ - __rom_bss_start__ = 0x10000300; - __rom_bss_end__ = 0x10000bc8; - __ram_table_start__ = 0x10000bc8; -/* - .ram.start.table : - { - - } > ROM_USED_RAM -*/ - .image2.table : - { - __image2_start__ = .; - __image2_entry_func__ = .; - KEEP(*(SORT(.image2.ram.data*))) - __image2_validate_code__ = .; - KEEP(*(.image2.validate.rodata*)) - } > BD_RAM - - .text : - { - . = ALIGN(4); - *(.infra.ram.start*) - *(.mon.ram.text*) - *(.hal.flash.text*) - *(.hal.sdrc.text*) - *(.hal.gpio.text*) - *(.text*) - - KEEP(*(.init)) - KEEP(*(.fini)) - - /* .ctors */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - - /* .dtors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - *(.rodata*) - KEEP(*(.eh_frame*)) - } > BD_RAM - __etext = .; - - - __data_start__ = .; - .data : - { - *(vtable) - *(.data*) - - . = ALIGN(4); - /* preinit data */ - PROVIDE (__preinit_array_start = .); - KEEP(*(.preinit_array)) - PROVIDE (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE (__init_array_start = .); - KEEP(*(SORT(.init_array.*))) - KEEP(*(.init_array)) - PROVIDE (__init_array_end = .); - - . = ALIGN(4); - /* finit data */ - PROVIDE (__fini_array_start = .); - KEEP(*(SORT(.fini_array.*))) - KEEP(*(.fini_array)) - PROVIDE (__fini_array_end = .); - - . = ALIGN(4); - - /* All data end */ - } > BD_RAM - __data_end__ = .; - __image2_end__ = .; - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - } > BD_RAM - - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > BD_RAM - __exidx_end = .; - - .bss : - { - __bss_start__ = .; - *(.bss*) - *(.bdsram.data*) - *(COMMON) - __bss_end__ = .; - } > BD_RAM - - - .bf_data : - { - __buffer_data_start__ = .; - *(.bfsram.data*) - __buffer_data_end__ = .; - } > BD_RAM - - .heap : - { - __end__ = .; - end = __end__; - *(.heap*) - __HeapLimit = .; - } > BD_RAM - - .TCM_overlay : - { - *lwip_mem.o (.bss*) - *lwip_memp.o (.bss*) - *(.tcm.heap*) - } > TCM - - /* .stack_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later */ - .stack_dummy : - { - *(.stack) - } > BD_RAM - - /* Set stack top to end of RAM, and stack limit move down by - * size of stack_dummy section */ - __StackTop = ORIGIN(BD_RAM) + LENGTH(BD_RAM); - __StackLimit = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__StackLimit >= __HeapLimit, "region RAM exceeds ram limit") - -} - diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_IAR/lib_peripheral_mbed_iar.a b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_IAR/lib_peripheral_mbed_iar.a index 1ec9f66ca4d..63c8d704d43 100644 Binary files a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_IAR/lib_peripheral_mbed_iar.a and b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_IAR/lib_peripheral_mbed_iar.a differ diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_IAR/rtl8195a.icf b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_IAR/rtl8195a.icf index 071b052d6f9..5244ef9a5c3 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_IAR/rtl8195a.icf +++ b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/TOOLCHAIN_IAR/rtl8195a.icf @@ -16,7 +16,7 @@ define symbol __ICFEDIT_region_ROM_USED_RAM_end__ = 0x10005FFF; //define symbol __ICFEDIT_region_RECY_RAM_start__ = 0x10002090; //define symbol __ICFEDIT_region_RECY_RAM_end__ = 0x100037FF; if( !isdefinedsymbol( __ICFEDIT_region_BD_RAM_start__ ) ) { - define symbol __ICFEDIT_region_BD_RAM_start__ = 0x10006000; + define symbol __ICFEDIT_region_BD_RAM_start__ = 0x10007000; } if( !isdefinedsymbol( __ICFEDIT_region_BD_RAM_end__ ) ) { define symbol __ICFEDIT_region_BD_RAM_end__ = 0x1006FFFF; @@ -31,12 +31,12 @@ define symbol __ICFEDIT_size_heap__ = 0x19000; define memory mem with size = 4G; -define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; -define region TCM_region = mem:[from __ICFEDIT_region_TCM_start__ to __ICFEDIT_region_TCM_end__]; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region TCM_region = mem:[from __ICFEDIT_region_TCM_start__ to __ICFEDIT_region_TCM_end__]; define region ROM_USED_RAM_region = mem:[from __ICFEDIT_region_ROM_USED_RAM_start__ to __ICFEDIT_region_ROM_USED_RAM_end__]; -//define region RECY_RAM_region = mem:[from __ICFEDIT_region_RECY_RAM_start__ to __ICFEDIT_region_RECY_RAM_end__]; -define region BD_RAM_region = mem:[from __ICFEDIT_region_BD_RAM_start__ to __ICFEDIT_region_BD_RAM_end__]; -define region SDRAM_RAM_region = mem:[from __ICFEDIT_region_SDRAM_RAM_start__ to __ICFEDIT_region_SDRAM_RAM_end__]; +//define region RECY_RAM_region = mem:[from __ICFEDIT_region_RECY_RAM_start__ to __ICFEDIT_region_RECY_RAM_end__]; +define region BD_RAM_region = mem:[from __ICFEDIT_region_BD_RAM_start__ to __ICFEDIT_region_BD_RAM_end__]; +define region SDRAM_RAM_region = mem:[from __ICFEDIT_region_SDRAM_RAM_start__ to __ICFEDIT_region_SDRAM_RAM_end__]; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; @@ -95,11 +95,11 @@ define block .ram_image1.data with fixed order{ section .image1.validate.rodata* section .infra.ram.data*, section .timer.ram.data*, section .cutb.ram.data*, - section .hal.ram.data* object rom.o, // for standard libaray __impure_data_ptr + section .hal.ram.data* object rom.o, // for standard libaray __impure_data_ptr section .cutc.ram.data*, section .hal.ram.data* }; -define block .ram_image1.bss with fixed order{ //section .hal.flash.data*, +define block .ram_image1.bss with fixed order{ //section .hal.flash.data*, section .hal.sdrc.data* }; @@ -113,13 +113,14 @@ define block IMAGE1 with fixed order { section LOADER }; define block IMAGE1_DBG with fixed order { block .ram.start.table, block .ram_image1.data, block .ram_image1.bss, block .ram_image1.text }; place at start of ROM_USED_RAM_region { - block .vector_table, - block .user_vector_table, - block .user_data_table, - block .rom.bss, - block IMAGE1 - }; - + block .vector_table, + block .user_vector_table, + block .user_data_table, + block .rom.bss, + block IMAGE1 + }; + + keep { section .image2.ram.data* }; define block .image2.start.table1 with fixed order{ section .image2.ram.data* }; @@ -133,97 +134,197 @@ define block CPP_INIT with alignment = 8, fixed order { block SHT$$INIT_ARRAY }; define block FPB_REMAP with alignment = 256,fixed order { - section .fpb.remap* - }; -define block .ram_image2.text with fixed order{ section .infra.ram.start*, - section .rodata*, - block CPP_INIT, + section .fpb.remap* + }; + +define block MBEDTLS_TEXT with alignment = 8, fixed order{ + section .text* object aes.o, + section .text* object aesni.o, + section .text* object arc4.o, + section .text* object asn1parse.o, + section .text* object asn1write.o, + section .text* object base64.o, + section .text* object bignum.o, + section .text* object blowfish.o, + section .text* object camellia.o, + section .text* object ccm.o, + section .text* object certs.o, + section .text* object cipher.o, + section .text* object cipher_wrap.o, + section .text* object cmac.o, + section .text* object ctr_drbg.o, + section .text* object debug.o, + section .text* object des.o, + section .text* object dhm.o, + section .text* object ecdh.o, + section .text* object ecdsa.o, + section .text* object ecjpake.o, + section .text* object ecp.o, + section .text* object ecp_curves.o, + section .text* object entropy.o, + section .text* object entropy_poll.o, + section .text* object error.o, + section .text* object gcm.o, + section .text* object havege.o, + section .text* object hmac_drbg.o, + section .text* object md.o, + section .text* object md2.o, + section .text* object md4.o, + section .text* object md5.o, + section .text* object md_wrap.o, + section .text* object memory_buffer_alloc.o, + section .text* object net_sockets.o, + section .text* object oid.o, + section .text* object padlock.o, + section .text* object pem.o, + section .text* object pk.o, + section .text* object pk_wrap.o, + section .text* object pkcs11.o, + section .text* object pkcs12.o, + section .text* object pkcs5.o, + section .text* object pkparse.o, + section .text* object pkwrite.o, + section .text* object platform.o, + section .text* object ripemd160.o, + section .text* object rsa.o, + section .text* object sha1.o, + section .text* object sha256.o, + section .text* object sha512.o, + section .text* object ssl_cache.o, + section .text* object ssl_ciphersuites.o, + section .text* object ssl_cli.o, + section .text* object ssl_cookie.o, + section .text* object ssl_srv.o, + section .text* object ssl_ticket.o, + section .text* object ssl_tls.o, + section .text* object threading.o, + section .text* object timing.o, + section .text* object version.o, + section .text* object version_features.o, + section .text* object x509.o, + section .text* object x509_create.o, + section .text* object x509_crl.o, + section .text* object x509_crt.o, + section .text* object x509_csr.o, + section .text* object x509write_crt.o, + section .text* object x509write_csr.o, + section .text* object xtea.o, + }; + +define block .sram1.text with fixed order { + block MBEDTLS_TEXT, + section .text* object Ticker.o, + section .text* object Timeout.o, + section .text* object TimerEvent.o, + section .text* object mbed_ticker_api.o, + section .text* object mbed_critical.o, + section .text* object us_ticker.o, + + section .text* object lib_peripheral_mbed_iar.a, + }; + +define block .sram2.text with fixed order { + block .image2.start.table1, + block .image2.start.table2, section .mon.ram.text*, section .hal.flash.text*, + section .hal.sdrc.text*, section .hal.gpio.text*, - section .text* object main.o, section .text*, - section .wlan.text, - section .wps.text, + section .infra.ram.start*, + section .rodata*, + }; + +define block .sram2.data with fixed order { + //section .infra.ram.start*, + //section .rodata*, + //section .wlan.text, + //section .wps.text, section CODE, - section .otg.rom.text, + //section .otg.rom.text, section Veneer object startup.o, section __DLIB_PERTHREAD, section .iar.dynexit*, + block CPP_INIT, //section .mdns.text - }; - -define block .ram.data with fixed order{ readwrite, readonly, - section .data*, - section .wlan.data, - section .wps.data, - section DATA, - section .ram.otg.data.a, - section .iar.init_table, - //section .mdns.data - }; + }; +define block .ram.data with fixed order { + readwrite, readonly, + section .data*, + section .wlan.data, + section .wps.data, + section DATA, + section .ram.otg.data.a, + section .iar.init_table, + //section .mdns.data, + //section .data* object lib_peripheral_mbed_iar.a, + }; + +define block .ram.bss with fixed order { + section .bss*, + section COMMON, + section .bdsram.data*, + }; + +define block IMAGE2 with fixed order { + block .sram1.text, + block .ram.data, + block .ram.bss + }; -define block IMAGE2 with fixed order { block .image2.start.table1, block .image2.start.table2, block .ram_image2.text, block .ram.data }; - -define block .ram.bss with fixed order{ section .bss*, - section .ssl_ram_map, - section .hal.flash.data*, - section .hal.gpio.data*, - section COMMON, - section .bdsram.data*, - section .bss* object heap_4.o - }; define block .bf_data with fixed order{ section .bfsram.data* }; define block .heap with fixed order{ section .heap* }; define block .stack_dummy with fixed order { section .stack }; -place at start of BD_RAM_region { +place at start of BD_RAM_region { block IMAGE2, //block IMAGE1_DBG, - block .ram.bss, + //block .ram.bss, //block .bf_data, - }; + }; -//place at address mem:0x10052b00 { readwrite, place at end of BD_RAM_region { block .bf_data, block HEAP, - }; - -define block SDRAM with fixed order{ section .sdram.text*, - section .sdram.data*, - section .mdns.text*, - section .mdns.data*, - block FPB_REMAP - }; + }; + +define block SDRAM with fixed order { + block .sram2.text, + block .sram2.data, + section .sdram.text*, + section .sdram.data*, + section .mdns.text*, + section .mdns.data*, + block FPB_REMAP + }; define block SDRBSS with fixed order{ - section .sdram.bss* - }; + section .sdram.bss* + }; -place at start of SDRAM_RAM_region { - block SDRAM, - block SDRBSS, - //block IMAGE1_DBG +place at start of SDRAM_RAM_region { + block SDRAM, + block SDRBSS, + //block IMAGE1_DBG }; /* TCM placement */ define overlay TCM_overlay { - section .tcm.heap, - section .bss object lwip_mem.o, - section .bss object lwip_memp.o, - block .heap, - block .stack_dummy - }; + section .tcm.heap, + section .bss object lwip_mem.o, + section .bss object lwip_memp.o, + block .heap, + block .stack_dummy + }; /* dummy code placement */ define overlay TCM_overlay { block IMAGE1_DBG }; -place at start of TCM_region { overlay TCM_overlay }; -place at end of TCM_region { block CSTACK}; - -define exported symbol __rom_bss_start__ = 0x10000300; // use in rom -define exported symbol __rom_bss_end__ = 0x10000bc8; // use in rom -define exported symbol __ram_start_table_start__= 0x10000bc8; // use in rom -define exported symbol __image1_validate_code__= 0x10000bdc; // needed by ram code -define exported symbol _rtl_impure_ptr = 0x10001c60; // for standard library +place at start of TCM_region { overlay TCM_overlay }; +place at end of TCM_region { block CSTACK}; + +define exported symbol __rom_bss_start__ = 0x10000300; // use in rom +define exported symbol __rom_bss_end__ = 0x10000bc8; // use in rom +define exported symbol __ram_start_table_start__= 0x10000bc8; // use in rom +define exported symbol __image1_validate_code__= 0x10000bdc; // needed by ram code +define exported symbol _rtl_impure_ptr = 0x10001c60; // for standard library define exported symbol __sdio_rom_bss_start__ = 0x1006D000; define exported symbol __sdio_rom_bss_end__ = 0x1006fa10; diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/platform_autoconf.h b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/platform_autoconf.h index f91dcfa39ad..6613bbd5244 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/platform_autoconf.h +++ b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/platform_autoconf.h @@ -186,7 +186,7 @@ #define CONFIG_UART_LOG_HISTORY 1 #undef CONFIG_CONSOLE_NORMALL_MODE #define CONFIG_CONSOLE_VERIFY_MODE 1 -#define CONFIG_DEBUG_LOG 1 +#undef CONFIG_DEBUG_LOG #define CONFIG_DEBUG_ERR_MSG 1 #undef CONFIG_DEBUG_WARN_MSG #undef CONFIG_DEBUG_INFO_MSG diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/rtl8195a_init.c b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/rtl8195a_init.c index bd83781b3a0..9e1faafe2f3 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/rtl8195a_init.c +++ b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/rtl8195a_init.c @@ -14,26 +14,39 @@ * limitations under the License. */ #include "rtl8195a.h" -#include "system_8195a.h" -#if defined ( __CC_ARM ) /* ARM Compiler 4/5 */ -extern uint8_t Image$$RW_IRAM1$$ZI$$Base[]; -#define __bss_start__ Image$$RW_IRAM1$$ZI$$Base -extern uint8_t Image$$RW_IRAM1$$ZI$$Limit[]; -#define __bss_end__ Image$$RW_IRAM1$$ZI$$Limit -#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler 6 */ -extern uint8_t Image$$RW_IRAM1$$ZI$$Base[]; -#define __bss_start__ Image$$RW_IRAM1$$ZI$$Base -extern uint8_t Image$$RW_IRAM1$$ZI$$Limit[]; -#define __bss_end__ Image$$RW_IRAM1$$ZI$$Limit - -#elif defined ( __ICCARM__ ) + +#if defined(__CC_ARM) +#include "cmsis_armcc.h" +#elif defined(__GNUC__) +#include "cmsis_gcc.h" +#else +#include +#endif + + +#if defined(__CC_ARM) || \ + (defined (__ARMCC_VERSION) && __ARMCC_VERSION >= 6010050) + +extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit; +extern uint8_t Image$$RW_IRAM2$$ZI$$Base[]; +extern uint8_t Image$$RW_IRAM2$$ZI$$Limit[]; +extern uint8_t Image$$TCM_OVERLAY$$ZI$$Base[]; +extern uint8_t Image$$TCM_OVERLAY$$ZI$$Limit[]; +extern uint8_t Image$$RW_DRAM2$$ZI$$Base[]; +extern uint8_t Image$$RW_DRAM2$$ZI$$Limit[]; +#define __bss_sram_start__ Image$$RW_IRAM2$$ZI$$Base +#define __bss_sram_end__ Image$$RW_IRAM2$$ZI$$Limit +#define __bss_dtcm_start__ Image$$TCM_OVERLAY$$ZI$$Base +#define __bss_dtcm_end__ Image$$TCM_OVERLAY$$ZI$$Limit +#define __bss_dram_start__ Image$$RW_DRAM2$$ZI$$Base +#define __bss_dram_end__ Image$$RW_DRAM2$$ZI$$Limit +#define __stackp Image$$ARM_LIB_STACK$$ZI$$Limit + +#elif defined (__ICCARM__) + #pragma section=".ram.bss" -#pragma section=".rom.bss" -#pragma section=".ram.start.table" -#pragma section=".ram_image1.bss" -#pragma section=".image2.start.table1" -#pragma section=".image2.start.table2" +extern uint32_t CSTACK$$Limit; uint8_t *__bss_start__; uint8_t *__bss_end__; @@ -42,30 +55,34 @@ void __iar_data_init_app(void) __bss_start__ = (uint8_t *)__section_begin(".ram.bss"); __bss_end__ = (uint8_t *)__section_end(".ram.bss"); } +#define __stackp CSTACK$$Limit + #else -extern uint8_t __bss_start__[]; -extern uint8_t __bss_end__[]; -extern uint8_t __image1_bss_start__[]; -extern uint8_t __image1_bss_end__[]; -extern uint8_t __image2_entry_func__[]; -extern uint8_t __image2_validate_code__[]; + +extern uint32_t __StackTop; +extern uint32_t __StackLimit; +extern uint8_t __bss_sram_start__[]; +extern uint8_t __bss_sram_end__[]; +extern uint8_t __bss_dtcm_start__[]; +extern uint8_t __bss_dtcm_end__[]; +extern uint8_t __bss_dram_start__[]; +extern uint8_t __bss_dram_end__[]; + +#define __stackp __StackTop #endif extern VECTOR_Func NewVectorTable[]; extern void SystemCoreClockUpdate(void); extern void PLAT_Start(void); extern void PLAT_Main(void); -extern HAL_TIMER_OP HalTimerOp; - -IMAGE2_START_RAM_FUN_SECTION const RAM_START_FUNCTION gImage2EntryFun0 = { - PLAT_Start -}; -IMAGE1_VALID_PATTEN_SECTION const uint8_t RAM_IMG1_VALID_PATTEN[] = { - 0x23, 0x79, 0x16, 0x88, 0xff, 0xff, 0xff, 0xff +IMAGE2_START_RAM_FUN_SECTION +const RAM_START_FUNCTION gImage2EntryFun0 = { + PLAT_Start }; -IMAGE2_VALID_PATTEN_SECTION const uint8_t RAM_IMG2_VALID_PATTEN[20] = { +IMAGE2_VALID_PATTEN_SECTION +const uint8_t IMAGE2_SIGNATURE[20] = { 'R', 'T', 'K', 'W', 'i', 'n', 0x0, 0xff, (FW_VERSION&0xff), ((FW_VERSION >> 8)&0xff), (FW_SUBVERSION&0xff), ((FW_SUBVERSION >> 8)&0xff), @@ -93,7 +110,7 @@ void TRAP_NMIHandler(void) #endif } -#if defined ( __ICCARM__ ) +#if defined (__ICCARM__) void __TRAP_HardFaultHandler_Patch(uint32_t addr) { uint32_t cfsr; @@ -118,9 +135,9 @@ void __TRAP_HardFaultHandler_Patch(uint32_t addr) * Otherwise it will keep hitting MemMange Fault on the same assembly code. * * To step to next command, we need parse the assembly code to check if - * it is 16-bit or 32-bit command. + * it is 16-bit or 32-bit command. * Ref: ARM Architecture Reference Manual (ARMv7-A and ARMv7-R edition), - * Chapter A6 - Thumb Instruction Set Encoding + * Chapter A6 - Thumb Instruction Set Encoding * * However, the fault assembly code (Ex. LDR or ADR) is not actually executed, * So the register value is un-predictable. @@ -154,96 +171,63 @@ void TRAP_HardFaultHandler_Patch(void) } #endif -// Override original Interrupt Vector Table -INFRA_START_SECTION void TRAP_OverrideTable(uint32_t stackp) +extern _LONG_CALL_ void * __rtl_memset_v1_00(void * m , int c , size_t n); +// Image2 Entry Function +void PLAT_Start(void) { - // Override NMI Handler - NewVectorTable[2] = (VECTOR_Func) TRAP_NMIHandler; + uint32_t val; - #if defined ( __ICCARM__ ) +#if defined (__ICCARM__) + __iar_data_init_app(); +#endif + + // Clear RAM BSS +#if defined (__ICCARM__) + __rtl_memset_v1_00((void *)__bss_start__, 0, __bss_end__ - __bss_start__); +#else + __rtl_memset_v1_00((void *)__bss_sram_start__, 0, __bss_sram_end__ - __bss_sram_start__); + __rtl_memset_v1_00((void *)__bss_dtcm_start__, 0, __bss_dtcm_end__ - __bss_dtcm_start__); + __rtl_memset_v1_00((void *)__bss_dram_start__, 0, __bss_dram_end__ - __bss_dram_start__); +#endif + + // Set MSP + __set_MSP((uint32_t)&__stackp - 0x100); + // Overwrite vector table + NewVectorTable[2] = (VECTOR_Func) TRAP_NMIHandler; +#if defined ( __ICCARM__ ) NewVectorTable[3] = (VECTOR_Func) TRAP_HardFaultHandler_Patch; - #endif -} +#endif -INFRA_START_SECTION void PLAT_Init(void) -{ - uint32_t val; + extern HAL_TIMER_OP_EXT HalTimerOpExt; + __rtl_memset_v1_00((void *)&HalTimerOpExt, 0, sizeof(HalTimerOpExt)); + __rtl_memset_v1_00((void *)&HalTimerOp, 0, sizeof(HalTimerOp)); + + HalTimerOpInit_Patch(&HalTimerOp); + SystemCoreClockUpdate(); - //Set SPS lower voltage + // Set SPS lower voltage val = __RTK_CTRL_READ32(REG_SYS_EFUSE_SYSCFG0); val &= 0xf0ffffff; val |= 0x6000000; __RTK_CTRL_WRITE32(REG_SYS_EFUSE_SYSCFG0, val); - - //xtal buffer driving current + + // xtal buffer driving current val = __RTK_CTRL_READ32(REG_SYS_XTAL_CTRL1); val &= ~(BIT_MASK_SYS_XTAL_DRV_RF1 << BIT_SHIFT_SYS_XTAL_DRV_RF1); val |= BIT_SYS_XTAL_DRV_RF1(1); __RTK_CTRL_WRITE32(REG_SYS_XTAL_CTRL1, val); -} - -//3 Image 2 -extern _LONG_CALL_ void * __rtl_memset_v1_00(void * m , int c , size_t n); -//extern uint32_t mbed_stack_isr_start; -//extern uint32_t mbed_stack_isr_size; -INFRA_START_SECTION void PLAT_Start(void) -{ - u8 isFlashEn; -#if defined ( __ICCARM__ ) - __iar_data_init_app(); -#endif - // Clear RAM BSS - __rtl_memset_v1_00((void *)__bss_start__, 0, __bss_end__ - __bss_start__); - - TRAP_OverrideTable(0x1FFFFFFC); -/* add by Ian --for mbed isr stack address setting */ - __set_MSP(0x1fffffbc); - - -#ifdef CONFIG_SPIC_MODULE - if ((HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & BIT_SOC_FLASH_EN) != 0) { - isFlashEn = 1; - } else { - isFlashEn = 0; - } -#endif + // Initialize SPIC, then disable it for power saving. + if ((HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & BIT_SOC_FLASH_EN) != 0) { + SpicNVMCalLoadAll(); + SpicReadIDRtl8195A(); + SpicDisableRtl8195A(); + } #ifdef CONFIG_TIMER_MODULE - HalTimerOpInit_Patch(&HalTimerOp); + Calibration32k(); #endif - //DBG_8195A("===== Enter Image 2 ====\n"); - - - SystemCoreClockUpdate(); - - if (isFlashEn) { -#if CONFIG_SPIC_EN && SPIC_CALIBRATION_IN_NVM - SpicNVMCalLoadAll(); -#endif - SpicReadIDRtl8195A(); - // turn off SPIC for power saving - SpicDisableRtl8195A(); - } - - - PLAT_Init(); -#ifdef CONFIG_TIMER_MODULE - Calibration32k(); - -#ifdef CONFIG_WDG -#ifdef CONFIG_WDG_TEST - WDGInit(); -#endif //CONFIG_WDG_TEST -#endif //CONFIG_WDG -#endif //CONFIG_TIMER_MODULE - -#ifdef CONFIG_SOC_PS_MODULE - //InitSoCPM(); -#endif - /* GPIOA_7 does not pull high at power on. It causes SDIO Device - * hardware to enable automatically and occupy GPIOA[7:0] */ #ifndef CONFIG_SDIO_DEVICE_EN SDIO_DEV_Disable(); #endif @@ -256,37 +240,41 @@ extern void SVC_Handler(void); extern void PendSV_Handler(void); extern void SysTick_Handler(void); +// The Main App entry point #if defined (__CC_ARM) __asm void ARM_PLAT_Main(void) { - IMPORT SystemInit - IMPORT __main - BL SystemInit - BL __main + IMPORT SystemInit + IMPORT __main + BL SystemInit + BL __main +} +#elif defined (__ICCARM__) +extern void __iar_program_start(void); + +void IAR_PLAT_Main(void) +{ + SystemInit(); + __iar_program_start(); } #endif -extern void __iar_program_start( void ); -// The Main App entry point void PLAT_Main(void) { TRAP_Init((void *)SVC_Handler, (void *)PendSV_Handler, (void *)SysTick_Handler); -#if defined (__ICCARM__) - //IAR_PLAT_Main(); - SystemInit(); - __iar_program_start(); -#elif defined (__CC_ARM) - ARM_PLAT_Main(); - -#elif defined (__GNUC__) - __asm ( - "ldr r0, =SystemInit \n" +#if defined (__CC_ARM) + ARM_PLAT_Main(); +#elif defined (__ICCARM__) + IAR_PLAT_Main(); +#else + __asm ("ldr r0, =SystemInit \n" "blx r0 \n" "ldr r0, =_start \n" "bx r0 \n" ); #endif + // Never reached - for(;;); + for (;;); } diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/rtl8195a_timer.h b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/rtl8195a_timer.h index 2dd16255dbc..caf8223d118 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/rtl8195a_timer.h +++ b/targets/TARGET_Realtek/TARGET_AMEBA/TARGET_RTL8195A/device/rtl8195a_timer.h @@ -15,7 +15,7 @@ #define _RTL8195A_TIMER_H_ -#define TIMER_TICK_US 31 +#define TIMER_TICK_US 32 #define TIMER_LOAD_COUNT_OFF 0x00 #define TIMER_CURRENT_VAL_OFF 0x04 diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/analogin_api.c b/targets/TARGET_Realtek/TARGET_AMEBA/analogin_api.c index 011008d7914..3011f412b15 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/analogin_api.c +++ b/targets/TARGET_Realtek/TARGET_AMEBA/analogin_api.c @@ -113,12 +113,10 @@ void analogin_init (analogin_t *obj, PinName pin) /* Load user setting */ if ((pHalADCInitDataTmp->ADCEndian == ADC_DATA_ENDIAN_LITTLE) || (pHalADCInitDataTmp->ADCEndian == ADC_DATA_ENDIAN_BIG)) { - DBG_8195A("K\n"); pSalADCHND->pInitDat->ADCEndian = pHalADCInitDataTmp->ADCEndian; } if ((pHalADCInitDataTmp->ADCAudioEn != ADC_FEATURE_DISABLED) && (pHalADCInitDataTmp->ADCAudioEn < 2)) { - DBG_8195A("O\n"); pSalADCHND->pInitDat->ADCAudioEn = pHalADCInitDataTmp->ADCAudioEn; } diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/ota_api.c b/targets/TARGET_Realtek/TARGET_AMEBA/ota_api.c new file mode 100644 index 00000000000..890a8ad5600 --- /dev/null +++ b/targets/TARGET_Realtek/TARGET_AMEBA/ota_api.c @@ -0,0 +1,154 @@ +/* mbed Microcontroller Library + * Copyright (c) 2013-2017 Realtek Semiconductor Corp. + * + * 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 +#include + +#include "mbed_wait_api.h" + +#include "rtl8195a.h" +#include "flash_ext.h" + +#define FLASH_TOP 0x200000 +#define FLASH_SECTOR_SIZE 0x1000 +#define FLASH_SECTOR_MASK ~(FLASH_SECTOR_SIZE - 1) +#define OTA_REGION1 0x0b000 +#define OTA_REGION2 0xc0000 +#define TAG_OFS 0xc +#define VER_OFS 0x10 + +#define TAG_DOWNLOAD 0x81950001 +#define TAG_VERIFIED 0x81950003 + +static flash_t flash_obj; + +typedef struct imginfo_s { + uint32_t base; + uint32_t tag; + uint64_t ver; +} imginfo_t; + + +void OTA_GetImageInfo(imginfo_t *info) +{ + uint32_t ver_hi, ver_lo; + + flash_ext_read_word(&flash_obj, info->base + TAG_OFS, &info->tag); + flash_ext_read_word(&flash_obj, info->base + VER_OFS, &ver_lo); + flash_ext_read_word(&flash_obj, info->base + VER_OFS + 4, &ver_hi); + + if (info->tag == TAG_DOWNLOAD) { + info->ver = ((uint64_t)ver_hi << 32) | (uint64_t) ver_lo; + } else { + info->ver = 0; + } +} + +uint32_t OTA_GetBase(void) +{ + static uint32_t ota_base = 0; + imginfo_t region1, region2; + + if (ota_base == OTA_REGION1 || ota_base == OTA_REGION2) { + return ota_base; + } + + region1.base = OTA_REGION1; + region2.base = OTA_REGION2; + + OTA_GetImageInfo(®ion1); + OTA_GetImageInfo(®ion2); + + if (region1.ver >= region2.ver) { + ota_base = region2.base; + } else { + ota_base = region1.base; + } + return ota_base; +} + +uint32_t OTA_MarkUpdateDone(void) +{ + uint32_t addr = OTA_GetBase() + TAG_OFS; + + return flash_ext_write_word(&flash_obj, addr, TAG_DOWNLOAD); +} + +uint32_t OTA_UpdateImage(uint32_t offset, uint32_t len, uint8_t *data) +{ + uint32_t addr, start, end, count, shift; + uint8_t *pdata = data; + uint8_t buf[FLASH_SECTOR_SIZE]; + + start = OTA_GetBase() + offset; + end = start + len; + + if (data == NULL || start > FLASH_TOP || end > FLASH_TOP) { + return 0; + } + + addr = start & FLASH_SECTOR_MASK; + if (addr != start) { + shift = start - addr; + count = MIN(FLASH_SECTOR_SIZE - shift, len); + flash_ext_stream_read(&flash_obj, addr, shift, buf); + memcpy((void *)(buf + shift), (void *)pdata, count); + + flash_ext_erase_sector(&flash_obj, addr); + flash_ext_stream_write(&flash_obj, addr, FLASH_SECTOR_SIZE, buf); + addr += FLASH_SECTOR_SIZE; + pdata += count; + } + + while (addr < end) { + printf("OTA: update addr=0x%lx, len=%ld\r\n", addr, len); + count = MIN(FLASH_SECTOR_SIZE, end - addr); + flash_ext_erase_sector(&flash_obj, addr); + flash_ext_stream_write(&flash_obj, addr, count, pdata); + addr += FLASH_SECTOR_SIZE; + pdata += count; + } + return len; +} + +uint32_t OTA_ReadImage(uint32_t offset, uint32_t len, uint8_t *data) +{ + uint32_t addr, endaddr; + + addr = OTA_GetBase() + offset; + endaddr = addr + len; + + if (data == NULL || addr > FLASH_TOP || endaddr > FLASH_TOP) { + return 0; + } + + printf("OTA: read addr=0x%lx\r\n", addr); + return flash_ext_stream_read(&flash_obj, addr, len, data); +} + +void OTA_ResetTarget(void) +{ + __RTK_CTRL_WRITE32(0x14, 0x00000021); + wait(1); + + // write SCB->AIRCR + HAL_WRITE32(0xE000ED00, 0x0C, + (0x5FA << 16) | // VECTKEY + (HAL_READ32(0xE000ED00, 0x0C) & (7 << 8)) | // PRIGROUP + (1 << 2)); // SYSRESETREQ + + // not reached + while (1); +} diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/ota_api.h b/targets/TARGET_Realtek/TARGET_AMEBA/ota_api.h new file mode 100644 index 00000000000..2b978a32368 --- /dev/null +++ b/targets/TARGET_Realtek/TARGET_AMEBA/ota_api.h @@ -0,0 +1,18 @@ +#ifndef MBED_OTA_API_H +#define MBED_OTA_API_H + +#ifdef __cplusplus + extern "C" { +#endif + +extern uint32_t OTA_UpdateImage(uint32_t offset, uint32_t len, uint8_t *data); +extern uint32_t OTA_ReadImage(uint32_t offset, uint32_t len, uint8_t *data); +extern uint32_t OTA_MarkUpdateDone(void); +extern void OTA_ResetTarget(void); + +#ifdef __cplusplus +} +#endif + +#endif /* MBED_OTA_API_H */ + diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/us_ticker.c b/targets/TARGET_Realtek/TARGET_AMEBA/us_ticker.c index 060ffccfb87..50bcd229d9d 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/us_ticker.c +++ b/targets/TARGET_Realtek/TARGET_AMEBA/us_ticker.c @@ -77,21 +77,22 @@ uint32_t us_ticker_read() void us_ticker_set_interrupt(timestamp_t timestamp) { uint32_t cur_time_us; - uint32_t time_def; - + uint32_t time_dif; + HalTimerOp.HalTimerDis((u32)TimerAdapter.TimerId); cur_time_us = us_ticker_read(); - if ((uint32_t)timestamp >= cur_time_us) { - time_def = (uint32_t)timestamp - cur_time_us; + if ((uint32_t)timestamp > cur_time_us) { + time_dif = (uint32_t)timestamp - cur_time_us; } else { - time_def = 0xffffffff - cur_time_us + (uint32_t)timestamp; + HalTimerOpExt.HalTimerReLoad((u32)TimerAdapter.TimerId, 0xffffffff); + HalTimerOpExt.HalTimerIrqEn((u32)TimerAdapter.TimerId); + HalTimerOp.HalTimerEn((u32)TimerAdapter.TimerId); + NVIC_SetPendingIRQ(TIMER2_7_IRQ); + return; } - if (time_def < TIMER_TICK_US) { - time_def = TIMER_TICK_US; // at least 1 tick - } - HalTimerOp.HalTimerDis((u32)TimerAdapter.TimerId); - HalTimerOpExt.HalTimerReLoad((u32)TimerAdapter.TimerId, time_def); + TimerAdapter.TimerLoadValueUs = time_dif; + HalTimerOpExt.HalTimerReLoad((u32)TimerAdapter.TimerId, time_dif / TIMER_TICK_US); HalTimerOpExt.HalTimerIrqEn((u32)TimerAdapter.TimerId); HalTimerOp.HalTimerEn((u32)TimerAdapter.TimerId); diff --git a/targets/TARGET_Realtek/mbed_rtx.h b/targets/TARGET_Realtek/mbed_rtx.h index 264a5ed53e5..a5a4e56833f 100644 --- a/targets/TARGET_Realtek/mbed_rtx.h +++ b/targets/TARGET_Realtek/mbed_rtx.h @@ -21,16 +21,14 @@ #include "rtl8195a.h" #if defined(__CC_ARM) -#ifdef CONFIG_RTL8195A - #define INITIAL_SP 0x10070000 - #define ISR_STACK_START 0x1FFFEFFC -#else - #ERROR "NOT SUPPORT NOW" -#endif + extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[]; + extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Length[]; + #define ISR_STACK_START (unsigned char *)(Image$$ARM_LIB_STACK$$ZI$$Base) + #define ISR_STACK_SIZE (uint32_t)(Image$$ARM_LIB_STACK$$ZI$$Length) + #define INITIAL_SP (uint32_t)(Image$$ARM_LIB_STACK$$ZI$$Base) #elif defined(__GNUC__) extern uint32_t __StackTop[]; extern uint32_t __StackLimit[]; -// extern uint32_t __end__[]; extern uint32_t __HeapLimit[]; #define INITIAL_SP (__StackTop) #endif @@ -54,4 +52,3 @@ #endif #endif - diff --git a/targets/TARGET_STM/TARGET_STM32F1/pin_device.h b/targets/TARGET_STM/TARGET_STM32F1/pin_device.h index 21f7008fa47..01a6d7d60ec 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/pin_device.h +++ b/targets/TARGET_STM/TARGET_STM32F1/pin_device.h @@ -37,6 +37,9 @@ extern const uint32_t ll_pin_defines[16]; static inline void stm_pin_DisconnectDebug(PinName pin) { + // Enable AFIO clock + __HAL_RCC_AFIO_CLK_ENABLE(); + // Disconnect JTAG-DP + SW-DP signals. // Warning: Need to reconnect under reset if ((pin == PA_13) || (pin == PA_14)) { diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/device/system_clock.c index 6fe069502b0..e80ad41e0fb 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/device/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/device/system_clock.c @@ -240,6 +240,8 @@ uint8_t SetSysClock_PLL_HSI(void) /******************************************************************************/ void HardFault_Handler(void) { +#if !defined(NDEBUG) || NDEBUG == 0 printf("Hard Fault\n"); +#endif NVIC_SystemReset(); } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/device/system_clock.c index 196b2e15af5..cf1e3832b3d 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/device/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/device/system_clock.c @@ -243,6 +243,8 @@ uint8_t SetSysClock_PLL_HSI(void) /******************************************************************************/ void HardFault_Handler(void) { +#if !defined(NDEBUG) || NDEBUG == 0 printf("Hard Fault\n"); +#endif NVIC_SystemReset(); } diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/device/hal_tick.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/device/hal_tick.h index 19d9584eee3..cedecee5453 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/device/hal_tick.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/device/hal_tick.h @@ -46,6 +46,7 @@ #define TIM_MST TIM5 #define TIM_MST_IRQ TIM5_IRQn #define TIM_MST_RCC __HAL_RCC_TIM5_CLK_ENABLE() +#define TIM_MST_DBGMCU_FREEZE __HAL_DBGMCU_FREEZE_TIM5() #define TIM_MST_RESET_ON __HAL_RCC_TIM5_FORCE_RESET() #define TIM_MST_RESET_OFF __HAL_RCC_TIM5_RELEASE_RESET() diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_UBLOX_EVK_ODIN_W2/PinNames.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_UBLOX_EVK_ODIN_W2/PinNames.h index bef42044006..08373f49235 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_UBLOX_EVK_ODIN_W2/PinNames.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/TARGET_UBLOX_EVK_ODIN_W2/PinNames.h @@ -95,7 +95,7 @@ typedef enum { P_A17 = PD_12, // GPIO-3 P_A18 = PA_3, // UART-DSR // B - // C + // C P_C5 = PG_4, // SPI-IRQ P_C6 = PE_13, // SPI-MISO P_C8 = PE_12, // Res @@ -153,9 +153,18 @@ typedef enum { LED1 = PE_0, // Red / Mode LED2 = PB_6, // Green / Switch-1 LED3 = PB_8, // Blue - LED4 = D10, + LED4 = D10, SW0 = PF_2, // Switch-0 SW1 = PB_6, // Green / Switch-1 + + LED_RED = LED1, + LED_GREEN = LED2, + LED_BLUE = LED3, + + // Standardized button names + BUTTON1 = SW0, + BUTTON2 = SW1, + // ST-Link USBRX = PA_10, USBTX = PA_9, diff --git a/targets/TARGET_STM/TARGET_STM32F4/analogin_api.c b/targets/TARGET_STM/TARGET_STM32F4/analogin_api.c index 7a85817c503..ada98bc4d79 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/analogin_api.c +++ b/targets/TARGET_STM/TARGET_STM32F4/analogin_api.c @@ -180,11 +180,12 @@ static inline uint16_t adc_read(analogin_t *obj) break; case 17: sConfig.Channel = ADC_CHANNEL_VREFINT; + /* From experiment, measurement needs max sampling time to be valid */ + sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; break; case 18: sConfig.Channel = ADC_CHANNEL_VBAT; - /* From experiment, VBAT measurement needs max - * sampling time to be avlid */ + /* From experiment, measurement needs max sampling time to be valid */ sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; break; default: diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/system_clock.c b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/system_clock.c index b7fad596118..19d80f38705 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/system_clock.c @@ -41,7 +41,7 @@ /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ /* #define VECT_TAB_SRAM */ -#define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field. +#define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ /* Select the clock sources (other than HSI) to start with (0=OFF, 1=ON) */ @@ -253,7 +253,9 @@ uint8_t SetSysClock_PLL_HSI(void) /******************************************************************************/ void HardFault_Handler(void) { +#if !defined(NDEBUG) || NDEBUG == 0 printf("Hard Fault\n"); +#endif NVIC_SystemReset(); } diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/xdot_low_power.c b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/xdot_low_power.c index 7ea04d40b59..cec303bd953 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/xdot_low_power.c +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/xdot_low_power.c @@ -31,6 +31,12 @@ #include "xdot_low_power.h" #include "stdio.h" +#if defined(NDEBUG) && NDEBUG == 1 +#define xdot_lp_debug(...) do {} while(0) +#else +#define xdot_lp_debug(...) printf(__VA_ARGS__) +#endif + static uint32_t portA[6]; static uint32_t portB[6]; static uint32_t portC[6]; @@ -230,7 +236,7 @@ void xdot_enter_stop_mode() { HSERCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL4; HSERCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV3; if (HAL_RCC_OscConfig(&HSERCC_OscInitStruct) != HAL_OK) { - printf("OSC initialization failed - initiating soft reset\r\n"); + xdot_lp_debug("OSC initialization failed - initiating soft reset\r\n"); NVIC_SystemReset(); } @@ -241,7 +247,7 @@ void xdot_enter_stop_mode() { RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; // 32 MHz RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 32 MHz if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { - printf("PLL initialization failed - initiating soft reset\r\n"); + xdot_lp_debug("PLL initialization failed - initiating soft reset\r\n"); NVIC_SystemReset(); } @@ -254,7 +260,7 @@ void xdot_enter_stop_mode() { HSIRCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; HAL_StatusTypeDef ret = HAL_RCC_OscConfig(&HSIRCC_OscInitStruct); if ( ret != HAL_OK ) { - printf("HSI initialization failed - ADC will not function properly\r\n"); + xdot_lp_debug("HSI initialization failed - ADC will not function properly\r\n"); } } diff --git a/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_spi.c b/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_spi.c index d60c326dcf4..95068ef614f 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_spi.c +++ b/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_spi.c @@ -655,6 +655,10 @@ HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint hspi->ErrorCode = HAL_SPI_ERROR_FLAG; } + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) { + __HAL_SPI_DISABLE(hspi); + } + /* Clear overrun flag in 2 Lines communication mode because received is not read */ if (hspi->Init.Direction == SPI_DIRECTION_2LINES) { diff --git a/targets/TARGET_STM/hal_tick_16b.c b/targets/TARGET_STM/hal_tick_16b.c index 8a2e43f17b1..fadd4e55880 100644 --- a/targets/TARGET_STM/hal_tick_16b.c +++ b/targets/TARGET_STM/hal_tick_16b.c @@ -148,6 +148,13 @@ HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) // Enable timer HAL_TIM_Base_Start(&TimMasterHandle); +#ifndef NDEBUG +#ifdef TIM_MST_DBGMCU_FREEZE + // Freeze timer on stop/breakpoint + TIM_MST_DBGMCU_FREEZE; +#endif +#endif + #if DEBUG_TICK > 0 __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct; diff --git a/targets/TARGET_STM/hal_tick_32b.c b/targets/TARGET_STM/hal_tick_32b.c index 2bcd0b7f3ae..6f1b715473c 100644 --- a/targets/TARGET_STM/hal_tick_32b.c +++ b/targets/TARGET_STM/hal_tick_32b.c @@ -118,6 +118,13 @@ HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) __HAL_TIM_SET_COMPARE(&TimMasterHandle, TIM_CHANNEL_2, PreviousVal + HAL_TICK_DELAY); __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC2); +#ifndef NDEBUG +#ifdef TIM_MST_DBGMCU_FREEZE + // Freeze timer on stop/breakpoint + TIM_MST_DBGMCU_FREEZE; +#endif +#endif + #if DEBUG_TICK > 0 __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct; diff --git a/targets/TARGET_STM/stm_spi_api.c b/targets/TARGET_STM/stm_spi_api.c index f231e3dee99..5706a3d722a 100644 --- a/targets/TARGET_STM/stm_spi_api.c +++ b/targets/TARGET_STM/stm_spi_api.c @@ -63,6 +63,9 @@ # define DEBUG_PRINTF(...) {} #endif +/* Consider 10ms as the default timeout for sending/receving 1 byte */ +#define TIMEOUT_1_BYTE 10 + void init_spi(spi_t *obj) { struct spi_s *spiobj = SPI_S(obj); @@ -75,7 +78,14 @@ void init_spi(spi_t *obj) error("Cannot initialize SPI"); } - __HAL_SPI_ENABLE(handle); + /* In case of standard 4 wires SPI,PI can be kept enabled all time + * and SCK will only be generated during the write operations. But in case + * of 3 wires, it should be only enabled during rd/wr unitary operations, + * which is handled inside STM32 HAL layer. + */ + if (handle->Init.Direction == SPI_DIRECTION_2LINES) { + __HAL_SPI_ENABLE(handle); + } } void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) @@ -156,7 +166,13 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel handle->Instance = SPI_INST(obj); handle->Init.Mode = SPI_MODE_MASTER; handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; - handle->Init.Direction = SPI_DIRECTION_2LINES; + + if (miso != NC) { + handle->Init.Direction = SPI_DIRECTION_2LINES; + } else { + handle->Init.Direction = SPI_DIRECTION_1LINE; + } + handle->Init.CLKPhase = SPI_PHASE_1EDGE; handle->Init.CLKPolarity = SPI_POLARITY_LOW; handle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; @@ -353,6 +369,10 @@ int spi_master_write(spi_t *obj, int value) struct spi_s *spiobj = SPI_S(obj); SPI_HandleTypeDef *handle = &(spiobj->handle); + if (handle->Init.Direction == SPI_DIRECTION_1LINE) { + return HAL_SPI_Transmit(handle, (uint8_t*)&value, 1, TIMEOUT_1_BYTE); + } + #if defined(LL_SPI_RX_FIFO_TH_HALF) /* Configure the default data size */ if (handle->Init.DataSize == SPI_DATASIZE_16BIT) { @@ -390,13 +410,31 @@ int spi_master_write(spi_t *obj, int value) int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, char write_fill) { + struct spi_s *spiobj = SPI_S(obj); + SPI_HandleTypeDef *handle = &(spiobj->handle); int total = (tx_length > rx_length) ? tx_length : rx_length; - - for (int i = 0; i < total; i++) { - char out = (i < tx_length) ? tx_buffer[i] : write_fill; - char in = spi_master_write(obj, out); - if (i < rx_length) { - rx_buffer[i] = in; + int i = 0; + if (handle->Init.Direction == SPI_DIRECTION_2LINES) { + for (i = 0; i < total; i++) { + char out = (i < tx_length) ? tx_buffer[i] : write_fill; + char in = spi_master_write(obj, out); + if (i < rx_length) { + rx_buffer[i] = in; + } + } + } else { + /* In case of 1 WIRE only, first handle TX, then Rx */ + if (tx_length != 0) { + if (HAL_OK != HAL_SPI_Transmit(handle, (uint8_t*)tx_buffer, tx_length, tx_length*TIMEOUT_1_BYTE)) { + /* report an error */ + total = 0; + } + } + if (rx_length != 0) { + if (HAL_OK != HAL_SPI_Receive(handle, (uint8_t*)rx_buffer, rx_length, rx_length*TIMEOUT_1_BYTE)) { + /* report an error */ + total = 0; + } } } @@ -410,17 +448,13 @@ int spi_slave_receive(spi_t *obj) int spi_slave_read(spi_t *obj) { - SPI_TypeDef *spi = SPI_INST(obj); struct spi_s *spiobj = SPI_S(obj); SPI_HandleTypeDef *handle = &(spiobj->handle); while (!ssp_readable(obj)); - if (handle->Init.DataSize == SPI_DATASIZE_8BIT) { - // Force 8-bit access to the data register - uint8_t *p_spi_dr = 0; - p_spi_dr = (uint8_t *) & (spi->DR); - return (int)(*p_spi_dr); + if (handle->Init.DataSize == SPI_DATASIZE_16BIT) { + return LL_SPI_ReceiveData16(SPI_INST(obj)); } else { - return (int)spi->DR; + return LL_SPI_ReceiveData8(SPI_INST(obj)); } } diff --git a/targets/targets.json b/targets/targets.json index fe84a72afbb..fa9dd534005 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -1594,7 +1594,8 @@ "macros_add": ["USBHOST_OTHER"], "device_has_add": ["ANALOGOUT", "CAN", "LOWPOWERTIMER", "SERIAL_FC", "TRNG", "FLASH"], "release_versions": ["2", "5"], - "device_name": "STM32L476VG" + "device_name": "STM32L476VG", + "bootloader_supported": true }, "MTS_MDOT_F405RG": { "inherits": ["FAMILY_STM32"], diff --git a/tools/bootloaders/REALTEK_RTL8195AM/ram_1_prepend.bin b/tools/bootloaders/REALTEK_RTL8195AM/ram_1.bin similarity index 79% rename from tools/bootloaders/REALTEK_RTL8195AM/ram_1_prepend.bin rename to tools/bootloaders/REALTEK_RTL8195AM/ram_1.bin index 821a8438c62..5306948efa7 100644 Binary files a/tools/bootloaders/REALTEK_RTL8195AM/ram_1_prepend.bin and b/tools/bootloaders/REALTEK_RTL8195AM/ram_1.bin differ diff --git a/tools/build_travis.py b/tools/build_travis.py index 0453a706db7..0982ee1a932 100644 --- a/tools/build_travis.py +++ b/tools/build_travis.py @@ -130,6 +130,7 @@ { "target": "NUMAKER_PFM_NUC472", "toolchains": "GCC_ARM", "libs": ["dsp", "usb"] }, { "target": "NUMAKER_PFM_M453", "toolchains": "GCC_ARM", "libs": ["dsp", "usb"] }, + { "target": "NUMAKER_PFM_M487", "toolchains": "GCC_ARM", "libs": ["dsp", "usb"] }, ) ################################################################################ @@ -264,6 +265,12 @@ } }, {"target": "NUMAKER_PFM_M453", + "toolchains": "GCC_ARM", + "tests": {"" : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"], + "usb" : ["USB_1", "USB_2" ,"USB_3"], + } + }, + {"target": "NUMAKER_PFM_M487", "toolchains": "GCC_ARM", "tests": {"" : ["MBED_2", "MBED_10", "MBED_11", "MBED_16"], "usb" : ["USB_1", "USB_2" ,"USB_3"], diff --git a/tools/targets/REALTEK_RTL8195AM.py b/tools/targets/REALTEK_RTL8195AM.py index 74fb1b2089f..86eda42934f 100644 --- a/tools/targets/REALTEK_RTL8195AM.py +++ b/tools/targets/REALTEK_RTL8195AM.py @@ -1,141 +1,276 @@ """ -mbed REALTEK_RTL8195AM elf2bin script -Copyright (c) 2011-2016 Realtek Semiconductor Corp. +Realtek Semiconductor Corp. -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. - -LIBRARIES BUILD +RTL8195A elf2bin script """ import sys, array, struct, os, re, subprocess import hashlib +import shutil from tools.paths import TOOLS_BOOTLOADERS from datetime import datetime # Constant Variables -RAM2_RSVD = 0x3131373835393138 +RAM2_RSVD = 0x00000000 +RAM2_VER = 0x8195FFFF00000000 +RAM2_TAG = 0x81950001 +RAM2_SHA = '0' def write_fixed_width_string(value, width, output): - # cut string to list & reverse - line = [value[i:i+2] for i in range(0, len(value), 2)] - output.write("".join([chr(long(b, 16)) for b in line])) + # cut string to list & reverse + line = [value[i:i+2] for i in range(0, len(value), 2)] + output.write("".join([chr(long(b, 16)) for b in line])) def write_fixed_width_value(value, width, output): - # convert to string - line = format(value, '0%dx' % (width)) - if len(line) > width: - print "[ERROR] value 0x%s cannot fit width %d" % (line, width) - sys.exit(-1) - # cut string to list & reverse - line = [line[i:i+2] for i in range(0, len(line), 2)] - line.reverse() - # convert to write buffer - output.write("".join([chr(long(b, 16)) for b in line])) + # convert to string + line = format(value, '0%dx' % (width)) + if len(line) > width: + print "[ERROR] value 0x%s cannot fit width %d" % (line, width) + sys.exit(-1) + # cut string to list & reverse + line = [line[i:i+2] for i in range(0, len(line), 2)] + line.reverse() + # convert to write buffer + output.write("".join([chr(long(b, 16)) for b in line])) def append_image_file(image, output): input = open(image, "rb") output.write(input.read()) input.close() -def prepend(image, image_prepend, toolchain, info): - output = open(image_prepend, "wb") - write_fixed_width_value(info['size'], 8, output) - write_fixed_width_value(info['addr'], 8, output) - write_fixed_width_value(RAM2_RSVD, 16, output) - with open(image, "rb") as input: - if toolchain == "IAR": - input.seek(info['addr']) - output.write(input.read(info['size'])) +def write_padding_bytes(output_name, size): + current_size = os.stat(output_name).st_size + padcount = size - current_size + if padcount < 0: + print "[ERROR] image is larger than expected size" + sys.exit(-1) + output = open(output_name, "ab") + output.write('\377' * padcount) output.close() -def parse_section(toolchain, elf, section): - info = {'addr':None, 'size':0}; - if toolchain not in ["GCC_ARM", "ARM_STD", "ARM", "ARM_MICRO", "IAR"]: - print "[ERROR] unsupported toolchain " + toolchain - sys.exit(-1) - - mapfile = elf.rsplit(".", 1)[0] + ".map" - - with open(mapfile, 'r') as infile: - # Search area to parse - for line in infile: - if toolchain == "GCC_ARM": - # .image2.table 0x[00000000]30000000 0x18 - # 0x[00000000]30000000 __image2_start__ = . - # 0x[00000000]30000000 __image2_entry_func__ = . - match = re.match(r'^' + section + \ - r'\s+0x0{,8}(?P[0-9A-Fa-f]{8})\s+0x(?P[0-9A-Fa-f]+).*$', line) - elif toolchain in ["ARM_STD", "ARM", "ARM_MICRO"]: - # Memory Map of the image - # Load Region LR_DRAM (Base: 0x30000000, Size: 0x00006a74, Max: 0x00200000, ABSOLUTE) - # Execution Region IMAGE2_TABLE (Base: 0x30000000, Size: 0x00000018, Max: 0xffffffff, ABSOLUTE, FIXED) - # Base Addr Size Type Attr Idx E Section Name Object - # 0x30000000 0x00000004 Data RO 5257 .image2.ram.data rtl8195a_init.o - match = re.match(r'^.*Region\s+' + section + \ - r'\s+\(Base: 0x(?P[0-9A-Fa-f]{8}),\s+Size: 0x(?P[0-9A-Fa-f]+), .*\)$', line) - elif toolchain == "IAR": - # Section Kind Address Size Object - # ------- ---- ------- ---- ------ - # "A3": 0x8470 - # IMAGE2 0x10006000 0x5d18 - # .ram_image2.text 0x10006000 0x5bbc - # .rodata const 0x10006000 0x14 retarget.o [17] - match = re.match(r'^\s+' + section + \ - r'\s+0x(?P[0-9A-Fa-f]{8})\s+0x(?P[0-9A-Fa-f]+)\s+.*$', line) - if match: - info['addr'] = int(match.group("addr"), 16) - try: - info['size'] = int(match.group("size"), 16) - except IndexError: - print "[WARNING] cannot find the size of section " + section - return info +def sha256_checksum(filename, block_size=65536): + sha256 = hashlib.sha256() + with open(filename, 'rb') as f: + for block in iter(lambda: f.read(block_size), b''): + sha256.update(block) + return sha256.hexdigest() - print "[ERROR] cannot find the address of section " + section - return info +def get_version_by_time(): + secs = int((datetime.now()-datetime(2016,11,1)).total_seconds()) + return RAM2_VER + secs # ---------------------------- # main function # ---------------------------- -def rtl8195a_elf2bin(toolchain, image_elf, image_bin): +def prepend(image, entry, segment, image_ram2, image_ota): + + # parse input arguments + output = open(image_ram2, "wb") + + write_fixed_width_value(os.stat(image).st_size, 8, output) + write_fixed_width_value(int(entry), 8, output) + write_fixed_width_value(int(segment), 8, output) + + RAM2_SHA = sha256_checksum(image) + write_fixed_width_value(RAM2_TAG, 8, output) + write_fixed_width_value(get_version_by_time(), 16, output) + write_fixed_width_string(RAM2_SHA, 64, output) + write_fixed_width_value(RAM2_RSVD, 8, output) + + append_image_file(image, output) + output.close() + + ota = open(image_ota, "wb") + write_fixed_width_value(os.stat(image).st_size, 8, ota) + write_fixed_width_value(int(entry), 8, ota) + write_fixed_width_value(int(segment), 8, ota) + write_fixed_width_value(0xFFFFFFFF, 8, ota) + write_fixed_width_value(get_version_by_time(), 16, ota) + write_fixed_width_string(RAM2_SHA, 64, ota) + write_fixed_width_value(RAM2_RSVD, 8, ota) + + append_image_file(image, ota) + ota.close() + +def find_symbol(toolchain, mapfile, symbol): + ret = None + + HEX = '0x0{,8}(?P[0-9A-Fa-f]{8})' + if toolchain == "GCC_ARM": + SYM = re.compile(r'^\s+' + HEX + r'\s+' + symbol + '\r?$') + elif toolchain in ["ARM_STD", "ARM", "ARM_MICRO"]: + SYM = re.compile(r'^\s+' + HEX + r'\s+0x[0-9A-Fa-f]{8}\s+Code.*\s+i\.' + symbol + r'\s+.*$') + elif toolchain == "IAR": + SYM = re.compile(r'^' + symbol + r'\s+' + HEX + '\s+.*$') + + with open(mapfile, 'r') as infile: + for line in infile: + match = re.match(SYM, line) + if match: + ret = match.group("addr") + + if not ret: + print "[ERROR] cannot find the address of symbol " + symbol + return 0 + + return int(ret,16) | 1 + +def parse_load_segment_gcc(image_elf): + # Program Headers: + # Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align + # LOAD 0x000034 0x10006000 0x10006000 0x026bc 0x026bc RW 0x8 + # LOAD 0x0026f0 0x30000000 0x30000000 0x06338 0x06338 RWE 0x4 + segment_list = [] + cmd = 'arm-none-eabi-readelf -l ' + image_elf + for line in subprocess.check_output(cmd, shell=True, universal_newlines=True).split("\n"): + if not line.startswith(" LOAD"): + continue + segment = line.split() + if len(segment) != 8: + continue + offset = int(segment[1][2:], 16) + addr = int(segment[2][2:], 16) + size = int(segment[4][2:], 16) + if addr != 0 and size != 0: + segment_list.append((offset, addr, size)) + return segment_list + +def parse_load_segment_armcc(image_elf): + # ==================================== + # + # ** Program header #2 + # + # Type : PT_LOAD (1) + # File Offset : 52 (0x34) + # Virtual Addr : 0x30000000 + # Physical Addr : 0x30000000 + # Size in file : 27260 bytes (0x6a7c) + # Size in memory: 42168 bytes (0xa4b8) + # Flags : PF_X + PF_W + PF_R + PF_ARM_ENTRY (0x80000007) + # Alignment : 8 + # + (offset, addr, size) = (0, 0, 0) + segment_list = [] + in_segment = False + cmd = 'fromelf --text -v --only=none ' + image_elf + for line in subprocess.check_output(cmd, shell=True, universal_newlines=True).split("\n"): + if line == "": + pass + elif line.startswith("** Program header"): + in_segment = True + elif in_segment == False: + pass + elif line.startswith("============"): + if addr != 0 and size != 0: + segment_list.append((offset, addr, size)) + in_segment = False + (offset, addr, size) = (0, 0, 0) + elif line.startswith(" Type"): + if not re.match(r'\s+Type\s+:\s+PT_LOAD\s.*$', line): + in_segment = False + elif line.startswith(" File Offset"): + match = re.match(r'^\s+File Offset\s+:\s+(?P\d+).*$', line) + if match: + offset = int(match.group("offset")) + elif line.startswith(" Virtual Addr"): + match = re.match(r'^\s+Virtual Addr\s+:\s+0x(?P[0-9a-f]+).*$', line) + if match: + addr = int(match.group("addr"), 16) + elif line.startswith(" Size in file"): + match = re.match(r'^\s+Size in file\s+:.*\(0x(?P[0-9a-f]+)\).*$', line) + if match: + size = int(match.group("size"), 16) + return segment_list + + +def parse_load_segment_iar(image_elf): + # SEGMENTS: + # + # Type Offset Virtual Physical File Sz Mem Sz Flags Align + # ---- ------ ------- -------- ------- ------ ----- ----- + # 0: load 0x34 0x10006000 0x10006000 0x26bc 0x26bc 0x6 WR 0x8 + # 1: load 0x26f0 0x30000000 0x30000000 0x6338 0x6338 0x7 XWR 0x4 + # + # SECTIONS: + # + # Name Type Addr Offset Size Aln Lnk Inf ESz Flags + # ---- ---- ---- ------ ---- --- --- --- --- ----- + # 1: .shstrtab strtab 0xfc4d8 0x60 0x4 + # 2: .strtab strtab 0xfc538 0xbb3f 0x4 + + segment_list = [] + in_segment = False + cmd = 'ielfdumparm ' + image_elf + for line in subprocess.check_output(cmd, shell=True, universal_newlines=True).split("\n"): + if line.startswith(" SEGMENTS:"): + in_segment = True + elif in_segment == False: + pass + elif line.startswith(" SECTIONS:"): + break + elif re.match(r'^\s+\w+:\s+load\s+.*$', line): + segment = line.split() + offset = int(segment[2][2:], 16) + addr = int(segment[3][2:], 16) + size = int(segment[5][2:], 16) + if addr < 0x10007000: + continue + if addr != 0 and size != 0: + segment_list.append((offset, addr, size)) + return segment_list + +def parse_load_segment(toolchain, image_elf): if toolchain == "GCC_ARM": - img2_sections = [".image2.table", ".text", ".data"] + return parse_load_segment_gcc(image_elf) elif toolchain in ["ARM_STD", "ARM", "ARM_MICRO"]: - img2_sections = [".image2.table", ".text", ".data"] + return parse_load_segment_armcc(image_elf) elif toolchain == "IAR": - # actually it's block - img2_sections = ["IMAGE2"] + return parse_load_segment_iar(image_elf) else: - print("[error] unsupported toolchain") + toolchain - return - ram2_info = {'addr':None, 'size':0} + return [] + +def write_load_segment(image_elf, image_bin, segment): + file_elf = open(image_elf, "rb") + file_bin = open(image_bin, "wb") + for (offset, addr, size) in segment: + file_elf.seek(offset) + # write image header - size & addr + write_fixed_width_value(addr, 8, file_bin) + write_fixed_width_value(size, 8, file_bin) + # write load segment + file_bin.write(file_elf.read(size)) + delta = size % 4 + if delta != 0: + padding = 4 - delta + write_fixed_width_value(0x0, padding * 2, file_bin) + file_bin.close() + file_elf.close() + +# ---------------------------- +# main function +# ---------------------------- +def rtl8195a_elf2bin(t_self, image_elf, image_bin): + # remove target binary file/path + if os.path.isfile(image_bin): + os.remove(image_bin) + else: + shutil.rmtree(image_bin) + + segment = parse_load_segment(t_self.name, image_elf) + write_load_segment(image_elf, image_bin, segment) + image_name = os.path.splitext(image_elf)[0] + image_map = image_name + '.map' + + ram2_ent = find_symbol(t_self.name, image_map, "PLAT_Start") + ram1_bin = os.path.join(TOOLS_BOOTLOADERS, "REALTEK_RTL8195AM", "ram_1.bin") + ram2_bin = image_name + '-ram_2.bin' + ota_bin = image_name + '-ota.bin' + prepend(image_bin, ram2_ent, len(segment), ram2_bin, ota_bin) - ram1_prepend_bin = os.path.join(TOOLS_BOOTLOADERS, "REALTEK_RTL8195AM", "ram_1_prepend.bin") - ram2_prepend_bin = image_name + '-ram_2_prepend.bin' - - old_bin = image_name + '.bin' - for section in img2_sections: - section_info = parse_section(toolchain, image_elf, section) - if ram2_info['addr'] is None or ram2_info['addr'] > section_info['addr']: - ram2_info['addr'] = section_info['addr'] - ram2_info['size'] = ram2_info['size'] + section_info['size'] - - prepend(old_bin, ram2_prepend_bin, toolchain, ram2_info) # write output file output = open(image_bin, "wb") - append_image_file(ram1_prepend_bin, output) - append_image_file(ram2_prepend_bin, output) + append_image_file(ram1_bin, output) + append_image_file(ram2_bin, output) output.close() - # post built done - diff --git a/tools/targets/__init__.py b/tools/targets/__init__.py index 9d02174234f..ce794777b6f 100644 --- a/tools/targets/__init__.py +++ b/tools/targets/__init__.py @@ -523,7 +523,7 @@ class RTL8195ACode: @staticmethod def binary_hook(t_self, resources, elf, binf): from tools.targets.REALTEK_RTL8195AM import rtl8195a_elf2bin - rtl8195a_elf2bin(t_self.name, elf, binf) + rtl8195a_elf2bin(t_self, elf, binf) ################################################################################ # Instantiate all public targets diff --git a/tools/test/config_test/test11/lib1/lib2/mbed_lib.json b/tools/test/config/app_override_libs/lib1/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test11/lib1/lib2/mbed_lib.json rename to tools/test/config/app_override_libs/lib1/lib2/mbed_lib.json diff --git a/tools/test/config_test/test12/lib1/mbed_lib.json b/tools/test/config/app_override_libs/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test12/lib1/mbed_lib.json rename to tools/test/config/app_override_libs/lib1/mbed_lib.json diff --git a/tools/test/config_test/test12/mbed_app.json b/tools/test/config/app_override_libs/mbed_app.json similarity index 100% rename from tools/test/config_test/test12/mbed_app.json rename to tools/test/config/app_override_libs/mbed_app.json diff --git a/tools/test/config_test/test12/targets.json b/tools/test/config/app_override_libs/targets.json similarity index 100% rename from tools/test/config_test/test12/targets.json rename to tools/test/config/app_override_libs/targets.json diff --git a/tools/test/config/app_override_libs/test_data.json b/tools/test/config/app_override_libs/test_data.json new file mode 100644 index 00000000000..b7a5ff3fd9d --- /dev/null +++ b/tools/test/config/app_override_libs/test_data.json @@ -0,0 +1,9 @@ +{ + "test_target": { + "lib1.p1": "v_p1_lib1_app", + "lib1.p2": "v_p2_lib1", + "lib1.p3": "v_p3_lib1", + "lib2.p1": "v_p1_lib2_app", + "lib2.p2": "v_p2_lib2" + } +} diff --git a/tools/test/config_test/test29/mbed_app.json b/tools/test/config/bootloader_missing/mbed_app.json similarity index 100% rename from tools/test/config_test/test29/mbed_app.json rename to tools/test/config/bootloader_missing/mbed_app.json diff --git a/tools/test/config/bootloader_missing/test_data.json b/tools/test/config/bootloader_missing/test_data.json new file mode 100644 index 00000000000..81592858644 --- /dev/null +++ b/tools/test/config/bootloader_missing/test_data.json @@ -0,0 +1,5 @@ +{ + "K64F": { + "exception_msg": "not found" + } +} diff --git a/tools/test/config_test/test02/targets.json b/tools/test/config/compound_inheritance/targets.json similarity index 82% rename from tools/test/config_test/test02/targets.json rename to tools/test/config/compound_inheritance/targets.json index faa880097b2..19ad992c0d4 100644 --- a/tools/test/config_test/test02/targets.json +++ b/tools/test/config/compound_inheritance/targets.json @@ -1,5 +1,5 @@ { - "b1": { + "base": { "extra_labels": [], "default_lib": "std", "core": "Cortex-M0", @@ -9,8 +9,8 @@ "base1_3": "v_base1_3_b1" } }, - "d1": { - "inherits": ["b1"], + "left_middle": { + "inherits": ["base"], "config": { "derived1": "v_derived1_d1", "derived2": "v_derived2_d1" @@ -20,8 +20,8 @@ "base1_2": "v_base1_2_d1" } }, - "b2": { - "inherits": ["b1"], + "right_middle": { + "inherits": ["base"], "config": { "base2_1": "v_base2_1_b2", "base2_2": "v_base2_2_b2" @@ -30,8 +30,8 @@ "base1_2": "v_base1_2_b2" } }, - "f": { - "inherits": ["d1", "b2"], + "inherits_diamond": { + "inherits": ["left_middle", "right_middle"], "config": { "f1_1": "v_f1_1_f", "f1_2": "v_f1_2_f" diff --git a/tools/test/config/compound_inheritance/test_data.json b/tools/test/config/compound_inheritance/test_data.json new file mode 100644 index 00000000000..89871d7cf99 --- /dev/null +++ b/tools/test/config/compound_inheritance/test_data.json @@ -0,0 +1,20 @@ +{ + "inherits_diamond": { + "target.base1_1": "v_base1_1_f", + "target.base1_2": "v_base1_2_b2", + "target.base1_3": "v_base1_3_b1", + "target.derived1": "v_derived1_d1", + "target.derived2": "v_derived2_f", + "target.base2_1": "v_base2_1_f", + "target.base2_2": "v_base2_2_b2", + "target.f1_1": "v_f1_1_f_override", + "target.f1_2": "v_f1_2_f" + }, + "right_middle": { + "target.base1_1": "v_base1_1_b1", + "target.base1_2": "v_base1_2_b2", + "target.base1_3": "v_base1_3_b1", + "target.base2_1": "v_base2_1_b2", + "target.base2_2": "v_base2_2_b2" + } +} diff --git a/tools/test/config/config_test.py b/tools/test/config/config_test.py index 114f088c28e..157dcb72d32 100644 --- a/tools/test/config/config_test.py +++ b/tools/test/config/config_test.py @@ -1,6 +1,6 @@ """ mbed SDK -Copyright (c) 2016 ARM Limited +Copyright (c) 2011-2017 ARM Limited Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,118 +15,161 @@ limitations under the License. """ -import os.path -import unittest +import os +import sys +import json +import pytest from mock import patch -from tools.config import Config - -""" -Tests for config.py -""" - -class ConfigTests(unittest.TestCase): +from hypothesis import given +from hypothesis.strategies import sampled_from +from os.path import join, isfile, dirname, abspath +from tools.build_api import get_config +from tools.targets import set_targets_json_location, Target, TARGET_NAMES +from tools.config import ConfigException, Config + +def compare_config(cfg, expected): + """Compare the output of config against a dictionary of known good results + + :param cfg: the configuration to check + :param expected: what to expect in that config """ - Test cases for Config class + try: + for k in cfg: + if cfg[k].value != expected[k]: + return "'%s': expected '%s', got '%s'" % (k, expected[k], cfg[k].value) + except KeyError: + return "Unexpected key '%s' in configuration data" % k + for k in expected: + if k not in ["expected_macros", "expected_features"] + cfg.keys(): + return "Expected key '%s' was not found in configuration data" % k + return "" + +def data_path(path): + """The expected data file for a particular test + + :param path: the path to the test """ + return join(path, "test_data.json") - def setUp(self): - """ - Called before each test case +def is_test(path): + """Does a directory represent a test? - :return: - """ - self.target = "K64F" + :param path: the path to the test + """ + return isfile(data_path(path)) - def tearDown(self): - """ - Called after each test case +root_dir = abspath(dirname(__file__)) - :return: - """ - pass +@pytest.mark.parametrize("name", filter(lambda d: is_test(join(root_dir, d)), + os.listdir(root_dir))) +def test_config(name): + """Run a particular configuration test - @patch.object(Config, '_process_config_and_overrides') - @patch('tools.config.json_file_to_dict') - def test_init_app_config(self, mock_json_file_to_dict, _): - """ - Test that the initialisation correctly uses app_config + :param name: test name (same as directory name) + """ + test_dir = join(root_dir, name) + test_data = json.load(open(data_path(test_dir))) + targets_json = os.path.join(test_dir, "targets.json") + set_targets_json_location(targets_json if isfile(targets_json) else None) + for target, expected in test_data.items(): + try: + cfg, macros, features = get_config(test_dir, target, "GCC_ARM") + res = compare_config(cfg, expected) + assert not(res), res + expected_macros = expected.get("expected_macros", None) + expected_features = expected.get("expected_features", None) + + if expected_macros is not None: + macros = Config.config_macros_to_macros(macros) + assert sorted(expected_macros) == sorted(macros) + if expected_features is not None: + assert sorted(expected_features) == sorted(features) + except ConfigException as e: + err_msg = e.message + if "exception_msg" not in expected: + assert not(err_msg), "Unexpected Error: %s" % e + else: + assert expected["exception_msg"] in err_msg + + +@pytest.mark.parametrize("target", ["K64F"]) +def test_init_app_config(target): + """ + Test that the initialisation correctly uses app_config - :param mock_json_file_to_dict: mock of function json_file_to_dict - :param _: mock of function _process_config_and_overrides (not tested) - :return: - """ + :param target: The target to use + """ + set_targets_json_location() + with patch.object(Config, '_process_config_and_overrides'),\ + patch('tools.config.json_file_to_dict') as mock_json_file_to_dict: app_config = "app_config" - mock_return = {'config': 'test'} + mock_return = {'config': {'test': False}} mock_json_file_to_dict.return_value = mock_return - config = Config(self.target, app_config=app_config) + config = Config(target, app_config=app_config) mock_json_file_to_dict.assert_called_with(app_config) - self.assertEqual(config.app_config_data, mock_return, - "app_config_data should be set to the returned value") + assert config.app_config_data == mock_return - @patch.object(Config, '_process_config_and_overrides') - @patch('tools.config.json_file_to_dict') - def test_init_no_app_config(self, mock_json_file_to_dict, _): - """ - Test that the initialisation works without app config - :param mock_json_file_to_dict: mock of function json_file_to_dict - :param _: patch of function _process_config_and_overrides (not tested) - :return: - """ - config = Config(self.target) +@pytest.mark.parametrize("target", ["K64F"]) +def test_init_no_app_config(target): + """ + Test that the initialisation works without app config + + :param target: The target to use + """ + set_targets_json_location() + with patch.object(Config, '_process_config_and_overrides'),\ + patch('tools.config.json_file_to_dict') as mock_json_file_to_dict: + config = Config(target) mock_json_file_to_dict.assert_not_called() - self.assertEqual(config.app_config_data, {}, - "app_config_data should be set an empty dictionary") - - @patch.object(Config, '_process_config_and_overrides') - @patch('os.path.isfile') - @patch('tools.config.json_file_to_dict') - def test_init_no_app_config_with_dir(self, mock_json_file_to_dict, mock_isfile, _): - """ - Test that the initialisation works without app config and with a - specified top level directory - - :param mock_json_file_to_dict: mock of function json_file_to_dict - :param _: patch of function _process_config_and_overrides (not tested) - :return: - """ + assert config.app_config_data == {} + + +@pytest.mark.parametrize("target", ["K64F"]) +def test_init_no_app_config_with_dir(target): + """ + Test that the initialisation works without app config and with a + specified top level directory + + :param target: The target to use + """ + set_targets_json_location() + with patch.object(Config, '_process_config_and_overrides'),\ + patch('os.path.isfile') as mock_isfile, \ + patch('tools.config.json_file_to_dict') as mock_json_file_to_dict: directory = '.' path = os.path.join('.', 'mbed_app.json') - mock_return = {'config': 'test'} + mock_return = {'config': {'test': False}} mock_json_file_to_dict.return_value = mock_return mock_isfile.return_value = True - config = Config(self.target, [directory]) + config = Config(target, [directory]) mock_isfile.assert_called_with(path) mock_json_file_to_dict.assert_called_once_with(path) - self.assertEqual(config.app_config_data, mock_return, - "app_config_data should be set to the returned value") - - @patch.object(Config, '_process_config_and_overrides') - @patch('tools.config.json_file_to_dict') - def test_init_override_app_config(self, mock_json_file_to_dict, _): - """ - Test that the initialisation uses app_config instead of top_level_dir - when both are specified - - :param mock_json_file_to_dict: mock of function json_file_to_dict - :param _: patch of function _process_config_and_overrides (not tested) - :return: - """ + assert config.app_config_data == mock_return + + +@pytest.mark.parametrize("target", ["K64F"]) +def test_init_override_app_config(target): + """ + Test that the initialisation uses app_config instead of top_level_dir + when both are specified + + :param target: The target to use + """ + set_targets_json_location() + with patch.object(Config, '_process_config_and_overrides'),\ + patch('tools.config.json_file_to_dict') as mock_json_file_to_dict: app_config = "app_config" directory = '.' - mock_return = {'config': 'test'} + mock_return = {'config': {'test': False}} mock_json_file_to_dict.return_value = mock_return - config = Config(self.target, [directory], app_config=app_config) + config = Config(target, [directory], app_config=app_config) mock_json_file_to_dict.assert_called_once_with(app_config) - self.assertEqual(config.app_config_data, mock_return, - "app_config_data should be set to the returned value") - -if __name__ == '__main__': - unittest.main() + assert config.app_config_data == mock_return diff --git a/tools/test/config_test/test04/targets.json b/tools/test/config/double_define/targets.json similarity index 69% rename from tools/test/config_test/test04/targets.json rename to tools/test/config/double_define/targets.json index 510f37b92ab..2dddbe28acb 100644 --- a/tools/test/config_test/test04/targets.json +++ b/tools/test/config/double_define/targets.json @@ -1,5 +1,5 @@ { - "b1": { + "first_base": { "extra_labels": [], "default_lib": "std", "core": "Cortex-M0", @@ -9,18 +9,7 @@ "base1_3": "v_base1_3_b1" } }, - "d1": { - "inherits": ["b1"], - "config": { - "derived1": "v_derived1_d1", - "derived2": "v_derived2_d1" - }, - "overrides": { - "base1_1": "v_base1_1_d1", - "base1_2": "v_base1_2_d1" - } - }, - "b2": { + "second_base": { "extra_labels": [], "default_lib": "std", "core": "Cortex-M0", @@ -30,8 +19,8 @@ "base1_1": "v_base1_1_b2" } }, - "f": { - "inherits": ["b2", "d1"], + "double_config": { + "inherits": ["first_base", "second_base"], "config": { "f1_1": "v_f1_1_f", "f1_2": "v_f1_2_f" diff --git a/tools/test/config/double_define/test_data.json b/tools/test/config/double_define/test_data.json new file mode 100644 index 00000000000..7c01c064cd7 --- /dev/null +++ b/tools/test/config/double_define/test_data.json @@ -0,0 +1,10 @@ +{ + "double_config": { + "exception_msg": "Parameter name 'base1_1' defined in both 'target:second_base' and 'target:first_base'" + }, + "second_base": { + "target.base2_1": "v_base2_1_b2", + "target.base2_2": "v_base2_2_b2", + "target.base1_1": "v_base1_1_b2" + } +} diff --git a/tools/test/config_test/test13/lib1/mbed_lib.json b/tools/test/config/duplicate_lib_name/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test13/lib1/mbed_lib.json rename to tools/test/config/duplicate_lib_name/lib1/mbed_lib.json diff --git a/tools/test/config_test/test13/lib2/mbed_lib.json b/tools/test/config/duplicate_lib_name/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test13/lib2/mbed_lib.json rename to tools/test/config/duplicate_lib_name/lib2/mbed_lib.json diff --git a/tools/test/config/duplicate_lib_name/test_data.json b/tools/test/config/duplicate_lib_name/test_data.json new file mode 100644 index 00000000000..65689b1fa49 --- /dev/null +++ b/tools/test/config/duplicate_lib_name/test_data.json @@ -0,0 +1,5 @@ +{ + "K64F": { + "exception_msg": "Library name 'lib1' is not unique" + } +} diff --git a/tools/test/config_test/test22/lib1/mbed_lib.json b/tools/test/config/feature_compesition/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test22/lib1/mbed_lib.json rename to tools/test/config/feature_compesition/lib1/mbed_lib.json diff --git a/tools/test/config_test/test22/mbed_app.json b/tools/test/config/feature_compesition/mbed_app.json similarity index 100% rename from tools/test/config_test/test22/mbed_app.json rename to tools/test/config/feature_compesition/mbed_app.json diff --git a/tools/test/config_test/test16/targets.json b/tools/test/config/feature_compesition/targets.json similarity index 100% rename from tools/test/config_test/test16/targets.json rename to tools/test/config/feature_compesition/targets.json diff --git a/tools/test/config/feature_compesition/test_data.json b/tools/test/config/feature_compesition/test_data.json new file mode 100644 index 00000000000..48c56ee168e --- /dev/null +++ b/tools/test/config/feature_compesition/test_data.json @@ -0,0 +1,5 @@ +{ + "test_target": { + "expected_features": ["IPV4", "STORAGE"] + } +} diff --git a/tools/test/config_test/test23/lib1/mbed_lib.json b/tools/test/config/feature_conflict/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test23/lib1/mbed_lib.json rename to tools/test/config/feature_conflict/lib1/mbed_lib.json diff --git a/tools/test/config_test/test23/lib2/mbed_lib.json b/tools/test/config/feature_conflict/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test23/lib2/mbed_lib.json rename to tools/test/config/feature_conflict/lib2/mbed_lib.json diff --git a/tools/test/config_test/test23/mbed_app.json b/tools/test/config/feature_conflict/mbed_app.json similarity index 100% rename from tools/test/config_test/test23/mbed_app.json rename to tools/test/config/feature_conflict/mbed_app.json diff --git a/tools/test/config_test/test23/test_data.py b/tools/test/config/feature_conflict/test_data.json similarity index 53% rename from tools/test/config_test/test23/test_data.py rename to tools/test/config/feature_conflict/test_data.json index b9ab156acf9..b2392658d19 100644 --- a/tools/test/config_test/test23/test_data.py +++ b/tools/test/config/feature_conflict/test_data.json @@ -1,8 +1,5 @@ -# Testing when two features collide - -expected_results = { +{ "K64F": { - "desc": "test feature collisions", "exception_msg": "Configuration conflict. The feature IPV4 both added and removed." } } diff --git a/tools/test/config_test/test24/FEATURE_IPV4/lib1/mbed_lib.json b/tools/test/config/feature_recursive_add/FEATURE_IPV4/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test24/FEATURE_IPV4/lib1/mbed_lib.json rename to tools/test/config/feature_recursive_add/FEATURE_IPV4/lib1/mbed_lib.json diff --git a/tools/test/config_test/test24/FEATURE_STORAGE/lib2/mbed_lib.json b/tools/test/config/feature_recursive_add/FEATURE_STORAGE/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test24/FEATURE_STORAGE/lib2/mbed_lib.json rename to tools/test/config/feature_recursive_add/FEATURE_STORAGE/lib2/mbed_lib.json diff --git a/tools/test/config_test/test24/mbed_app.json b/tools/test/config/feature_recursive_add/mbed_app.json similarity index 100% rename from tools/test/config_test/test24/mbed_app.json rename to tools/test/config/feature_recursive_add/mbed_app.json diff --git a/tools/test/config_test/test21/targets.json b/tools/test/config/feature_recursive_add/targets.json similarity index 100% rename from tools/test/config_test/test21/targets.json rename to tools/test/config/feature_recursive_add/targets.json diff --git a/tools/test/config/feature_recursive_add/test_data.json b/tools/test/config/feature_recursive_add/test_data.json new file mode 100644 index 00000000000..08885e7f526 --- /dev/null +++ b/tools/test/config/feature_recursive_add/test_data.json @@ -0,0 +1,5 @@ +{ + "test_target": { + "expected_features": ["IPV4", "STORAGE", "UVISOR"] + } +} diff --git a/tools/test/config_test/test25/FEATURE_STORAGE/FEATURE_IPV4/lib1/mbed_lib.json b/tools/test/config/feature_recursive_complex/FEATURE_IPV4/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test25/FEATURE_STORAGE/FEATURE_IPV4/lib1/mbed_lib.json rename to tools/test/config/feature_recursive_complex/FEATURE_IPV4/lib1/mbed_lib.json diff --git a/tools/test/config_test/test26/FEATURE_STORAGE/lib2/mbed_lib.json b/tools/test/config/feature_recursive_complex/FEATURE_STORAGE/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test26/FEATURE_STORAGE/lib2/mbed_lib.json rename to tools/test/config/feature_recursive_complex/FEATURE_STORAGE/lib2/mbed_lib.json diff --git a/tools/test/config_test/test26/mbed_app.json b/tools/test/config/feature_recursive_complex/mbed_app.json similarity index 100% rename from tools/test/config_test/test26/mbed_app.json rename to tools/test/config/feature_recursive_complex/mbed_app.json diff --git a/tools/test/config_test/test22/targets.json b/tools/test/config/feature_recursive_complex/targets.json similarity index 100% rename from tools/test/config_test/test22/targets.json rename to tools/test/config/feature_recursive_complex/targets.json diff --git a/tools/test/config/feature_recursive_complex/test_data.json b/tools/test/config/feature_recursive_complex/test_data.json new file mode 100644 index 00000000000..04be347b3ca --- /dev/null +++ b/tools/test/config/feature_recursive_complex/test_data.json @@ -0,0 +1,5 @@ +{ + "test_target": { + "lib2.test": "GOOD" + } +} diff --git a/tools/test/config_test/test27/lib1/mbed_lib.json b/tools/test/config/feature_remove/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test27/lib1/mbed_lib.json rename to tools/test/config/feature_remove/lib1/mbed_lib.json diff --git a/tools/test/config_test/test27/targets.json b/tools/test/config/feature_remove/targets.json similarity index 100% rename from tools/test/config_test/test27/targets.json rename to tools/test/config/feature_remove/targets.json diff --git a/tools/test/config/feature_remove/test_data.json b/tools/test/config/feature_remove/test_data.json new file mode 100644 index 00000000000..8fa0d08dd00 --- /dev/null +++ b/tools/test/config/feature_remove/test_data.json @@ -0,0 +1,5 @@ +{ + "test_target": { + "expected_features": [] + } +} diff --git a/tools/test/config_test/test28/mbed_app.json b/tools/test/config/feature_uvisor/mbed_app.json similarity index 100% rename from tools/test/config_test/test28/mbed_app.json rename to tools/test/config/feature_uvisor/mbed_app.json diff --git a/tools/test/config_test/test24/targets.json b/tools/test/config/feature_uvisor/targets.json similarity index 100% rename from tools/test/config_test/test24/targets.json rename to tools/test/config/feature_uvisor/targets.json diff --git a/tools/test/config/feature_uvisor/test_data.json b/tools/test/config/feature_uvisor/test_data.json new file mode 100644 index 00000000000..0c29a33c353 --- /dev/null +++ b/tools/test/config/feature_uvisor/test_data.json @@ -0,0 +1,5 @@ +{ + "test_target": { + "expected_features": ["UVISOR"] + } +} diff --git a/tools/test/config_test/test26/FEATURE_IPV4/lib1/mbed_lib.json b/tools/test/config/fetaure_recursive_conflict/FEATURE_STORAGE/FEATURE_IPV4/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test26/FEATURE_IPV4/lib1/mbed_lib.json rename to tools/test/config/fetaure_recursive_conflict/FEATURE_STORAGE/FEATURE_IPV4/lib1/mbed_lib.json diff --git a/tools/test/config_test/test25/FEATURE_STORAGE/lib2/mbed_lib.json b/tools/test/config/fetaure_recursive_conflict/FEATURE_STORAGE/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test25/FEATURE_STORAGE/lib2/mbed_lib.json rename to tools/test/config/fetaure_recursive_conflict/FEATURE_STORAGE/lib2/mbed_lib.json diff --git a/tools/test/config_test/test25/mbed_app.json b/tools/test/config/fetaure_recursive_conflict/mbed_app.json similarity index 100% rename from tools/test/config_test/test25/mbed_app.json rename to tools/test/config/fetaure_recursive_conflict/mbed_app.json diff --git a/tools/test/config/fetaure_recursive_conflict/test_data.json b/tools/test/config/fetaure_recursive_conflict/test_data.json new file mode 100644 index 00000000000..b31573bcba2 --- /dev/null +++ b/tools/test/config/fetaure_recursive_conflict/test_data.json @@ -0,0 +1,5 @@ +{ + "K64F": { + "exception_msg": "Configuration conflict. The feature UVISOR both added and removed." + } +} diff --git a/tools/test/config_test/test16/lib1/mbed_lib.json b/tools/test/config/invalid_app_macro_define/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test16/lib1/mbed_lib.json rename to tools/test/config/invalid_app_macro_define/lib1/mbed_lib.json diff --git a/tools/test/config_test/test16/lib2/mbed_lib.json b/tools/test/config/invalid_app_macro_define/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test16/lib2/mbed_lib.json rename to tools/test/config/invalid_app_macro_define/lib2/mbed_lib.json diff --git a/tools/test/config_test/test17/mbed_app.json b/tools/test/config/invalid_app_macro_define/mbed_app.json similarity index 100% rename from tools/test/config_test/test17/mbed_app.json rename to tools/test/config/invalid_app_macro_define/mbed_app.json diff --git a/tools/test/config/invalid_app_macro_define/test_data.json b/tools/test/config/invalid_app_macro_define/test_data.json new file mode 100644 index 00000000000..e679e6f59a4 --- /dev/null +++ b/tools/test/config/invalid_app_macro_define/test_data.json @@ -0,0 +1,5 @@ +{ + "K64F": { + "exception_msg": "Macro 'LIB2_1' defined in both 'library:lib2' and 'application' with incompatible values" + } +} diff --git a/tools/test/config_test/test14/mbed_app.json b/tools/test/config/invalid_key/mbed_app.json similarity index 100% rename from tools/test/config_test/test14/mbed_app.json rename to tools/test/config/invalid_key/mbed_app.json diff --git a/tools/test/config/invalid_key/test_data.json b/tools/test/config/invalid_key/test_data.json new file mode 100644 index 00000000000..564461ad6e3 --- /dev/null +++ b/tools/test/config/invalid_key/test_data.json @@ -0,0 +1,5 @@ +{ + "K64F": { + "exception_msg": "Unknown key(s)" + } +} diff --git a/tools/test/config_test/test15/lib1/mbed_lib.json b/tools/test/config/invalid_key_lib/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test15/lib1/mbed_lib.json rename to tools/test/config/invalid_key_lib/lib1/mbed_lib.json diff --git a/tools/test/config/invalid_key_lib/test_data.json b/tools/test/config/invalid_key_lib/test_data.json new file mode 100644 index 00000000000..564461ad6e3 --- /dev/null +++ b/tools/test/config/invalid_key_lib/test_data.json @@ -0,0 +1,5 @@ +{ + "K64F": { + "exception_msg": "Unknown key(s)" + } +} diff --git a/tools/test/config_test/test17/lib1/mbed_lib.json b/tools/test/config/invalid_lib_macro_define/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test17/lib1/mbed_lib.json rename to tools/test/config/invalid_lib_macro_define/lib1/mbed_lib.json diff --git a/tools/test/config_test/test18/lib2/mbed_lib.json b/tools/test/config/invalid_lib_macro_define/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test18/lib2/mbed_lib.json rename to tools/test/config/invalid_lib_macro_define/lib2/mbed_lib.json diff --git a/tools/test/config_test/test16/mbed_app.json b/tools/test/config/invalid_lib_macro_define/mbed_app.json similarity index 100% rename from tools/test/config_test/test16/mbed_app.json rename to tools/test/config/invalid_lib_macro_define/mbed_app.json diff --git a/tools/test/config/invalid_lib_macro_define/test_data.json b/tools/test/config/invalid_lib_macro_define/test_data.json new file mode 100644 index 00000000000..34835b12eca --- /dev/null +++ b/tools/test/config/invalid_lib_macro_define/test_data.json @@ -0,0 +1,5 @@ +{ + "K64F": { + "exception_msg": "defined in both" + } +} diff --git a/tools/test/config_test/test18/lib1/mbed_lib.json b/tools/test/config/macro_inheritance/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test18/lib1/mbed_lib.json rename to tools/test/config/macro_inheritance/lib1/mbed_lib.json diff --git a/tools/test/config_test/test17/lib2/mbed_lib.json b/tools/test/config/macro_inheritance/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test17/lib2/mbed_lib.json rename to tools/test/config/macro_inheritance/lib2/mbed_lib.json diff --git a/tools/test/config_test/test18/mbed_app.json b/tools/test/config/macro_inheritance/mbed_app.json similarity index 100% rename from tools/test/config_test/test18/mbed_app.json rename to tools/test/config/macro_inheritance/mbed_app.json diff --git a/tools/test/config_test/test26/targets.json b/tools/test/config/macro_inheritance/targets.json similarity index 100% rename from tools/test/config_test/test26/targets.json rename to tools/test/config/macro_inheritance/targets.json diff --git a/tools/test/config/macro_inheritance/test_data.json b/tools/test/config/macro_inheritance/test_data.json new file mode 100644 index 00000000000..a513dc97c5d --- /dev/null +++ b/tools/test/config/macro_inheritance/test_data.json @@ -0,0 +1,5 @@ +{ + "test_target": { + "expected_macros": ["APP1=10", "APP2", "LIB1_1=1","LIB1_2", "LIB2_1=5"] + } +} diff --git a/tools/test/config_test/test06/lib1/lib2/mbed_lib.json b/tools/test/config/override_labels_libs/lib1/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test06/lib1/lib2/mbed_lib.json rename to tools/test/config/override_labels_libs/lib1/lib2/mbed_lib.json diff --git a/tools/test/config_test/test06/lib1/mbed_lib.json b/tools/test/config/override_labels_libs/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test06/lib1/mbed_lib.json rename to tools/test/config/override_labels_libs/lib1/mbed_lib.json diff --git a/tools/test/config_test/test06/mbed_app.json b/tools/test/config/override_labels_libs/mbed_app.json similarity index 100% rename from tools/test/config_test/test06/mbed_app.json rename to tools/test/config/override_labels_libs/mbed_app.json diff --git a/tools/test/config_test/test05/targets.json b/tools/test/config/override_labels_libs/targets.json similarity index 100% rename from tools/test/config_test/test05/targets.json rename to tools/test/config/override_labels_libs/targets.json diff --git a/tools/test/config_test/test06/test_data.py b/tools/test/config/override_labels_libs/test_data.json similarity index 57% rename from tools/test/config_test/test06/test_data.py rename to tools/test/config/override_labels_libs/test_data.json index 0a91823b40a..df30ae9e106 100644 --- a/tools/test/config_test/test06/test_data.py +++ b/tools/test/config/override_labels_libs/test_data.json @@ -1,9 +1,5 @@ -# This build on top of test5 by adding a few libraries with their own configurations -# and overrides. The same targets are used for building and testing (base, b1, b2, both) - -expected_results = { +{ "base": { - "desc": "override values based on labels with libs (no labels)", "app.app1": "v_app1", "app.app2": "v_app2", "lib1.p1": "v_p1_lib1", @@ -13,7 +9,6 @@ "lib2.p2": "v_p2_lib2" }, "b1": { - "desc": "override values based on labels with libs (first label)", "app.app1": "v_app1[b1_label]", "app.app2": "v_app2", "lib1.p1": "v_p1_lib1[b1_label]", @@ -23,7 +18,6 @@ "lib2.p2": "v_p2_lib2[b1_label]" }, "b2": { - "desc": "override values based on labels with libs (second label)", "app.app1": "v_app1", "app.app2": "v_app2[b2_label]", "lib1.p1": "v_p1_lib1", @@ -32,12 +26,7 @@ "lib2.p1": "v_p1_lib2[b2_label]", "lib2.p2": "v_p2_lib2[b2_label]" }, - # The values for lib2.p1 and lib2.p2 illustrate how overriding on multiple - # labels work. In lib2, both lib2.p1 and lib2.p2 are overriden for both - # labels (b1_label and b2_label). However, since "b2_label" is specified - # after "b1_label", it sets the final values of the overrides. "both": { - "desc": "override values based on labels with libs (both labels)", "app.app1": "v_app1[b1_label]", "app.app2": "v_app2[b2_label]", "lib1.p1": "v_p1_lib1[b1_label]", @@ -45,5 +34,5 @@ "lib1.p3": "v_p3_lib1", "lib2.p1": "v_p1_lib2[b2_label]", "lib2.p2": "v_p2_lib2[b2_label]" - }, + } } diff --git a/tools/test/config_test/test07/lib1/lib2/mbed_lib.json b/tools/test/config/override_labels_libs_more/lib1/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test07/lib1/lib2/mbed_lib.json rename to tools/test/config/override_labels_libs_more/lib1/lib2/mbed_lib.json diff --git a/tools/test/config_test/test07/lib1/mbed_lib.json b/tools/test/config/override_labels_libs_more/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test07/lib1/mbed_lib.json rename to tools/test/config/override_labels_libs_more/lib1/mbed_lib.json diff --git a/tools/test/config_test/test07/mbed_app.json b/tools/test/config/override_labels_libs_more/mbed_app.json similarity index 100% rename from tools/test/config_test/test07/mbed_app.json rename to tools/test/config/override_labels_libs_more/mbed_app.json diff --git a/tools/test/config_test/test06/targets.json b/tools/test/config/override_labels_libs_more/targets.json similarity index 100% rename from tools/test/config_test/test06/targets.json rename to tools/test/config/override_labels_libs_more/targets.json diff --git a/tools/test/config_test/test07/test_data.py b/tools/test/config/override_labels_libs_more/test_data.json similarity index 61% rename from tools/test/config_test/test07/test_data.py rename to tools/test/config/override_labels_libs_more/test_data.json index e9d605acfa2..46ae967b0ff 100644 --- a/tools/test/config_test/test07/test_data.py +++ b/tools/test/config/override_labels_libs_more/test_data.json @@ -1,8 +1,5 @@ -# This build on top of test6 by adding overrides for libs in the application - -expected_results = { +{ "base": { - "desc": "override values based on labels with libs (no labels)", "app.app1": "v_app1", "app.app2": "v_app2", "lib1.p1": "v_p1_lib1_app", @@ -12,7 +9,6 @@ "lib2.p2": "v_p2_lib2" }, "b1": { - "desc": "override values based on labels with libs (first label)", "app.app1": "v_app1[b1_label]", "app.app2": "v_app2", "lib1.p1": "v_p1_lib1_app", @@ -22,7 +18,6 @@ "lib2.p2": "v_p2_lib2[b1_label]" }, "b2": { - "desc": "override values based on labels with libs (second label)", "app.app1": "v_app1", "app.app2": "v_app2[b2_label]", "lib1.p1": "v_p1_lib1_app", @@ -31,12 +26,7 @@ "lib2.p1": "v_p1_lib2_app", "lib2.p2": "v_p2_lib2[b2_label]" }, - # The values for lib2.p1 and lib2.p2 illustrate how overriding on multiple - # labels work. In lib2, both lib2.p1 and lib2.p2 are overriden for both - # labels (b1_label and b2_label). However, since "b2_label" is specified - # after "b1_label", it sets the final values of the overrides. "both": { - "desc": "override values based on labels with libs (both labels)", "app.app1": "v_app1[b1_label]", "app.app2": "v_app2[b2_label]", "lib1.p1": "v_p1_lib1_app", diff --git a/tools/test/config_test/test08/lib1/lib2/mbed_lib.json b/tools/test/config/override_labels_targets/lib1/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test08/lib1/lib2/mbed_lib.json rename to tools/test/config/override_labels_targets/lib1/lib2/mbed_lib.json diff --git a/tools/test/config_test/test08/lib1/mbed_lib.json b/tools/test/config/override_labels_targets/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test08/lib1/mbed_lib.json rename to tools/test/config/override_labels_targets/lib1/mbed_lib.json diff --git a/tools/test/config_test/test08/mbed_app.json b/tools/test/config/override_labels_targets/mbed_app.json similarity index 100% rename from tools/test/config_test/test08/mbed_app.json rename to tools/test/config/override_labels_targets/mbed_app.json diff --git a/tools/test/config_test/test08/targets.json b/tools/test/config/override_labels_targets/targets.json similarity index 100% rename from tools/test/config_test/test08/targets.json rename to tools/test/config/override_labels_targets/targets.json diff --git a/tools/test/config_test/test08/test_data.py b/tools/test/config/override_labels_targets/test_data.json similarity index 75% rename from tools/test/config_test/test08/test_data.py rename to tools/test/config/override_labels_targets/test_data.json index 141bf397255..f115f5baffe 100644 --- a/tools/test/config_test/test08/test_data.py +++ b/tools/test/config/override_labels_targets/test_data.json @@ -1,9 +1,5 @@ -# This build on top of test7 by adding some configuration values in targets -# and overriding them in the application - -expected_results = { +{ "base": { - "desc": "override values based on labels with libs and target params (no labels)", "app.app1": "v_app1", "app.app2": "v_app2", "lib1.p1": "v_p1_lib1_app", @@ -16,7 +12,6 @@ "target.par3": "v_par3_base" }, "b1": { - "desc": "override values based on labels with libs and target params (first label)", "app.app1": "v_app1[b1_label]", "app.app2": "v_app2", "lib1.p1": "v_p1_lib1_app", @@ -29,7 +24,6 @@ "target.par3": "v_par3_base" }, "b2": { - "desc": "override values based on labels with libs and target params (second label)", "app.app1": "v_app1", "app.app2": "v_app2[b2_label]", "lib1.p1": "v_p1_lib1_app", @@ -42,7 +36,6 @@ "target.par3": "v_par3_base" }, "both": { - "desc": "override values based on labels with libs and target params (both labels)", "app.app1": "v_app1[b1_label]", "app.app2": "v_app2[b2_label]", "lib1.p1": "v_p1_lib1_app", diff --git a/tools/test/config_test/test09/lib1/lib2/mbed_lib.json b/tools/test/config/override_precidence/lib1/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test09/lib1/lib2/mbed_lib.json rename to tools/test/config/override_precidence/lib1/lib2/mbed_lib.json diff --git a/tools/test/config_test/test09/lib1/mbed_lib.json b/tools/test/config/override_precidence/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test09/lib1/mbed_lib.json rename to tools/test/config/override_precidence/lib1/mbed_lib.json diff --git a/tools/test/config_test/test10/mbed_app.json b/tools/test/config/override_precidence/mbed_app.json similarity index 100% rename from tools/test/config_test/test10/mbed_app.json rename to tools/test/config/override_precidence/mbed_app.json diff --git a/tools/test/config_test/test10/targets.json b/tools/test/config/override_precidence/targets.json similarity index 100% rename from tools/test/config_test/test10/targets.json rename to tools/test/config/override_precidence/targets.json diff --git a/tools/test/config_test/test10/test_data.py b/tools/test/config/override_precidence/test_data.json similarity index 74% rename from tools/test/config_test/test10/test_data.py rename to tools/test/config/override_precidence/test_data.json index 7ed62e2ad93..fd853cb7982 100644 --- a/tools/test/config_test/test10/test_data.py +++ b/tools/test/config/override_precidence/test_data.json @@ -1,8 +1,5 @@ -# This builds on top of test8 by adding target-conditional overrides in mbed_app_config.json. - -expected_results = { +{ "base": { - "desc": "override values based on labels with libs, target params and target overrides (no labels)", "app.app1": "v_app1", "app.app2": "v_app2", "lib1.p1": "v_p1_lib1_app", @@ -15,7 +12,6 @@ "target.par3": "v_par3_base" }, "b1": { - "desc": "override values based on labels with libs, target params and target overrides (first label)", "app.app1": "v_app1[b1_label_label]", "app.app2": "v_app2", "lib1.p1": "v_p1_lib1_app", @@ -28,7 +24,6 @@ "target.par3": "v_par3_base" }, "b2": { - "desc": "override values based on labels with libs, target params and target overrides (second label)", "app.app1": "v_app1", "app.app2": "v_app2[b2_label]", "lib1.p1": "v_p1_lib1_app", @@ -41,7 +36,6 @@ "target.par3": "v_par3_base" }, "both": { - "desc": "override values based on labels with libs, target params and target overrides (both labels)", "app.app1": "v_app1[b1_label_label]", "app.app2": "v_app2[b2_label]", "lib1.p1": "v_p1_lib1_app", diff --git a/tools/test/config_test/test03/targets.json b/tools/test/config/override_undefined/targets.json similarity index 82% rename from tools/test/config_test/test03/targets.json rename to tools/test/config/override_undefined/targets.json index 5a287888d10..ae1cf7c3007 100644 --- a/tools/test/config_test/test03/targets.json +++ b/tools/test/config/override_undefined/targets.json @@ -1,5 +1,5 @@ { - "b1": { + "first_base_target": { "extra_labels": [], "default_lib": "std", "core": "Cortex-M0", @@ -9,8 +9,8 @@ "base1_3": "v_base1_3_b1" } }, - "d1": { - "inherits": ["b1"], + "intermediate": { + "inherits": ["first_base_target"], "config": { "derived1": "v_derived1_d1", "derived2": "v_derived2_d1" @@ -20,7 +20,7 @@ "base1_2": "v_base1_2_d1" } }, - "b2": { + "second_base_target": { "config": { "base2_1": "v_base2_1_b2", "base2_2": "v_base2_2_b2" @@ -29,8 +29,8 @@ "base1_1": "v_base1_1_b2" } }, - "f": { - "inherits": ["b2", "d1"], + "should_fail": { + "inherits": ["second_base_target", "intermediate"], "config": { "f1_1": "v_f1_1_f", "f1_2": "v_f1_2_f" diff --git a/tools/test/config/override_undefined/test_data.json b/tools/test/config/override_undefined/test_data.json new file mode 100644 index 00000000000..f5ca6574d9e --- /dev/null +++ b/tools/test/config/override_undefined/test_data.json @@ -0,0 +1,12 @@ +{ + "should_fail": { + "exception_msg": "Attempt to override undefined parameter 'base1_1' in 'target:second_base_target'" + }, + "intermediate": { + "target.base1_1": "v_base1_1_d1", + "target.base1_2": "v_base1_2_d1", + "target.base1_3": "v_base1_3_b1", + "target.derived1": "v_derived1_d1", + "target.derived2": "v_derived2_d1" + } +} diff --git a/tools/test/config_test/test10/lib1/lib2/mbed_lib.json b/tools/test/config/override_undefined_libs/lib1/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test10/lib1/lib2/mbed_lib.json rename to tools/test/config/override_undefined_libs/lib1/lib2/mbed_lib.json diff --git a/tools/test/config_test/test10/lib1/mbed_lib.json b/tools/test/config/override_undefined_libs/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test10/lib1/mbed_lib.json rename to tools/test/config/override_undefined_libs/lib1/mbed_lib.json diff --git a/tools/test/config_test/test09/mbed_app.json b/tools/test/config/override_undefined_libs/mbed_app.json similarity index 100% rename from tools/test/config_test/test09/mbed_app.json rename to tools/test/config/override_undefined_libs/mbed_app.json diff --git a/tools/test/config_test/test09/targets.json b/tools/test/config/override_undefined_libs/targets.json similarity index 70% rename from tools/test/config_test/test09/targets.json rename to tools/test/config/override_undefined_libs/targets.json index d045de8670f..16c687b6c6b 100644 --- a/tools/test/config_test/test09/targets.json +++ b/tools/test/config/override_undefined_libs/targets.json @@ -4,15 +4,15 @@ "default_lib": "std", "core": "Cortex-M0" }, - "b1": { + "left_intermediate": { "inherits": ["base"], "extra_labels_add": ["b1_label"] }, - "b2": { + "right_intermediate": { "inherits": ["base"], "extra_labels_add": ["b2_label"] }, "both": { - "inherits": ["b1", "b2"] + "inherits": ["left_intermediate", "right_intermediate"] } } diff --git a/tools/test/config_test/test09/test_data.py b/tools/test/config/override_undefined_libs/test_data.json similarity index 55% rename from tools/test/config_test/test09/test_data.py rename to tools/test/config/override_undefined_libs/test_data.json index 04757485a90..15c806215f3 100644 --- a/tools/test/config_test/test09/test_data.py +++ b/tools/test/config/override_undefined_libs/test_data.json @@ -1,10 +1,5 @@ -# This build on top of test6 by adding an invalid override in mbed_app_override.json for b1_label. -# This will prevent the configuration for working for b1 and both, but it should still -# work for base and b2. - -expected_results = { +{ "base": { - "desc": "override values based on labels with libs (no labels)", "app.app1": "v_app1", "app.app2": "v_app2", "lib1.p1": "v_p1_lib1", @@ -13,12 +8,10 @@ "lib2.p1": "v_p1_lib2", "lib2.p2": "v_p2_lib2" }, - "b1": { - "desc": "override values based on labels with libs - invalid override (first label)", + "left_intermediate": { "exception_msg": "Attempt to override undefined parameter 'app.app_wrong' in 'application[b1_label]" }, - "b2": { - "desc": "override values based on labels with libs (second label)", + "right_intermediate": { "app.app1": "v_app1", "app.app2": "v_app2[b2_label]", "lib1.p1": "v_p1_lib1", @@ -28,7 +21,6 @@ "lib2.p2": "v_p2_lib2[b2_label]" }, "both": { - "desc": "override values based on labels with libs - invalid override (both labels)", "exception_msg": "Attempt to override undefined parameter 'app.app_wrong' in 'application[b1_label]" - }, + } } diff --git a/tools/test/config_test/test05/mbed_app.json b/tools/test/config/override_with_labels/mbed_app.json similarity index 55% rename from tools/test/config_test/test05/mbed_app.json rename to tools/test/config/override_with_labels/mbed_app.json index b6ce5881c84..716165a37e5 100644 --- a/tools/test/config_test/test05/mbed_app.json +++ b/tools/test/config/override_with_labels/mbed_app.json @@ -4,11 +4,11 @@ "app2": "v_app2" }, "target_overrides": { - "b1_label": { - "app1": "v_app1[b1_label]" + "left_intermediate_label": { + "app1": "v_app1[left_intermediate_label]" }, - "b2_label": { - "app2": "v_app2[b2_label]" + "right_intermediate_label": { + "app2": "v_app2[right_intermediate_label]" }, "dummy_label": { "app1": "dummy.app1", diff --git a/tools/test/config/override_with_labels/targets.json b/tools/test/config/override_with_labels/targets.json new file mode 100644 index 00000000000..3d78e3ef9c8 --- /dev/null +++ b/tools/test/config/override_with_labels/targets.json @@ -0,0 +1,18 @@ +{ + "base": { + "extra_labels": [], + "default_lib": "std", + "core": "Cortex-M0" + }, + "left_intermediate": { + "inherits": ["base"], + "extra_labels_add": ["left_intermediate_label"] + }, + "right_intermediate": { + "inherits": ["base"], + "extra_labels_add": ["right_intermediate_label"] + }, + "both": { + "inherits": ["left_intermediate", "right_intermediate"] + } +} diff --git a/tools/test/config/override_with_labels/test_data.json b/tools/test/config/override_with_labels/test_data.json new file mode 100644 index 00000000000..7fbc15e7b7d --- /dev/null +++ b/tools/test/config/override_with_labels/test_data.json @@ -0,0 +1,18 @@ +{ + "left_intermediate": { + "app.app1": "v_app1[left_intermediate_label]", + "app.app2": "v_app2" + }, + "right_intermediate": { + "app.app1": "v_app1", + "app.app2": "v_app2[right_intermediate_label]" + }, + "both": { + "app.app1": "v_app1[left_intermediate_label]", + "app.app2": "v_app2[right_intermediate_label]" + }, + "base": { + "app.app1": "v_app1", + "app.app2": "v_app2" + } +} diff --git a/tools/test/config_test/test12/lib1/lib2/mbed_lib.json b/tools/test/config/parameter_outside_lib/lib1/lib2/mbed_lib.json similarity index 100% rename from tools/test/config_test/test12/lib1/lib2/mbed_lib.json rename to tools/test/config/parameter_outside_lib/lib1/lib2/mbed_lib.json diff --git a/tools/test/config_test/test11/lib1/mbed_lib.json b/tools/test/config/parameter_outside_lib/lib1/mbed_lib.json similarity index 100% rename from tools/test/config_test/test11/lib1/mbed_lib.json rename to tools/test/config/parameter_outside_lib/lib1/mbed_lib.json diff --git a/tools/test/config/parameter_outside_lib/test_data.json b/tools/test/config/parameter_outside_lib/test_data.json new file mode 100644 index 00000000000..1975443ec72 --- /dev/null +++ b/tools/test/config/parameter_outside_lib/test_data.json @@ -0,0 +1,5 @@ +{ + "K64F": { + "exception_msg": "Invalid prefix 'lib2' for parameter name 'lib2.p1' in 'library:lib1[K64F]'" + } +} diff --git a/tools/test/config_test/test21/mbed_app.json b/tools/test/config/simple_features/mbed_app.json similarity index 100% rename from tools/test/config_test/test21/mbed_app.json rename to tools/test/config/simple_features/mbed_app.json diff --git a/tools/test/config_test/test28/targets.json b/tools/test/config/simple_features/targets.json similarity index 100% rename from tools/test/config_test/test28/targets.json rename to tools/test/config/simple_features/targets.json diff --git a/tools/test/config/simple_features/test_data.json b/tools/test/config/simple_features/test_data.json new file mode 100644 index 00000000000..2639e0bc1f9 --- /dev/null +++ b/tools/test/config/simple_features/test_data.json @@ -0,0 +1,5 @@ +{ + "test_target": { + "expected_features": ["IPV4"] + } +} diff --git a/tools/test/config_test/test01/targets.json b/tools/test/config/simple_iheritance/targets.json similarity index 83% rename from tools/test/config_test/test01/targets.json rename to tools/test/config/simple_iheritance/targets.json index bf874e47de3..16083664779 100644 --- a/tools/test/config_test/test01/targets.json +++ b/tools/test/config/simple_iheritance/targets.json @@ -1,5 +1,5 @@ { - "b1": { + "first_base": { "extra_labels": [], "default_lib": "std", "core": "Cortex-M0", @@ -9,8 +9,8 @@ "base1_3": "v_base1_3_b1" } }, - "d1": { - "inherits": ["b1"], + "intermediate": { + "inherits": ["first_base"], "config": { "derived1": "v_derived1_d1", "derived2": "v_derived2_d1" @@ -20,14 +20,14 @@ "base1_2": "v_base1_2_d1" } }, - "b2": { + "second_base": { "config": { "base2_1": "v_base2_1_b2", "base2_2": "v_base2_2_b2" } }, - "f": { - "inherits": ["b2", "d1"], + "inherits_tree": { + "inherits": ["second_base", "intermediate"], "config": { "f1_1": "v_f1_1_f", "f1_2": "v_f1_2_f" diff --git a/tools/test/config/simple_iheritance/test_data.json b/tools/test/config/simple_iheritance/test_data.json new file mode 100644 index 00000000000..10ba4a7f69b --- /dev/null +++ b/tools/test/config/simple_iheritance/test_data.json @@ -0,0 +1,25 @@ +{ + "inherits_tree": { + "target.base1_1": "v_base1_1_f", + "target.base1_2": "v_base1_2_d1", + "target.base1_3": "v_base1_3_b1", + "target.derived1": "v_derived1_d1", + "target.derived2": "v_derived2_f", + "target.base2_1": "v_base2_1_f", + "target.base2_2": "v_base2_2_b2", + "target.f1_1": "v_f1_1_f_override", + "target.f1_2": "v_f1_2_f" + }, + "first_base": { + "target.base1_1": "v_base1_1_b1", + "target.base1_2": "v_base1_2_b1", + "target.base1_3": "v_base1_3_b1" + }, + "intermediate": { + "target.base1_1": "v_base1_1_d1", + "target.base1_2": "v_base1_2_d1", + "target.base1_3": "v_base1_3_b1", + "target.derived1": "v_derived1_d1", + "target.derived2": "v_derived2_d1" + } +} diff --git a/tools/test/config_test/config_test.py b/tools/test/config_test/config_test.py deleted file mode 100644 index ac7d1d1a7e1..00000000000 --- a/tools/test/config_test/config_test.py +++ /dev/null @@ -1,113 +0,0 @@ -""" -mbed SDK -Copyright (c) 2011-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. -""" - -from tools.build_api import get_config -from tools.targets import set_targets_json_location, Target -from tools.config import ConfigException, Config -import os, sys - -# Compare the output of config against a dictionary of known good results -def compare_config(cfg, expected): - try: - for k in cfg: - if cfg[k].value != expected[k]: - return "'%s': expected '%s', got '%s'" % (k, expected[k], cfg[k].value) - except KeyError: - raise - return "Unexpected key '%s' in configuration data" % k - for k in expected: - if k not in ["desc", "expected_macros", "expected_features"] + cfg.keys(): - return "Expected key '%s' was not found in configuration data" % k - return "" - -def test_tree(full_name, name): - failed = 0 - sys.path.append(full_name) - if "test_data" in sys.modules: - del sys.modules["test_data"] - import test_data - # If the test defines custom targets, they must exist in a file called - # "targets.json" in the test's directory. - if os.path.isfile(os.path.join(full_name, "targets.json")): - set_targets_json_location(os.path.join(full_name, "targets.json")) - else: # uset the regular set of targets - set_targets_json_location() - for target, expected in test_data.expected_results.items(): - sys.stdout.write("%s:'%s'(%s) " % (name, expected["desc"], target)) - sys.stdout.flush() - err_msg = None - try: - cfg, macros, features = get_config(full_name, target, "GCC_ARM") - macros = Config.config_macros_to_macros(macros) - except ConfigException as e: - err_msg = e.message - if err_msg: - if expected.has_key("exception_msg"): - if err_msg.find(expected["exception_msg"]) == -1: - print "FAILED!" - sys.stderr.write(" Unexpected error message!\n") - sys.stderr.write(" Expected: '%s'\n" % expected["exception_msg"]) - sys.stderr.write(" Got: '%s'\n" % err_msg) - failed += 1 - else: - print "OK" - else: - print "FAILED!" - sys.stderr.write(" Error while getting configuration!\n") - sys.stderr.write(" " + err_msg + "\n") - failed += 1 - else: - res = compare_config(cfg, expected) - expected_macros = expected.get("expected_macros", None) - expected_features = expected.get("expected_features", None) - - if res: - print "FAILED!" - sys.stdout.write(" " + res + "\n") - failed += 1 - elif expected_macros is not None: - if sorted(expected_macros) != sorted(macros): - print "FAILED!" - sys.stderr.write(" List of macros doesn't match\n") - sys.stderr.write(" Expected: '%s'\n" % ",".join(sorted(expected_macros))) - sys.stderr.write(" Got: '%s'\n" % ",".join(sorted(expected_macros))) - failed += 1 - else: - print "OK" - elif expected_features is not None: - if sorted(expected_features) != sorted(features): - print "FAILED!" - sys.stderr.write(" List of features doesn't match\n") - sys.stderr.write(" Expected: '%s'\n" % ",".join(sorted(expected_features))) - sys.stderr.write(" Got: '%s'\n" % ",".join(sorted(expected_features))) - failed += 1 - else: - print "OK" - else: - print "OK" - sys.path.remove(full_name) - return failed - -failed = 0 -root_dir = os.path.abspath(os.path.dirname(__file__)) -tlist = sorted(os.listdir(root_dir), key = lambda e: int(e[4:]) if e.startswith('test') else -1) -for test_name in tlist: - full_name = os.path.join(root_dir, test_name) - if os.path.isdir(full_name) and test_name.startswith('test'): - failed += test_tree(full_name, test_name) -sys.exit(failed) - diff --git a/tools/test/config_test/test01/test_data.py b/tools/test/config_test/test01/test_data.py deleted file mode 100644 index 878ae936900..00000000000 --- a/tools/test/config_test/test01/test_data.py +++ /dev/null @@ -1,46 +0,0 @@ -# Test for configuration data defined in targets -# A base target (B1) defines 3 configuration parameters (base1_1, base1_2 and base1_3) -# A derived target (D1) inherits drom B1 and defines one configuration parameters (derived1 and derived2) and overrides base1_1 and base1_2 -# Another base target (B2) defines its own configuration parameters (base2_1 and base2_2) -# The final target F derives from B2 and D1, defines two configuration paramaters (f1_1 and f1_2) -# and overrides base2_1, base1_1, derived2 and its own configuration parameter f1_1 (which is legal) -# Final result: -# base1_1 must have the value defined in F -# base1_2 must have the value defined in D1 -# base1_3 must have the value defined in B1 -# derived1 must have the value defined in D1 -# derived2 must have the value defined in F -# base2_1 must have the value defined in F -# base2_2 must have the value defined in B2 -# f1_1 must have the value defined and then overriden in F -# f1_2 must have the value defined in F - -expected_results = { - "f": { - "desc": "test multiple target inheritance", - "target.base1_1": "v_base1_1_f", - "target.base1_2": "v_base1_2_d1", - "target.base1_3": "v_base1_3_b1", - "target.derived1": "v_derived1_d1", - "target.derived2": "v_derived2_f", - "target.base2_1": "v_base2_1_f", - "target.base2_2": "v_base2_2_b2", - "target.f1_1": "v_f1_1_f_override", - "target.f1_2": "v_f1_2_f" - }, - "b1": { - "desc": "test with a single base target, no inheritance", - "target.base1_1": "v_base1_1_b1", - "target.base1_2": "v_base1_2_b1", - "target.base1_3": "v_base1_3_b1" - }, - "d1": { - "desc": "test single target inheritance", - "target.base1_1": "v_base1_1_d1", - "target.base1_2": "v_base1_2_d1", - "target.base1_3": "v_base1_3_b1", - "target.derived1": "v_derived1_d1", - "target.derived2": "v_derived2_d1" - } -} - diff --git a/tools/test/config_test/test02/test_data.py b/tools/test/config_test/test02/test_data.py deleted file mode 100644 index b915a17ed41..00000000000 --- a/tools/test/config_test/test02/test_data.py +++ /dev/null @@ -1,30 +0,0 @@ -# This is similar to test1, but this time B2 also inherits from B1, which allows it to override its config data. -# B2 also overrides base1_2, like D1. -# The order of inheritace in F is also reversed ([D1, B2] instead of [B2, D1]) -# Since the last override of base1_2 in inheritance order is in B2, base1_2 must now -# have the value that was overriden in B2, not in D1. -# This test also shows that multiple inheritance works for a simple diamond shaped inheritance pattern - -expected_results = { - "f": { - "desc": "test multiple target inheritance (diamond shape)", - "target.base1_1": "v_base1_1_f", - "target.base1_2": "v_base1_2_b2", - "target.base1_3": "v_base1_3_b1", - "target.derived1": "v_derived1_d1", - "target.derived2": "v_derived2_f", - "target.base2_1": "v_base2_1_f", - "target.base2_2": "v_base2_2_b2", - "target.f1_1": "v_f1_1_f_override", - "target.f1_2": "v_f1_2_f" - }, - "b2": { - "desc": "another single inheritance test", - "target.base1_1": "v_base1_1_b1", - "target.base1_2": "v_base1_2_b2", - "target.base1_3": "v_base1_3_b1", - "target.base2_1": "v_base2_1_b2", - "target.base2_2": "v_base2_2_b2" - } -} - diff --git a/tools/test/config_test/test03/test_data.py b/tools/test/config_test/test03/test_data.py deleted file mode 100644 index 3540131961a..00000000000 --- a/tools/test/config_test/test03/test_data.py +++ /dev/null @@ -1,18 +0,0 @@ -# Similar to test1, but this time B2 attempt to override base1_1. Since B2 doesn't directly inherit -# from B1, this must raise an error - -expected_results = { - "f": { - "desc": "attempt to override undefined parameter in inherited target", - "exception_msg": "Attempt to override undefined parameter 'base1_1' in 'target:b2'" - }, - "d1": { - "desc": "single target inheritance again", - "target.base1_1": "v_base1_1_d1", - "target.base1_2": "v_base1_2_d1", - "target.base1_3": "v_base1_3_b1", - "target.derived1": "v_derived1_d1", - "target.derived2": "v_derived2_d1" - } -} - diff --git a/tools/test/config_test/test04/test_data.py b/tools/test/config_test/test04/test_data.py deleted file mode 100644 index 50fbfcdb068..00000000000 --- a/tools/test/config_test/test04/test_data.py +++ /dev/null @@ -1,18 +0,0 @@ -# Similar to test1, but this time B2 attempt to define base1_1. Since base1_1 -# is already defined in B1 and F derives from both B1 and B2, this results -# in an error. However, when building for B2 instead of F, defining base1_1 -# should be OK. - -expected_results = { - "f": { - "desc": "attempt to redefine parameter in target inheritance tree", - "exception_msg": "Parameter name 'base1_1' defined in both 'target:b2' and 'target:b1'" - }, - "b2": { - "desc": "it should be OK to define parameters with the same name in non-related targets", - "target.base2_1": "v_base2_1_b2", - "target.base2_2": "v_base2_2_b2", - "target.base1_1": "v_base1_1_b2" - } -} - diff --git a/tools/test/config_test/test05/test_data.py b/tools/test/config_test/test05/test_data.py deleted file mode 100644 index 65ac4cd7180..00000000000 --- a/tools/test/config_test/test05/test_data.py +++ /dev/null @@ -1,29 +0,0 @@ -# This tests overriding configuration values based on target labels. -# Four targets are defined: -# - "base" is the base target, it doesn't define any extra labels -# - "b1" inherits from "base" and adds the "b1_label" label -# - "b2" inherits from "base" and adds the "b2_label" label -# - "both" inherits from both "b1" and "b2", so it inherits both labels - -expected_results = { - "b1": { - "desc": "override values based on labels (first label)", - "app.app1": "v_app1[b1_label]", - "app.app2": "v_app2" - }, - "b2": { - "desc": "override values based on labels (second label)", - "app.app1": "v_app1", - "app.app2": "v_app2[b2_label]" - }, - "both": { - "desc": "override values based on labels (both labels)", - "app.app1": "v_app1[b1_label]", - "app.app2": "v_app2[b2_label]" - }, - "base": { - "desc": "override values based on labels (no labels)", - "app.app1": "v_app1", - "app.app2": "v_app2" - } -} diff --git a/tools/test/config_test/test07/targets.json b/tools/test/config_test/test07/targets.json deleted file mode 100644 index d045de8670f..00000000000 --- a/tools/test/config_test/test07/targets.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "base": { - "extra_labels": [], - "default_lib": "std", - "core": "Cortex-M0" - }, - "b1": { - "inherits": ["base"], - "extra_labels_add": ["b1_label"] - }, - "b2": { - "inherits": ["base"], - "extra_labels_add": ["b2_label"] - }, - "both": { - "inherits": ["b1", "b2"] - } -} diff --git a/tools/test/config_test/test11/test_data.py b/tools/test/config_test/test11/test_data.py deleted file mode 100644 index 6bcaed1091e..00000000000 --- a/tools/test/config_test/test11/test_data.py +++ /dev/null @@ -1,9 +0,0 @@ -# Two libraries (lib1 and lib2) define their own configuration parameters -# lib1 tries to override a configuration parameter in lib2, which raises an error - -expected_results = { - "K64F": { - "desc": "lib1 trying to override a config parameter in lib2", - "exception_msg": "Invalid prefix 'lib2' for parameter name 'lib2.p1' in 'library:lib1[K64F]'" - } -} diff --git a/tools/test/config_test/test12/test_data.py b/tools/test/config_test/test12/test_data.py deleted file mode 100644 index d2489dc7732..00000000000 --- a/tools/test/config_test/test12/test_data.py +++ /dev/null @@ -1,14 +0,0 @@ -# Two libraries (lib1 and lib2) define their own configuration parameters -# The application config doesn't have any parameters itself, it just overrides the parameter -# named p1 from both lib1 and lib2. - -expected_results = { - "test_target": { - "desc": "app without its own parameters overrides parameters in other libs", - "lib1.p1": "v_p1_lib1_app", - "lib1.p2": "v_p2_lib1", - "lib1.p3": "v_p3_lib1", - "lib2.p1": "v_p1_lib2_app", - "lib2.p2": "v_p2_lib2" - } -} diff --git a/tools/test/config_test/test13/test_data.py b/tools/test/config_test/test13/test_data.py deleted file mode 100644 index 7d394e84ec1..00000000000 --- a/tools/test/config_test/test13/test_data.py +++ /dev/null @@ -1,8 +0,0 @@ -# Create two libraries named "lib1", which must raise an error - -expected_results = { - "K64F": { - "desc": "attempt to configure two libraries named 'lib1'", - "exception_msg": "Library name 'lib1' is not unique" - } -} diff --git a/tools/test/config_test/test14/test_data.py b/tools/test/config_test/test14/test_data.py deleted file mode 100644 index 1db33cd6d4c..00000000000 --- a/tools/test/config_test/test14/test_data.py +++ /dev/null @@ -1,8 +0,0 @@ -# Put an invalid key in the application configuration - -expected_results = { - "K64F": { - "desc": "invalid key in mbed_app_config.json", - "exception_msg": "Unknown key(s)" - } -} diff --git a/tools/test/config_test/test15/test_data.py b/tools/test/config_test/test15/test_data.py deleted file mode 100644 index 4518f78783f..00000000000 --- a/tools/test/config_test/test15/test_data.py +++ /dev/null @@ -1,8 +0,0 @@ -# Put an invalid key in the library configuration - -expected_results = { - "K64F": { - "desc": "invalid key in mbed_lib_config.json", - "exception_msg": "Unknown key(s)" - } -} diff --git a/tools/test/config_test/test16/test_data.py b/tools/test/config_test/test16/test_data.py deleted file mode 100644 index 5a106b742b9..00000000000 --- a/tools/test/config_test/test16/test_data.py +++ /dev/null @@ -1,12 +0,0 @@ -# Macro test: defined macros in the top level app and 2 libs, check if they -# are reported properly. -# The app defines one macro with value the same as lib2, while lib2 defined -# the same macro without value as lib1. Since the definitions are comptabile, -# no error should be raised - -expected_results = { - "test_target": { - "desc": "test macro definitions", - "expected_macros": ["APP1=10", "APP2", "LIB1_1=1","LIB1_2", "LIB2_1=5"] - } -} diff --git a/tools/test/config_test/test17/test_data.py b/tools/test/config_test/test17/test_data.py deleted file mode 100644 index b55da016d1c..00000000000 --- a/tools/test/config_test/test17/test_data.py +++ /dev/null @@ -1,9 +0,0 @@ -# Build on top of test16 -# Adds an invalid macro redefinition in the app - -expected_results = { - "K64F": { - "desc": "test invalid macro re-definition in the app", - "exception_msg": "Macro 'LIB2_1' defined in both 'library:lib2' and 'application' with incompatible values" - } -} diff --git a/tools/test/config_test/test18/test_data.py b/tools/test/config_test/test18/test_data.py deleted file mode 100644 index e2288333817..00000000000 --- a/tools/test/config_test/test18/test_data.py +++ /dev/null @@ -1,8 +0,0 @@ -# Like test17, but this time the invalid re-definition is in lib2, not in the app - -expected_results = { - "K64F": { - "desc": "test invalid macro re-definition in a library", - "exception_msg": "defined in both" - } -} diff --git a/tools/test/config_test/test19/mbed_app.json b/tools/test/config_test/test19/mbed_app.json deleted file mode 100644 index 6970156cd2a..00000000000 --- a/tools/test/config_test/test19/mbed_app.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "macros": [], - "invalid_key": "invalid_value" -} diff --git a/tools/test/config_test/test19/test_data.py b/tools/test/config_test/test19/test_data.py deleted file mode 100644 index 40e250b8653..00000000000 --- a/tools/test/config_test/test19/test_data.py +++ /dev/null @@ -1,8 +0,0 @@ -# Test that invalid keys in application configuration are not allowed - -expected_results = { - "K64F": { - "desc": "test invalid key in application config", - "exception_msg": "Unknown key(s) 'invalid_key'" - } -} diff --git a/tools/test/config_test/test20/lib1/mbed_lib.json b/tools/test/config_test/test20/lib1/mbed_lib.json deleted file mode 100644 index a42cdd3eba8..00000000000 --- a/tools/test/config_test/test20/lib1/mbed_lib.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "lib1", - "macros": [], - "invalid_key": "invalid_value" -} diff --git a/tools/test/config_test/test20/test_data.py b/tools/test/config_test/test20/test_data.py deleted file mode 100644 index 7e9f6461b93..00000000000 --- a/tools/test/config_test/test20/test_data.py +++ /dev/null @@ -1,8 +0,0 @@ -# Like test19, but this time check invalid key in a library configuration - -expected_results = { - "K64F": { - "desc": "test invalid key in lib config", - "exception_msg": "Unknown key(s) 'invalid_key'" - } -} diff --git a/tools/test/config_test/test21/test_data.py b/tools/test/config_test/test21/test_data.py deleted file mode 100644 index 4f7ae443e96..00000000000 --- a/tools/test/config_test/test21/test_data.py +++ /dev/null @@ -1,8 +0,0 @@ -# Testing basic features - -expected_results = { - "test_target": { - "desc": "test basic features", - "expected_features": ["IPV4"] - } -} diff --git a/tools/test/config_test/test22/test_data.py b/tools/test/config_test/test22/test_data.py deleted file mode 100644 index 5edfe17891e..00000000000 --- a/tools/test/config_test/test22/test_data.py +++ /dev/null @@ -1,8 +0,0 @@ -# Testing when adding two features - -expected_results = { - "test_target": { - "desc": "test composing features", - "expected_features": ["IPV4", "STORAGE"] - } -} diff --git a/tools/test/config_test/test24/test_data.py b/tools/test/config_test/test24/test_data.py deleted file mode 100644 index a77f0267589..00000000000 --- a/tools/test/config_test/test24/test_data.py +++ /dev/null @@ -1,8 +0,0 @@ -# Testing if features can enable other features - -expected_results = { - "test_target": { - "desc": "test recursive features", - "expected_features": ["IPV4", "STORAGE", "UVISOR"] - } -} diff --git a/tools/test/config_test/test25/test_data.py b/tools/test/config_test/test25/test_data.py deleted file mode 100644 index 360d392130e..00000000000 --- a/tools/test/config_test/test25/test_data.py +++ /dev/null @@ -1,8 +0,0 @@ -# Testing if feature collisions are detected accross recursive features - -expected_results = { - "K64F": { - "desc": "test recursive feature collisions", - "exception_msg": "Configuration conflict. The feature UVISOR both added and removed." - } -} diff --git a/tools/test/config_test/test26/test_data.py b/tools/test/config_test/test26/test_data.py deleted file mode 100644 index 2d16a8bf347..00000000000 --- a/tools/test/config_test/test26/test_data.py +++ /dev/null @@ -1,8 +0,0 @@ -# Testing if config settings work in recursive features - -expected_results = { - "test_target": { - "desc": "test recursive feature configurations", - "lib2.test": "GOOD" - } -} diff --git a/tools/test/config_test/test27/test_data.py b/tools/test/config_test/test27/test_data.py deleted file mode 100644 index 53853318a43..00000000000 --- a/tools/test/config_test/test27/test_data.py +++ /dev/null @@ -1,8 +0,0 @@ -# Testing when adding two features - -expected_results = { - "test_target": { - "desc": "test removing features", - "expected_features": [] - } -} diff --git a/tools/test/config_test/test28/test_data.py b/tools/test/config_test/test28/test_data.py deleted file mode 100644 index 4f69bfceef4..00000000000 --- a/tools/test/config_test/test28/test_data.py +++ /dev/null @@ -1,8 +0,0 @@ -# Testing when adding two features - -expected_results = { - "test_target": { - "desc": "test uvisor feature", - "expected_features": ["UVISOR"] - } -} diff --git a/tools/test/config_test/test29/test_data.py b/tools/test/config_test/test29/test_data.py deleted file mode 100644 index 935d3d9037a..00000000000 --- a/tools/test/config_test/test29/test_data.py +++ /dev/null @@ -1,6 +0,0 @@ -expected_results = { - "K64F": { - "desc": "error when bootloader not found", - "exception_msg": "not found" - } -} diff --git a/tools/test/memap/memap_test.py b/tools/test/memap/memap_test.py index 13fed8b73e8..a0c84dda51d 100644 --- a/tools/test/memap/memap_test.py +++ b/tools/test/memap/memap_test.py @@ -1,6 +1,6 @@ """ mbed SDK -Copyright (c) 2016 ARM Limited +Copyright (c) 2017 ARM Limited Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,13 +15,11 @@ limitations under the License. """ import sys -import os +from os.path import isfile, join import json -ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "..")) -sys.path.insert(0, ROOT) +import pytest -import unittest from tools.memap import MemapParser from copy import deepcopy @@ -29,190 +27,184 @@ Tests for test_api.py """ -class MemapParserTests(unittest.TestCase): +@pytest.fixture +def memap_parser(): """ - Test cases for Test Api + Called before each test case + + :return: + """ + memap_parser = MemapParser() + + memap_parser.modules = { + "mbed-os/targets/TARGET/TARGET_MCUS/api/pinmap.o": { + ".text": 1, + ".data": 2, + ".bss": 3, + ".heap": 0, + ".stack": 0, + ".interrupts_ram":0, + ".init":0, + ".ARM.extab":0, + ".ARM.exidx":0, + ".ARM.attributes":0, + ".eh_frame":0, + ".init_array":0, + ".fini_array":0, + ".jcr":0, + ".stab":0, + ".stabstr":0, + ".ARM.exidx":0, + ".ARM":0, + ".interrupts":0, + ".flash_config":0, + "unknown":0, + "OUTPUT":0, + }, + "[lib]/libc.a/lib_a-printf.o": { + ".text": 4, + ".data": 5, + ".bss": 6, + ".heap": 0, + ".stack": 0, + ".interrupts_ram":0, + ".init":0, + ".ARM.extab":0, + ".ARM.exidx":0, + ".ARM.attributes":0, + ".eh_frame":0, + ".init_array":0, + ".fini_array":0, + ".jcr":0, + ".stab":0, + ".stabstr":0, + ".ARM.exidx":0, + ".ARM":0, + ".interrupts":0, + ".flash_config":0, + "unknown":0, + "OUTPUT":0, + }, + "main.o": { + ".text": 7, + ".data": 8, + ".bss": 0, + ".heap": 0, + ".stack": 0, + ".interrupts_ram":0, + ".init":0, + ".ARM.extab":0, + ".ARM.exidx":0, + ".ARM.attributes":0, + ".eh_frame":0, + ".init_array":0, + ".fini_array":0, + ".jcr":0, + ".stab":0, + ".stabstr":0, + ".ARM.exidx":0, + ".ARM":0, + ".interrupts":0, + ".flash_config":0, + "unknown":0, + "OUTPUT":0, + }, + "test.o": { + ".text": 0, + ".data": 0, + ".bss": 0, + ".heap": 0, + ".stack": 0, + ".interrupts_ram":0, + ".init":0, + ".ARM.extab":0, + ".ARM.exidx":0, + ".ARM.attributes":0, + ".eh_frame":0, + ".init_array":0, + ".fini_array":0, + ".jcr":0, + ".stab":0, + ".stabstr":0, + ".ARM.exidx":0, + ".ARM":0, + ".interrupts":0, + ".flash_config":0, + "unknown":0, + "OUTPUT":0, + }, + } + return memap_parser + + +def generate_test_helper(memap_parser, format, depth, file_output=None): + """ + Helper that tests that the member variables "modules" is + unchanged after calling "generate_output" + + :param memap_parser: the parser object + :param depth: how much detail to put in the report + :param format: the file type to output + :param file_output: the file to output to + """ + + old_modules = deepcopy(memap_parser.modules) + + memap_parser.generate_output(format, depth, file_output=file_output) + + assert memap_parser.modules == old_modules,\ + "generate_output modified the 'modules' property" + + +@pytest.mark.parametrize("depth", [1, 2, 20]) +def test_report_computed(memap_parser, depth): + """ + Test that a report and summary are computed + + :param memap_parser: Mocked parser + :param depth: the detail of the output + """ + + memap_parser.generate_output('table', depth) + + # Report is created after generating output + assert memap_parser.mem_summary + assert memap_parser.mem_report + + +@pytest.mark.parametrize("depth", [1, 2, 20]) +def test_generate_output_table(memap_parser, depth): """ + Test that an output of type "table" can be generated correctly + :param memap_parser: Mocked parser + :param depth: the detail of the output + """ + generate_test_helper(memap_parser, 'table', depth) + - def setUp(self): - """ - Called before each test case - - :return: - """ - self.memap_parser = MemapParser() - - self.memap_parser.modules = { - "mbed-os/targets/TARGET/TARGET_MCUS/api/pinmap.o": { - ".text": 1, - ".data": 2, - ".bss": 3, - ".heap": 0, - ".stack": 0, - ".interrupts_ram":0, - ".init":0, - ".ARM.extab":0, - ".ARM.exidx":0, - ".ARM.attributes":0, - ".eh_frame":0, - ".init_array":0, - ".fini_array":0, - ".jcr":0, - ".stab":0, - ".stabstr":0, - ".ARM.exidx":0, - ".ARM":0, - ".interrupts":0, - ".flash_config":0, - "unknown":0, - "OUTPUT":0, - }, - "[lib]/libc.a/lib_a-printf.o": { - ".text": 4, - ".data": 5, - ".bss": 6, - ".heap": 0, - ".stack": 0, - ".interrupts_ram":0, - ".init":0, - ".ARM.extab":0, - ".ARM.exidx":0, - ".ARM.attributes":0, - ".eh_frame":0, - ".init_array":0, - ".fini_array":0, - ".jcr":0, - ".stab":0, - ".stabstr":0, - ".ARM.exidx":0, - ".ARM":0, - ".interrupts":0, - ".flash_config":0, - "unknown":0, - "OUTPUT":0, - }, - "main.o": { - ".text": 7, - ".data": 8, - ".bss": 0, - ".heap": 0, - ".stack": 0, - ".interrupts_ram":0, - ".init":0, - ".ARM.extab":0, - ".ARM.exidx":0, - ".ARM.attributes":0, - ".eh_frame":0, - ".init_array":0, - ".fini_array":0, - ".jcr":0, - ".stab":0, - ".stabstr":0, - ".ARM.exidx":0, - ".ARM":0, - ".interrupts":0, - ".flash_config":0, - "unknown":0, - "OUTPUT":0, - }, - "test.o": { - ".text": 0, - ".data": 0, - ".bss": 0, - ".heap": 0, - ".stack": 0, - ".interrupts_ram":0, - ".init":0, - ".ARM.extab":0, - ".ARM.exidx":0, - ".ARM.attributes":0, - ".eh_frame":0, - ".init_array":0, - ".fini_array":0, - ".jcr":0, - ".stab":0, - ".stabstr":0, - ".ARM.exidx":0, - ".ARM":0, - ".interrupts":0, - ".flash_config":0, - "unknown":0, - "OUTPUT":0, - }, - } - - def tearDown(self): - """ - Called after each test case - - :return: - """ - pass - - def generate_test_helper(self, output_type, depth, file_output=None): - """ - Helper that ensures that the member variables "modules" is - 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) - - self.memap_parser.generate_output(output_type, depth, file_output) - - self.assertEqual(self.memap_parser.modules, old_modules, - "generate_output modified the 'modules' property") - - - def test_report_computed(self): - """ - Test ensures the report and summary are computed - - :return: - """ - - self.memap_parser.generate_output('table', 2) - - # Report is created after generating output - self.assertTrue(self.memap_parser.mem_summary) - self.assertTrue(self.memap_parser.mem_report) - - def test_generate_output_table(self): - """ - Test ensures that an output of type "table" can be generated correctly - - :return: - """ - depth = 2 - self.generate_test_helper('table', depth) - - 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' - depth = 2 - self.generate_test_helper('json', depth, 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' - depth = 2 - self.generate_test_helper('csv-ci', depth, 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() +@pytest.mark.parametrize("depth", [1, 2, 20]) +def test_generate_output_json(memap_parser, tmpdir, depth): + """ + Test that an output of type "json" can be generated correctly + :param memap_parser: Mocked parser + :param tmpdir: a unique location to place an output file + :param depth: the detail of the output + """ + file_name = str(tmpdir.join('output.json').realpath()) + generate_test_helper(memap_parser, 'json', depth, file_name) + assert isfile(file_name), "Failed to create json file" + json.load(open(file_name)) + + +@pytest.mark.parametrize("depth", [1, 2, 20]) +def test_generate_output_csv_ci(memap_parser, tmpdir, depth): + """ + Test ensures that an output of type "csv-ci" can be generated correctly + + :param memap_parser: Mocked parser + :param tmpdir: a unique location to place an output file + :param depth: the detail of the output + """ + file_name = str(tmpdir.join('output.csv').realpath()) + generate_test_helper(memap_parser, 'csv-ci', depth, file_name) + assert isfile(file_name), "Failed to create csv-ci file" diff --git a/tools/test/targets/target_test.py b/tools/test/targets/target_test.py index 0e555ca74b7..eff7b3f305e 100644 --- a/tools/test/targets/target_test.py +++ b/tools/test/targets/target_test.py @@ -21,121 +21,113 @@ import tempfile from os.path import join, abspath, dirname from contextlib import contextmanager -import unittest - -# Be sure that the tools directory is in the search path - -ROOT = abspath(join(dirname(__file__), "..", "..", "..")) -sys.path.insert(0, ROOT) +import pytest from tools.targets import TARGETS, TARGET_MAP, Target, update_target_data from tools.arm_pack_manager import Cache -class TestTargets(unittest.TestCase): - - def test_device_name(self): - """Assert device name is in a pack""" - cache = Cache(True, True) - named_targets = (target for target in TARGETS if - hasattr(target, "device_name")) - for target in named_targets: - self.assertTrue(target.device_name in cache.index, - "Target %s contains invalid device_name %s" % - (target.name, target.device_name)) +def test_device_name(): + """Assert device name is in a pack""" + cache = Cache(True, True) + named_targets = (target for target in TARGETS if + hasattr(target, "device_name")) + for target in named_targets: + assert target.device_name in cache.index,\ + ("Target %s contains invalid device_name %s" % + (target.name, target.device_name)) + +@contextmanager +def temp_target_file(extra_target, json_filename='custom_targets.json'): + """Create an extra targets temp file in a context manager + + :param extra_target: the contents of the extra targets temp file + """ + tempdir = tempfile.mkdtemp() + try: + targetfile = os.path.join(tempdir, json_filename) + with open(targetfile, 'w') as f: + f.write(extra_target) + yield tempdir + finally: + # Reset extra targets + Target.set_targets_json_location() + # Delete temp files + shutil.rmtree(tempdir) + +def test_add_extra_targets(): + """Search for extra targets json in a source folder""" + test_target_json = """ + { + "Test_Target": { + "inherits": ["Target"] + } + } + """ + with temp_target_file(test_target_json) as source_dir: + Target.add_extra_targets(source_dir=source_dir) + update_target_data() + + assert 'Test_Target' in TARGET_MAP + assert TARGET_MAP['Test_Target'].core is None, \ + "attributes should be inherited from Target" + +def test_modify_existing_target(): + """Set default targets file, then override base Target definition""" + initial_target_json = """ + { + "Target": { + "core": null, + "default_toolchain": "ARM", + "supported_toolchains": null, + "extra_labels": [], + "is_disk_virtual": false, + "macros": [], + "device_has": [], + "features": [], + "detect_code": [], + "public": false, + "default_lib": "std", + "bootloader_supported": false + }, + "Test_Target": { + "inherits": ["Target"], + "core": "Cortex-M4", + "supported_toolchains": ["ARM"] + } + }""" + + test_target_json = """ + { + "Target": { + "core": "Cortex-M0", + "default_toolchain": "GCC_ARM", + "supported_toolchains": null, + "extra_labels": [], + "is_disk_virtual": false, + "macros": [], + "device_has": [], + "features": [], + "detect_code": [], + "public": false, + "default_lib": "std", + "bootloader_supported": true + } + } + """ - @contextmanager - def temp_target_file(self, extra_target, json_filename='custom_targets.json'): - """Create an extra targets temp file in a context manager""" - tempdir = tempfile.mkdtemp() - try: - targetfile = os.path.join(tempdir, json_filename) - with open(targetfile, 'w') as f: - f.write(extra_target) - yield tempdir - finally: - # Reset extra targets - Target.set_targets_json_location() - # Delete temp files - shutil.rmtree(tempdir) + with temp_target_file(initial_target_json, json_filename="targets.json") as targets_dir: + Target.set_targets_json_location(os.path.join(targets_dir, "targets.json")) + update_target_data() + assert TARGET_MAP["Test_Target"].core == "Cortex-M4" + assert TARGET_MAP["Test_Target"].default_toolchain == 'ARM' + assert TARGET_MAP["Test_Target"].bootloader_supported == False - def test_add_extra_targets(self): - """Search for extra targets json in a source folder""" - test_target_json = """ - { - "Test_Target": { - "inherits": ["Target"] - } - } - """ - with self.temp_target_file(test_target_json) as source_dir: + with temp_target_file(test_target_json) as source_dir: Target.add_extra_targets(source_dir=source_dir) update_target_data() - assert 'Test_Target' in TARGET_MAP - assert TARGET_MAP['Test_Target'].core is None, \ - "attributes should be inherited from Target" - - def test_modify_existing_target(self): - """Set default targets file, then override base Target definition""" - initial_target_json = """ - { - "Target": { - "core": null, - "default_toolchain": "ARM", - "supported_toolchains": null, - "extra_labels": [], - "is_disk_virtual": false, - "macros": [], - "device_has": [], - "features": [], - "detect_code": [], - "public": false, - "default_lib": "std", - "bootloader_supported": false - }, - "Test_Target": { - "inherits": ["Target"], - "core": "Cortex-M4", - "supported_toolchains": ["ARM"] - } - }""" - - test_target_json = """ - { - "Target": { - "core": "Cortex-M0", - "default_toolchain": "GCC_ARM", - "supported_toolchains": null, - "extra_labels": [], - "is_disk_virtual": false, - "macros": [], - "device_has": [], - "features": [], - "detect_code": [], - "public": false, - "default_lib": "std", - "bootloader_supported": true - } - } - """ - - with self.temp_target_file(initial_target_json, json_filename="targets.json") as targets_dir: - Target.set_targets_json_location(os.path.join(targets_dir, "targets.json")) - update_target_data() assert TARGET_MAP["Test_Target"].core == "Cortex-M4" - assert TARGET_MAP["Test_Target"].default_toolchain == 'ARM' - assert TARGET_MAP["Test_Target"].bootloader_supported == False - - with self.temp_target_file(test_target_json) as source_dir: - Target.add_extra_targets(source_dir=source_dir) - update_target_data() - - assert TARGET_MAP["Test_Target"].core == "Cortex-M4" - # The existing target should not be modified by custom targets - assert TARGET_MAP["Test_Target"].default_toolchain != 'GCC_ARM' - assert TARGET_MAP["Test_Target"].bootloader_supported != True - - -if __name__ == '__main__': - unittest.main() + # The existing target should not be modified by custom targets + assert TARGET_MAP["Test_Target"].default_toolchain != 'GCC_ARM' + assert TARGET_MAP["Test_Target"].bootloader_supported != True diff --git a/tools/test/test_api/test_api_test.py b/tools/test/test_api/test_api_test.py index 9f16941b04d..ef3a977c326 100644 --- a/tools/test/test_api/test_api_test.py +++ b/tools/test/test_api/test_api_test.py @@ -15,127 +15,79 @@ limitations under the License. """ -import unittest +import pytest from mock import patch +from tools.targets import set_targets_json_location from tools.test_api import find_tests, build_tests """ Tests for test_api.py """ -class TestApiTests(unittest.TestCase): +def setUp(self): """ - Test cases for Test Api + Called before each test case + + :return: + """ + self.base_dir = 'base_dir' + self.target = "K64F" + self.toolchain_name = "ARM" + +@pytest.mark.parametrize("base_dir", ["base_dir"]) +@pytest.mark.parametrize("target", ["K64F"]) +@pytest.mark.parametrize("toolchain_name", ["ARM"]) +@pytest.mark.parametrize("app_config", ["app_config", None]) +def test_find_tests_app_config(base_dir, target, toolchain_name, app_config): """ + Test find_tests for correct use of app_config - def setUp(self): - """ - Called before each test case - - :return: - """ - self.base_dir = 'base_dir' - self.target = "K64F" - self.toolchain_name = "ARM" - - def tearDown(self): - """ - Called after each test case - - :return: - """ - pass - - @patch('tools.test_api.scan_resources') - @patch('tools.test_api.prepare_toolchain') - def test_find_tests_app_config(self, mock_prepare_toolchain, mock_scan_resources): - """ - Test find_tests for correct use of app_config - - :param mock_prepare_toolchain: mock of function prepare_toolchain - :param mock_scan_resources: mock of function scan_resources - :return: - """ - app_config = "app_config" + :param base_dir: dummy value for the test base directory + :param target: the target to "test" for + :param toolchain_name: the toolchain to use for "testing" + :param app_config: Application configuration parameter to find tests + """ + set_targets_json_location() + with patch('tools.test_api.scan_resources') as mock_scan_resources,\ + patch('tools.test_api.prepare_toolchain') as mock_prepare_toolchain: mock_scan_resources().inc_dirs.return_value = [] - find_tests(self.base_dir, self.target, self.toolchain_name, app_config=app_config) + find_tests(base_dir, target, toolchain_name, app_config=app_config) args = mock_prepare_toolchain.call_args - self.assertTrue('app_config' in args[1], - "prepare_toolchain was not called with app_config") - self.assertEqual(args[1]['app_config'], app_config, - "prepare_toolchain was called with an incorrect app_config") - - @patch('tools.test_api.scan_resources') - @patch('tools.test_api.prepare_toolchain') - def test_find_tests_no_app_config(self, mock_prepare_toolchain, mock_scan_resources): - """ - Test find_tests correctly deals with no app_config - - :param mock_prepare_toolchain: mock of function prepare_toolchain - :param mock_scan_resources: mock of function scan_resources - :return: - """ - mock_scan_resources().inc_dirs.return_value = [] + assert 'app_config' in args[1],\ + "prepare_toolchain was not called with app_config" + assert args[1]['app_config'] == app_config,\ + "prepare_toolchain was called with an incorrect app_config" - find_tests(self.base_dir, self.target, self.toolchain_name) - args = mock_prepare_toolchain.call_args - self.assertTrue('app_config' in args[1], - "prepare_toolchain was not called with app_config") - self.assertEqual(args[1]['app_config'], None, - "prepare_toolchain was called with an incorrect app_config") - - @patch('tools.test_api.scan_resources') - @patch('tools.test_api.build_project') - def test_build_tests_app_config(self, mock_build_project, mock_scan_resources): - """ - Test build_tests for correct use of app_config - - :param mock_prepare_toolchain: mock of function prepare_toolchain - :param mock_scan_resources: mock of function scan_resources - :return: - """ - tests = {'test1': 'test1_path','test2': 'test2_path'} - src_paths = ['.'] - build_path = "build_path" - app_config = "app_config" - mock_build_project.return_value = "build_project" - - build_tests(tests, src_paths, build_path, self.target, self.toolchain_name, - app_config=app_config) +@pytest.mark.parametrize("build_path", ["build_path"]) +@pytest.mark.parametrize("target", ["K64F"]) +@pytest.mark.parametrize("toolchain_name", ["ARM"]) +@pytest.mark.parametrize("app_config", ["app_config", None]) +def test_find_tests_app_config(build_path, target, toolchain_name, app_config): + """ + Test find_tests for correct use of app_config - arg_list = mock_build_project.call_args_list - for args in arg_list: - self.assertTrue('app_config' in args[1], - "build_tests was not called with app_config") - self.assertEqual(args[1]['app_config'], app_config, - "build_tests was called with an incorrect app_config") - - @patch('tools.test_api.scan_resources') - @patch('tools.test_api.build_project') - def test_build_tests_no_app_config(self, mock_build_project, mock_scan_resources): - """ - Test build_tests correctly deals with no app_config - - :param mock_prepare_toolchain: mock of function prepare_toolchain - :param mock_scan_resources: mock of function scan_resources - :return: - """ - tests = {'test1': 'test1_path', 'test2': 'test2_path'} - src_paths = ['.'] - build_path = "build_path" + :param base_dir: dummy value for the test base directory + :param target: the target to "test" for + :param toolchain_name: the toolchain to use for "testing" + :param app_config: Application configuration parameter to find tests + """ + tests = {'test1': 'test1_path','test2': 'test2_path'} + src_paths = ['.'] + set_targets_json_location() + with patch('tools.test_api.scan_resources') as mock_scan_resources,\ + patch('tools.test_api.build_project') as mock_build_project: mock_build_project.return_value = "build_project" + mock_scan_resources().inc_dirs.return_value = [] - build_tests(tests, src_paths, build_path, self.target, self.toolchain_name) + build_tests(tests, src_paths, build_path, target, toolchain_name, + app_config=app_config) arg_list = mock_build_project.call_args_list for args in arg_list: - self.assertTrue('app_config' in args[1], - "build_tests was not called with app_config") - self.assertEqual(args[1]['app_config'], None, - "build_tests was called with an incorrect app_config") - -if __name__ == '__main__': - unittest.main() + assert 'app_config' in args[1],\ + "build_tests was not called with app_config" + assert args[1]['app_config'] == app_config,\ + "build_tests was called with an incorrect app_config" diff --git a/tools/test/toolchains/api.py b/tools/test/toolchains/api_test.py similarity index 100% rename from tools/test/toolchains/api.py rename to tools/test/toolchains/api_test.py diff --git a/tools/test_api.py b/tools/test_api.py index 70cc6d234d1..985c318e851 100644 --- a/tools/test_api.py +++ b/tools/test_api.py @@ -365,6 +365,7 @@ def execute_thread_slice(self, q, target, toolchains, clean, test_ids, build_rep 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) + stats_depth = self.opts.stats_depth or 2 try: @@ -481,23 +482,13 @@ def execute_thread_slice(self, q, target, toolchains, clean, test_ids, build_rep project_name = self.opts_firmware_global_name if self.opts_firmware_global_name else None try: - path = build_project(test.source_dir, - join(build_dir, test_id), - T, - toolchain, - test.dependencies, - clean=clean_project_options, - verbose=self.opts_verbose, - name=project_name, - macros=MACROS, - inc_dirs=INC_DIRS, - jobs=self.opts_jobs, - report=build_report, - properties=build_properties, - project_id=test_id, - project_description=test.get_description(), - build_profile=profile, - stats_depth=stats_depth) + path = build_project(test.source_dir, join(build_dir, test_id), T, + toolchain, test.dependencies, clean=clean_project_options, + verbose=self.opts_verbose, name=project_name, macros=MACROS, + inc_dirs=INC_DIRS, jobs=self.opts_jobs, report=build_report, + properties=build_properties, project_id=test_id, + project_description=test.get_description(), + build_profile=profile, stats_depth=stats_depth) except Exception, e: project_name_str = project_name if project_name is not None else test_id @@ -1988,6 +1979,12 @@ def get_default_test_options_parser(): default=False, action="store_true", help='Prints script version and exits') + + parser.add_argument('--stats-depth', + dest='stats_depth', + default=2, + type=int, + help="Depth level for static memory report") return parser def test_path_to_name(path, base): @@ -2198,9 +2195,10 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name, results.remove(r) # Take report from the kwargs and merge it into existing report - report_entry = worker_result['kwargs']['report'][target_name][toolchain_name] - for test_key in report_entry.keys(): - report[target_name][toolchain_name][test_key] = report_entry[test_key] + if report: + report_entry = worker_result['kwargs']['report'][target_name][toolchain_name] + for test_key in report_entry.keys(): + report[target_name][toolchain_name][test_key] = report_entry[test_key] # Set the overall result to a failure if a build failure occurred if ('reason' in worker_result and @@ -2224,7 +2222,8 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name, } test_key = worker_result['kwargs']['project_id'].upper() - print report[target_name][toolchain_name][test_key][0][0]['output'].rstrip() + if report: + print report[target_name][toolchain_name][test_key][0][0]['output'].rstrip() print 'Image: %s\n' % bin_file except: diff --git a/tools/toolchains/iar.py b/tools/toolchains/iar.py index c7b36ced10b..4e0d8e4d104 100644 --- a/tools/toolchains/iar.py +++ b/tools/toolchains/iar.py @@ -145,15 +145,16 @@ def get_config_option(self, config_header): def get_compile_options(self, defines, includes, for_asm=False): opts = ['-D%s' % d for d in defines] + if for_asm : + return opts if self.RESPONSE_FILES: opts += ['-f', self.get_inc_file(includes)] else: opts += ["-I%s" % i for i in includes] - if not for_asm: - config_header = self.get_config_header() - if config_header is not None: - opts = opts + self.get_config_option(config_header) + config_header = self.get_config_header() + if config_header is not None: + opts = opts + self.get_config_option(config_header) return opts @hook_tool