This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Connecting an nRF9160 to AWS

Hello,

I'm attempting to connect the nRF9160 DK to our AWS IoT account. I've been following the information in this question: https://devzone.nordicsemi.com/f/nordic-q-a/44528/switch-cloud-endpoint-from-nordic-aws-to-our-own-aws-account but I'm having an issue establishing the connection.

So far I have been able to call the certificates from a replica of 'certificates.h' and flash these onto the nRF91 using the nrf_inbuilt_key commands and have been able to establish a broker connection but receive a time out error when connecting to AWS with MQTT. I am currently modifying mqtt_simple to acheve this connection.

So far I have updated 'pj.conf' with:

# General config
CONFIG_TEST_RANDOM_GENERATOR=y

# Networking
CONFIG_NETWORKING=y
CONFIG_NET_SOCKETS_OFFLOAD=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y

# LTE link control
CONFIG_LTE_LINK_CONTROL=y
CONFIG_LTE_AUTO_INIT_AND_CONNECT=n
CONFIG_NRF_CLOUD_PROVISION_CERTIFICATES=y

# BSD library
CONFIG_BSD_LIBRARY=y

# AT Host
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_AT_HOST_LIBRARY=y

# MQTT
CONFIG_MQTT_LIB=y
CONFIG_MQTT_LIB_TLS=y

# Appliaction
CONFIG_MQTT_PUB_TOPIC="my/publish/topic"
CONFIG_MQTT_SUB_TOPIC="my/subscribe/topic"
CONFIG_MQTT_CLIENT_ID="MQTT_TEST"
CONFIG_MQTT_BROKER_HOSTNAME="xxxxxxxxxxx.iot.eu-west-1.amazonaws.com" (redacted)
CONFIG_MQTT_BROKER_PORT=8883
CONFIG_NRF_CLOUD_SEC_TAG=1234

# Main thread
CONFIG_MAIN_THREAD_PRIORITY=7
CONFIG_MAIN_STACK_SIZE=4096

CONFIG_HEAP_MEM_POOL_SIZE=1024

I have added the following additional functions to mqtt_simple:

#include "certificates.h"

#define NRF_CLOUD_HOSTNAME CONFIG_MQTT_BROKER_HOSTNAME
#define NRF_CLOUD_SEC_TAG CONFIG_NRF_CLOUD_SEC_TAG

static struct nct {
	struct mqtt_sec_config tls_config;
	struct mqtt_client client;
	struct sockaddr_storage broker;
	struct mqtt_utf8 dc_tx_endp;
	struct mqtt_utf8 dc_rx_endp;
	u32_t message_id;
} nct;

static void client_init(struct mqtt_client *client)
{
	mqtt_client_init(client);

	broker_init();

	/* MQTT client configuration */
	client->broker = &broker;
	client->evt_cb = mqtt_evt_handler;
	client->client_id.utf8 = (u8_t *)CONFIG_MQTT_CLIENT_ID;
	client->client_id.size = strlen(CONFIG_MQTT_CLIENT_ID);
	client->password = NULL;
	client->user_name = NULL;
	client->protocol_version = MQTT_VERSION_3_1_1;

	/* MQTT buffers configuration */
	client->rx_buf = rx_buffer;
	client->rx_buf_size = sizeof(rx_buffer);
	client->tx_buf = tx_buffer;
	client->tx_buf_size = sizeof(tx_buffer);

	nct.client.transport.type = MQTT_TRANSPORT_SECURE;

	struct mqtt_sec_config *tls_config = &nct.client.transport.tls.config;

	memcpy(tls_config, &nct.tls_config, sizeof(struct mqtt_sec_config));
}

static int nct_provision(void)
{
    printk("nct provisions active\n");
    
    static sec_tag_t sec_tag_list[] = {NRF_CLOUD_SEC_TAG};
    
    nct.tls_config.peer_verify = 2;
    nct.tls_config.cipher_count = 0;
    nct.tls_config.cipher_list = NULL;
    nct.tls_config.sec_tag_count = ARRAY_SIZE(sec_tag_list);
    nct.tls_config.sec_tag_list = sec_tag_list;
    nct.tls_config.hostname = CONFIG_MQTT_BROKER_HOSTNAME;
    
    
    int err;
    
    printk("BSD and Cloud provisions defined\n");
    /* Delete certificates */
    nrf_sec_tag_t sec_tag = NRF_CLOUD_SEC_TAG;
    
    for (nrf_key_mgnt_cred_type_t type = 0; type < 5; type++) {
    	err = nrf_inbuilt_key_delete(sec_tag, type);
    	printk("nrf_inbuilt_key_delete(%d, %d) => result=%d\n",
    		sec_tag, type, err);
    }
    err = nrf_inbuilt_key_delete(0,0);
    printk("nrf_inbuilt_key_delete(0, 0) => result=%d\n",
    	err);
    /* Provision CA Certificate. */
    err = nrf_inbuilt_key_write(NRF_CLOUD_SEC_TAG,
    			NRF_KEY_MGMT_CRED_TYPE_CA_CHAIN,
    			NRF_CLOUD_CA_CERTIFICATE,
    			strlen(NRF_CLOUD_CA_CERTIFICATE));
    printk("nrf_inbuilt_key_write(%d, root-CA => result=%d)\n",
    	NRF_CLOUD_SEC_TAG, err);
    if (err) {
    	printk("NRF_CLOUD_CA_CERTIFICATE err: %d", err);
    	return err;
    }
    
    /* Provision Private Certificate. */
    err = nrf_inbuilt_key_write(
    	NRF_CLOUD_SEC_TAG,
    	NRF_KEY_MGMT_CRED_TYPE_PRIVATE_CERT,
    	NRF_CLOUD_CLIENT_PRIVATE_KEY,
    	strlen(NRF_CLOUD_CLIENT_PRIVATE_KEY));
    	printk("nrf_inbuilt_key_write(%d, Private Key => result=%d)\n",
    		NRF_CLOUD_SEC_TAG, err);
    if (err) {
    	printk("NRF_CLOUD_CLIENT_PRIVATE_KEY err: %d", err);
    	return err;
    }
    
    /* Provision Public Certificate. */
    err = nrf_inbuilt_key_write(
    	NRF_CLOUD_SEC_TAG,
    	NRF_KEY_MGMT_CRED_TYPE_PUBLIC_CERT,
    	NRF_CLOUD_CLIENT_PUBLIC_CERTIFICATE,
    	strlen(NRF_CLOUD_CLIENT_PUBLIC_CERTIFICATE));
    	printk("nrf_inbuilt_key_write(%d, Public Cert => result=%d)\n",
    		NRF_CLOUD_SEC_TAG, err);
    if (err) {
    	printk("NRF_CLOUD_CLIENT_PUBLIC_CERTIFICATE err: %d",
    		err);
    	return err;
    }
    return 0;
}

