Merge pull request #5083 from ARMmbed/release-candidate

Release candidate for mbed-os-5.5.7
mbed-os-5.5 mbed_lib_rev151
Anna Bridge 2017-09-14 11:46:30 +01:00 committed by GitHub
commit ca661f9d28
216 changed files with 4354 additions and 1904 deletions

View File

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

View File

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

View File

@ -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
template<uint8_t thread_id, uint32_t wait_ms, uint32_t send_count>
void send_thread(Mail<mail_t, QUEUE_SIZE> *m)
{
uint32_t data = thread_id * DATA_BASE;
Mail<mail_t, QUEUE_SIZE> 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);
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");
Thread thread(osPriorityNormal, STACK_SIZE);
thread.start(send_thread);
bool result = true;
template<uint8_t thread_id, uint32_t queue_size, uint32_t wait_ms>
void receive_thread(Mail<mail_t, queue_size> *m)
{
int result_counter = 0;
uint32_t data = thread_id * DATA_BASE;
while (true) {
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;
// 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_t, QUEUE_SIZE> mail_box;
// mail send thread creation
Thread thread(osPriorityNormal, THREAD_STACK_SIZE);
thread.start(callback(send_thread<THREAD_1_ID, QUEUE_PUT_DELAY_1, QUEUE_SIZE>, &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 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_t, QUEUE_SIZE> 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<THREAD_1_ID, QUEUE_PUT_DELAY_1, 7>, &mail_box));
thread2.start(callback(send_thread<THREAD_2_ID, QUEUE_PUT_DELAY_2, 5>, &mail_box));
thread3.start(callback(send_thread<THREAD_3_ID, QUEUE_PUT_DELAY_3, 4>, &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_t, 4> 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<THREAD_1_ID, 4, 0>, mail_box + 1));
thread2.start(callback(receive_thread<THREAD_2_ID, 4, 10>, mail_box + 2));
thread3.start(callback(receive_thread<THREAD_3_ID, 4, 100>, 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<uint32_t, 4> 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<uint32_t, 4> 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<uint32_t, 4> 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<uint32_t, 4> 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<uint32_t, 4> 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<int32_t, 4> 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<uint32_t, 4> 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<typename T>
void test_data_type(void)
{
osStatus status;
Mail<T, 4> 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<uint32_t, 1> 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<uint8_t>),
Case("Test message type uint16", test_data_type<uint16_t>),
Case("Test message type uint32", test_data_type<uint32_t>),
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);
}

View File

@ -51,7 +51,7 @@ extern "C" {
#include <pthread.h>
#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;

View File

@ -798,7 +798,7 @@ public:
* @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.

View File

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

View File

@ -56,7 +56,7 @@ public:
*
* @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 @@ public:
/**
* Type for the registered callbacks added to the disconnection event
* callchain. Refer to Gap::onDisconnetion().
* callchain. Refer to Gap::onDisconnection().
*/
typedef FunctionPointerWithContext<const DisconnectionCallbackParams_t*> DisconnectionEventCallback_t;
/**
@ -447,7 +447,7 @@ public:
* @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 @@ public:
*
* @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) {

View File

@ -160,7 +160,7 @@ public:
}
/**
* Get The advertising timeout.
* Get the advertising timeout.
*
* @return The advertising timeout (in seconds).
*/

View File

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

View File

@ -395,7 +395,7 @@ public:
/**
* 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 @@ public:
* 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 @@ public:
}
/**
* 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 @@ public:
/**
* 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 @@ private:
/**
* 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 @@ public:
* @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 @@ public:
* @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 @@ public:
* @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 @@ public:
* 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 @@ public:
* 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 @@ public:
* 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.

View File

@ -109,7 +109,7 @@ public:
* @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) {

View File

@ -96,7 +96,7 @@ public:
* 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 @@ protected:
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<uint8_t, SIZEOF_CONTROL_BYTES> 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];

View File

@ -112,7 +112,7 @@ public:
* 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()) {

View File

@ -78,7 +78,7 @@ protected:
* 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()) {

View File

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

View File

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

View File

@ -1,6 +1,6 @@
{
"name": "mbed-coap",
"version": "4.0.9",
"version": "4.0.10",
"description": "COAP library",
"keywords": [
"coap",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -68,15 +68,15 @@ protected:
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 @@ private:
#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);

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
#if defined(TARGET_NUMAKER_PFM_M453)
#if defined(TARGET_M451)
#include "USBHAL.h"
#include "M451Series.h"

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

4
mbed.h
View File

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

View File

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

View File

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

View File

@ -24,7 +24,7 @@
#include <stdint.h>
#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 @@ private:
osTimerId_t _id;
osTimerAttr_t _attr;
os_timer_t _obj_mem;
mbed_rtos_storage_timer_t _obj_mem;
mbed::Callback<void()> _function;
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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_DRAM 0x30000000 0x1FFFFF{
_DRAM_CODE 0x30000000 0x1FFFFF{
}
}
LR_TCM 0x1FFF0000 0x10000 {
TCM_OVERLAY 0x1FFF0000 0x10000 {
*lwip_mem.o(.bss*)
*lwip_memp.o(.bss*)
*.o(.tcm.heap*)
}
}
LR_DRAM 0x30000000 0x200000 {
ER_DRAM +0 FIXED {
.ANY (+RO)
}
RW_DRAM1 +0 UNINIT FIXED {
.ANY (+RW)
}
RW_DRAM2 +0 UNINIT FIXED {
.ANY (+ZI)
}
}

View File

@ -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 <rt_misc.h>
#include <stdint.h>
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

View File

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

View File

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

View File

@ -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,
//section .data* object lib_peripheral_mbed_iar.a,
};
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.bss with fixed order {
section .bss*,
section COMMON,
section .bdsram.data*,
};
define block IMAGE2 with fixed order { block .image2.start.table1, block .image2.start.table2, block .ram_image2.text, block .ram.data };
define block IMAGE2 with fixed order {
block .sram1.text,
block .ram.data,
block .ram.bss
};
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};
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 __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;

View File

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

View File

@ -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 <cmsis_iar.h>
#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 = {
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_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)
{
// Override NMI Handler
NewVectorTable[2] = (VECTOR_Func) TRAP_NMIHandler;
#if defined ( __ICCARM__ )
NewVectorTable[3] = (VECTOR_Func) TRAP_HardFaultHandler_Patch;
#endif
}
INFRA_START_SECTION void PLAT_Init(void)
extern _LONG_CALL_ void * __rtl_memset_v1_00(void * m , int c , size_t n);
// Image2 Entry Function
void PLAT_Start(void)
{
uint32_t val;
//Set SPS lower voltage
#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
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
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 (;;);
}

View File

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

View File

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

View File

@ -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 <stdio.h>
#include <string.h>
#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(&region1);
OTA_GetImageInfo(&region2);
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);
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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();
}

View File

@ -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();
}

View File

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

View File

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

View File

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

View File

@ -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();
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -130,6 +130,7 @@ build_list = (
{ "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 @@ linking_list = [
}
},
{"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"],

View File

@ -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<addr>[0-9A-Fa-f]{8})\s+0x(?P<size>[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<addr>[0-9A-Fa-f]{8}),\s+Size: 0x(?P<size>[0-9A-Fa-f]+), .*\)$', line)
elif toolchain == "IAR":
# Section Kind Address Size Object
# ------- ---- ------- ---- ------
# "A3": 0x8470
# IMAGE2 0x10006000 0x5d18 <Block>
# .ram_image2.text 0x10006000 0x5bbc <Block>
# .rodata const 0x10006000 0x14 retarget.o [17]
match = re.match(r'^\s+' + section + \
r'\s+0x(?P<addr>[0-9A-Fa-f]{8})\s+0x(?P<size>[0-9A-Fa-f]+)\s+.*<Block>$', 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<addr>[0-9A-Fa-f]{8})'
if toolchain == "GCC_ARM":
img2_sections = [".image2.table", ".text", ".data"]
SYM = re.compile(r'^\s+' + HEX + r'\s+' + symbol + '\r?$')
elif toolchain in ["ARM_STD", "ARM", "ARM_MICRO"]:
img2_sections = [".image2.table", ".text", ".data"]
SYM = re.compile(r'^\s+' + HEX + r'\s+0x[0-9A-Fa-f]{8}\s+Code.*\s+i\.' + symbol + r'\s+.*$')
elif toolchain == "IAR":
# actually it's block
img2_sections = ["IMAGE2"]
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<offset>\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<addr>[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<size>[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":
return parse_load_segment_gcc(image_elf)
elif toolchain in ["ARM_STD", "ARM", "ARM_MICRO"]:
return parse_load_segment_armcc(image_elf)
elif toolchain == "IAR":
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'
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']
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)
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

View File

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

View File

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

View File

@ -0,0 +1,5 @@
{
"K64F": {
"exception_msg": "not found"
}
}

View File

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

View File

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

View File

@ -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 @@ See the License for the specific language governing permissions and
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
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
"""
Tests for config.py
"""
def compare_config(cfg, expected):
"""Compare the output of config against a dictionary of known good results
class ConfigTests(unittest.TestCase):
: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)
:param mock_json_file_to_dict: mock of function json_file_to_dict
:param _: mock of function _process_config_and_overrides (not tested)
:return:
"""
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 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")
assert config.app_config_data == {}
@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:
"""
@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")
assert config.app_config_data == mock_return
@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:
"""
@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

View File

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

View File

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

View File

@ -0,0 +1,5 @@
{
"K64F": {
"exception_msg": "Library name 'lib1' is not unique"
}
}

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