mirror of https://github.com/ARMmbed/mbed-os.git
Updated EMAC test environment for LPCxx boards
Updated EMAC memory manager to use libservice nsdynmemlib for EMAC memory buffers. Located the nsdynmemlib buffer heap to DMA safe memory bank on LPCxx boards. Optimized placement of static variables on EMAC test environment for LPCxx boards to maximize available memory.pull/7103/head
parent
66e3409a37
commit
9095b037aa
|
@ -27,6 +27,11 @@
|
||||||
|
|
||||||
#include "rtos/Mutex.h"
|
#include "rtos/Mutex.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "arm_hal_interrupt_private.h"
|
||||||
|
}
|
||||||
|
#include "nsdynmemLIB.h"
|
||||||
|
|
||||||
#include "EMACMemoryManager.h"
|
#include "EMACMemoryManager.h"
|
||||||
#include "emac_TestMemoryManager.h"
|
#include "emac_TestMemoryManager.h"
|
||||||
|
|
||||||
|
@ -43,12 +48,57 @@
|
||||||
|
|
||||||
char s_trace_buffer[100] = MEM_MNGR_TRACE;
|
char s_trace_buffer[100] = MEM_MNGR_TRACE;
|
||||||
|
|
||||||
|
/* For LPC boards define the heap memory bank ourselves to give us section placement
|
||||||
|
control */
|
||||||
|
#ifndef ETHMEM_SECTION
|
||||||
|
#if defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM)
|
||||||
|
# if defined (__ICCARM__)
|
||||||
|
# define ETHMEM_SECTION
|
||||||
|
# elif defined(TOOLCHAIN_GCC_CR)
|
||||||
|
# define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32")))
|
||||||
|
# else
|
||||||
|
# define ETHMEM_SECTION __attribute__((section("AHBSRAM1"),aligned))
|
||||||
|
# endif
|
||||||
|
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC1769)
|
||||||
|
# if defined (__ICCARM__)
|
||||||
|
# define ETHMEM_SECTION
|
||||||
|
# elif defined(TOOLCHAIN_GCC_CR)
|
||||||
|
# define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32")))
|
||||||
|
# else
|
||||||
|
# define ETHMEM_SECTION __attribute__((section("AHBSRAM0"),aligned))
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ETHMEM_SECTION
|
||||||
|
// Use nanostack libservice dynamic memory library
|
||||||
|
#define EMAC_HEAP_SIZE 16300
|
||||||
|
|
||||||
|
#if defined (__ICCARM__)
|
||||||
|
#pragma location = ".ethusbram"
|
||||||
|
#endif
|
||||||
|
ETHMEM_SECTION static unsigned char ns_heap[EMAC_HEAP_SIZE];
|
||||||
|
|
||||||
|
void emac_heap_error_handler(heap_fail_t event)
|
||||||
|
{
|
||||||
|
MBED_ASSERT(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
EmacTestMemoryManager::EmacTestMemoryManager()
|
EmacTestMemoryManager::EmacTestMemoryManager()
|
||||||
: m_mem_mutex(),
|
: m_mem_mutex(),
|
||||||
m_mem_buffers(),
|
m_mem_buffers(),
|
||||||
m_alloc_unit(BUF_POOL_SIZE),
|
m_alloc_unit(BUF_POOL_SIZE),
|
||||||
m_memory_available(true)
|
m_memory_available(true)
|
||||||
{
|
{
|
||||||
|
#ifdef ETHMEM_SECTION
|
||||||
|
static bool ns_heap_init = false;
|
||||||
|
if (!ns_heap_init) {
|
||||||
|
platform_critical_init(); // Create mutex for dynamic memory library
|
||||||
|
ns_dyn_mem_init(ns_heap, EMAC_HEAP_SIZE, emac_heap_error_handler, NULL);
|
||||||
|
ns_heap_init = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
emac_mem_buf_t *EmacTestMemoryManager::alloc_heap(uint32_t size, uint32_t align)
|
emac_mem_buf_t *EmacTestMemoryManager::alloc_heap(uint32_t size, uint32_t align)
|
||||||
|
@ -74,7 +124,11 @@ emac_mem_buf_t *EmacTestMemoryManager::alloc_heap(uint32_t size, uint32_t align,
|
||||||
|
|
||||||
CHECK_ASSERT(buf, "alloc_heap() no memory");
|
CHECK_ASSERT(buf, "alloc_heap() no memory");
|
||||||
|
|
||||||
|
#ifdef ETHMEM_SECTION
|
||||||
|
buf->buffer = ns_dyn_mem_alloc(BUF_HEAD_SIZE + size + align + BUF_TAIL_SIZE);
|
||||||
|
#else
|
||||||
buf->buffer = std::malloc(BUF_HEAD_SIZE + size + align + BUF_TAIL_SIZE);
|
buf->buffer = std::malloc(BUF_HEAD_SIZE + size + align + BUF_TAIL_SIZE);
|
||||||
|
#endif
|
||||||
|
|
||||||
CHECK_ASSERT(buf->buffer, "alloc_heap() no memory");
|
CHECK_ASSERT(buf->buffer, "alloc_heap() no memory");
|
||||||
|
|
||||||
|
@ -218,7 +272,12 @@ void EmacTestMemoryManager::free(emac_mem_buf_t *buf)
|
||||||
emac_memory_t *next = mem_buf->next;
|
emac_memory_t *next = mem_buf->next;
|
||||||
|
|
||||||
m_mem_buffers.erase(mem_buf_entry);
|
m_mem_buffers.erase(mem_buf_entry);
|
||||||
|
|
||||||
|
#ifdef ETHMEM_SECTION
|
||||||
|
ns_dyn_mem_free(mem_buf->buffer);
|
||||||
|
#else
|
||||||
std::free(mem_buf->buffer);
|
std::free(mem_buf->buffer);
|
||||||
|
#endif
|
||||||
delete mem_buf;
|
delete mem_buf;
|
||||||
|
|
||||||
mem_buf = next;
|
mem_buf = next;
|
||||||
|
|
|
@ -39,6 +39,18 @@ nsapi_error_t EmacTestNetworkStack::add_dns_server(const SocketAddress &address)
|
||||||
return NSAPI_ERROR_OK;
|
return NSAPI_ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsapi_error_t EmacTestNetworkStack::call_in(int delay, mbed::Callback<void()> func)
|
||||||
|
{
|
||||||
|
// Implemented as empty to save memory
|
||||||
|
return NSAPI_ERROR_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmacTestNetworkStack::call_in_callback_cb_t EmacTestNetworkStack::get_call_in_callback()
|
||||||
|
{
|
||||||
|
call_in_callback_cb_t cb(this, &EmacTestNetworkStack::call_in);
|
||||||
|
return cb;
|
||||||
|
}
|
||||||
|
|
||||||
nsapi_error_t EmacTestNetworkStack::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto)
|
nsapi_error_t EmacTestNetworkStack::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto)
|
||||||
{
|
{
|
||||||
return NSAPI_ERROR_OK;
|
return NSAPI_ERROR_OK;
|
||||||
|
|
|
@ -356,6 +356,38 @@ protected:
|
||||||
int optname, void *optval, unsigned *optlen);
|
int optname, void *optval, unsigned *optlen);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/** Call in callback
|
||||||
|
*
|
||||||
|
* Callback is used to call the call in method of the network stack.
|
||||||
|
*/
|
||||||
|
typedef mbed::Callback<nsapi_error_t (int delay_ms, mbed::Callback<void()> user_cb)> call_in_callback_cb_t;
|
||||||
|
|
||||||
|
/** Get a call in callback
|
||||||
|
*
|
||||||
|
* Get a call in callback from the network stack context.
|
||||||
|
*
|
||||||
|
* Callback should not take more than 10ms to execute, otherwise it might
|
||||||
|
* prevent underlying thread processing. A portable user of the callback
|
||||||
|
* should not make calls to network operations due to stack size limitations.
|
||||||
|
* The callback should not perform expensive operations such as socket recv/send
|
||||||
|
* calls or blocking operations.
|
||||||
|
*
|
||||||
|
* @return Call in callback
|
||||||
|
*/
|
||||||
|
virtual call_in_callback_cb_t get_call_in_callback();
|
||||||
|
|
||||||
|
/** Call a callback after a delay
|
||||||
|
*
|
||||||
|
* Call a callback from the network stack context after a delay. If function
|
||||||
|
* returns error callback will not be called.
|
||||||
|
*
|
||||||
|
* @param delay Delay in milliseconds
|
||||||
|
* @param func Callback to be called
|
||||||
|
* @return 0 on success, negative error code on failure
|
||||||
|
*/
|
||||||
|
virtual nsapi_error_t call_in(int delay, mbed::Callback<void()> func);
|
||||||
|
|
||||||
Interface *m_interface;
|
Interface *m_interface;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,32 @@
|
||||||
|
|
||||||
using namespace utest::v1;
|
using namespace utest::v1;
|
||||||
|
|
||||||
|
/* For LPC boards define the memory bank ourselves to give us section placement
|
||||||
|
control */
|
||||||
|
#ifndef ETHMEM_SECTION
|
||||||
|
#if defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM)
|
||||||
|
# if defined (__ICCARM__)
|
||||||
|
# define ETHMEM_SECTION
|
||||||
|
# elif defined(TOOLCHAIN_GCC_CR)
|
||||||
|
# define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32")))
|
||||||
|
# else
|
||||||
|
# define ETHMEM_SECTION __attribute__((section("AHBSRAM0"),aligned))
|
||||||
|
# endif
|
||||||
|
#elif defined(TARGET_LPC1768) || defined(TARGET_LPC1769)
|
||||||
|
# if defined (__ICCARM__)
|
||||||
|
# define ETHMEM_SECTION
|
||||||
|
# elif defined(TOOLCHAIN_GCC_CR)
|
||||||
|
# define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32")))
|
||||||
|
# else
|
||||||
|
# define ETHMEM_SECTION __attribute__((section("AHBSRAM1"),aligned))
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ETHMEM_SECTION
|
||||||
|
#define ETHMEM_SECTION
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int length;
|
int length;
|
||||||
int receipt_number;
|
int receipt_number;
|
||||||
|
@ -63,7 +89,12 @@ static int eth_mtu_size = 0;
|
||||||
// Event queue
|
// Event queue
|
||||||
static rtos::Semaphore worker_loop_semaphore;
|
static rtos::Semaphore worker_loop_semaphore;
|
||||||
static rtos::Semaphore link_status_semaphore;
|
static rtos::Semaphore link_status_semaphore;
|
||||||
static EventQueue worker_loop_event_queue(20 * EVENTS_EVENT_SIZE);
|
|
||||||
|
#if defined (__ICCARM__)
|
||||||
|
#pragma location = ".ethusbram"
|
||||||
|
#endif
|
||||||
|
ETHMEM_SECTION static EventQueue worker_loop_event_queue(20 * EVENTS_EVENT_SIZE);
|
||||||
|
|
||||||
static void worker_loop_event_cb(int event);
|
static void worker_loop_event_cb(int event);
|
||||||
static Event<void(int)> worker_loop_event(&worker_loop_event_queue, worker_loop_event_cb);
|
static Event<void(int)> worker_loop_event(&worker_loop_event_queue, worker_loop_event_cb);
|
||||||
static void link_input_event_cb(void *buf);
|
static void link_input_event_cb(void *buf);
|
||||||
|
@ -460,7 +491,11 @@ static void link_input_event_cb(void *buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char thread_stack[2048];
|
|
||||||
|
#if defined (__ICCARM__)
|
||||||
|
#pragma location = ".ethusbram"
|
||||||
|
#endif
|
||||||
|
ETHMEM_SECTION static unsigned char thread_stack[2048];
|
||||||
|
|
||||||
void worker_loop(void);
|
void worker_loop(void);
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ extern const unsigned char eth_mac_broadcast_addr[];
|
||||||
#define RESET_ERROR_FLAGS(flags) emac_if_reset_error_flags(flags)
|
#define RESET_ERROR_FLAGS(flags) emac_if_reset_error_flags(flags)
|
||||||
|
|
||||||
#define ETH_FRAME_HEADER_LEN 28
|
#define ETH_FRAME_HEADER_LEN 28
|
||||||
#define ETH_FRAME_MIN_LEN 60
|
#define ETH_FRAME_MIN_LEN 60 + 4
|
||||||
#define ETH_MAC_ADDR_LEN 6
|
#define ETH_MAC_ADDR_LEN 6
|
||||||
|
|
||||||
#define TIMEOUT 1
|
#define TIMEOUT 1
|
||||||
|
|
Loading…
Reference in New Issue