- Note
- This page has been updated to reference GM cellular modules. GM cellular modules are a direct replacement for RYZ. RYZ cellular modules are deprecated and will be removed from FSP in a future release.
-
The Azure Embedded Wireless Framework is still in beta and not all APIs may be fully implemented yet.
Overview
This documentation is for the GMxxx ports of the Azure Embedded Wireless Framework.
Features
- Various APIs to control/access GMxxx modem features via AT commands.
- Raw AT command APIs
- IPv4 sockets using TCP/UDP
- The EWF framework is usable standalone with bare metal and ThreadX.
- The framework can also be used with NetX when coupled with a EWF NetX middleware layer.
Limitations
The following are the limitations of the Azure EWF Library:
- DTC is not supported. The lower level interface using R_UART relies on processing data one byte at a time via the interrupt callback and UART_EVENT_RX_CHAR.
- Server mode sockets should be supported but have not been fully tested due to APN limitations.
- There are potential issues when using the default (-Os) optimization or above with AC6. All files under embedded_wireless_framework should be set to compile with no optimization (-O0) when using AC6.
nx_ip_status_check
does not currently work for the EWF middleware.
- When using socket send functions (
ewf_adapter_tcp_send
and ewf_adapter_udp_send
) the GM port is limited to sending only 1460 bytes at a time. Data sent using these functions should be broken into 1460 byte chunks or less.
- When using NetX the packet size for the driver packet pool should be set to 1460 bytes or less. Using larger packet sizes will work but the NetX Middleware Driver will potentially break up the packets inefficiently.
Unsupported NetX Duo Features
These features are handled directly on the GMxxx hardware or are not supported yet in the EWF library. NetX APIs for these features should not be used:
- IPv6 functionality (the EWF library doesn't yet support IPv6)
- ARP is handled directly by the cellular modem
- DHCP is handled directly by the cellular modem.
Configuration
The GM02S port for the Embedded Wireless Framework can be added to the Stacks tab via New Stack > Networking > Azure EWF Adapter on GM02S.
Build Time Configurations for Common
The following build time configurations are defined in fsp_cfg/azure/ewf/ewf.config.h:
Configuration | Options | Default | Description |
Parameter Checking |
| Enabled | This enables checking of function parameters. When this is disabled, parameter checking code is not present and the footprint is reduced |
Enable Logging |
| Disabled | This enables logging and the compilation of debug code. When disabled, logging and debug code is not present and the footprint is reduced. |
Verbose Logging |
| Disabled | This enables verbose logging. Verbose logging will only work if a EWF Log Function is set and logging is enabled. |
EWF Log Function | Manual Entry | printf(__VA_ARGS__) | Function the library uses for standard log messages when logging is enabled. |
EWF Log Error Function | Manual Entry | printf(__VA_ARGS__) | Function the library uses for error log messages when logging is enabled. |
Usage Notes
The basic setup for the library is as follows:
- Note
- **The message allocator (
EWF_ALLOCATOR_THREADX_STATIC_DECLARE
) should be at least 1500 bytes for GM**
- Declare an allocator, interface, and adapter using appropriate macros (
EWF_ALLOCATOR_THREADX_STATIC_DECLARE
/EWF_ALLOCATOR_MEMORY_POOL_STATIC_DECLARE
/EWF_ALLOCATOR_C_HEAP_STATIC_DECLARE
, EWF_INTERFACE_RA_UART_STATIC_DECLARE
, EWF_ADAPTER_RENESAS_GM02S_STATIC_DECLARE
).
- Start the adapter with
ewf_adapter_start
.
- Setup modem service if necessary with functions from
ewf_adapter_api_modem.h
and other included api_modem_*
files.
- Set functionality with
ewf_adapter_modem_functionality_set
.
- Wait for network registration (can use
ewf_adapter_modem_network_registration_check
to wait).
- Do a service activate to set desired PDP context with
ewf_adapter_modem_packet_service_activate
. This should be called regardless of whether context is already activated as it sets an internal library context number for functions like ewf_adapter_get_ipv4_address
.
- Call other network functions as needed from desired headers (i.e. TCP functions are in
ewf_adapter_api_tcp.h
).
When using NetX Duo the following must be done:
- Before creating an IP instance make sure that the modem adapter is started and connected to a network.
- After creating an IP instance the adapter pointer has to be stored manually to the IP instance:
g_ip.nx_ip_interface->nx_interface_additional_link_info = adapter_ptr;
.
- After creating an IP instance the gateway address should be set to the IP of the modem in order to satisfy NetX Duo's internal routing algorithms (packets are actually routed by the modem hardware):
nx_ip_gateway_address_set(&g_ip, RM_NETXDUO_TESTS_IP_ADDR);
.
Examples
Basic TCP Socket Example
- Note
- The user should choose the relevant EWF_ALLOCATOR and EWF_ADAPTER macros from this example to use based on the hardware and RTOS being used
#define EWF_LOG_BUFFER_SIZE (256)
#define EWF_MODEM_NETWORK_WAIT_TIME_SECONDS (30)
#define EWF_HTTP_GET_SERVER "www.microsoft.com"
#define EWF_HTTP_GET "GET / HTTP/1.1\r\nHost:www.microsoft.com\r\n\r\n"
#define EWF_HTTP_PORT (80)
ewf_allocator * message_allocator_ptr = NULL;
ewf_interface * interface_ptr = NULL;
ewf_adapter * adapter_ptr = NULL;
char ewf_log_buffer[EWF_LOG_BUFFER_SIZE];
void rm_azure_ewf_gm_example ()
{
static uint8_t buffer[2048];
uint32_t buffer_length = sizeof(buffer);
EWF_ALLOCATOR_THREADX_STATIC_DECLARE(message_allocator_ptr, message_allocator, 12, 2048);
EWF_ALLOCATOR_MEMORY_POOL_STATIC_DECLARE(message_allocator_ptr, message_allocator, 12, 2048);
EWF_ALLOCATOR_C_HEAP_STATIC_DECLARE(message_allocator_ptr, message_allocator, 12, 2048);
EWF_INTERFACE_RA_UART_STATIC_DECLARE(interface_ptr, sci_uart);
EWF_ADAPTER_RENESAS_GM01Q_STATIC_DECLARE(adapter_ptr, renesas_gm01q, message_allocator_ptr, NULL, interface_ptr);
EWF_ADAPTER_RENESAS_GM02S_STATIC_DECLARE(adapter_ptr, renesas_gm02s, message_allocator_ptr, NULL, interface_ptr);
assert(EWF_RESULT_OK == ewf_adapter_start(adapter_ptr));
assert(EWF_RESULT_OK == ewf_adapter_modem_functionality_set(adapter_ptr, "1"));
assert(EWF_RESULT_OK ==
ewf_adapter_modem_network_registration_check(adapter_ptr, EWF_ADAPTER_MODEM_CMD_QUERY_EPS_NETWORK_REG,
EWF_MODEM_NETWORK_WAIT_TIME_SECONDS));
ewf_adapter_modem_packet_service_activate(adapter_ptr, 1);
ewf_socket_tcp socket_tcp = {0};
assert(EWF_RESULT_OK == ewf_adapter_tcp_open(adapter_ptr, &socket_tcp));
assert(EWF_RESULT_OK == ewf_adapter_tcp_connect(&socket_tcp, EWF_HTTP_GET_SERVER, EWF_HTTP_PORT));
assert(EWF_RESULT_OK == ewf_adapter_tcp_send(&socket_tcp, (const uint8_t *) EWF_HTTP_GET, strlen(EWF_HTTP_GET)));
assert(EWF_RESULT_OK == ewf_adapter_tcp_receive(&socket_tcp, buffer, &buffer_length, true));
assert(EWF_RESULT_OK == ewf_adapter_tcp_shutdown(&socket_tcp));
assert(EWF_RESULT_OK == ewf_adapter_tcp_close(&socket_tcp));
}
NetX Duo Example
#define NETXDUO_EXAMPLE_PACKET_SIZE (1568U)
#define NETXDUO_EXAMPLE_PACKET_NUM (100U)
#define NETXDUO_EXAMPLE_PACKET_POOL_SIZE ((sizeof(NX_PACKET) + NETXDUO_EXAMPLE_PACKET_SIZE) * \
NETXDUO_EXAMPLE_PACKET_NUM)
#define NETXDUO_EXAMPLE_IP_STACK_SIZE (2048U)
NX_PACKET_POOL g_packet_pool;
NX_IP g_ip;
static uint8_t g_ip_stack_memory[NETXDUO_EXAMPLE_IP_STACK_SIZE] BSP_ALIGN_VARIABLE(4);
static uint8_t g_packet_pool_memory[NETXDUO_EXAMPLE_PACKET_POOL_SIZE] BSP_ALIGN_VARIABLE(4);
void rm_azure_ewf_gm_netx_example ()
{
uint32_t modem_ip_addr;
EWF_ALLOCATOR_THREADX_STATIC_DECLARE(message_allocator_ptr, message_allocator, 12, 2048);
EWF_INTERFACE_RA_UART_STATIC_DECLARE(interface_ptr, sci_uart);
EWF_ADAPTER_RENESAS_GM01Q_STATIC_DECLARE(adapter_ptr, renesas_gm01q, message_allocator_ptr, NULL, interface_ptr);
EWF_ADAPTER_RENESAS_GM02S_STATIC_DECLARE(adapter_ptr, renesas_gm02s, message_allocator_ptr, NULL, interface_ptr);
assert(EWF_RESULT_OK == ewf_adapter_start(adapter_ptr));
assert(EWF_RESULT_OK == ewf_adapter_modem_functionality_set(adapter_ptr, "1"));
assert(EWF_RESULT_OK ==
ewf_adapter_modem_network_registration_check(adapter_ptr, EWF_ADAPTER_MODEM_CMD_QUERY_EPS_NETWORK_REG,
EWF_MODEM_NETWORK_WAIT_TIME_SECONDS));
ewf_adapter_modem_packet_service_activate(adapter_ptr, 1);
assert(EWF_RESULT_OK == ewf_adapter_get_ipv4_address(adapter_ptr, &modem_ip_addr));
UINT status;
status = nx_packet_pool_create(&g_packet_pool,
"Packet Pool",
NETXDUO_EXAMPLE_PACKET_SIZE,
&g_packet_pool_memory[0],
NETXDUO_EXAMPLE_PACKET_POOL_SIZE);
assert(NX_SUCCESS == status);
status = nx_ip_create(&g_ip,
"IP Instance",
modem_ip_addr,
IP_ADDRESS(255, 255, 255, 0),
&g_packet_pool,
nx_driver_ewf_adapter,
&g_ip_stack_memory[0],
sizeof(g_ip_stack_memory),
15);
assert(NX_SUCCESS == status);
g_ip.nx_ip_interface->nx_interface_additional_link_info = adapter_ptr;
status = nx_ip_gateway_address_set(&g_ip, modem_ip_addr);
assert(NX_SUCCESS == status);
}