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

BSD library initialization

Hello I'm contacting you about the nRF Connect SDK and especially the BSD library.
I’m a student in Embedded Systems and for a personal project in board support package I want to add LTE modem support to Mbed OS for nRF9160 board.
I’ve done a partial Mbed OS support for nRF9160 such as secure and NS mode for GPIOs, UARTE, TIMERS, RTC. The RTOS is working good as the Mbed TLS part.

Now, I would like to add LTE modem support and I’ve found your samples built around Zephyr OS with nrfxlib libraries. Therefore, I had BSD library (soft-float) to Mbed (with headers) and the bsd_os source file (bsd_os.c that is the entry point for BSD library).

I know Nordic samples are done for working with Zephyr and not Mbed and that Mbed support is not covered by this forum. I’m looking for an explanation about the bsd library init (IRQ numbers, IRQ handlers if possible). I also wonder if the bsd library sources are available (but I think this is proprietary).

---------------------------------------------------------------------------------------------------------------------
There is above a description of my problem if useful.

I respected the BSD library needs in terms of security with all the requested peripheral set as NS (like described in the nRF Connect secure boot part). I think I had the right IRQs as described in bsd_os.c and the IRQ handlers are called. However, the end of bsd library init failed (function  authenticated_atcmd_init taken from debug).

Here is what I thing the problem is about. An IRQ is appearing and not handled. However the number (taken from IPSR register is surprising : it’s the 58th and I don’t know what to do).

I attached modified files (taken from git respo).
---------------------------------------------------------------------------------------------------------------------

I’ve not succeed compiling asset_tracker sample (wrong git respos versions and I’ve problems using west for getting the sources). I’m also not sure about the error source because I think that a previous init didn’t work properly.

Could I have an explanation about how the bsd library init work ?
Thanks a lot for your time,

Kindest regards,
Guillaume.


bsd_init.hbsd_irq.h

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

#include <bsd_os.h>
#include <bsd.h>
#include <bsd_platform.h>
#include <nrf.h>

#include <nrf_errno.h>
#include <mbed_error.h>
#include <errno.h>
#include "bsd_init.h"
#include "bsd_irq.h"


#ifdef CONFIG_BSD_LIBRARY_TRACE_ENABLED
#include <nrfx_uarte.h>
#endif

#ifndef ENOKEY
#define ENOKEY 2001
#endif

#ifndef EKEYEXPIRED
#define EKEYEXPIRED 2002
#endif

#ifndef EKEYREVOKED
#define EKEYREVOKED 2003
#endif

#ifndef EKEYREJECTED
#define EKEYREJECTED 2004
#endif

#define UNUSED_FLAGS 0

/* Handle modem traces from IRQ context with lower priority. */
#define TRACE_IRQ EGU2_IRQn
#define TRACE_IRQ_PRIORITY 6

#ifdef CONFIG_BSD_LIBRARY_TRACE_ENABLED
/* Use UARTE1 as a dedicated peripheral to print traces. */
static const nrfx_uarte_t uarte_inst = NRFX_UARTE_INSTANCE(1);
#endif

void IPC_IRQHandler(void);

int32_t bsd_os_timedwait(uint32_t context, uint32_t timeout)
{
	osDelay(timeout);
	return 0;
}


void bsd_os_errno_set(int err_code)
{
	switch (err_code) {
	case NRF_EPERM:
		errno = EPERM;
		break;
	case NRF_ENOENT:
		errno = ENOENT;
		break;
	case NRF_EIO:
		errno = EIO;
		break;
	case NRF_EBADF:
		errno = EBADF;
		break;
	case NRF_ENOMEM:
		errno = ENOMEM;
		break;
	case NRF_EACCES:
		errno = EACCES;
		break;
	case NRF_EFAULT:
		errno = EFAULT;
		break;
	case NRF_EINVAL:
		errno = EINVAL;
		break;
	case NRF_EMFILE:
		errno = EMFILE;
		break;
	case NRF_EAGAIN:
		errno = EAGAIN;
		break;
	case NRF_EPROTOTYPE:
		errno = EPROTOTYPE;
		break;
	case NRF_ENOPROTOOPT:
		errno = ENOPROTOOPT;
		break;
	case NRF_EPROTONOSUPPORT:
		errno = EPROTONOSUPPORT;
		break;
	case NRF_ESOCKTNOSUPPORT:
		errno = ESOCKTNOSUPPORT;
		break;
	case NRF_EOPNOTSUPP:
		errno = EOPNOTSUPP;
		break;
	case NRF_EAFNOSUPPORT:
		errno = EAFNOSUPPORT;
		break;
	case NRF_EADDRINUSE:
		errno = EADDRINUSE;
		break;
	case NRF_ENETDOWN:
		errno = ENETDOWN;
		break;
	case NRF_ENETUNREACH:
		errno = ENETUNREACH;
		break;
	case NRF_ECONNRESET:
		errno = ECONNRESET;
		break;
	case NRF_EISCONN:
		errno = EISCONN;
		break;
	case NRF_ENOTCONN:
		errno = ENOTCONN;
		break;
	case NRF_ETIMEDOUT:
		errno = ETIMEDOUT;
		break;
	case NRF_ENOBUFS:
		errno = ENOBUFS;
		break;
	case NRF_EHOSTDOWN:
		errno = EHOSTDOWN;
		break;
	case NRF_EINPROGRESS:
		errno = EINPROGRESS;
		break;
	case NRF_ECANCELED:
		errno = ECANCELED;
		break;
	case NRF_ENOKEY:
		errno = ENOKEY;
		break;
	case NRF_EKEYEXPIRED:
		errno = EKEYEXPIRED;
		break;
	case NRF_EKEYREVOKED:
		errno = EKEYREVOKED;
		break;
	case NRF_EKEYREJECTED:
		errno = EKEYREJECTED;
		break;
	default:
		errno = EINVAL;
		break;
	}
}