void main(void)
{
	int err;
	int err_provision;
	printk("The MQTT simple sample started\n");

 	err_provision = nct_provision();
	if (err_provision != 0) {
		printk("ERROR: nct_provision failure %d\n", err_provision);
		return;
	}
	printk("err_provision = %d\n", err_provision);
	modem_configure();

	client_init(&client);

I have changed the following in Kconfig:

menu "MQTT simple sample"
config MQTT_PUB_TOPIC
	string "MQTT publish topic"
	default "my/publish/topic"

config MQTT_SUB_TOPIC
	string "MQTT subscribe topic"
	default "my/subscribe/topic"

config MQTT_CLIENT_ID
	string "MQTT Client ID"
	default "MQTT_TEST"

config MQTT_BROKER_HOSTNAME
	string "MQTT broker hostname"
	default "xxxxxxxxx.iot.eu-west-1.amazonaws.com" (redacted)

config MQTT_BROKER_PORT
	int "MQTT broker port"
	default 8883

config MQTT_MESSAGE_BUFFER_SIZE
	int ""
	default 128

config MQTT_PAYLOAD_BUFFER_SIZE
	int ""
	default 128

config NRF_CLOUD_SEC_TAG
	int ""
	default 1234

Finally, the certs are inside certificates.h:

/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: BSD-5-Clause-Nordic
 */

#define NRF_CLOUD_CLIENT_ID "MQTT_TEST"

#define NRF_CLOUD_CLIENT_PRIVATE_KEY \
	"-----BEGIN RSA PRIVATE KEY-----\r\n" \
	"xxxxxxx\r\n" \
	"xxxxxxx\r\n" \
	"xxxxxxx\r\n" \
	"xxxxxxx\r\n" \
	"xxxxxxx\r\n" \
	"xxxxxxx\r\n" \
	"-----END RSA PRIVATE KEY-----\r\n"

#define NRF_CLOUD_CLIENT_PUBLIC_CERTIFICATE \
	"-----BEGIN CERTIFICATE-----\r\n" \
	"xxxxxxx\r\n" \
	"xxxxxxx\r\n" \
	"xxxxxxx\r\n" \
	"xxxxxxx\r\n" \
	"xxxxxxx\r\n" \
	"xxxxxxx\r\n" \
	"-----END CERTIFICATE-----\r\n"

#define NRF_CLOUD_CA_CERTIFICATE \
	"-----BEGIN CERTIFICATE-----\r\n" \
	"xxxxxxx\r\n" \
	"xxxxxxx\r\n" \
	"xxxxxxx\r\n" \
	"xxxxxxx\r\n" \
	"xxxxxxx\r\n" \
	"xxxxxxx\r\n" \
	"-----END CERTIFICATE-----\r\n"

I'm not sure what is still left to change in order to make the connection to AWS.

Parents
  • Hi,

     

    You are using \r\n as the line ending (normal is \n only), but both shall be accepted by the nrf_inbuilt API.

    I do not see any problems specific to your implementation, but what you could do is to verify that you have the latest modem installed, which can be found here:

    https://www.nordicsemi.com/Products/Low-power-cellular-IoT/nRF9160/Download#infotabs

     

    Do you always get the same error message, even if you try several times? if you enter debug mode, and debug the function mqtt_transport_socket_tls.c::mqtt_client_tls_connect(), which function returns the err?

     

    Kind regards,

    Håkon

  • Apologises for the delayed response. I have identified the issue with the connection. Turns out the network provider requires a whitelisted IP address that is incompatible with the dynamic IPs of AWS IoT Core.

    As the device I am using is deployed in another area of the UK, I can't manually update the modem to the latest version without risking something going wrong. I'd rather avoid updating the modem at this moment if I can get away with it. The device is hooked up to a Raspberry Pi with internet access which can faciliate re-flashing with JLinkExe but hasn't been set up with the modem update tools.

    I've been busy figuring out a counter to this issue and have decided to take a different path and use the BSD library to create a UDP connection to a static IP bounded EC2 instance on AWS. I have encountered a different problem with setting up this kind of connection however.

    The code compiles but the nRF9160 reports back a hard fault when the code is loaded onto the device. It will run the code until the UDP IPv4 socket information structure (struct nrf_sockaddr_in) is populated. I've tried to follow what examples I have found of this structure in the ncs repo but I seem to be missing something.

    This is were it appears the code gets to before hard fault, I placed printks to figure out where the code reaches before faulting:

    /**@brief Configures modem to test connection. Blocks until link is
     * successfully established. Creates a UDP socket and connects to
     * AWS EC2 instance
     */
    static int UDP_Socket_Config_and_Connect(void)
    {
    	int err;
    	int UDP_Socket;
    
    	// Sets up UDP Socket information
    	struct nrf_sockaddr_in *UDP_sockaddr;
    			printk("code checkpoint 0\n");
    	UDP_sockaddr->sin_len 					=		sizeof(struct nrf_sockaddr_in);			/**< Length of this data structure */
    			printk("code checkpoint 1\n");
    	UDP_sockaddr->sin_port					=		NRF_HTONS(xxxxx);              	        /**< Port, in network byte order */
    			printk("code checkpoint 2\n");
    	UDP_sockaddr->sin_family 				=		NRF_AF_INET;            				/**< Socket family, IPv4 socket */
    			printk("code checkpoint 3\n");
    	UDP_sockaddr->sin_addr.s_addr	    	= 	    0xXXXXXXXX;							    /**< IPv4 address, in hex format */
    			printk("code checkpoint 4\n");
    
    	UDP_Socket = nrf_socket(NRF_AF_LTE, NRF_SOCK_DGRAM, NRF_IPPROTO_UDP); //Opens UDP socket using UDP protocols
    	if (UDP_Socket == -1) {
    		printk("Socket failed to open\n");
    		return -EFAULT;
    	}
    	printk("Socket created for init\n");
    
    	err = nrf_connect(UDP_Socket, UDP_sockaddr, UDP_sockaddr->sin_len); //Tests connection to UDP IPv4 address
    	if(err)
    	{
    		printk("Failure to establish connection via nrf_connect, closing socket\n");
    		close(UDP_Socket);
    	}
    	close(UDP_Socket);
    	printk("Config and Connect Successful\n");
    	return err;
    }

    This is the UART information when the device resets until faulting:

    Flash region		Domain		Permissions
    00 0x00000 0x02000 	Secure		rwxl
    01 0x02000 0x04000 	Non-Secure	rwxl
    02 0x04000 0x06000 	Non-Secure	rwxl
    03 0x06000 0x08000 	Non-Secure	rwxl
    04 0x08000 0x0a000 	Non-Secure	rwxl
    05 0x0a000 0x0c000 	Non-Secure	rwxl
    06 0x0c000 0x0e000 	Non-Secure	rwxl
    07 0x0e000 0x10000 	Non-Secure	rwxl
    08 0x10000 0x12000 	Non-Secure	rwxl
    09 0x12000 0x14000 	Non-Secure	rwxl
    10 0x14000 0x16000 	Non-Secure	rwxl
    11 0x16000 0x18000 	Non-Secure	rwxl
    12 0x18000 0x1a000 	Non-Secure	rwxl
    13 0x1a00ecure	rwxl
    14 0x1c000 0x1e000 	Non-Secure	rwxl
    15 0x1e000 0x20000 	Non-Secure	rwxl
    16 0x20000 0x22000 	Non-Secure	rwxl
    17 0x22000 0x24000 	Non-Secure	rwxl
    18 0x24000 0x26000 	Non-Secure	rwxl
    19 0x26000 0x28000 	Non-Secure	rwxl
    20 0x28000 0x2a000 	Non-Secure	rwxl
    21 0x2a000 0x2c000 	Non-Secure	rwxl
    22 0x2c000 0x2e000 	Non-Secure	rwxl
    23 0x2e000 0x30000 	Non-Secure	rwxl
    24 0x30000 0x32000 	Non-Secure	rwxl
    25 0x32000 0x34000 	Non-Secure	rwxl
    26 0x34000 0x36000 	Non-Secure	rwxl
    27 0x36000 0x38000 	Non-Secure	rwxl
    28 0x38000 0x3a000 	Non-Secure	rwxl
    29 0x3a000 0x3c000 	Non-Secure	rwxl
    30 0x3c000 0x3e000 	Non-Secure	rwxl
    31 0x3e000 0x40000 	Non-Secure	rwxl
    
    SRAM region		Domain		Permissions
    00 0x00000 0x01000	Secure		rwxl
    01 0x01000 0x02000	Secure		rwxl
    02 0x02000 0x03000	Secure		rwxl
    03 0x03000 0x04000	Secure		rwxl
    04 0x04000 0x05000	Secure		rwxl
    05 0x05000 0x06000	Secure		rwxl
    06 0x06000 0x07000	Secure		rwxl
    07 0x07000 0x08000	Secure		rwxl
    08 0x08000 0x09000	Non-Secure	rwxl
    09 0x09000 0x0a000	Non-Secure	rwxl
    10 0x0a000 0x0b000	Non-Secure	rwxl
    11 0x0b000 0x0c000	Non-Secure	rwxl
    12 0x0c000 0x0d000	Non-Secure	rwxl
    13 0x0d000 0x0e000	Non-Secure	rwxl
    14 0x0e000 0x0f000	Non-Secure	rwxl
    15 0x0f000 0x10000	Non-Secure	rwxl
    16 0x10000 0x11000	Non-Secure	rwxl
    17 0x11000 0x12000	Non-Secure	rwxl
    18 0x12000 0x13000	Non-Secure	rwxl
    19 0x13000 0x14000	Non-Secure	rwxl
    20 0x14000 0x15000	Non-Secure	rwxl
    21 0x15000 0x16000	Non-Secure	rwxl
    22 0x16000 0x17000	Non-Secure	rwxl
    23 0x17000 0x18000	Non-Secure	rwxl
    24 0x18000 0x19000	Non-Secure	rwxl
    25 0x19000 0x1a000	Non-Secure	rwxl
    26 0x1a000 0x1b000	Non-Secure	rwxl
    27 0x1b000 0x1c000	Non-Secure	rwxl
    28 0x1c000 0x1d000	Non-Secure	rwxl
    29 0x1d000 0x1e000	Non-Secure	rwxl
    30 0x1e000 0x1f000	Non-Secure	rwxl
    31 0x1f000 0x20000	Non-Secure	rwxl
    
    Peripheral		Domain		Status
    00 NRF_P0		Non-Secure	OK
    01 NRF_CLOCK		Non-Secure	OK
    02 NRF_RTC1		Non-Secure	OK
    03 NRF_NVMC		Non-Secure	OK
    04 NRF_UARTE1		Non-Secure	OK
    05 NRF_UARTE2		Secure		SKIP
    06 NRF_IPC		Non-Secure	OK
    07 NRF_VMC		Non-Secure	OK
    08 NRF_FPU		Non-Secure	ERROR
    09 NRF_EGU1		Non-Secure	OK
    10 NRF_EGU2		Non-Secure	OK
    11 NRF_TWIM2		Non-Secure	OK
    12 NRF_SPIM3		Non-Secure	OK
    13 NRF_TIMER0		Non-Secure	OK
    14 NRF_TIMER1		Non-Secure	OK
    15 NRF_TIMER2		Non-Secure	OK
    16 NRF_SAADC		Non-Secure	OK
    17 NRF_GPIOTE1		Non-Secure	OK
    
    SPM: MSP_NS 20022e00
    SPM: prepare to jump to Non-Secure image
    ***** Booting Zephyr OS v1.13.99-ncs1-6044-g4eaddb50e90b *****
    UDP_Test Application started
    code checkpoint 0
    Exception occurred in Secure State
    ***** HARD FAULT *****
      Fault escalation (see below)
    ***** BUS FAULT *****
      Precise data bus error
      BFAR Address: 0x50008120
    ***** Hardware exception *****
    Current thread ID = 0x20020150
    Faulting instruction address = 0x93da
    Fatal fault in ISR! Spinning...

    This is main.c

    /*
     * Copyright (c) 2018 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
     */
    
    #include <zephyr.h>
    #include <stdio.h>
    #include <uart.h>
    #include <string.h>
    
    //#include "certificates.h"
    //#include "provisions/provision.h"
    #include "../../../../../nrfxlib/bsdlib/include/nrf_socket.h"
    
    #if defined(CONFIG_BSD_LIBRARY)
    
    /**@brief Recoverable BSD library error. */
    void bsd_recoverable_error_handler(uint32_t err)
    {
    	printk("bsdlib recoverable error: %u\n", err);
    }
    
    /**@brief Irrecoverable BSD library error. */
    void bsd_irrecoverable_error_handler(uint32_t err)
    {
    	printk("bsdlib irrecoverable error: %u\n", err);
    
    	__ASSERT_NO_MSG(false);
    }
    
    #endif /* defined(CONFIG_BSD_LIBRARY) */
    
    // #if defined(CONFIG_BSD_LIBRARY) //Includes nrf secure key manager code, not impliment yet
    // #include "nrf_inbuilt_key.h"
    // #endif
    
    /**@brief Configures modem to test connection. Blocks until link is
     * successfully established. Creates a UDP socket and connects to
     * AWS EC2 instance
     */
    static int UDP_Socket_Config_and_Connect(void)
    {
    	int err;
    	int UDP_Socket;
    
    	// Sets up UDP Socket information
    	struct nrf_sockaddr_in *UDP_sockaddr;
    			printk("code checkpoint 0\n");
    	UDP_sockaddr->sin_len 					=		sizeof(struct nrf_sockaddr_in);						/**< Length of this data structure */
    			printk("code checkpoint 1\n");
    	UDP_sockaddr->sin_port					=		NRF_HTONS(xxxxx);              	/**< Port, in network byte order */
    			printk("code checkpoint 2\n");
    	UDP_sockaddr->sin_family 				=		NRF_AF_INET;            				/**< Socket family, IPv4 socket */
    			printk("code checkpoint 3\n");
    	UDP_sockaddr->sin_addr.s_addr		= 	0xXXXXXXXX;											/**< IPv4 address, in hex format */
    			printk("code checkpoint 4\n");
    
    	UDP_Socket = nrf_socket(NRF_AF_LTE, NRF_SOCK_DGRAM, NRF_IPPROTO_UDP); //Opens UDP socket using UDP protocols
    	if (UDP_Socket == -1) {
    		printk("Socket failed to open\n");
    		return -EFAULT;
    	}
    	printk("Socket created for init\n");
    
    	err = nrf_connect(UDP_Socket, UDP_sockaddr, UDP_sockaddr->sin_len); //Tests connection to UDP IPv4 address
    	if(err)
    	{
    		printk("Failure to establish connection via nrf_connect, closing socket\n");
    		close(UDP_Socket);
    	}
    	close(UDP_Socket);
    	printk("Config and Connect Successful\n");
    	return err;
    }
    
    /**@brief Sends a test UDP packet to AWS. Uses non-blocking mode. */
    
    static int UDP_Send(const char *UDP_buff)
    {
    	int err;
    	int UDP_Socket;
    
    	struct nrf_sockaddr_in *UDP_sockaddr;
    	UDP_sockaddr->sin_family =		NRF_AF_INET;            				/**< Socket family. */
    	UDP_sockaddr->sin_port		=		NRF_HTONS(xxxxx);              	/**< Port, in network byte order. */
    	UDP_sockaddr->sin_addr.s_addr		= 	0xXXXXXXXX;								/**< IPv4 address. */
    	UDP_sockaddr->sin_len 		=		sizeof(struct nrf_sockaddr_in);						/**< Length of this data structure. */
    
    	UDP_Socket = nrf_socket(NRF_AF_LTE, NRF_SOCK_DGRAM, NRF_IPPROTO_UDP);
    	if (UDP_Socket == -1) {
    		printk("Socket failed to open\n");
    		return -EFAULT;
    	}
    	printk("Socket created for transfer\n");
    
    	err = nrf_connect(UDP_Socket, UDP_sockaddr, UDP_sockaddr->sin_len);
    	if(err)
    	{
    		printk("Failure to establish connection via nrf_connect, closing socket\n");
    		close(UDP_Socket);
    	}
    	printk("Send socket connected\n");
    	return err;
    
    	err = nrf_send(UDP_Socket, UDP_buff, strlen(UDP_buff), NRF_MSG_DONTWAIT); //Sends UDP Buffer to AWS EC2 with non-blocking flag
    	if (err)
    	{
    		printk("Error sending %s to IP %08x\n", UDP_buff, UDP_sockaddr->sin_addr.s_addr);
    		close(UDP_Socket);
    	}
    	printk("Sent %s to IP %08x\n", UDP_buff, UDP_sockaddr->sin_addr.s_addr);
    }
    
    void main(void)
    {
    	printk("UDP_Test Application started\n");
    
    	const char Buff[] = "Hello World\n";
    
    	//Set up Zephyr 10 second timer that will call UDP_Send
    	struct k_timer my_timer;
    	void my_work_handler(struct k_timer *timer_1)
    	{
    		UDP_Send(Buff);
    		printk("timer triggered!\n");
    	}
    
    	UDP_Socket_Config_and_Connect(); //Test UDP connection
    
    	//Initialize and activate timer
    	k_timer_init(&my_timer, my_work_handler, NULL);
    	k_timer_start(&my_timer, K_SECONDS(10), K_SECONDS(10));
    
    	while(true)
    	{
    		k_sleep(K_MSEC(10));
    		/* Put CPU to idle to save power */
    		k_cpu_idle();
    	}
    }
    

    EDIT: I should clarify, I have one DK deployed in an area of NB-IoT coverage that can be re-flashed remotely. I have a second DK beside me that I can use to test flashes operate as expected, but without any NB-IoT coverage in this area, before taking the merged zephyr hex file and remotely flashing using JLinkExe.

  • Hi,

    I copied across the files for the ntp example and ran it as it is in the repo.

    Did it require a specific checkout of the supporting repos (Zephyr, MCUBoot, nrfxlib)?

    Running it as is ended with a bus fault after getaddrinfo. Never made it to socket creation.

    ***** Booting Zephyr OS v1.14.99-ncs1-3-g3c4f27282002 *****
    Flash region		Domain		Permissions
    00 0x00000 0x08000 	Secure		rwxl
    01 0x08000 0x10000 	Non-Secure	rwxl
    02 0x10000 0x18000 	Non-Secure	rwxl
    03 0x18000 0x20000 	Non-Secure	rwxl
    04 0x20000 0x28000 	Non-Secure	rwxl
    05 0x28000 0x30000 	Non-Secure	rwxl
    06 0x30000 0x38000 	Non-Secure	rwxl
    07 0x38000 0x40000 	Non-Secure	rwxl
    08 0x40000 0x48000 	Non-Secure	rwxl
    09 0x48000 0x50000 	Non-Secure	rwxl
    10 0x50000 0x58000 	Non-Secure	rwxl
    11 0x58000 0x60000 	Non-Secure00 	Non-Secure	rwxl
    13 0x68000 0x70000 	Non-Secure	rwxl
    14 0x70000 0x78000 	Non-Secure	rwxl
    15 0x78000 0x80000 	Non-Secure	rwxl
    16 0x80000 0x88000 	Non-Secure	rwxl
    17 0x88000 0x90000 	Non-Secure	rwxl
    18 0x90000 0x98000 	Non-Secure	rwxl
    19 0x98000 0xa0000 	Non-Secure	rwxl
    20 0xa0000 0xa8000 	Non-Secure	rwxl
    21 0xa8000 0xb0000 	Non-Secure	rwxl
    22 0xb0000 0xb8000 	Non-Secure	rwxl
    23 0xb8000 0xc0000 	Non-Secure	rwxl
    24 0xc0000 0xc8000 	Non-Secure	rwxl
    25 0xc8000 0xd0000 	Non-Secure	rwxl
    26 0xd0000 0xd8000 	Non-Secure	rwxl
    27 0xd8000 0xe0000 	Non-Secure	rwxl
    28 0xe0000 0xe8000 	Non-Secure	rwxl
    29 0xe8000 0xf0000 	Non-Secure	rwxl
    30 0xf0000 0xf8000 	Non-Secure	rwxl
    31 0xf8000 0x100000 	Non-Secure	rwxl
    
    SRAM region		Domain		Permissions
    00 0x00000 0x02000	Secure		rwxl
    01 0x02000 0x04000	Secure		rwxl
    02 0x04000 0x06000	Secure		rwxl
    03 0x06000 0x08000	Secure		rwxl
    04 0x08000 0x0a000	Secure		rwxl
    05 0x0a000 0x0c000	Secure		rwxl
    06 0x0c000 0x0e000	Secure		rwxl
    07 0x0e000 0x10000	Secure		rwxl
    08 0x10000 0x12000	Non-Secure	rwxl
    09 0x12000 0x14000	Non-Secure	rwxl
    10 0x14000 0x16000	Non-Secure	rwxl
    11 0x16000 0x18000	Non-Secure	rwxl
    12 0x18000 0x1a000	Non-Secure	rwxl
    13 0x1a000 0x1c000	Non-Secure	rwxl
    14 0x1c000 0x1e000	Non-Secure	rwxl
    15 0x1e000 0x20000	Non-Secure	rwxl
    16 0x20000 0x22000	Non-Secure	rwxl
    17 0x22000 0x24000	Non-Secure	rwxl
    18 0x24000 0x26000	Non-Secure	rwxl
    19 0x26000 0x28000	Non-Secure	rwxl
    20 0x28000 0x2a000	Non-Secure	rwxl
    21 0x2a000 0x2c000	Non-Secure	rwxl
    22 0x2c000 0x2e000	Non-Secure	rwxl
    23 0x2e000 0x30000	Non-Secure	rwxl
    24 0x30000 0x32000	Non-Secure	rwxl
    25 0x32000 0x34000	Non-Secure	rwxl
    26 0x34000 0x36000	Non-Secure	rwxl
    27 0x36000 0x38000	Non-Secure	rwxl
    28 0x38000 0x3a000	Non-Secure	rwxl
    29 0x3a000 0x3c000	Non-Secure	rwxl
    30 0x3c000 0x3e000	Non-Secure	rwxl
    31 0x3e000 0x40000	Non-Secure	rwxl
    
    Peripheral		Domain		Status
    00 NRF_P0		Non-Secure	OK
    01 NRF_CLOCK		Non-Secure	OK
    02 NRF_RTC1		Non-Secure	OK
    03 NRF_NVMC		Non-Secure	OK
    04 NRF_UARTE1		Non-Secure	OK
    05 NRF_UARTE2		Secure		SKIP
    06 NRF_IPC		Non-Secure	OK
    07 NRF_VMC		Non-Secure	OK
    08 NRF_FPU		Non-Secure	OK
    09 NRF_EGU1		Non-Secure	OK
    10 NRF_EGU2		Non-Secure	OK
    11 NRF_TWIM2		Non-Secure	OK
    12 NRF_SPIM3		Non-Secure	OK
    13 NRF_TIMER0		Non-Secure	OK
    14 NRF_TIMER1		Non-Secure	OK
    15 NRF_TIMER2		Non-Secure	OK
    16 NRF_SAADC		Non-Secure	OK
    17 NRF_GPIOTE1		Non-Secure	OK
    
    SPM: NS image at 0x8000
    SPM: NS MSP at 0x200232d0
    SPM: NS reset vector at 0xedd9
    SPM: prepare to jump to Non-Secure image.
    ***** Booting Zephyr OS v1.14.99-ncs1-3-g3c4f27282002 *****
    getaddrinfo err: 22
    
    Exception occurred in Secure State
    ***** HARD FAULT *****
      Fault escalation (see below)
    ***** BUS FAULT *****
      Precise data bus error
      BFAR Address: 0x50008120
    ***** Hardware exception *****
    Current thread ID = 0x2002026c
    Faulting instruction address = 0xd904
    Fatal fault in ISR! Spinning...

  • the getaddrinfo fails, indicating that your telecom provider might not provide DNS.

    You could try the ftp example in the same repository, as it hardcodes the IP to ftp.uninett.no.

     

    Kind regards,

    Håkon

  • Hi,

    I tried the ftp example, both as it is in the repo and edited. The code doesn't make it past boot up. The printk() line for the application start does not get sent to the link monitor, program just hard faults again. Error fault address at 0x0

    You are correct, my provider does not support anything other than a whitelisted IP address given to them in advance.

    I have gone back to my original program that was giving back the errno 134. Taking what you said, I have removed all <net/socket> commands and used only the nrf_socket library. The code now reports an errno of 22 which I believe is EINVAL (invalid argument) so at least it's not erroring an unknown value for errno.

    ***** Booting Zephyr OS v1.14.99-ncs1-3-g3c4f27282002 *****
    UDP_Test Application started
    Socket ID: 2
    Modem enabled
    Socket created for init
    Socket ID: 2
    Attempting to establish connection to EC2
    Connect Error: -1:22
    

    Arguments passed to blocking_connect():

    	int err;
    	int UDP_Socket;
    	ssize_t bytes_sent;
    
    	struct nrf_sockaddr_in my_sockaddr; // memset if not populating everything
    	struct nrf_sockaddr_in *UDP_sockaddr = &my_sockaddr;
    	UDP_sockaddr->sin_len 					=		sizeof(struct nrf_sockaddr_in);			/**< Length of this data structure */
    	UDP_sockaddr->sin_port					=		NRF_HTONS(xxxxx);              	        /**< Port, in network byte order */
    	UDP_sockaddr->sin_family 				=		NRF_AF_INET;            				/**< Socket family, IPv4 socket */
    	UDP_sockaddr->sin_addr.s_addr	  = 	0xXXXXXXXX;							    /**< IPv4 address, in hex format */
    
    	UDP_Socket = nrf_socket(NRF_AF_INET, NRF_SOCK_DGRAM, 0);
    	printk("Socket ID: %d\n", UDP_Socket);
    	if (UDP_Socket == -1)
    	{
    		printk("Socket failed to open\n");
    		return -EFAULT;
    	}
    	else
    	{
    		printk("Socket created for transfer\n");
    	}
    
    	err = blocking_connect(UDP_Socket, (struct nrf_sockaddr *)&UDP_sockaddr, sizeof(struct nrf_sockaddr_in));

    I also want to check the required prj.conf in case this is also causing issues; apologises if this is all wrong, never used this kind of file structure before and I'm piecing it together with what I learn from the other examples. Unlike the other examples, I'm not calling Link Control as the code should manually init the modem (it needs to be able to do this to change between NB-IoT and GPS later). The one I'm currently using is:

    # Use the development test RNG (not for production)
    CONFIG_TEST_RANDOM_GENERATOR=y
    
    # Networking, enable networking APIs
    CONFIG_NETWORKING=y
    CONFIG_NET_SOCKETS_OFFLOAD=y
    CONFIG_NET_SOCKETS=y
    
    # Allow Socket APIs to use POSIX names like socket(), send(), etc
    # Careful with close(), close() only works on sockets when enabled
    CONFIG_NET_SOCKETS_POSIX_NAMES=y
    
    # BSD library
    CONFIG_BSD_LIBRARY=y
    
    # Main thread, reuse init stack
    CONFIG_MAIN_THREAD_PRIORITY=7
    CONFIG_MAIN_STACK_SIZE=4096
    
    # Available memory for k_malloc
    CONFIG_HEAP_MEM_POOL_SIZE=1024
    
    # Enable stdout for printfs
    CONFIG_STDOUT_CONSOLE=y
    
    # Logging
    CONFIG_LOG=y
    CONFIG_LOG_DEFAULT_LEVEL=4
    
    # Build with newlib c library
    CONFIG_NEWLIB_LIBC=y
    CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
    
    # Enable non-secure firmware as Normal mode
    CONFIG_TRUSTED_EXECUTION_NONSECURE=y
    

    Also, a question about the ftp code. In that code there is a converter for IP to Hex, inet_addr(). I implimented this into my code and printed the result to find that the IP address was backwards from what I expected it to be using manual conversion or something like https://www.browserling.com/tools/ip-to-hex . I have amended the function to put the bytes in the order I would expect but just want to check, is it supposed to be that way or is that an oversight in this checkout?

    Michael

    EDIT:

    I made a seperate version of the code that uses only the net/sockets.h library (like all examples of the nRF9160's data transfer capablities), it is doing the same as before, errno is 134 again. I'm not sure what else needs to be done to make this code block until connection.

  • Hi,

     

     

    MJD093 said:
    I tried the ftp example, both as it is in the repo and edited. The code doesn't make it past boot up. The printk() line for the application start does not get sent to the link monitor, program just hard faults again. Error fault address at 0x0

     Sorry, this is an issue with the newer code base, where it requires a higher stack size for the main thread. Could you try to add this line to the prj.conf and see if it helps?

    CONFIG_MAIN_STACK_SIZE=4096

     

    MJD093 said:
    I have gone back to my original program that was giving back the errno 134. Taking what you said, I have removed all <net/socket> commands and used only the nrf_socket library. The code now reports an errno of 22 which I believe is EINVAL (invalid argument) so at least it's not erroring an unknown value for errno.

    Have you removed all the socket APIs, and used the nrf_* prefixed function calls?

     

    MJD093 said:
    Also, a question about the ftp code. In that code there is a converter for IP to Hex, inet_addr(). I implimented this into my code and printed the result to find that the IP address was backwards from what I expected it to be using manual conversion or something like https://www.browserling.com/tools/ip-to-hex . I have amended the function to put the bytes in the order I would expect but just want to check, is it supposed to be that way or is that an oversight in this checkout?

     This is due to byte ordering on ARM vs. x86. The function in firmware is correct for ARM LE arch.

     

    MJD093 said:
    I made a seperate version of the code that uses only the net/sockets.h library (like all examples of the nRF9160's data transfer capablities), it is doing the same as before, errno is 134 again. I'm not sure what else needs to be done to make this code block until connection.

     No nrf_* prefixed structs or function calls? I am very unsure what this errno is, as there's nothing that should set it to this value. How are you printing the errno?

     

    Kind regards,

    Håkon

  • CONFIG_MAIN_STACK_SIZE=4096

    Ok so that solved the hard fault error but the main program still doesn't seem to load into the main loop. Device boots up Zephyr and then, nothing. Link Monitor just ends there. No printk for the application starting nor any other printks for errors or ones added to check liveness.

    10 NRF_EGU2		Non-Secure	OK
    11 NRF_TWIM2		Non-Secure	OK
    12 NRF_SPIM3		Non-Secure	OK
    13 NRF_TIMER0		Non-Secure	OK
    14 NRF_TIMER1		Non-Secure	OK
    15 NRF_TIMER2		Non-Secure	OK
    16 NRF_SAADC		Non-Secure	OK
    17 NRF_GPIOTE1		Non-Secure	OK
    
    SPM: NS image at 0x8000
    SPM: NS MSP at 0x20023688
    SPM: NS reset vector at 0xd8fd
    SPM: prepare to jump to Non-Secure image.
    ***** Booting Zephyr OS v1.14.99-ncs1-3-g3c4f27282002 *****

    Have you removed all the socket APIs, and used the nrf_* prefixed function calls?

    I believe so yes, I have edited all socket commands to use the nrf_* prefixed versions found in nrf_socket.h. <net/sockets> has been removed and should flag errors if I try to call any non-nrf_* socket commands.

    I have been doing some reading into the Socket API and in any example, this is the way the connect API is called and its arguments are set. Not sure why it would return EINVAL.

     This is due to byte ordering on ARM vs. x86. The function in firmware is correct for ARM LE arch.

    Ok, I have returned that function back to the way it is set in the ftp example.

     No nrf_* prefixed structs or function calls? I am very unsure what this errno is, as there's nothing that should set it to this value. How are you printing the errno?

    None. As mentioned before, in this example I no longer include nrf_socket.h so all references to nrf_* prefixed commands cause compilation errors.

    Unless I'm mistaken, errno is just an int value that is defined in errno.h to represent different error types. So I have just been printing err and errno as:

    	printk("Attempting to establish connection to EC2\n");
    	do {
    		err = connect(UDP_Socket, (struct sockaddr *)&UDP_sockaddr, sizeof(UDP_sockaddr));
    	} while (err < 0 && errno == EAGAIN);
    
    		printk("Connect Error: %d:%d\n", err, errno);

    When in the code for the nrf_* prefixed version, it returns this value, err = -1 and errno = 22:

    Timer trigger for UDPSend!
    Socket ID: 2
    Socket created for transfer
    Attempting to establish connection to EC2
    Connect Error: -1:22
    Failure to establish connection via nrf_connect, closing socket

    When in the code for the non-nrf_* version, it returns this value, err = -1 and errno = 134:

    Socket ID: 2
    Socket created for transfer
    Attempting to establish connection to EC2
    Connect Error: -1:134
    Failure to establish connection via nrf_connect, closing socket

    EDIT:

    I think I got the error. This is UDP and connect() is supposed to auto return immediately under DGRAM. It's not supposed to take any time to connect so blocking isn't necessary as all connect() does for UDP is assign a destination address to the socket without attempting to request a connection and receive an ACK back. Blocking makes sense from the examples as they used TCP Sockets.

    As for the connect() failing with err = -1, I believe it was the line:

    struct sockaddr_in *UDP_sockaddr = &my_sockaddr;

    Removing the * and making a sole struct with [struct sockaddr_in UDP_sockaddr] seems to let err = 0 and errno = 0.

    	int err;
    	int UDP_Socket;
    
    	// Sets up UDP Socket information
    	struct sockaddr_in UDP_sockaddr;
    	UDP_sockaddr.sin_port						=		htons(xxxx);              	/**< Port, in network byte order */
    	UDP_sockaddr.sin_family 				=		AF_INET;            				/**< Socket family, IPv4 socket */
    	UDP_sockaddr.sin_addr.s_addr	  = 	inet_addr(xx,xx,xxx,xx);		/**< IPv4 address, in hex format */
    	printk("IP address: %x\n", UDP_sockaddr.sin_addr.s_addr);
    
    	UDP_Socket = socket(AF_INET, SOCK_DGRAM, 0); //Opens UDP socket using UDP protocols

    I am also curious if errno is actually cleared between functions as send() will fail on my test kit as it can't actually attach to a network to execute the send() command. As send() fails it reports errno as 114 which then appears for the connect() function's errno when it is called again, Setting errno = 0 after the send() function errors out shows that errno still is 0 (and not 114) when connect is called during the next timer trigger.

    The new Link Monitor output is:

    16 NRF_SAADC		Non-Secure	OK
    17 NRF_GPIOTE1		Non-Secure	OK
    
    SPM: NS image at 0x8000
    SPM: NS MSP at 0x200232e8
    SPM: NS reset vector at 0xd97d
    SPM: prepare to jump to Non-Secure image.
    ***** Booting Zephyr OS v1.14.99-ncs1-3-g3c4f27282002 *****
    UDP_Test Application started
    Socket ID: 2
    Sending AT command: AT+CFUN=4
    Modem response: OK
    Sending AT command: AT%XSYSTEMMODE=0,1,0,0
    Modem response: OK
    Sending AT command: AT%XMAGPIO
    Modem response: OK
    Sending AT command: AT+CFUN=1
    Modem response: OK
    Modem enabled
    IP address: XXXXXXXX
    Socket created for init
    Socket ID: 2
    Attempting to establish connection to EC2
    Connect Error: 0:0
    Config and Connect Successful
    Socket ID: 2
    Socket created for transfer
    Attempting to establish connection to EC2
    Connect Error: 0:0
    Send socket connected
    Error sending Hello AWS
     to IP XXXXXXXX
    Send Error: -1:114
    Dropping into main while loop
    Timer trigger for UDPSend!
    Socket ID: 2
    Socket created for transfer
    Attempting to establish connection to EC2
    Connect Error: 0:0
    Send socket connected
    Error sending Timer Trigger
     to IP XXXXXXXX
    Send Error: -1:114
    

    Happily, this has also solved the issue where sockets would start to fail to be created (even though the sockets were closing after failing out) after about 7 timer calls. I hope to be able to test this bit of code soon when the remote kit in an NB-IoT area is available tomorrow. Will update when I test it.

Reply
  • CONFIG_MAIN_STACK_SIZE=4096

    Ok so that solved the hard fault error but the main program still doesn't seem to load into the main loop. Device boots up Zephyr and then, nothing. Link Monitor just ends there. No printk for the application starting nor any other printks for errors or ones added to check liveness.

    10 NRF_EGU2		Non-Secure	OK
    11 NRF_TWIM2		Non-Secure	OK
    12 NRF_SPIM3		Non-Secure	OK
    13 NRF_TIMER0		Non-Secure	OK
    14 NRF_TIMER1		Non-Secure	OK
    15 NRF_TIMER2		Non-Secure	OK
    16 NRF_SAADC		Non-Secure	OK
    17 NRF_GPIOTE1		Non-Secure	OK
    
    SPM: NS image at 0x8000
    SPM: NS MSP at 0x20023688
    SPM: NS reset vector at 0xd8fd
    SPM: prepare to jump to Non-Secure image.
    ***** Booting Zephyr OS v1.14.99-ncs1-3-g3c4f27282002 *****

    Have you removed all the socket APIs, and used the nrf_* prefixed function calls?

    I believe so yes, I have edited all socket commands to use the nrf_* prefixed versions found in nrf_socket.h. <net/sockets> has been removed and should flag errors if I try to call any non-nrf_* socket commands.

    I have been doing some reading into the Socket API and in any example, this is the way the connect API is called and its arguments are set. Not sure why it would return EINVAL.

     This is due to byte ordering on ARM vs. x86. The function in firmware is correct for ARM LE arch.

    Ok, I have returned that function back to the way it is set in the ftp example.

     No nrf_* prefixed structs or function calls? I am very unsure what this errno is, as there's nothing that should set it to this value. How are you printing the errno?

    None. As mentioned before, in this example I no longer include nrf_socket.h so all references to nrf_* prefixed commands cause compilation errors.

    Unless I'm mistaken, errno is just an int value that is defined in errno.h to represent different error types. So I have just been printing err and errno as:

    	printk("Attempting to establish connection to EC2\n");
    	do {
    		err = connect(UDP_Socket, (struct sockaddr *)&UDP_sockaddr, sizeof(UDP_sockaddr));
    	} while (err < 0 && errno == EAGAIN);
    
    		printk("Connect Error: %d:%d\n", err, errno);

    When in the code for the nrf_* prefixed version, it returns this value, err = -1 and errno = 22:

    Timer trigger for UDPSend!
    Socket ID: 2
    Socket created for transfer
    Attempting to establish connection to EC2
    Connect Error: -1:22
    Failure to establish connection via nrf_connect, closing socket

    When in the code for the non-nrf_* version, it returns this value, err = -1 and errno = 134:

    Socket ID: 2
    Socket created for transfer
    Attempting to establish connection to EC2
    Connect Error: -1:134
    Failure to establish connection via nrf_connect, closing socket

    EDIT:

    I think I got the error. This is UDP and connect() is supposed to auto return immediately under DGRAM. It's not supposed to take any time to connect so blocking isn't necessary as all connect() does for UDP is assign a destination address to the socket without attempting to request a connection and receive an ACK back. Blocking makes sense from the examples as they used TCP Sockets.

    As for the connect() failing with err = -1, I believe it was the line:

    struct sockaddr_in *UDP_sockaddr = &my_sockaddr;

    Removing the * and making a sole struct with [struct sockaddr_in UDP_sockaddr] seems to let err = 0 and errno = 0.

    	int err;
    	int UDP_Socket;
    
    	// Sets up UDP Socket information
    	struct sockaddr_in UDP_sockaddr;
    	UDP_sockaddr.sin_port						=		htons(xxxx);              	/**< Port, in network byte order */
    	UDP_sockaddr.sin_family 				=		AF_INET;            				/**< Socket family, IPv4 socket */
    	UDP_sockaddr.sin_addr.s_addr	  = 	inet_addr(xx,xx,xxx,xx);		/**< IPv4 address, in hex format */
    	printk("IP address: %x\n", UDP_sockaddr.sin_addr.s_addr);
    
    	UDP_Socket = socket(AF_INET, SOCK_DGRAM, 0); //Opens UDP socket using UDP protocols

    I am also curious if errno is actually cleared between functions as send() will fail on my test kit as it can't actually attach to a network to execute the send() command. As send() fails it reports errno as 114 which then appears for the connect() function's errno when it is called again, Setting errno = 0 after the send() function errors out shows that errno still is 0 (and not 114) when connect is called during the next timer trigger.

    The new Link Monitor output is:

    16 NRF_SAADC		Non-Secure	OK
    17 NRF_GPIOTE1		Non-Secure	OK
    
    SPM: NS image at 0x8000
    SPM: NS MSP at 0x200232e8
    SPM: NS reset vector at 0xd97d
    SPM: prepare to jump to Non-Secure image.
    ***** Booting Zephyr OS v1.14.99-ncs1-3-g3c4f27282002 *****
    UDP_Test Application started
    Socket ID: 2
    Sending AT command: AT+CFUN=4
    Modem response: OK
    Sending AT command: AT%XSYSTEMMODE=0,1,0,0
    Modem response: OK
    Sending AT command: AT%XMAGPIO
    Modem response: OK
    Sending AT command: AT+CFUN=1
    Modem response: OK
    Modem enabled
    IP address: XXXXXXXX
    Socket created for init
    Socket ID: 2
    Attempting to establish connection to EC2
    Connect Error: 0:0
    Config and Connect Successful
    Socket ID: 2
    Socket created for transfer
    Attempting to establish connection to EC2
    Connect Error: 0:0
    Send socket connected
    Error sending Hello AWS
     to IP XXXXXXXX
    Send Error: -1:114
    Dropping into main while loop
    Timer trigger for UDPSend!
    Socket ID: 2
    Socket created for transfer
    Attempting to establish connection to EC2
    Connect Error: 0:0
    Send socket connected
    Error sending Timer Trigger
     to IP XXXXXXXX
    Send Error: -1:114
    

    Happily, this has also solved the issue where sockets would start to fail to be created (even though the sockets were closing after failing out) after about 7 timer calls. I hope to be able to test this bit of code soon when the remote kit in an NB-IoT area is available tomorrow. Will update when I test it.

Children
Related