mirror of https://github.com/ARMmbed/mbed-os.git
Reactivate EMAC Greentea test (#378)
* Migrate emac test code into a library * Build passes now! * Fix STLINK bug, update README * Reduce verbosity a bit * Formatting * Fix licensespull/15530/head
parent
197e043d78
commit
e72b38a2be
|
@ -17,7 +17,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
@ -68,7 +68,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
@ -90,7 +90,7 @@ jobs:
|
|||
steps:
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
@ -143,7 +143,7 @@ jobs:
|
|||
steps:
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
|
@ -216,7 +216,7 @@ jobs:
|
|||
steps:
|
||||
-
|
||||
name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
@ -244,7 +244,7 @@ jobs:
|
|||
steps:
|
||||
-
|
||||
name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install python3-venv
|
||||
run: |
|
||||
|
|
|
@ -11,7 +11,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install python3-venv
|
||||
run: |
|
||||
|
|
|
@ -8,7 +8,7 @@ jobs:
|
|||
container: ghcr.io/armmbed/mbed-os-env:master-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Python packages
|
||||
# Note: pip>=20.3 is needed to install dependencies of cysecuretools
|
||||
|
|
|
@ -13,8 +13,9 @@ Arm Mbed OS is an open source embedded operating system designed specifically fo
|
|||
Mbed OS provides a platform that includes:
|
||||
|
||||
- Security foundations.
|
||||
- Cloud management services.
|
||||
- Drivers for sensors, I/O devices and connectivity.
|
||||
- Embedded networking libraries, e.g Wi-Fi and Ethernet drivers and network libraries using them
|
||||
- Drivers for microcontroller hardware features, including digital and analog I/O, PWM, and communications busses
|
||||
- Storage features, including file system and block device abstractions and low-level drivers
|
||||
|
||||
This is Mbed OS Community Edition (CE), a fork focused on improving the build system and tooling, fixing bugs, and keeping maintenance going after ARM's step back from the Mbed project.
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@ target_sources(mbed-nanostack-libservice
|
|||
source/nvmHelper/ns_nvm_helper.c
|
||||
)
|
||||
|
||||
target_link_libraries(mbed-nanostack-libservice PUBLIC mbed-nanostack-hal_mbed_cmsis_rtos)
|
||||
|
||||
# The definition, source files and include directories below
|
||||
# are needed by mbed-trace which is part of the mbed-core CMake target
|
||||
target_compile_definitions(mbed-core-flags
|
||||
|
|
|
@ -18,6 +18,14 @@
|
|||
#ifndef ARM_HAL_INTERRUPT_PRIVATE_H_
|
||||
#define ARM_HAL_INTERRUPT_PRIVATE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void platform_critical_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
# Copyright (c) 2020 ARM Limited. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
add_subdirectory(tests/emac_test_utils)
|
||||
|
||||
if(MBED_ENABLE_OS_INTERNAL_TESTS)
|
||||
if(MBED_BUILD_GREENTEA_TESTS)
|
||||
add_subdirectory(tests/TESTS)
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
add_subdirectory(emac)
|
||||
add_subdirectory(interface)
|
||||
add_subdirectory(wifi)
|
|
@ -1,23 +1,15 @@
|
|||
# Copyright (c) 2020 ARM Limited. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR)
|
||||
|
||||
set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../.. CACHE INTERNAL "")
|
||||
set(TEST_TARGET mbed-connectivity-netsocket-network-emac)
|
||||
|
||||
include(${MBED_PATH}/tools/cmake/mbed_greentea.cmake)
|
||||
|
||||
project(${TEST_TARGET})
|
||||
if(NOT "MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE=WIFI" IN_LIST MBED_CONFIG_DEFINITIONS AND
|
||||
NOT "MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE=ETHERNET" IN_LIST MBED_CONFIG_DEFINITIONS)
|
||||
set(TEST_SKIPPED "Requires wi-fi or ethernet to be the default network interface")
|
||||
endif()
|
||||
|
||||
list(
|
||||
APPEND
|
||||
TEST_SOURCE_LIST
|
||||
main.cpp
|
||||
emac_TestMemoryManager.cpp
|
||||
emac_TestNetworkStack.cpp
|
||||
emac_ctp.cpp
|
||||
emac_membuf.cpp
|
||||
emac_test_broadcast.cpp
|
||||
emac_test_initialize.cpp
|
||||
emac_test_memory.cpp
|
||||
|
@ -26,14 +18,16 @@ list(
|
|||
emac_test_unicast_burst.cpp
|
||||
emac_test_unicast_frame_len.cpp
|
||||
emac_test_unicast_long.cpp
|
||||
emac_util.cpp
|
||||
)
|
||||
|
||||
mbed_greentea_add_test(
|
||||
TEST_NAME
|
||||
${TEST_TARGET}
|
||||
mbed-connectivity-network-emac
|
||||
TEST_SOURCES
|
||||
${TEST_SOURCE_LIST}
|
||||
TEST_REQUIRED_LIBS
|
||||
mbed-emac
|
||||
mbed-netsocket
|
||||
mbed-emac-test-utils
|
||||
TEST_SKIPPED
|
||||
${TEST_SKIPPED}
|
||||
)
|
||||
|
|
|
@ -4,7 +4,7 @@ This document describes how to run EMAC tests. The EMAC test cases are made usin
|
|||
|
||||
## Configuring the CTP echo server
|
||||
|
||||
To configure a device to be a CTP echo server, you need to enable the `echo-server` setting in the `json` file of the test environment application. When you configure a device to be a CTP echo server, it starts to forward CTP messages automatically when it is on and continues to do so until you switch it off.
|
||||
To configure a device to be a CTP echo server, you need to flash it with the [mbed-ethernet-ctp-server](https://github.com/mbed-ce/mbed-ethernet-ctp-server) application. When you configure a device to be a CTP echo server, it starts to forward CTP messages automatically when it is on and continues to do so until you switch it off.
|
||||
|
||||
## Other configuration options
|
||||
|
||||
|
@ -56,28 +56,6 @@ Please refer to the following table for priorities of test cases. Priorities are
|
|||
|
||||
## Example commands
|
||||
|
||||
### CTP echo server
|
||||
|
||||
You can use the following command to a build CTP echo server:
|
||||
|
||||
`mbed test --compile -m TARGET -t GCC_ARM -v -n tests-network-emac --app-config TESTS/network/emac/template_mbed_app_echo_server.txt`
|
||||
|
||||
Replace TARGET with the target device. After building, flash the binary to the CTP echo server device.
|
||||
|
||||
You can verify that the CTP echo server has started properly by making a terminal connection to the device, resetting it and verifying that `echo server started successfully` prints on the terminal. You can run host tests when the CTP echo server is running on the Ethernet segment.
|
||||
|
||||
For Wi-Fi tests, the CTP echo server can also run on the ethernet side as long as the network configuration is such that Ethernet frames are routed between Wi-Fi and Ethernet.
|
||||
|
||||
The CTP echo server sends a 100-byte long broadcast CTP Ethernet frame every 60 seconds to inform the network of its presence.
|
||||
|
||||
### Running tests
|
||||
|
||||
You can use the following command to run tests:
|
||||
|
||||
`mbed test --compile --run -m TARGET -t GCC_ARM -v -n tests-network-emac --app-config TESTS/network/emac/template_mbed_app.txt`
|
||||
|
||||
Replace TARGET with the target device.
|
||||
|
||||
## Traces
|
||||
|
||||
Test cases have different trace levels based on how much tracing can be done without affecting the performance of the test case. Configure tracing using `SET\_TRACE\_LEVEL` macro.
|
||||
|
|
|
@ -1,229 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef EMAC_TEST_MEMORY_MANAGER_H
|
||||
#define EMAC_TEST_MEMORY_MANAGER_H
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "EMACMemoryManager.h"
|
||||
|
||||
#define MEM_CHECK 0x01
|
||||
#define MEM_NO_ALIGN 0x02
|
||||
|
||||
typedef struct emac_memory {
|
||||
struct emac_memory *next;
|
||||
void *buffer; /**< Pointer to allocated buffer */
|
||||
unsigned int orig_len; /**< Original buffer length (set_len() does not change) */
|
||||
unsigned int len; /**< Buffer length */
|
||||
void *ptr; /**< Aligned pointer */
|
||||
bool first;
|
||||
} emac_memory_t;
|
||||
|
||||
class EmacTestMemoryManager : public EMACMemoryManager {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates emac test memory manager
|
||||
*/
|
||||
EmacTestMemoryManager();
|
||||
|
||||
/*
|
||||
* Gets static instance
|
||||
*/
|
||||
static EmacTestMemoryManager &get_instance();
|
||||
|
||||
/**
|
||||
* Allocates memory buffer from the heap
|
||||
*
|
||||
* Memory buffer allocated from heap is always contiguous and can be arbitrary size.
|
||||
*
|
||||
* @param size Size of the memory to allocate in bytes
|
||||
* @param align Memory alignment requirement in bytes
|
||||
* @return Allocated memory buffer, or NULL in case of error
|
||||
*/
|
||||
virtual emac_mem_buf_t *alloc_heap(uint32_t size, uint32_t align);
|
||||
|
||||
/**
|
||||
* Allocates memory buffer from the heap
|
||||
*
|
||||
* Memory buffer allocated from heap is always contiguous and can be arbitrary size.
|
||||
*
|
||||
* @param size Size of the memory to allocate in bytes
|
||||
* @param align Memory alignment requirement in bytes
|
||||
* @param opt Options
|
||||
* @return Allocated memory buffer, or NULL in case of error
|
||||
*/
|
||||
emac_mem_buf_t *alloc_heap(uint32_t size, uint32_t align, uint8_t opt);
|
||||
|
||||
/**
|
||||
* Allocates memory buffer chain from a pool
|
||||
*
|
||||
* Memory allocated from pool is contiguous if size is equal or less than
|
||||
* (aligned) allocation unit, otherwise may be chained. Will typically come from
|
||||
* fixed-size packet pool memory.
|
||||
*
|
||||
* @param size Total size of the memory to allocate in bytes
|
||||
* @param align Memory alignment requirement for each buffer in bytes
|
||||
* @return Allocated memory buffer chain, or NULL in case of error
|
||||
*/
|
||||
virtual emac_mem_buf_t *alloc_pool(uint32_t size, uint32_t align);
|
||||
|
||||
/**
|
||||
* Allocates memory buffer chain from a pool
|
||||
*
|
||||
* Memory allocated from pool is contiguous if size is equal or less than
|
||||
* (aligned) allocation unit, otherwise may be chained. Will typically come from
|
||||
* fixed-size packet pool memory.
|
||||
*
|
||||
* @param size Total size of the memory to allocate in bytes
|
||||
* @param align Memory alignment requirement for each buffer in bytes
|
||||
* @param opt Options
|
||||
* @return Allocated memory buffer chain, or NULL in case of error
|
||||
*/
|
||||
emac_mem_buf_t *alloc_pool(uint32_t size, uint32_t align, uint8_t opt);
|
||||
|
||||
/**
|
||||
* Get memory buffer pool allocation unit
|
||||
*
|
||||
* Returns the maximum size of contiguous memory that can be allocated from a pool.
|
||||
*
|
||||
* @param align Memory alignment requirement in bytes
|
||||
* @return Contiguous memory size
|
||||
*/
|
||||
virtual uint32_t get_pool_alloc_unit(uint32_t align) const;
|
||||
|
||||
/**
|
||||
* Free memory buffer chain
|
||||
*
|
||||
* If memory buffer is chained must point to the start of the chain. Frees all buffers
|
||||
* from the chained list.
|
||||
*
|
||||
* @param buf Memory buffer chain to be freed.
|
||||
*/
|
||||
virtual void free(emac_mem_buf_t *buf);
|
||||
|
||||
/**
|
||||
* Return total length of a memory buffer chain
|
||||
*
|
||||
* Returns a total length of this buffer and any following buffers in the chain.
|
||||
*
|
||||
* @param buf Memory buffer chain
|
||||
* @return Total length in bytes
|
||||
*/
|
||||
virtual uint32_t get_total_len(const emac_mem_buf_t *buf) const;
|
||||
|
||||
/**
|
||||
* Copy a memory buffer chain
|
||||
*
|
||||
* Copies data from one buffer chain to another. Copy operation does not adjust the lengths
|
||||
* of the copied-to memory buffer chain, so chain total lengths must be the same.
|
||||
*
|
||||
* @param to_buf Memory buffer chain to copy to
|
||||
* @param from_buf Memory buffer chain to copy from
|
||||
*/
|
||||
virtual void copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_buf);
|
||||
|
||||
/**
|
||||
* Concatenate two memory buffer chains
|
||||
*
|
||||
* Concatenates buffer chain to end of the other buffer chain. Concatenated-to buffer total length
|
||||
* is adjusted accordingly. cat_buf must point to the start of a the chain. After concatenation
|
||||
* to_buf's chain now owns those buffers, and they will be freed when the to_buf chain is freed.
|
||||
*
|
||||
* @param to_buf Memory buffer chain to concatenate to
|
||||
* @param cat_buf Memory buffer chain to concatenate
|
||||
*/
|
||||
virtual void cat(emac_mem_buf_t *to_buf, emac_mem_buf_t *cat_buf);
|
||||
|
||||
/**
|
||||
* Returns the next buffer
|
||||
*
|
||||
* Returns the next buffer from the memory buffer chain.
|
||||
*
|
||||
* @param buf Memory buffer
|
||||
* @return The next memory buffer, or NULL if last
|
||||
*/
|
||||
virtual emac_mem_buf_t *get_next(const emac_mem_buf_t *buf) const;
|
||||
|
||||
/**
|
||||
* Return pointer to the payload of the buffer
|
||||
*
|
||||
* @param buf Memory buffer
|
||||
* @return Pointer to the payload
|
||||
*/
|
||||
virtual void *get_ptr(const emac_mem_buf_t *buf) const;
|
||||
|
||||
/**
|
||||
* Return payload size of the buffer
|
||||
*
|
||||
* @param buf Memory buffer
|
||||
* @return Size in bytes
|
||||
*/
|
||||
virtual uint32_t get_len(const emac_mem_buf_t *buf) const;
|
||||
|
||||
/**
|
||||
* Sets the payload size of the buffer
|
||||
*
|
||||
* The allocated payload size will not change. It is not permitted
|
||||
* to change the length of a buffer that is not the first (or only) in a chain.
|
||||
*
|
||||
* @param buf Memory buffer
|
||||
* @param len Payload size, must be less or equal allocated size
|
||||
*/
|
||||
virtual void set_len(emac_mem_buf_t *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* Sets memory buffer pool allocation unit
|
||||
*
|
||||
* Sets the maximum size of contiguous memory that can be allocated from a pool.
|
||||
*
|
||||
* @param alloc_unit Contiguous memory size
|
||||
*/
|
||||
virtual void set_alloc_unit(uint32_t alloc_unit);
|
||||
|
||||
/**
|
||||
* Sets whether memory is available
|
||||
*
|
||||
* Can be used to disable memory allocation request from emac.
|
||||
*
|
||||
* @param memory True if memory is available
|
||||
*/
|
||||
void set_memory_available(bool memory);
|
||||
|
||||
/**
|
||||
* Gets memory statistics
|
||||
*
|
||||
* Gets memory usage statistics
|
||||
*
|
||||
* @param buffers Number of buffers that are reserved
|
||||
* @param memory Reserved memory in bytes
|
||||
*/
|
||||
void get_memory_statistics(int *buffers, int *memory);
|
||||
|
||||
private:
|
||||
void validate_list() const;
|
||||
template <typename TYPE> void check_value(TYPE value, const char *fmt, ...) const;
|
||||
bool validate_ptr(const emac_mem_buf_t *buf) const;
|
||||
void check_align(uint32_t align) const;
|
||||
mutable rtos::Mutex m_mem_mutex;
|
||||
std::list<emac_memory_t *> m_mem_buffers;
|
||||
unsigned int m_alloc_unit;
|
||||
bool m_memory_available;
|
||||
};
|
||||
|
||||
#endif /* EMAC_TEST_MEMORY_MANAGER_H */
|
|
@ -1,411 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef EMAC_TEST_NETWORK_STACK_H
|
||||
#define EMAC_TEST_NETWORK_STACK_H
|
||||
|
||||
#include "netsocket/nsapi_types.h"
|
||||
#include "netsocket/EMAC.h"
|
||||
#include "netsocket/OnboardNetworkStack.h"
|
||||
|
||||
#include "emac_TestMemoryManager.h"
|
||||
|
||||
class EmacTestNetworkStack : public OnboardNetworkStack, private mbed::NonCopyable<EmacTestNetworkStack> {
|
||||
public:
|
||||
|
||||
static EmacTestNetworkStack &get_instance();
|
||||
|
||||
EmacTestNetworkStack();
|
||||
virtual ~EmacTestNetworkStack() {}
|
||||
|
||||
class Interface : public OnboardNetworkStack::Interface {
|
||||
public:
|
||||
|
||||
static Interface &get_instance();
|
||||
|
||||
/** Connect the interface to the network
|
||||
*
|
||||
* Sets up a connection on specified network interface, using DHCP or provided network details. If the @a dhcp is set to
|
||||
* true all the remaining parameters are ignored.
|
||||
*
|
||||
* @param dhcp true if the network details should be acquired using DHCP
|
||||
* @param ip IP address to be used for the interface as "W:X:Y:Z" or NULL
|
||||
* @param netmask Net mask to be used for the interface as "W:X:Y:Z" or NULL
|
||||
* @param gw Gateway address to be used for the interface as "W:X:Y:Z" or NULL
|
||||
* @param stack Allow manual selection of IPv4 and/or IPv6.
|
||||
* @param blocking Specify whether bringup blocks for connection completion.
|
||||
* @return NSAPI_ERROR_OK on success, or error code
|
||||
*/
|
||||
virtual nsapi_error_t bringup(bool dhcp, const char *ip,
|
||||
const char *netmask, const char *gw,
|
||||
nsapi_ip_stack_t stack = DEFAULT_STACK,
|
||||
bool blocking = true
|
||||
);
|
||||
|
||||
/** Disconnect interface from the network
|
||||
*
|
||||
* After this call the network interface is inactive, to use it again user needs to call @a mbed_ipstack_bringup again.
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success, or error code
|
||||
*/
|
||||
virtual nsapi_error_t bringdown();
|
||||
|
||||
/** Register callback for status reporting
|
||||
*
|
||||
* The specified status callback function will be called on status changes
|
||||
* on the network. The parameters on the callback are the event type and
|
||||
* event-type dependent reason parameter.
|
||||
*
|
||||
* @param status_cb The callback for status changes
|
||||
*/
|
||||
virtual void attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb);
|
||||
|
||||
/** Get the connection status
|
||||
*
|
||||
* @return The connection status according to ConnectionStatusType
|
||||
*/
|
||||
virtual nsapi_connection_status_t get_connection_status() const;
|
||||
|
||||
/** Return MAC address of the network interface
|
||||
*
|
||||
* @return MAC address as "V:W:X:Y:Z"
|
||||
*/
|
||||
virtual char *get_mac_address(char *buf, nsapi_size_t buflen);
|
||||
|
||||
/** Set MAC address on the network interface
|
||||
*
|
||||
* @param mac_addr Buffer containing the MAC address in hexadecimal format.
|
||||
* @param addr_len Length of provided buffer in bytes (6 or 8)
|
||||
* @retval NSAPI_ERROR_OK on success
|
||||
* @retval NSAPI_ERROR_UNSUPPORTED if this feature is not supported
|
||||
* @retval NSAPI_ERROR_PARAMETER if address is not valid
|
||||
* @retval NSAPI_ERROR_BUSY if address can't be set.
|
||||
*/
|
||||
virtual nsapi_error_t set_mac_address(uint8_t *mac_addr, nsapi_size_t addr_len);
|
||||
|
||||
/** Copies IP address of the network interface to user supplied buffer
|
||||
*
|
||||
* @param buf buffer to which IP address will be copied as "W:X:Y:Z"
|
||||
* @param buflen size of supplied buffer
|
||||
* @return Pointer to a buffer, or NULL if the buffer is too small
|
||||
*/
|
||||
virtual nsapi_error_t get_ip_address(SocketAddress *address);
|
||||
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.15", "String-based APIs are deprecated")
|
||||
virtual char *get_ip_address(char *buf, nsapi_size_t buflen);
|
||||
|
||||
/** Copies netmask of the network interface to user supplied buffer
|
||||
*
|
||||
* @param buf buffer to which netmask will be copied as "W:X:Y:Z"
|
||||
* @param buflen size of supplied buffer
|
||||
* @return Pointer to a buffer, or NULL if the buffer is too small
|
||||
*/
|
||||
virtual nsapi_error_t get_netmask(SocketAddress *address);
|
||||
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.15", "String-based APIs are deprecated")
|
||||
virtual char *get_netmask(char *buf, nsapi_size_t buflen);
|
||||
|
||||
/** Copies gateway address of the network interface to user supplied buffer
|
||||
*
|
||||
* @param buf buffer to which gateway address will be copied as "W:X:Y:Z"
|
||||
* @param buflen size of supplied buffer
|
||||
* @return Pointer to a buffer, or NULL if the buffer is too small
|
||||
*/
|
||||
virtual nsapi_error_t get_gateway(SocketAddress *address);
|
||||
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.15", "String-based APIs are deprecated")
|
||||
virtual char *get_gateway(char *buf, nsapi_size_t buflen);
|
||||
|
||||
private:
|
||||
friend EmacTestNetworkStack;
|
||||
|
||||
Interface();
|
||||
|
||||
EMAC *m_emac;
|
||||
};
|
||||
|
||||
/** Register a network interface with the IP stack
|
||||
*
|
||||
* Connects EMAC layer with the IP stack and initializes all the required infrastructure.
|
||||
* This function should be called only once for each available interface.
|
||||
*
|
||||
* @param emac EMAC HAL implementation for this network interface
|
||||
* @param default_if true if the interface should be treated as the default one
|
||||
* @param[out] interface_out pointer to stack interface object controlling the EMAC
|
||||
* @return NSAPI_ERROR_OK on success, or error code
|
||||
*/
|
||||
virtual nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out, NetworkInterface *user_network_interface);
|
||||
|
||||
/** Translates a hostname to an IP address with specific version
|
||||
*
|
||||
* The hostname may be either a domain name or an IP address. If the
|
||||
* hostname is an IP address, no network transactions will be performed.
|
||||
*
|
||||
* If no stack-specific DNS resolution is provided, the hostname
|
||||
* will be resolve using a UDP socket on the stack.
|
||||
*
|
||||
* @param host Hostname to resolve
|
||||
* @param address Destination for the host SocketAddress
|
||||
* @param version IP version of address to resolve, NSAPI_UNSPEC indicates
|
||||
* version is chosen by the stack (defaults to NSAPI_UNSPEC)
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t gethostbyname(const char *host,
|
||||
SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC);
|
||||
|
||||
/** Add a domain name server to list of servers to query
|
||||
*
|
||||
* @param address Destination for the host address
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t add_dns_server(const SocketAddress &address);
|
||||
|
||||
protected:
|
||||
|
||||
/** Opens a socket
|
||||
*
|
||||
* Creates a network socket and stores it in the specified handle.
|
||||
* The handle must be passed to following calls on the socket.
|
||||
*
|
||||
* A stack may have a finite number of sockets, in this case
|
||||
* NSAPI_ERROR_NO_SOCKET is returned if no socket is available.
|
||||
*
|
||||
* @param handle Destination for the handle to a newly created socket
|
||||
* @param proto Protocol of socket to open, NSAPI_TCP or NSAPI_UDP
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto);
|
||||
|
||||
/** Close the socket
|
||||
*
|
||||
* Closes any open connection and deallocates any memory associated
|
||||
* with the socket.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t socket_close(nsapi_socket_t handle);
|
||||
|
||||
/** Bind a specific address to a socket
|
||||
*
|
||||
* Binding a socket specifies the address and port on which to receive
|
||||
* data. If the IP address is zeroed, only the port is bound.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param address Local address to bind
|
||||
* @return 0 on success, negative error code on failure.
|
||||
*/
|
||||
virtual nsapi_error_t socket_bind(nsapi_socket_t handle, const SocketAddress &address);
|
||||
|
||||
/** Listen for connections on a TCP socket
|
||||
*
|
||||
* Marks the socket as a passive socket that can be used to accept
|
||||
* incoming connections.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param backlog Number of pending connections that can be queued
|
||||
* simultaneously
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t socket_listen(nsapi_socket_t handle, int backlog);
|
||||
|
||||
/** Connects TCP socket to a remote host
|
||||
*
|
||||
* Initiates a connection to a remote server specified by the
|
||||
* indicated address.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param address The SocketAddress of the remote host
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t socket_connect(nsapi_socket_t handle, const SocketAddress &address);
|
||||
|
||||
/** Accepts a connection on a TCP socket
|
||||
*
|
||||
* The server socket must be bound and set to listen for connections.
|
||||
* On a new connection, creates a network socket and stores it in the
|
||||
* specified handle. The handle must be passed to following calls on
|
||||
* the socket.
|
||||
*
|
||||
* A stack may have a finite number of sockets, in this case
|
||||
* NSAPI_ERROR_NO_SOCKET is returned if no socket is available.
|
||||
*
|
||||
* This call is non-blocking. If accept would block,
|
||||
* NSAPI_ERROR_WOULD_BLOCK is returned immediately.
|
||||
*
|
||||
* @param server Socket handle to server to accept from
|
||||
* @param handle Destination for a handle to the newly created socket
|
||||
* @param address Destination for the remote address or NULL
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t socket_accept(nsapi_socket_t server,
|
||||
nsapi_socket_t *handle, SocketAddress *address = 0);
|
||||
|
||||
/** Send data over a TCP socket
|
||||
*
|
||||
* The socket must be connected to a remote host. Returns the number of
|
||||
* bytes sent from the buffer.
|
||||
*
|
||||
* This call is non-blocking. If send would block,
|
||||
* NSAPI_ERROR_WOULD_BLOCK is returned immediately.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param data Buffer of data to send to the host
|
||||
* @param size Size of the buffer in bytes
|
||||
* @return Number of sent bytes on success, negative error
|
||||
* code on failure
|
||||
*/
|
||||
virtual nsapi_size_or_error_t socket_send(nsapi_socket_t handle,
|
||||
const void *data, nsapi_size_t size);
|
||||
|
||||
/** Receive data over a TCP socket
|
||||
*
|
||||
* The socket must be connected to a remote host. Returns the number of
|
||||
* bytes received into the buffer.
|
||||
*
|
||||
* This call is non-blocking. If recv would block,
|
||||
* NSAPI_ERROR_WOULD_BLOCK is returned immediately.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param data Destination buffer for data received from the host
|
||||
* @param size Size of the buffer in bytes
|
||||
* @return Number of received bytes on success, negative error
|
||||
* code on failure
|
||||
*/
|
||||
virtual nsapi_size_or_error_t socket_recv(nsapi_socket_t handle,
|
||||
void *data, nsapi_size_t size);
|
||||
|
||||
/** Send a packet over a UDP socket
|
||||
*
|
||||
* Sends data to the specified address. Returns the number of bytes
|
||||
* sent from the buffer.
|
||||
*
|
||||
* This call is non-blocking. If sendto would block,
|
||||
* NSAPI_ERROR_WOULD_BLOCK is returned immediately.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param address The SocketAddress of the remote host
|
||||
* @param data Buffer of data to send to the host
|
||||
* @param size Size of the buffer in bytes
|
||||
* @return Number of sent bytes on success, negative error
|
||||
* code on failure
|
||||
*/
|
||||
virtual nsapi_size_or_error_t socket_sendto(nsapi_socket_t handle, const SocketAddress &address,
|
||||
const void *data, nsapi_size_t size);
|
||||
|
||||
/** Receive a packet over a UDP socket
|
||||
*
|
||||
* Receives data and stores the source address in address if address
|
||||
* is not NULL. Returns the number of bytes received into the buffer.
|
||||
*
|
||||
* This call is non-blocking. If recvfrom would block,
|
||||
* NSAPI_ERROR_WOULD_BLOCK is returned immediately.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param address Destination for the source address or NULL
|
||||
* @param buffer Destination buffer for data received from the host
|
||||
* @param size Size of the buffer in bytes
|
||||
* @return Number of received bytes on success, negative error
|
||||
* code on failure
|
||||
*/
|
||||
virtual nsapi_size_or_error_t socket_recvfrom(nsapi_socket_t handle, SocketAddress *address,
|
||||
void *buffer, nsapi_size_t size);
|
||||
|
||||
/** Register a callback on state change of the socket
|
||||
*
|
||||
* The specified callback will be called on state changes such as when
|
||||
* the socket can recv/send/accept successfully and on when an error
|
||||
* occurs. The callback may also be called spuriously without reason.
|
||||
*
|
||||
* The callback may be called in an interrupt context and should not
|
||||
* perform expensive operations such as recv/send calls.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param callback Function to call on state change
|
||||
* @param data Argument to pass to callback
|
||||
*/
|
||||
virtual void socket_attach(nsapi_socket_t handle, void (*callback)(void *), void *data);
|
||||
|
||||
/* Set stack-specific socket options
|
||||
*
|
||||
* The setsockopt allow an application to pass stack-specific hints
|
||||
* to the underlying stack. For unsupported options,
|
||||
* NSAPI_ERROR_UNSUPPORTED is returned and the socket is unmodified.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param level Stack-specific protocol level
|
||||
* @param optname Stack-specific option identifier
|
||||
* @param optval Option value
|
||||
* @param optlen Length of the option value
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t setsockopt(nsapi_socket_t handle, int level,
|
||||
int optname, const void *optval, unsigned optlen);
|
||||
|
||||
/* Get stack-specific socket options
|
||||
*
|
||||
* The getstackopt allow an application to retrieve stack-specific hints
|
||||
* from the underlying stack. For unsupported options,
|
||||
* NSAPI_ERROR_UNSUPPORTED is returned and optval is unmodified.
|
||||
*
|
||||
* @param handle Socket handle
|
||||
* @param level Stack-specific protocol level
|
||||
* @param optname Stack-specific option identifier
|
||||
* @param optval Destination for option value
|
||||
* @param optlen Length of the option value
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t getsockopt(nsapi_socket_t handle, int level,
|
||||
int optname, void *optval, unsigned *optlen);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#endif /* EMAC_TEST_NETWORK_STACK_H */
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef EMAC_INITIALIZE_H
|
||||
#define EMAC_INITIALIZE_H
|
||||
|
||||
unsigned char *emac_if_get_hw_addr(void);
|
||||
bool emac_if_init(EMAC *emac);
|
||||
EMAC *emac_if_get(void);
|
||||
EmacTestMemoryManager *emac_m_mngr_get(void);
|
||||
|
||||
#endif /* EMAC_INITIALIZE_H */
|
|
@ -93,7 +93,7 @@ void test_emac_broadcast(void)
|
|||
RESET_ALL_ERROR_FLAGS;
|
||||
SET_TRACE_LEVEL(TRACE_SEND | TRACE_ETH_FRAMES | TRACE_SUCCESS | TRACE_FAILURE);
|
||||
|
||||
START_TEST_LOOP(test_emac_broadcast_cb, 1 * SECOND_TO_MS);
|
||||
START_TEST_LOOP(test_emac_broadcast_cb, 1s);
|
||||
|
||||
PRINT_ERROR_FLAGS;
|
||||
TEST_ASSERT_FALSE(ERROR_FLAGS);
|
||||
|
|
|
@ -16,54 +16,25 @@
|
|||
*/
|
||||
#if defined(MBED_CONF_RTOS_PRESENT)
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "mbed.h"
|
||||
#include "mbed_stats.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
|
||||
#include "NetworkInterface.h"
|
||||
#include "EMAC.h"
|
||||
#include "EMACMemoryManager.h"
|
||||
#include "emac_TestMemoryManager.h"
|
||||
#include "emac_TestNetworkStack.h"
|
||||
#include "emac_initialize.h"
|
||||
#include "EmacTestNetworkStack.h"
|
||||
#include "emac_tests.h"
|
||||
#include "emac_util.h"
|
||||
#include "greentea_get_network_interface.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
static unsigned char eth_mac_addr[ETH_MAC_ADDR_LEN];
|
||||
EMAC *emac_handle = NULL;
|
||||
|
||||
void test_emac_initialize()
|
||||
{
|
||||
worker_loop_init();
|
||||
|
||||
static NetworkInterface *network_interface = NetworkInterface::get_default_instance();
|
||||
|
||||
#define WIFI 2
|
||||
#if MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE == WIFI
|
||||
#if MBED_CONF_APP_WIFI_SCAN
|
||||
WiFiAccessPoint ap[30];
|
||||
|
||||
int size = network_interface->wifiInterface()->scan(ap, 30);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
const char *ssid = ap[i].get_ssid();
|
||||
nsapi_security_t security = ap[i].get_security();
|
||||
int8_t rssi = ap[i].get_rssi();
|
||||
char ch = ap[i].get_channel();
|
||||
|
||||
printf("BS %i\r\n", i);
|
||||
printf("ssid %s\r\n", ssid);
|
||||
printf("security %i\r\n", security);
|
||||
printf("rssi %i\r\n", rssi);
|
||||
printf("ch %i\r\n\r\n", ch);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
static NetworkInterface *network_interface = get_network_interface();
|
||||
|
||||
// Power up the interface and emac driver
|
||||
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, network_interface->connect());
|
||||
|
@ -71,51 +42,4 @@ void test_emac_initialize()
|
|||
worker_loop_link_up_wait();
|
||||
}
|
||||
|
||||
unsigned char *emac_if_get_hw_addr(void)
|
||||
{
|
||||
return ð_mac_addr[0];
|
||||
}
|
||||
|
||||
EMAC *emac_if_get(void)
|
||||
{
|
||||
return emac_handle;
|
||||
}
|
||||
|
||||
EmacTestMemoryManager *emac_m_mngr_get(void)
|
||||
{
|
||||
return &EmacTestMemoryManager::get_instance();
|
||||
}
|
||||
|
||||
bool emac_if_init(EMAC *emac)
|
||||
{
|
||||
emac_handle = emac;
|
||||
|
||||
emac->set_link_input_cb(emac_if_link_input_cb);
|
||||
emac->set_link_state_cb(emac_if_link_state_change_cb);
|
||||
|
||||
if (!emac->power_up()) {
|
||||
TEST_ASSERT_MESSAGE(0, "emac power up failed!");
|
||||
}
|
||||
|
||||
int hwaddr_len = emac->get_hwaddr_size();
|
||||
printf("emac hwaddr length %i\r\n\r\n", hwaddr_len);
|
||||
|
||||
TEST_ASSERT_MESSAGE(hwaddr_len == 6, "invalid emac hwaddr length!");
|
||||
|
||||
// If driver updates this, write it back, otherwise write default from mbed_mac_address
|
||||
mbed_mac_address(reinterpret_cast<char *>(ð_mac_addr[0]));
|
||||
emac->get_hwaddr(eth_mac_addr);
|
||||
emac->set_hwaddr(eth_mac_addr);
|
||||
printf("emac hwaddr %x:%x:%x:%x:%x:%x\r\n\r\n", eth_mac_addr[0], eth_mac_addr[1], eth_mac_addr[2], eth_mac_addr[3], eth_mac_addr[4], eth_mac_addr[5]);
|
||||
|
||||
int mtu_size = emac->get_mtu_size();
|
||||
printf("emac mtu %i\r\n\r\n", mtu_size);
|
||||
emac_if_set_mtu_size(mtu_size);
|
||||
|
||||
char hw_name[11];
|
||||
emac->get_ifname(hw_name, 10);
|
||||
printf("emac if name %s\r\n\r\n", hw_name);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif // defined(MBED_CONF_RTOS_PRESENT)
|
||||
|
|
|
@ -152,10 +152,10 @@ void test_emac_memory_cb(int opt)
|
|||
void test_emac_memory()
|
||||
{
|
||||
RESET_ALL_ERROR_FLAGS;
|
||||
SET_TRACE_LEVEL(TRACE_SEND | TRACE_SUCCESS | TRACE_FAILURE);
|
||||
SET_TRACE_LEVEL(TRACE_FAILURE);
|
||||
|
||||
if (ECHO_SERVER_ADDRESS_KNOWN) {
|
||||
START_TEST_LOOP(test_emac_memory_cb, 100);
|
||||
START_TEST_LOOP(test_emac_memory_cb, 100ms);
|
||||
}
|
||||
|
||||
PRINT_ERROR_FLAGS;
|
||||
|
|
|
@ -45,7 +45,7 @@ void test_emac_multicast_filter_cb(int opt)
|
|||
case 0:
|
||||
printf("STEP 0: check unicast message functionality\r\n\r\n");
|
||||
{
|
||||
unsigned char *own_addr = emac_if_get_own_addr();
|
||||
unsigned char const *own_addr = emac_if_get_own_addr();
|
||||
memcpy(forward_addr, own_addr, 6);
|
||||
}
|
||||
receive = true;
|
||||
|
@ -165,7 +165,7 @@ void test_emac_multicast_filter()
|
|||
SET_TRACE_LEVEL(TRACE_SEND | TRACE_ETH_FRAMES | TRACE_SUCCESS | TRACE_FAILURE);
|
||||
|
||||
if (ECHO_SERVER_ADDRESS_KNOWN) {
|
||||
START_TEST_LOOP(test_emac_multicast_filter_cb, 1 * SECOND_TO_MS);
|
||||
START_TEST_LOOP(test_emac_multicast_filter_cb, 1s);
|
||||
}
|
||||
|
||||
PRINT_ERROR_FLAGS;
|
||||
|
|
|
@ -69,7 +69,7 @@ void test_emac_unicast()
|
|||
SET_TRACE_LEVEL(TRACE_SEND | TRACE_ETH_FRAMES | TRACE_SUCCESS | TRACE_FAILURE);
|
||||
|
||||
if (ECHO_SERVER_ADDRESS_KNOWN) {
|
||||
START_TEST_LOOP(test_emac_unicast_cb, 1 * SECOND_TO_MS);
|
||||
START_TEST_LOOP(test_emac_unicast_cb, 1ms);
|
||||
}
|
||||
|
||||
PRINT_ERROR_FLAGS;
|
||||
|
|
|
@ -78,7 +78,7 @@ void test_emac_unicast_burst()
|
|||
SET_TRACE_LEVEL(TRACE_SEND | TRACE_SUCCESS | TRACE_FAILURE);
|
||||
|
||||
if (ECHO_SERVER_ADDRESS_KNOWN) {
|
||||
START_TEST_LOOP(test_emac_unicast_burst_cb, 100);
|
||||
START_TEST_LOOP(test_emac_unicast_burst_cb, 100ms);
|
||||
}
|
||||
|
||||
PRINT_ERROR_FLAGS;
|
||||
|
|
|
@ -73,7 +73,7 @@ void test_emac_unicast_frame_len()
|
|||
SET_TRACE_LEVEL(TRACE_SEND | TRACE_SUCCESS | TRACE_FAILURE);
|
||||
|
||||
if (ECHO_SERVER_ADDRESS_KNOWN) {
|
||||
START_TEST_LOOP(test_emac_unicast_frame_len_cb, 100);
|
||||
START_TEST_LOOP(test_emac_unicast_frame_len_cb, 100ms);
|
||||
}
|
||||
|
||||
PRINT_ERROR_FLAGS;
|
||||
|
|
|
@ -75,7 +75,7 @@ void test_emac_unicast_long()
|
|||
SET_TRACE_LEVEL(TRACE_FAILURE);
|
||||
|
||||
if (ECHO_SERVER_ADDRESS_KNOWN) {
|
||||
START_TEST_LOOP(test_emac_unicast_long_cb, 1);
|
||||
START_TEST_LOOP(test_emac_unicast_long_cb, 1ms);
|
||||
}
|
||||
|
||||
PRINT_ERROR_FLAGS;
|
||||
|
|
|
@ -18,40 +18,28 @@
|
|||
#error [NOT_SUPPORTED] EMAC test cases require a RTOS to run
|
||||
#else
|
||||
|
||||
#if !defined(MBED_CONF_APP_ECHO_SERVER) || \
|
||||
!defined(MBED_CONF_APP_ECHO_SERVER_TRACE) || \
|
||||
!defined(MBED_CONF_APP_WIFI_SCAN)
|
||||
#error [NOT_SUPPORTED] Requires parameters from mbed_app.json
|
||||
#else
|
||||
|
||||
#define ETHERNET 1
|
||||
#define WIFI 2
|
||||
|
||||
#if MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE != ETHERNET && \
|
||||
MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE != WIFI
|
||||
#error [NOT_SUPPORTED] Either wifi or ethernet testing need to be enabled
|
||||
#else
|
||||
|
||||
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
|
||||
#include "emac_tests.h"
|
||||
#include "emac_util.h"
|
||||
#include "OnboardNetworkStack.h"
|
||||
#include "EmacTestNetworkStack.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
// Test setup
|
||||
utest::v1::status_t test_setup(const size_t number_of_cases)
|
||||
{
|
||||
#if !MBED_CONF_APP_ECHO_SERVER
|
||||
#ifdef MBED_GREENTEA_TEST_EMAC_TIMEOUT_S
|
||||
GREENTEA_SETUP(MBED_GREENTEA_TEST_EMAC_TIMEOUT_S, "default_auto");
|
||||
#else
|
||||
GREENTEA_SETUP(1400, "default_auto");
|
||||
#endif // #ifdef MBED_GREENTEA_TEST_EMAC_TIMEOUT_S
|
||||
#endif // #if !MBED_CONF_APP_ECHO_SERVER
|
||||
|
||||
return verbose_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
@ -77,6 +65,10 @@ int main()
|
|||
return !Harness::run(specification);
|
||||
}
|
||||
|
||||
#endif // (MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE != ETHERNET && MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE != WIFI)
|
||||
#endif // !defined(MBED_CONF_APP_ECHO_SERVER) || !defined(MBED_CONF_APP_ECHO_SERVER_TRACE) || !defined(MBED_CONF_APP_WIFI_SCAN)
|
||||
// Override network stack selection to return the EmacTest network stack
|
||||
OnboardNetworkStack &OnboardNetworkStack::get_default_instance()
|
||||
{
|
||||
return EmacTestNetworkStack::get_instance();
|
||||
}
|
||||
|
||||
#endif // !defined(MBED_CONF_RTOS_PRESENT)
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
add_library(mbed-emac-test-utils STATIC EXCLUDE_FROM_ALL)
|
||||
target_sources(mbed-emac-test-utils PRIVATE
|
||||
emac_membuf.cpp
|
||||
emac_ctp.cpp
|
||||
emac_util.cpp
|
||||
EmacTestMemoryManager.cpp
|
||||
EmacTestNetworkStack.cpp)
|
||||
target_include_directories(mbed-emac-test-utils PUBLIC .)
|
||||
target_link_libraries(mbed-emac-test-utils PUBLIC
|
||||
mbed-core-flags
|
||||
mbed-rtos-flags
|
||||
mbed-netsocket-api
|
||||
mbed-nanostack-libservice
|
||||
mbed-nanostack-hal_mbed_cmsis_rtos)
|
|
@ -21,17 +21,13 @@
|
|||
#include <list>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "unity.h"
|
||||
|
||||
#include "rtos/Mutex.h"
|
||||
|
||||
extern "C" {
|
||||
#include "arm_hal_interrupt_private.h"
|
||||
}
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "arm_hal_interrupt_private.h"
|
||||
|
||||
#include "EMACMemoryManager.h"
|
||||
#include "emac_TestMemoryManager.h"
|
||||
#include "EmacTestMemoryManager.h"
|
||||
|
||||
#define BUF_HEAD "headheadheadhead"
|
||||
#define BUF_HEAD_SIZE 16
|
||||
|
@ -480,9 +476,9 @@ template <typename TYPE> void EmacTestMemoryManager::check_value(TYPE value, con
|
|||
if (!value) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
snprintf(s_trace_buffer + sizeof(MEM_MNGR_TRACE) - 1, sizeof(s_trace_buffer) - sizeof(MEM_MNGR_TRACE) - 1, fmt, ap);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
assert(false);
|
||||
va_end(ap);
|
||||
TEST_ASSERT_MESSAGE(0, s_trace_buffer);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef EMAC_TEST_MEMORY_MANAGER_H
|
||||
#define EMAC_TEST_MEMORY_MANAGER_H
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "EMACMemoryManager.h"
|
||||
|
||||
#define MEM_CHECK 0x01
|
||||
#define MEM_NO_ALIGN 0x02
|
||||
|
||||
typedef struct emac_memory {
|
||||
struct emac_memory *next;
|
||||
void *buffer; /**< Pointer to allocated buffer */
|
||||
unsigned int orig_len; /**< Original buffer length (set_len() does not change) */
|
||||
unsigned int len; /**< Buffer length */
|
||||
void *ptr; /**< Aligned pointer */
|
||||
bool first;
|
||||
} emac_memory_t;
|
||||
|
||||
class EmacTestMemoryManager : public EMACMemoryManager {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates emac test memory manager
|
||||
*/
|
||||
EmacTestMemoryManager();
|
||||
|
||||
/*
|
||||
* Gets static instance
|
||||
*/
|
||||
static EmacTestMemoryManager &get_instance();
|
||||
|
||||
emac_mem_buf_t *alloc_heap(uint32_t size, uint32_t align) override;
|
||||
|
||||
emac_mem_buf_t *alloc_pool(uint32_t size, uint32_t align) override;
|
||||
|
||||
uint32_t get_pool_alloc_unit(uint32_t align) const override;
|
||||
|
||||
void free(emac_mem_buf_t *buf) override;
|
||||
|
||||
uint32_t get_total_len(const emac_mem_buf_t *buf) const override;
|
||||
|
||||
void copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_buf) override;
|
||||
|
||||
void cat(emac_mem_buf_t *to_buf, emac_mem_buf_t *cat_buf) override;
|
||||
|
||||
emac_mem_buf_t *get_next(const emac_mem_buf_t *buf) const override;
|
||||
|
||||
void *get_ptr(const emac_mem_buf_t *buf) const override;
|
||||
|
||||
uint32_t get_len(const emac_mem_buf_t *buf) const override;
|
||||
|
||||
void set_len(emac_mem_buf_t *buf, uint32_t len) override;
|
||||
|
||||
/**
|
||||
* Allocates memory buffer from the heap
|
||||
*
|
||||
* Memory buffer allocated from heap is always contiguous and can be arbitrary size.
|
||||
*
|
||||
* @param size Size of the memory to allocate in bytes
|
||||
* @param align Memory alignment requirement in bytes
|
||||
* @param opt Options
|
||||
* @return Allocated memory buffer, or NULL in case of error
|
||||
*/
|
||||
emac_mem_buf_t *alloc_heap(uint32_t size, uint32_t align, uint8_t opt);
|
||||
|
||||
/**
|
||||
* Allocates memory buffer chain from a pool
|
||||
*
|
||||
* Memory allocated from pool is contiguous if size is equal or less than
|
||||
* (aligned) allocation unit, otherwise may be chained. Will typically come from
|
||||
* fixed-size packet pool memory.
|
||||
*
|
||||
* @param size Total size of the memory to allocate in bytes
|
||||
* @param align Memory alignment requirement for each buffer in bytes
|
||||
* @param opt Options
|
||||
* @return Allocated memory buffer chain, or NULL in case of error
|
||||
*/
|
||||
emac_mem_buf_t *alloc_pool(uint32_t size, uint32_t align, uint8_t opt);
|
||||
|
||||
/**
|
||||
* Sets memory buffer pool allocation unit
|
||||
*
|
||||
* Sets the maximum size of contiguous memory that can be allocated from a pool.
|
||||
*
|
||||
* @param alloc_unit Contiguous memory size
|
||||
*/
|
||||
virtual void set_alloc_unit(uint32_t alloc_unit);
|
||||
|
||||
/**
|
||||
* Sets whether memory is available
|
||||
*
|
||||
* Can be used to disable memory allocation request from emac.
|
||||
*
|
||||
* @param memory True if memory is available
|
||||
*/
|
||||
void set_memory_available(bool memory);
|
||||
|
||||
/**
|
||||
* Gets memory statistics
|
||||
*
|
||||
* Gets memory usage statistics
|
||||
*
|
||||
* @param buffers Number of buffers that are reserved
|
||||
* @param memory Reserved memory in bytes
|
||||
*/
|
||||
void get_memory_statistics(int *buffers, int *memory);
|
||||
|
||||
private:
|
||||
void validate_list() const;
|
||||
template <typename TYPE> void check_value(TYPE value, const char *fmt, ...) const;
|
||||
bool validate_ptr(const emac_mem_buf_t *buf) const;
|
||||
void check_align(uint32_t align) const;
|
||||
mutable rtos::Mutex m_mem_mutex;
|
||||
std::list<emac_memory_t *> m_mem_buffers;
|
||||
unsigned int m_alloc_unit;
|
||||
bool m_memory_available;
|
||||
};
|
||||
|
||||
#endif /* EMAC_TEST_MEMORY_MANAGER_H */
|
|
@ -14,29 +14,52 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#if defined(MBED_CONF_RTOS_PRESENT)
|
||||
|
||||
#include "unity.h"
|
||||
|
||||
#include "EMACMemoryManager.h"
|
||||
#include "emac_TestNetworkStack.h"
|
||||
#include "emac_initialize.h"
|
||||
#include "EmacTestNetworkStack.h"
|
||||
|
||||
#include "mbed_interface.h"
|
||||
|
||||
bool EmacTestNetworkStack::emac_if_init(EMAC *emac)
|
||||
{
|
||||
emac->set_link_input_cb(emac_if_link_input_cb);
|
||||
emac->set_link_state_cb(emac_if_link_state_change_cb);
|
||||
|
||||
if (!emac->power_up()) {
|
||||
printf("emac power up failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
int hwaddr_len = emac->get_hwaddr_size();
|
||||
printf("emac hwaddr length %i\r\n\r\n", hwaddr_len);
|
||||
|
||||
if (hwaddr_len != 6) {
|
||||
printf("invalid emac hwaddr length %d!\n", hwaddr_len);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If driver updates this, write it back, otherwise write default from mbed_mac_address
|
||||
mbed_mac_address(reinterpret_cast<char *>(ð_mac_addr[0]));
|
||||
emac->get_hwaddr(eth_mac_addr);
|
||||
emac->set_hwaddr(eth_mac_addr);
|
||||
printf("emac hwaddr %x:%x:%x:%x:%x:%x\r\n\r\n", eth_mac_addr[0], eth_mac_addr[1], eth_mac_addr[2], eth_mac_addr[3], eth_mac_addr[4], eth_mac_addr[5]);
|
||||
|
||||
int mtu_size = emac->get_mtu_size();
|
||||
printf("emac mtu %i\r\n\r\n", mtu_size);
|
||||
emac_if_set_mtu_size(mtu_size);
|
||||
|
||||
char hw_name[11];
|
||||
emac->get_ifname(hw_name, 10);
|
||||
printf("emac if name %s\r\n\r\n", hw_name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
EmacTestNetworkStack::EmacTestNetworkStack()
|
||||
: m_interface(NULL)
|
||||
: m_interface(*this)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
nsapi_error_t EmacTestNetworkStack::gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t EmacTestNetworkStack::add_dns_server(const SocketAddress &address)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t EmacTestNetworkStack::call_in(int delay, mbed::Callback<void()> func)
|
||||
{
|
||||
|
@ -117,24 +140,34 @@ void EmacTestNetworkStack::socket_attach(nsapi_socket_t handle, void (*callback)
|
|||
|
||||
nsapi_error_t EmacTestNetworkStack::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out, NetworkInterface *user_network_interface)
|
||||
{
|
||||
// Test network stack supports only one interface
|
||||
TEST_ASSERT_MESSAGE(!m_interface, "Only one interface supported!");
|
||||
// Only one interface is supported
|
||||
if (m_interface.m_emac != nullptr) {
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
m_interface = &EmacTestNetworkStack::Interface::get_instance();
|
||||
TEST_ASSERT_MESSAGE(m_interface, "Invalid interface!");
|
||||
|
||||
m_interface->m_emac = &emac;
|
||||
m_interface.m_emac = &emac;
|
||||
|
||||
EmacTestMemoryManager *memory_manager = &EmacTestMemoryManager::get_instance();
|
||||
emac.set_memory_manager(*memory_manager);
|
||||
|
||||
*interface_out = m_interface;
|
||||
*interface_out = &m_interface;
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
EmacTestNetworkStack::Interface::Interface()
|
||||
: m_emac(NULL)
|
||||
EMAC *EmacTestNetworkStack::get_emac()
|
||||
{
|
||||
return m_interface.m_emac;
|
||||
}
|
||||
|
||||
unsigned char const *EmacTestNetworkStack::get_mac_addr() const
|
||||
{
|
||||
return eth_mac_addr;
|
||||
}
|
||||
|
||||
EmacTestNetworkStack::Interface::Interface(EmacTestNetworkStack &netStack):
|
||||
m_netStack(netStack),
|
||||
m_emac(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -152,7 +185,7 @@ nsapi_connection_status_t EmacTestNetworkStack::Interface::get_connection_status
|
|||
|
||||
char *EmacTestNetworkStack::Interface::get_mac_address(char *buf, nsapi_size_t buflen)
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsapi_error_t EmacTestNetworkStack::Interface::set_mac_address(uint8_t *buf, nsapi_size_t buflen)
|
||||
|
@ -165,35 +198,20 @@ nsapi_error_t EmacTestNetworkStack::Interface::get_ip_address(SocketAddress *add
|
|||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
char *EmacTestNetworkStack::Interface::get_ip_address(char *buf, nsapi_size_t buflen)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsapi_error_t EmacTestNetworkStack::Interface::get_netmask(SocketAddress *address)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
char *EmacTestNetworkStack::Interface::get_netmask(char *buf, nsapi_size_t buflen)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsapi_error_t EmacTestNetworkStack::Interface::get_gateway(SocketAddress *address)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
char *EmacTestNetworkStack::Interface::get_gateway(char *buf, nsapi_size_t buflen)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsapi_error_t EmacTestNetworkStack::Interface::bringup(bool dhcp, const char *ip, const char *netmask, const char *gw, const nsapi_ip_stack_t stack, bool blocking)
|
||||
{
|
||||
if (!emac_if_init(m_emac)) {
|
||||
TEST_ASSERT_MESSAGE(0, "emac initialization failed!");
|
||||
if (!m_netStack.emac_if_init(m_emac)) {
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
|
@ -204,24 +222,8 @@ nsapi_error_t EmacTestNetworkStack::Interface::bringdown()
|
|||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
EmacTestNetworkStack::Interface &EmacTestNetworkStack::Interface::get_instance()
|
||||
{
|
||||
static EmacTestNetworkStack::Interface test_interface;
|
||||
return test_interface;
|
||||
}
|
||||
|
||||
EmacTestNetworkStack &EmacTestNetworkStack::get_instance()
|
||||
{
|
||||
static EmacTestNetworkStack test_stack;
|
||||
return test_stack;
|
||||
}
|
||||
|
||||
#define TEST 0x33254234
|
||||
#if MBED_CONF_NSAPI_DEFAULT_STACK == TEST
|
||||
#undef TEST
|
||||
OnboardNetworkStack &OnboardNetworkStack::get_default_instance()
|
||||
{
|
||||
return EmacTestNetworkStack::get_instance();
|
||||
}
|
||||
#endif // defined(MBED_CONF_RTOS_PRESENT)
|
||||
#endif
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef EMAC_TEST_NETWORK_STACK_H
|
||||
#define EMAC_TEST_NETWORK_STACK_H
|
||||
|
||||
#include "netsocket/nsapi_types.h"
|
||||
#include "netsocket/EMAC.h"
|
||||
#include "netsocket/OnboardNetworkStack.h"
|
||||
|
||||
#include "EmacTestMemoryManager.h"
|
||||
#include "emac_util.h"
|
||||
|
||||
class EmacTestNetworkStack : public OnboardNetworkStack, private mbed::NonCopyable<EmacTestNetworkStack> {
|
||||
|
||||
unsigned char eth_mac_addr[ETH_MAC_ADDR_LEN];
|
||||
|
||||
bool emac_if_init(EMAC *emac);
|
||||
public:
|
||||
|
||||
static EmacTestNetworkStack &get_instance();
|
||||
|
||||
EmacTestNetworkStack();
|
||||
virtual ~EmacTestNetworkStack() {}
|
||||
|
||||
class Interface : public OnboardNetworkStack::Interface {
|
||||
public:
|
||||
|
||||
/** Set MAC address on the network interface
|
||||
*
|
||||
* @param mac_addr Buffer containing the MAC address in hexadecimal format.
|
||||
* @param addr_len Length of provided buffer in bytes (6 or 8)
|
||||
* @retval NSAPI_ERROR_OK on success
|
||||
* @retval NSAPI_ERROR_UNSUPPORTED if this feature is not supported
|
||||
* @retval NSAPI_ERROR_PARAMETER if address is not valid
|
||||
* @retval NSAPI_ERROR_BUSY if address can't be set.
|
||||
*/
|
||||
nsapi_error_t set_mac_address(uint8_t *mac_addr, nsapi_size_t addr_len);
|
||||
|
||||
nsapi_error_t bringup(bool dhcp, const char *ip,
|
||||
const char *netmask, const char *gw,
|
||||
nsapi_ip_stack_t stack,
|
||||
bool blocking
|
||||
) override;
|
||||
|
||||
nsapi_error_t bringdown() override;
|
||||
|
||||
void attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb) override;
|
||||
|
||||
nsapi_connection_status_t get_connection_status() const override;
|
||||
|
||||
char *get_mac_address(char *buf, nsapi_size_t buflen) override;
|
||||
|
||||
nsapi_error_t get_ip_address(SocketAddress *address) override;
|
||||
|
||||
nsapi_error_t get_netmask(SocketAddress *address) override;
|
||||
|
||||
nsapi_error_t get_gateway(SocketAddress *address) override;
|
||||
private:
|
||||
friend EmacTestNetworkStack;
|
||||
|
||||
explicit Interface(EmacTestNetworkStack &netStack);
|
||||
|
||||
EmacTestNetworkStack &m_netStack;
|
||||
EMAC *m_emac;
|
||||
};
|
||||
|
||||
nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out, NetworkInterface *user_network_interface) override;
|
||||
|
||||
/// Get a pointer to the EMAC driver. Will return nullptr if no interface has been added yet.
|
||||
EMAC *get_emac();
|
||||
|
||||
/// Get the MAC address being used for the ethernet port
|
||||
unsigned char const *get_mac_addr() const;
|
||||
|
||||
protected:
|
||||
|
||||
nsapi_error_t socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto) override;
|
||||
|
||||
nsapi_error_t socket_close(nsapi_socket_t handle) override;
|
||||
|
||||
nsapi_error_t socket_bind(nsapi_socket_t handle, const SocketAddress &address) override;
|
||||
|
||||
nsapi_error_t socket_listen(nsapi_socket_t handle, int backlog) override;
|
||||
|
||||
nsapi_error_t socket_connect(nsapi_socket_t handle, const SocketAddress &address) override;
|
||||
|
||||
nsapi_error_t socket_accept(nsapi_socket_t server,
|
||||
nsapi_socket_t *handle, SocketAddress *address = 0) override;
|
||||
|
||||
nsapi_size_or_error_t socket_send(nsapi_socket_t handle,
|
||||
const void *data, nsapi_size_t size) override;
|
||||
|
||||
nsapi_size_or_error_t socket_recv(nsapi_socket_t handle,
|
||||
void *data, nsapi_size_t size) override;
|
||||
|
||||
nsapi_size_or_error_t socket_sendto(nsapi_socket_t handle, const SocketAddress &address,
|
||||
const void *data, nsapi_size_t size) override;
|
||||
|
||||
nsapi_size_or_error_t socket_recvfrom(nsapi_socket_t handle, SocketAddress *address,
|
||||
void *buffer, nsapi_size_t size) override;
|
||||
|
||||
void socket_attach(nsapi_socket_t handle, void (*callback)(void *), void *data) override;
|
||||
|
||||
nsapi_error_t setsockopt(nsapi_socket_t handle, int level,
|
||||
int optname, const void *optval, unsigned optlen) override;
|
||||
|
||||
nsapi_error_t getsockopt(nsapi_socket_t handle, int level,
|
||||
int optname, void *optval, unsigned *optlen) override;
|
||||
|
||||
private:
|
||||
call_in_callback_cb_t get_call_in_callback() override;
|
||||
|
||||
nsapi_error_t call_in(int delay, mbed::Callback<void()> func) override;
|
||||
|
||||
Interface m_interface;
|
||||
};
|
||||
|
||||
#endif /* EMAC_TEST_NETWORK_STACK_H */
|
|
@ -0,0 +1,2 @@
|
|||
# EMAC Test Utils library
|
||||
This folder contains a testing implementation of a network stack and a memory manager, as well as code for sending and receiving Connection Test Protocol (CTP) packets. It is used in the EMAC test and in the CTP echo server.
|
|
@ -14,26 +14,18 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#if defined(MBED_CONF_RTOS_PRESENT)
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity/unity.h"
|
||||
#include "utest.h"
|
||||
|
||||
#include "mbed.h"
|
||||
|
||||
#include "EMAC.h"
|
||||
#include "EMACMemoryManager.h"
|
||||
#include "emac_TestMemoryManager.h"
|
||||
#include "EmacTestMemoryManager.h"
|
||||
#include "EmacTestNetworkStack.h"
|
||||
|
||||
#include "emac_tests.h"
|
||||
#include "emac_ctp.h"
|
||||
|
||||
#include "emac_initialize.h"
|
||||
#include "emac_util.h"
|
||||
#include "emac_membuf.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
// Unique identifier for message
|
||||
static int receipt_number = 0;
|
||||
|
||||
|
@ -64,7 +56,7 @@ static int emac_if_ctp_header_build(unsigned char *eth_frame, const unsigned cha
|
|||
return receipt_number;
|
||||
}
|
||||
|
||||
ctp_function emac_if_ctp_header_handle(unsigned char *eth_input_frame, unsigned char *eth_output_frame, unsigned char *origin_addr, int *receipt_number)
|
||||
ctp_function emac_if_ctp_header_handle(unsigned char *eth_input_frame, unsigned char *eth_output_frame, unsigned char const *origin_addr, int *receipt_number)
|
||||
{
|
||||
if (eth_input_frame[12] != 0x90 || eth_input_frame[13] != 0x00) {
|
||||
return CTP_NONE;
|
||||
|
@ -123,10 +115,10 @@ void emac_if_ctp_msg_build(int eth_frame_len, const unsigned char *dest_addr, co
|
|||
|
||||
emac_mem_buf_t *buf;
|
||||
if (options & CTP_OPT_HEAP) {
|
||||
buf = emac_m_mngr_get()->alloc_heap(eth_frame_len, align, alloc_opt);
|
||||
buf = EmacTestMemoryManager::get_instance().alloc_heap(eth_frame_len, align, alloc_opt);
|
||||
} else {
|
||||
// Default allocation is from pool
|
||||
buf = emac_m_mngr_get()->alloc_pool(eth_frame_len, align, alloc_opt);
|
||||
buf = EmacTestMemoryManager::get_instance().alloc_pool(eth_frame_len, align, alloc_opt);
|
||||
}
|
||||
|
||||
if (!buf) {
|
||||
|
@ -146,7 +138,6 @@ void emac_if_ctp_msg_build(int eth_frame_len, const unsigned char *dest_addr, co
|
|||
emac_if_memory_buffer_write(buf, eth_output_frame_data, true);
|
||||
|
||||
emac_if_check_memory(true);
|
||||
emac_if_get()->link_out(buf);
|
||||
EmacTestNetworkStack::get_instance().get_emac()->link_out(buf);
|
||||
emac_if_check_memory(false);
|
||||
}
|
||||
#endif // defined(MBED_CONF_RTOS_PRESENT)
|
|
@ -34,7 +34,7 @@ enum ctp_function {
|
|||
#define CTP_MSG_SEND(length, send_to_address, own_address, forward_to_address, mem_mngr_options) \
|
||||
emac_if_ctp_msg_build(length, send_to_address, own_address, forward_to_address, mem_mngr_options)
|
||||
|
||||
ctp_function emac_if_ctp_header_handle(unsigned char *eth_input_frame, unsigned char *eth_output_frame, unsigned char *origin_addr, int *receipt_number);
|
||||
ctp_function emac_if_ctp_header_handle(unsigned char *eth_input_frame, unsigned char *eth_output_frame, unsigned char const *origin_addr, int *receipt_number);
|
||||
void emac_if_ctp_msg_build(int eth_frame_len, const unsigned char *dest_addr, const unsigned char *origin_addr, const unsigned char *forward_addr, int options);
|
||||
void emac_if_ctp_reply_handle(int lenght, int invalid_data_index);
|
||||
|
|
@ -17,17 +17,13 @@
|
|||
#if defined(MBED_CONF_RTOS_PRESENT)
|
||||
|
||||
#include "mbed.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
|
||||
#include "mbed.h"
|
||||
|
||||
#include "EMAC.h"
|
||||
#include "EMACMemoryManager.h"
|
||||
#include "emac_TestMemoryManager.h"
|
||||
#include "EmacTestMemoryManager.h"
|
||||
|
||||
#include "emac_initialize.h"
|
||||
#include "emac_membuf.h"
|
||||
#include "emac_util.h"
|
||||
|
||||
|
@ -36,9 +32,9 @@ int emac_if_memory_buffer_read(void *buf, unsigned char *eth_frame)
|
|||
int eth_frame_index = 0;
|
||||
int invalid_data_index = 0;
|
||||
|
||||
for (emac_mem_buf_t *mem_buf = buf; mem_buf != NULL; mem_buf = emac_m_mngr_get()->get_next(mem_buf)) {
|
||||
unsigned char *buf_payload = (unsigned char *) emac_m_mngr_get()->get_ptr(mem_buf);
|
||||
int buf_payload_len = emac_m_mngr_get()->get_len(mem_buf);
|
||||
for (emac_mem_buf_t *mem_buf = buf; mem_buf != NULL; mem_buf = EmacTestMemoryManager::get_instance().get_next(mem_buf)) {
|
||||
unsigned char *buf_payload = (unsigned char *) EmacTestMemoryManager::get_instance().get_ptr(mem_buf);
|
||||
int buf_payload_len = EmacTestMemoryManager::get_instance().get_len(mem_buf);
|
||||
|
||||
for (int index = 0; index < buf_payload_len; index++) {
|
||||
if (eth_frame_index < ETH_FRAME_HEADER_LEN) {
|
||||
|
@ -60,9 +56,9 @@ void emac_if_memory_buffer_write(void *buf, unsigned char *eth_frame, bool write
|
|||
{
|
||||
int eth_frame_index = 0;
|
||||
|
||||
for (emac_mem_buf_t *mem_buf = buf; mem_buf != NULL; mem_buf = emac_m_mngr_get()->get_next(mem_buf)) {
|
||||
unsigned char *buf_payload = (unsigned char *) emac_m_mngr_get()->get_ptr(mem_buf);
|
||||
int buf_payload_len = emac_m_mngr_get()->get_len(mem_buf);
|
||||
for (emac_mem_buf_t *mem_buf = buf; mem_buf != NULL; mem_buf = EmacTestMemoryManager::get_instance().get_next(mem_buf)) {
|
||||
unsigned char *buf_payload = (unsigned char *) EmacTestMemoryManager::get_instance().get_ptr(mem_buf);
|
||||
int buf_payload_len = EmacTestMemoryManager::get_instance().get_len(mem_buf);
|
||||
|
||||
for (int index = 0; index < buf_payload_len; index++) {
|
||||
if (eth_frame_index < ETH_FRAME_HEADER_LEN) {
|
|
@ -14,38 +14,23 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#if defined(MBED_CONF_RTOS_PRESENT)
|
||||
|
||||
#include "mbed.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
|
||||
#include "mbed.h"
|
||||
|
||||
#include "EMAC.h"
|
||||
#include "EMACMemoryManager.h"
|
||||
#include "emac_TestMemoryManager.h"
|
||||
#include "EmacTestMemoryManager.h"
|
||||
#include "EmacTestNetworkStack.h"
|
||||
|
||||
#include "emac_tests.h"
|
||||
#include "emac_initialize.h"
|
||||
#include "emac_util.h"
|
||||
#include "emac_membuf.h"
|
||||
#include "emac_ctp.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
/* For LPC boards define the memory bank ourselves to give us section placement
|
||||
control */
|
||||
#ifndef ETHMEM_SECTION
|
||||
#if defined(TARGET_LPC1768)
|
||||
# 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
|
||||
#define ETHMEM_SECTION __attribute__((section("AHBSRAM1"),aligned))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -108,6 +93,8 @@ static unsigned int error_flags = 0;
|
|||
static unsigned int no_response_cnt = 0;
|
||||
static bool link_up = false;
|
||||
|
||||
static bool ctp_server_mode = false;
|
||||
|
||||
int emac_if_find_outgoing_msg(int receipt_number)
|
||||
{
|
||||
for (int i = 0; i < OUTGOING_MSG_COUNT; i++) {
|
||||
|
@ -376,12 +363,12 @@ void emac_if_trace_to_ascii_hex_dump(const char *prefix, int len, unsigned char
|
|||
|
||||
void emac_if_set_all_multicast(bool all)
|
||||
{
|
||||
emac_if_get()->set_all_multicast(all);
|
||||
EmacTestNetworkStack::get_instance().get_emac()->set_all_multicast(all);
|
||||
}
|
||||
|
||||
void emac_if_add_multicast_group(uint8_t *address)
|
||||
{
|
||||
emac_if_get()->add_multicast_group(address);
|
||||
EmacTestNetworkStack::get_instance().get_emac()->add_multicast_group(address);
|
||||
}
|
||||
|
||||
void emac_if_set_output_memory(bool memory)
|
||||
|
@ -410,8 +397,7 @@ void emac_if_set_memory(bool memory)
|
|||
static bool memory_value = true;
|
||||
if (memory_value != memory) {
|
||||
memory_value = memory;
|
||||
EmacTestMemoryManager *mem_mngr = emac_m_mngr_get();
|
||||
mem_mngr->set_memory_available(memory);
|
||||
EmacTestMemoryManager::get_instance().set_memory_available(memory);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -428,18 +414,18 @@ void emac_if_link_input_cb(void *buf)
|
|||
{
|
||||
if (link_input_event.post(buf) == 0) {
|
||||
if (buf) {
|
||||
emac_m_mngr_get()->free(buf);
|
||||
EmacTestMemoryManager::get_instance().free(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void link_input_event_cb(void *buf)
|
||||
{
|
||||
int length = emac_m_mngr_get()->get_total_len(buf);
|
||||
int length = EmacTestMemoryManager::get_instance().get_total_len(buf);
|
||||
|
||||
if (length >= ETH_FRAME_HEADER_LEN) {
|
||||
// Ethernet input frame
|
||||
unsigned char eth_input_frame_data[ETH_FRAME_HEADER_LEN];
|
||||
static unsigned char eth_input_frame_data[ETH_FRAME_HEADER_LEN];
|
||||
memset(eth_input_frame_data, 0, ETH_FRAME_HEADER_LEN);
|
||||
|
||||
int invalid_data_index = emac_if_memory_buffer_read(buf, eth_input_frame_data);
|
||||
|
@ -448,7 +434,7 @@ static void link_input_event_cb(void *buf)
|
|||
unsigned char eth_output_frame_data[ETH_FRAME_HEADER_LEN];
|
||||
int receipt_number;
|
||||
|
||||
ctp_function function = emac_if_ctp_header_handle(eth_input_frame_data, eth_output_frame_data, emac_if_get_hw_addr(), &receipt_number);
|
||||
ctp_function function = emac_if_ctp_header_handle(eth_input_frame_data, eth_output_frame_data, EmacTestNetworkStack::get_instance().get_mac_addr(), &receipt_number);
|
||||
|
||||
if (function == CTP_REPLY) {
|
||||
// If reply has valid receipt number
|
||||
|
@ -462,13 +448,12 @@ static void link_input_event_cb(void *buf)
|
|||
// Calls test loop
|
||||
worker_loop_event_queue.call(current_test_step_cb_fnc, INPUT);
|
||||
}
|
||||
#if MBED_CONF_APP_ECHO_SERVER
|
||||
// Echoes only if configured as echo server
|
||||
} else if (function == CTP_FORWARD) {
|
||||
}
|
||||
// Echoes only if configured as echo server
|
||||
else if (function == CTP_FORWARD && ctp_server_mode) {
|
||||
emac_if_memory_buffer_write(buf, eth_output_frame_data, false);
|
||||
emac_if_get()->link_out(buf);
|
||||
buf = 0;
|
||||
#endif
|
||||
EmacTestNetworkStack::get_instance().get_emac()->link_out(buf);
|
||||
buf = nullptr;
|
||||
}
|
||||
|
||||
emac_if_add_echo_server_addr(ð_input_frame_data[6]);
|
||||
|
@ -482,7 +467,7 @@ static void link_input_event_cb(void *buf)
|
|||
}
|
||||
|
||||
if (buf) {
|
||||
emac_m_mngr_get()->free(buf);
|
||||
EmacTestMemoryManager::get_instance().free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -508,24 +493,24 @@ void worker_loop_init(void)
|
|||
}
|
||||
}
|
||||
|
||||
void worker_loop_start(void (*test_step_cb_fnc)(int opt), int timeout)
|
||||
void worker_loop_start(void (*test_step_cb_fnc)(int opt), std::chrono::milliseconds poll_rate, bool loop_forever)
|
||||
{
|
||||
current_test_step_cb_fnc = test_step_cb_fnc;
|
||||
|
||||
int test_step_cb_timer = worker_loop_event_queue.call_every(timeout, test_step_cb_fnc, TIMEOUT);
|
||||
int timeout_outgoing_msg_timer = worker_loop_event_queue.call_every(1000, emac_if_timeout_outgoing_msg);
|
||||
int test_step_cb_timer = worker_loop_event_queue.call_every(poll_rate, test_step_cb_fnc, TIMEOUT);
|
||||
int timeout_outgoing_msg_timer = worker_loop_event_queue.call_every(1000ms, emac_if_timeout_outgoing_msg);
|
||||
|
||||
int validate_outgoing_msg_timer = 0;
|
||||
if (timeout > 500) {
|
||||
if (poll_rate > 500ms) {
|
||||
// For long test step callback timeouts validates messages also between callback timeouts
|
||||
validate_outgoing_msg_timer = worker_loop_event_queue.call_every(200, emac_if_validate_outgoing_msg);
|
||||
validate_outgoing_msg_timer = worker_loop_event_queue.call_every(200ms, emac_if_validate_outgoing_msg);
|
||||
}
|
||||
|
||||
#if MBED_CONF_APP_ECHO_SERVER
|
||||
worker_loop_semaphore.acquire();
|
||||
#else
|
||||
worker_loop_semaphore.try_acquire_for(600 * SECOND_TO_MS);
|
||||
#endif
|
||||
if (loop_forever) {
|
||||
worker_loop_semaphore.acquire();
|
||||
} else {
|
||||
worker_loop_semaphore.try_acquire_for(600s);
|
||||
}
|
||||
|
||||
worker_loop_event_queue.cancel(test_step_cb_timer);
|
||||
worker_loop_event_queue.cancel(timeout_outgoing_msg_timer);
|
||||
|
@ -565,9 +550,9 @@ void worker_loop(void)
|
|||
worker_loop_event_queue.dispatch_forever();
|
||||
}
|
||||
|
||||
unsigned char *emac_if_get_own_addr(void)
|
||||
unsigned char const *emac_if_get_own_addr(void)
|
||||
{
|
||||
return (emac_if_get_hw_addr());
|
||||
return EmacTestNetworkStack::get_instance().get_mac_addr();
|
||||
}
|
||||
|
||||
int emac_if_get_mtu_size()
|
||||
|
@ -579,4 +564,8 @@ void emac_if_set_mtu_size(int mtu_size)
|
|||
{
|
||||
eth_mtu_size = mtu_size;
|
||||
}
|
||||
#endif // defined(MBED_CONF_RTOS_PRESENT)
|
||||
|
||||
void emac_if_set_ctp_server_enabled(bool enabled)
|
||||
{
|
||||
ctp_server_mode = enabled;
|
||||
}
|
|
@ -18,9 +18,8 @@
|
|||
#ifndef EMAC_UTIL_H
|
||||
#define EMAC_UTIL_H
|
||||
|
||||
#define SECOND_TO_US 1000000
|
||||
#define SECOND_TO_MS 1000
|
||||
#define MS_TO_US 1000
|
||||
#include <cstdint>
|
||||
#include <chrono>
|
||||
|
||||
extern const unsigned char eth_mac_broadcast_addr[];
|
||||
|
||||
|
@ -102,7 +101,7 @@ char emac_if_get_trace_level();
|
|||
|
||||
void emac_if_trace_to_ascii_hex_dump(const char *prefix, int len, char *data);
|
||||
|
||||
unsigned char *emac_if_get_own_addr(void);
|
||||
unsigned char const *emac_if_get_own_addr(void);
|
||||
|
||||
int emac_if_get_mtu_size();
|
||||
void emac_if_set_mtu_size(int mtu_size);
|
||||
|
@ -118,8 +117,10 @@ void emac_if_set_input_memory(bool memory);
|
|||
void emac_if_check_memory(bool output);
|
||||
void emac_if_set_memory(bool memory);
|
||||
|
||||
void emac_if_set_ctp_server_enabled(bool enabled);
|
||||
|
||||
void worker_loop_init(void);
|
||||
void worker_loop_start(void (*test_step_cb_fnc)(int opt), int timeout);
|
||||
void worker_loop_start(void (*test_step_cb_fnc)(int opt), std::chrono::milliseconds poll_rate, bool loop_forever = false);
|
||||
void worker_loop_end(void);
|
||||
void worker_loop_link_up_wait(void);
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2024 Jamie Smith
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Script to run the Astyle formatter on the Mbed OS code base.
|
||||
# Run before submitting code changes!
|
||||
|
||||
git diff --name-only --diff-filter=d origin/master \
|
||||
| ( grep '.*\.\(c\|cpp\|h\|hpp\)$' || true ) \
|
||||
| ( grep -v -f .codecheckignore || true ) \
|
||||
| while read file; do astyle -n --options=.astylerc "${file}"; done
|
|
@ -66,11 +66,12 @@ set(MBED_GDB_PORT 23331 CACHE STRING "Port that the GDB server will be started o
|
|||
set(MBED_UPLOAD_SERIAL_NUMBER "" CACHE STRING "Serial number of the Mbed board or the programming tool, for upload methods that select by serial number.")
|
||||
|
||||
# Handle legacy per-upload-method aliases for the upload serial number
|
||||
foreach(LEGACY_VAR_NAME JLINK_USB_SERIAL_NUMBER LINKSERVER_PROBE_SN MBED_TARGET_UID OPENOCD_ADAPTER_SERIAL PYOCD_PROBE_UID STLINK_SERIAL_ARGUMENT STM32CUBE_PROBE_SN)
|
||||
foreach(LEGACY_VAR_NAME JLINK_USB_SERIAL_NUMBER LINKSERVER_PROBE_SN MBED_TARGET_UID OPENOCD_ADAPTER_SERIAL PYOCD_PROBE_UID STLINK_PROBE_SN STM32CUBE_PROBE_SN)
|
||||
if(DEFINED ${LEGACY_VAR_NAME})
|
||||
if(NOT "${${LEGACY_VAR_NAME}}" STREQUAL "")
|
||||
message(WARNING "${LEGACY_VAR_NAME} is deprecated, set the MBED_UPLOAD_SERIAL_NUMBER variable instead. MBED_UPLOAD_SERIAL_NUMBER will be set to the value of ${LEGACY_VAR_NAME}.")
|
||||
set(MBED_UPLOAD_SERIAL_NUMBER ${${LEGACY_VAR_NAME}} CACHE STRING "" FORCE)
|
||||
unset(STLINK_PROBE_SN CACHE)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
|
|
@ -99,7 +99,7 @@ class MemoryBankInfo:
|
|||
|
||||
class _Parser(ABC):
|
||||
"""Internal interface for parsing"""
|
||||
SECTIONS = ('.text', '.data', '.bss', '.heap', '.stack')
|
||||
SECTIONS = ('.text', '.data', '.bss', '.heap', '.heap_0', '.stack')
|
||||
MISC_FLASH_SECTIONS = ('.interrupts', '.flash_config')
|
||||
OTHER_SECTIONS = ('.interrupts_ram', '.init', '.ARM.extab',
|
||||
'.ARM.exidx', '.ARM.attributes', '.eh_frame',
|
||||
|
|
Loading…
Reference in New Issue