void bsd_os_application_irq_set(void)
{
	NVIC_SetPendingIRQ(BSD_APPLICATION_IRQ);
}

void bsd_os_application_irq_clear(void)
{
	NVIC_ClearPendingIRQ(BSD_APPLICATION_IRQ);
}

void bsd_os_trace_irq_set(void)
{
	NVIC_SetPendingIRQ(TRACE_IRQ);
}

void bsd_os_trace_irq_clear(void)
{
	NVIC_ClearPendingIRQ(TRACE_IRQ);
}

ISR_DIRECT_DECLARE(ipc_proxy_irq_handler)
{
	IPC_IRQHandler();
	ISR_DIRECT_PM(); /* PM done after servicing interrupt for best latency
			  */
	return 1; /* We should check if scheduling decision should be made */
}

ISR_DIRECT_DECLARE(rpc_proxy_irq_handler)
{
	bsd_os_application_irq_handler();
	ISR_DIRECT_PM(); /* PM done after servicing interrupt for best latency
			  */
	return 1; /* We should check if scheduling decision should be made */
}


ISR_DIRECT_DECLARE(trace_proxy_irq_handler)
{
	/*
	 * Process traces.
	 * The function has to be called even if UART traces are disabled.
	 */
	bsd_os_trace_irq_handler();
	ISR_DIRECT_PM(); /* PM done after servicing interrupt for best latency
			  */
	return 1; /* We should check if scheduling decision should be made */
}

void test2(void){
	__asm("bkpt #0");
	
}

void trace_task_create(void)
{
	//IRQ_DIRECT_CONNECT(TRACE_IRQ, TRACE_IRQ_PRIORITY,
			   //trace_proxy_irq_handler, UNUSED_FLAGS);
	NVIC_SetVector(TRACE_IRQ, test2);
	irq_enable(TRACE_IRQ);
}


void test(void){
	__asm("bkpt #0");
	rpc_proxy_irq_handler();
}

void read_task_create(void)
{
	//IRQ_DIRECT_CONNECT(BSD_APPLICATION_IRQ, BSD_APPLICATION_IRQ_PRIORITY,
			   //rpc_proxy_irq_handler, UNUSED_FLAGS);

	NVIC_SetVector(BSD_APPLICATION_IRQ, test);
	irq_enable(BSD_APPLICATION_IRQ);
}


void trace_uart_init(void)
{
#ifdef CONFIG_BSD_LIBRARY_TRACE_ENABLED
	/* UART pins are defined in "nrf9160_pca10090.dts". */
	const nrfx_uarte_config_t config = {
		/* Use UARTE1 pins routed on VCOM2. */
		.pseltxd = UART_1_TX_PIN,
		.pselrxd = UART_1_RX_PIN,
		.pselcts = UART_1_CTS_PIN,
		.pselrts = UART_1_RTS_PIN,

		.hwfc = NRF_UARTE_HWFC_DISABLED,
		.parity = NRF_UARTE_PARITY_EXCLUDED,
		.baudrate = NRF_UARTE_BAUDRATE_1000000,

		/* IRQ handler not used. Blocking mode.*/
		.interrupt_priority = NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY,
		.p_context = NULL,
	};

	/* Initialize nrfx UARTE driver in blocking mode. */
	/* TODO: use UARTE in non-blocking mode with IRQ handler. */
	nrfx_uarte_init(&uarte_inst, &config, NULL);
#endif
}

/* This function is called by bsd_init and must not be called explicitly. */
void bsd_os_init(void)
{
	read_task_create();

	/* Configure and enable modem tracing over UART. */
	//trace_uart_init();
	trace_task_create();
	
}

int32_t bsd_os_trace_put(const uint8_t * const data, uint32_t len)
{
#ifdef CONFIG_BSD_LIBRARY_TRACE_ENABLED
	/* FIXME: Due to a bug in nrfx, max DMA transfers are 255 bytes. */

	/* Split RAM buffer into smaller chunks to be transferred using DMA. */
	u32_t remaining_bytes = len;

	while (remaining_bytes) {
		u8_t transfer_len = min(remaining_bytes, UINT8_MAX);
		u32_t idx = len - remaining_bytes;

		nrfx_uarte_tx(&uarte_inst, &data[idx], transfer_len);
		remaining_bytes -= transfer_len;
	}
#endif

	return 0;
}

void IRQ_58_handler(void){
	__asm("bkpt #0");
}

int _bsd_driver_init()
{
	/* Setup the two IRQs used by the BSD library.
	 * Note: No enable irq_enable here. This is done through bsd_init.
	 */
	//IRQ_DIRECT_CONNECT(BSD_NETWORK_IRQ, BSD_NETWORK_IRQ_PRIORITY, ipc_proxy_irq_handler, UNUSED_FLAGS);
	NVIC_SetVector(IPC_IRQn, ipc_proxy_irq_handler);
	NVIC_SetVector(58, IRQ_58_handler);
	irq_enable(58);
	bsd_init();

	return 0;
}

//SYS_INIT(_bsd_driver_init, POST_KERNEL, 0);


Related