add support for NuttX

This commit is contained in:
Matias N
2020-09-20 16:33:49 -03:00
committed by Andrzej Kaczmarek
parent 542806abc0
commit c14c47bb68
37 changed files with 3663 additions and 11 deletions
+1
View File
@@ -21,6 +21,7 @@
#define H_BLE_HS_LOG_
#include "modlog/modlog.h"
#include "log/log.h"
/* Only include the logcfg header if this version of newt can generate it. */
#if MYNEWT_VAL(NEWT_FEATURE_LOGCFG)
@@ -28,4 +28,6 @@
int ble_svc_bas_battery_level_set(uint8_t level);
void ble_svc_bas_init(void);
#endif
@@ -34,6 +34,7 @@ extern "C" {
#define BLE_SVC_GAP_APPEARANCE_GEN_UNKNOWN 0
#define BLE_SVC_GAP_APPEARANCE_GEN_COMPUTER 128
#define BLE_SVC_GAP_APPEARANCE_GEN_HID 960
#define BLE_SVC_GAP_APPEARANCE_CYC_SPEED_AND_CADENCE_SENSOR 1157
typedef void (ble_svc_gap_chr_changed_fn) (uint16_t uuid);
+171 -10
View File
@@ -53,19 +53,22 @@
#if MYNEWT_VAL(BLE_SOCK_USE_LINUX_BLUE)
#include <sys/errno.h>
#define BTPROTO_HCI 1
#define HCI_CHANNEL_RAW 0
#define HCI_CHANNEL_USER 1
#define HCIDEVUP _IOW('H', 201, int)
#define HCIDEVDOWN _IOW('H', 202, int)
#define HCIDEVRESET _IOW('H', 203, int)
#define HCIGETDEVLIST _IOR('H', 210, int)
#define BTPROTO_HCI 1
#define HCI_CHANNEL_RAW 0
#define HCI_CHANNEL_USER 1
#define HCIDEVUP _IOW('H', 201, int)
#define HCIDEVDOWN _IOW('H', 202, int)
#define HCIDEVRESET _IOW('H', 203, int)
#define HCIGETDEVLIST _IOR('H', 210, int)
struct sockaddr_hci {
sa_family_t hci_family;
unsigned short hci_dev;
unsigned short hci_channel;
sa_family_t hci_family;
unsigned short hci_dev;
unsigned short hci_channel;
};
#elif MYNEWT_VAL(BLE_SOCK_USE_NUTTX)
#include <errno.h>
#include <netpacket/bluetooth.h>
#endif
#include <fcntl.h>
@@ -205,6 +208,8 @@ static struct ble_hci_sock_state {
static int s_ble_hci_device = MYNEWT_VAL(BLE_SOCK_TCP_PORT);
#elif MYNEWT_VAL(BLE_SOCK_USE_LINUX_BLUE)
static int s_ble_hci_device = MYNEWT_VAL(BLE_SOCK_LINUX_DEV);
#elif MYNEWT_VAL(BLE_SOCK_USE_NUTTX)
static int s_ble_hci_device = 0;
#endif
/**
@@ -227,6 +232,7 @@ ble_hci_trans_acl_buf_alloc(void)
return m;
}
#if MYNEWT_VAL(BLE_SOCK_USE_LINUX_BLUE)
static int
ble_hci_sock_acl_tx(struct os_mbuf *om)
{
@@ -268,10 +274,66 @@ ble_hci_sock_acl_tx(struct os_mbuf *om)
}
return 0;
}
#elif MYNEWT_VAL(BLE_SOCK_USE_NUTTX)
static int
ble_hci_sock_acl_tx(struct os_mbuf *om)
{
size_t len;
uint8_t *buf;
int i;
struct os_mbuf *m;
struct sockaddr_hci addr;
addr.hci_family = AF_BLUETOOTH;
addr.hci_channel = HCI_CHANNEL_RAW;
addr.hci_dev = 0;
memcpy(&addr, &addr, sizeof(struct sockaddr_hci));
len = 1;
for (m = om; m; m = SLIST_NEXT(m, om_next)) {
len += m->om_len;
}
buf = (uint8_t *)malloc(len);
buf[0] = BLE_HCI_UART_H4_ACL;
i = 1;
for (m = om; m; m = SLIST_NEXT(m, om_next)) {
memcpy(&buf[i], m->om_data, m->om_len);
i += m->om_len;
}
STATS_INC(hci_sock_stats, omsg);
STATS_INC(hci_sock_stats, oacl);
STATS_INCN(hci_sock_stats, obytes, OS_MBUF_PKTLEN(om) + 1);
i = sendto(ble_hci_sock_state.sock, buf, len, 0,
(struct sockaddr *)&addr, sizeof(struct sockaddr_hci));
free(buf);
os_mbuf_free_chain(om);
if (i != OS_MBUF_PKTLEN(om) + 1) {
if (i < 0) {
dprintf(1, "sendto() failed : %d\n", errno);
} else {
dprintf(1, "sendto() partial write: %d\n", i);
}
STATS_INC(hci_sock_stats, oerr);
return BLE_ERR_MEM_CAPACITY;
}
return 0;
}
#endif
#if MYNEWT_VAL(BLE_SOCK_USE_LINUX_BLUE)
static int
ble_hci_sock_cmdevt_tx(uint8_t *hci_ev, uint8_t h4_type)
{
uint8_t btaddr[6];
struct msghdr msg;
struct iovec iov[8];
int len;
@@ -316,6 +378,57 @@ ble_hci_sock_cmdevt_tx(uint8_t *hci_ev, uint8_t h4_type)
return 0;
}
#elif MYNEWT_VAL(BLE_SOCK_USE_NUTTX)
static int
ble_hci_sock_cmdevt_tx(uint8_t *hci_ev, uint8_t h4_type)
{
uint8_t *buf;
size_t len;
struct sockaddr_hci addr;
int i;
addr.hci_family = AF_BLUETOOTH;
addr.hci_channel = HCI_CHANNEL_RAW;
addr.hci_dev = 0;
memcpy(&addr, &addr, sizeof(struct sockaddr_hci));
if (h4_type == BLE_HCI_UART_H4_CMD) {
len = sizeof(struct ble_hci_cmd) + hci_ev[2];
STATS_INC(hci_sock_stats, ocmd);
} else if (h4_type == BLE_HCI_UART_H4_EVT) {
len = sizeof(struct ble_hci_ev) + hci_ev[1];
STATS_INC(hci_sock_stats, oevt);
} else {
assert(0);
}
STATS_INC(hci_sock_stats, omsg);
STATS_INCN(hci_sock_stats, obytes, len + 1);
buf = (uint8_t *)malloc(len + 1);
buf[0] = h4_type;
memcpy(&buf[1], hci_ev, len);
i = sendto(ble_hci_sock_state.sock, buf, len + 1, 0,
(struct sockaddr *)&addr, sizeof(struct sockaddr_hci));
free(buf);
ble_hci_trans_buf_free(hci_ev);
if (i != len + 1) {
if (i < 0) {
dprintf(1, "sendto() failed : %d\n", errno);
} else {
dprintf(1, "sendto() partial write: %d\n", i);
}
STATS_INC(hci_sock_stats, oerr);
return BLE_ERR_MEM_CAPACITY;
}
return 0;
}
#endif
static int
ble_hci_sock_rx_msg(void)
@@ -427,6 +540,7 @@ ble_hci_sock_rx_msg(void)
STATS_INC(hci_sock_stats, ierr);
break;
}
memmove(bhss->rx_data, &bhss->rx_data[len], bhss->rx_off - len);
bhss->rx_off -= len;
}
@@ -565,7 +679,54 @@ err:
}
return BLE_ERR_HW_FAIL;
}
#elif MYNEWT_VAL(BLE_SOCK_USE_NUTTX)
static int
ble_hci_sock_config(void)
{
struct sockaddr_hci shci;
int s;
int rc;
ble_npl_time_t timeout;
memset(&shci, 0, sizeof(shci));
shci.hci_family = AF_BLUETOOTH;
shci.hci_dev = 0;
shci.hci_channel = HCI_CHANNEL_RAW;
if (ble_hci_sock_state.sock >= 0) {
close(ble_hci_sock_state.sock);
ble_hci_sock_state.sock = -1;
}
s = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (s < 0) {
dprintf(1, "socket() failed %d\n", errno);
goto err;
}
rc = bind(s, (struct sockaddr *)&shci, sizeof(shci));
if (rc) {
dprintf(1, "bind() failed %d hci%d\n", errno, shci.hci_dev);
goto err;
}
ble_hci_sock_state.sock = s;
rc = ble_npl_time_ms_to_ticks(10, &timeout);
if (rc) {
goto err;
}
ble_npl_callout_reset(&ble_hci_sock_state.timer, timeout);
return 0;
err:
if (s >= 0) {
close(s);
}
return BLE_ERR_HW_FAIL;
}
#endif
/**
* Sends an HCI event from the controller to the host.
*
+58
View File
@@ -0,0 +1,58 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
#
# Configure NimBLE variables
NIMBLE_CFG_TINYCRYPT := 1
# Skip files that don't build for this port
NIMBLE_IGNORE := $(NIMBLE_ROOT)/porting/nimble/src/hal_timer.c \
$(NIMBLE_ROOT)/porting/nimble/src/os_cputime.c \
$(NIMBLE_ROOT)/porting/nimble/src/os_cputime_pwr2.c
include $(NIMBLE_ROOT)/porting/nimble/Makefile.defs
CSRCS := $(NIMBLE_SRC)
# Source files for NPL OSAL
CSRCS += \
$(wildcard $(NIMBLE_ROOT)/porting/npl/nuttx/src/*.c) \
$(wildcard $(NIMBLE_ROOT)/nimble/transport/socket/src/*.c) \
$(TINYCRYPT_SRC)
# Source files for demo app
CSRCS += $(NIMBLE_ROOT)/porting/examples/nuttx/ble.c
MAINSRC = $(NIMBLE_ROOT)/porting/examples/nuttx/main.c
# Add NPL and all NimBLE directories to include paths
INC = \
$(wildcard $(NIMBLE_ROOT)/porting/examples/nuttx/include) \
$(NIMBLE_ROOT)/porting/npl/nuttx/include \
$(NIMBLE_ROOT)/nimble/transport/socket/include \
$(NIMBLE_INCLUDE) \
$(TINYCRYPT_INCLUDE)
INCLUDES := $(addprefix -I, $(INC))
CFLAGS += \
$(NIMBLE_CFLAGS) \
$(INCLUDES) \
$(TINYCRYPT_CFLAGS) \
-DNIMBLE_CFG_CONTROLLER=0 -DOS_CFG_ALIGN_4=4 -DOS_CFG_ALIGNMENT=4 \
-Ddefault_RNG_defined=0
PROGNAME=nimble
+118
View File
@@ -0,0 +1,118 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include "nimble/nimble_port.h"
#include "host/ble_hs.h"
#include "host/util/util.h"
#include "services/gap/ble_svc_gap.h"
static const char gap_name[] = "nimble";
static uint8_t own_addr_type;
static void start_advertise(void);
static void
put_ad(uint8_t ad_type, uint8_t ad_len, const void *ad, uint8_t *buf,
uint8_t *len)
{
buf[(*len)++] = ad_len + 1;
buf[(*len)++] = ad_type;
memcpy(&buf[*len], ad, ad_len);
*len += ad_len;
}
static void
update_ad(void)
{
uint8_t ad[BLE_HS_ADV_MAX_SZ];
uint8_t ad_len = 0;
uint8_t ad_flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP;
put_ad(BLE_HS_ADV_TYPE_FLAGS, 1, &ad_flags, ad, &ad_len);
put_ad(BLE_HS_ADV_TYPE_COMP_NAME, sizeof(gap_name), gap_name, ad, &ad_len);
ble_gap_adv_set_data(ad, ad_len);
}
static int
gap_event_cb(struct ble_gap_event *event, void *arg)
{
switch (event->type) {
case BLE_GAP_EVENT_CONNECT:
if (event->connect.status) {
start_advertise();
}
break;
case BLE_GAP_EVENT_DISCONNECT:
start_advertise();
break;
}
return 0;
}
static void
start_advertise(void)
{
struct ble_gap_adv_params advp;
int rc;
printf("advertise\n");
update_ad();
memset(&advp, 0, sizeof advp);
advp.conn_mode = BLE_GAP_CONN_MODE_UND;
advp.disc_mode = BLE_GAP_DISC_MODE_GEN;
rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER,
&advp, gap_event_cb, NULL);
assert(rc == 0);
}
static void
app_ble_sync_cb(void)
{
int rc;
rc = ble_hs_util_ensure_addr(0);
assert(rc == 0);
rc = ble_hs_id_infer_auto(0, &own_addr_type);
assert(rc == 0);
start_advertise();
}
void
nimble_host_task(void *param)
{
ble_hs_cfg.sync_cb = app_ble_sync_cb;
ble_svc_gap_device_name_set(gap_name);
nimble_port_run();
}
@@ -0,0 +1,32 @@
/**
* This file was generated by Apache newt version: 1.9.0-dev
*/
#ifndef H_MYNEWT_LOGCFG_
#define H_MYNEWT_LOGCFG_
#include "modlog/modlog.h"
#include "log_common/log_common.h"
#define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__)
#define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__)
#define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__)
#define BLE_HS_LOG_ERROR(...) MODLOG_ERROR(4, __VA_ARGS__)
#define BLE_HS_LOG_CRITICAL(...) MODLOG_CRITICAL(4, __VA_ARGS__)
#define BLE_HS_LOG_DISABLED(...) MODLOG_DISABLED(4, __VA_ARGS__)
#define DFLT_LOG_DEBUG(...) IGNORE(__VA_ARGS__)
#define DFLT_LOG_INFO(...) MODLOG_INFO(0, __VA_ARGS__)
#define DFLT_LOG_WARN(...) MODLOG_WARN(0, __VA_ARGS__)
#define DFLT_LOG_ERROR(...) MODLOG_ERROR(0, __VA_ARGS__)
#define DFLT_LOG_CRITICAL(...) MODLOG_CRITICAL(0, __VA_ARGS__)
#define DFLT_LOG_DISABLED(...) MODLOG_DISABLED(0, __VA_ARGS__)
#define MFG_LOG_DEBUG(...) IGNORE(__VA_ARGS__)
#define MFG_LOG_INFO(...) IGNORE(__VA_ARGS__)
#define MFG_LOG_WARN(...) IGNORE(__VA_ARGS__)
#define MFG_LOG_ERROR(...) IGNORE(__VA_ARGS__)
#define MFG_LOG_CRITICAL(...) IGNORE(__VA_ARGS__)
#define MFG_LOG_DISABLED(...) MODLOG_DISABLED(128, __VA_ARGS__)
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,24 @@
/**
* This file was generated by Apache newt version: 1.9.0-dev
*/
#ifndef H_MYNEWT_SYSFLASH_
#define H_MYNEWT_SYSFLASH_
#include "flash_map/flash_map.h"
/**
* This flash map definition is used for two purposes:
* 1. To locate the meta area, which contains the true flash map definition.
* 2. As a fallback in case the meta area cannot be read from flash.
*/
extern const struct flash_area sysflash_map_dflt[6];
#define FLASH_AREA_BOOTLOADER 0
#define FLASH_AREA_IMAGE_0 1
#define FLASH_AREA_IMAGE_1 2
#define FLASH_AREA_IMAGE_SCRATCH 3
#define FLASH_AREA_REBOOT_LOG 16
#define FLASH_AREA_NFFS 17
#endif
+124
View File
@@ -0,0 +1,124 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
#include <nuttx/config.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include "nimble/nimble_npl.h"
#include "nimble/nimble_port.h"
#include "services/gap/ble_svc_gap.h"
#include "services/gatt/ble_svc_gatt.h"
#include "services/ans/ble_svc_ans.h"
#include "services/ias/ble_svc_ias.h"
#include "services/lls/ble_svc_lls.h"
#include "services/tps/ble_svc_tps.h"
static struct ble_npl_task s_task_host;
static struct ble_npl_task s_task_hci;
void nimble_host_task(void *param);
void ble_hci_sock_ack_handler(void *param);
void ble_hci_sock_init(void);
void ble_hci_sock_set_device(int dev);
void ble_store_ram_init(void);
#define TASK_DEFAULT_PRIORITY 1
#define TASK_DEFAULT_STACK NULL
#define TASK_DEFAULT_STACK_SIZE 400
void *ble_hci_sock_task(void *param)
{
printf("hci sock task\n");
ble_hci_sock_ack_handler(param);
return NULL;
}
void *ble_host_task(void *param)
{
printf("host task\n");
nimble_host_task(param);
return NULL;
}
int main(int argc, char *argv[])
{
int ret = 0;
/* allow to specify custom hci */
if (argc > 1) {
ble_hci_sock_set_device(atoi(argv[1]));
}
printf("hci init\n");
ble_hci_sock_init();
printf("port init\n");
nimble_port_init();
/* This example provides GATT Alert service */
printf("gap init\n");
ble_svc_gap_init();
printf("gatt init\n");
ble_svc_gatt_init();
printf("ans init\n");
ble_svc_ans_init();
printf("ias init\n");
ble_svc_ias_init();
printf("lls init\n");
ble_svc_lls_init();
printf("tps init\n");
ble_svc_tps_init();
/* XXX Need to have template for store */
ble_store_ram_init();
printf("hci_sock task init\n");
ret = ble_npl_task_init(&s_task_hci, "hci_sock", ble_hci_sock_task,
NULL, TASK_DEFAULT_PRIORITY, BLE_NPL_TIME_FOREVER,
TASK_DEFAULT_STACK, TASK_DEFAULT_STACK_SIZE);
if (ret != 0)
{
fprintf(stderr, "error starting hci task: %i\n", ret);
}
/* Create task which handles default event queue for host stack. */
printf("ble_host task init\n");
ret = ble_npl_task_init(&s_task_host, "ble_host", ble_host_task,
NULL, TASK_DEFAULT_PRIORITY, BLE_NPL_TIME_FOREVER,
TASK_DEFAULT_STACK, TASK_DEFAULT_STACK_SIZE);
if (ret != 0)
{
fprintf(stderr, "error starting ble task: %i\n", ret);
}
while (true)
{
usleep(100);
//pause();
}
return 0;
}
+2
View File
@@ -30,6 +30,7 @@ NIMBLE_INCLUDE := \
$(NIMBLE_ROOT)/nimble/host/services/gap/include \
$(NIMBLE_ROOT)/nimble/host/services/gatt/include \
$(NIMBLE_ROOT)/nimble/host/services/ias/include \
$(NIMBLE_ROOT)/nimble/host/services/dis/include \
$(NIMBLE_ROOT)/nimble/host/services/lls/include \
$(NIMBLE_ROOT)/nimble/host/services/tps/include \
$(NIMBLE_ROOT)/nimble/host/store/ram/include \
@@ -46,6 +47,7 @@ NIMBLE_SRC := \
$(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/bas/src/*.c)) \
$(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/gap/src/*.c)) \
$(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/gatt/src/*.c)) \
$(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/dis/src/*.c)) \
$(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/ias/src/*.c)) \
$(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/lls/src/*.c)) \
$(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/tps/src/*.c)) \
+2
View File
@@ -30,11 +30,13 @@ log_dummy(void *log, ...)
(void)log;
}
#if MYNEWT
#define LOG_DEBUG(_log, _mod, ...) log_dummy(_log, ## __VA_ARGS__)
#define LOG_INFO(_log, _mod, ...) log_dummy(_log, ## __VA_ARGS__)
#define LOG_WARN(_log, _mod, ...) log_dummy(_log, ## __VA_ARGS__)
#define LOG_ERROR(_log, _mod, ...) log_dummy(_log, ## __VA_ARGS__)
#define LOG_CRITICAL(_log, _mod, ...) log_dummy(_log, ## __VA_ARGS__)
#endif
struct log {
};
+104 -1
View File
@@ -20,20 +20,123 @@
#ifndef H_LOG_COMMON_
#define H_LOG_COMMON_
#include <stdint.h>
#include "log_common/ignore.h"
#ifdef __cplusplus
extern "C" {
#endif
struct log;
#define LOG_VERSION_V3 3
#define LOG_TYPE_STREAM (0)
#define LOG_TYPE_MEMORY (1)
#define LOG_TYPE_STORAGE (2)
#define LOG_LEVEL_DEBUG (0)
#define LOG_LEVEL_INFO (1)
#define LOG_LEVEL_WARN (2)
#define LOG_LEVEL_ERROR (3)
#define LOG_LEVEL_CRITICAL (4)
/* Up to 7 custom log levels. */
/* Up to 10 custom log levels. */
#define LOG_LEVEL_MAX (15)
#define LOG_LEVEL_STR(level) \
(LOG_LEVEL_DEBUG == level ? "DEBUG" :\
(LOG_LEVEL_INFO == level ? "INFO" :\
(LOG_LEVEL_WARN == level ? "WARN" :\
(LOG_LEVEL_ERROR == level ? "ERROR" :\
(LOG_LEVEL_CRITICAL == level ? "CRITICAL" :\
"UNKNOWN")))))
/* XXX: These module IDs are defined for backwards compatibility. Application
* code should use the syscfg settings directly. These defines will be removed
* in a future release.
*/
#define LOG_MODULE_DEFAULT 0
#define LOG_MODULE_OS 1
#define LOG_MODULE_NEWTMGR 2
#define LOG_MODULE_NIMBLE_CTLR 3
#define LOG_MODULE_NIMBLE_HOST 4
#define LOG_MODULE_NFFS 5
#define LOG_MODULE_REBOOT 6
#define LOG_MODULE_IOTIVITY 7
#define LOG_MODULE_TEST 8
#define LOG_MODULE_PERUSER 64
#define LOG_MODULE_MAX (255)
#define LOG_ETYPE_STRING (0)
#define LOG_ETYPE_CBOR (1)
#define LOG_ETYPE_BINARY (2)
/* UTC Timestamp for Jan 2016 00:00:00 */
#define UTC01_01_2016 1451606400
#define LOG_NAME_MAX_LEN (64)
#ifndef MYNEWT_VAL_LOG_LEVEL
#define LOG_SYSLEVEL ((uint8_t)LOG_LEVEL_MAX)
#else
#define LOG_SYSLEVEL ((uint8_t)MYNEWT_VAL_LOG_LEVEL)
#endif
/**
* @brief Determines if a log module will accept an entry with a given level.
*
* A log entry is only accepted if its level is less than or equal to both:
* o Global log level setting (LOG_LEVEL), and
* o The specified module log level
*
* @param mod_level The module's minimum log level.
* @param entry_level The level of the entry to be logged.
*
* @return true if the entry would be logged;
* false otherwise.
*/
#define LOG_MOD_LEVEL_IS_ACTIVE(mod_level, entry_level) \
(LOG_LEVEL <= (entry_level) && (mod_level) <= (entry_level))
/* Newtmgr Log opcodes */
#define LOGS_NMGR_OP_READ (0)
#define LOGS_NMGR_OP_CLEAR (1)
#define LOGS_NMGR_OP_APPEND (2)
#define LOGS_NMGR_OP_MODULE_LIST (3)
#define LOGS_NMGR_OP_LEVEL_LIST (4)
#define LOGS_NMGR_OP_LOGS_LIST (5)
#define LOGS_NMGR_OP_SET_WATERMARK (6)
#define LOGS_NMGR_OP_MODLEVEL (8)
#define LOG_PRINTF_MAX_ENTRY_LEN (128)
/* Global log info */
struct log_info {
#if MYNEWT_VAL(LOG_GLOBAL_IDX)
uint32_t li_next_index;
#endif
uint8_t li_version;
};
extern struct log_info g_log_info;
/** @typedef log_append_cb
* @brief Callback that is executed each time the corresponding log is appended
* to.
*
* @param log The log that was just appended to.
* @param idx The index of newly appended log entry.
*/
typedef void log_append_cb(struct log *log, uint32_t idx);
/** @typdef log_notify_rotate_cb
* @brief Callback that is executed each time we are about to rotate a log.
*
* @param log The log that is about to rotate
*/
typedef void log_notify_rotate_cb(const struct log *log);
#ifdef __cplusplus
}
#endif
+1
View File
@@ -22,6 +22,7 @@
#include <stdio.h>
#include "log_common/log_common.h"
#include "log/log.h"
#define MODLOG_MODULE_DFLT 255
@@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 __CONSOLE_H__
#define __CONSOLE_H__
#include <nuttx/config.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#define console_printf(_fmt, ...) printf(_fmt, ##__VA_ARGS__)
#ifdef __cplusplus
}
#endif
#endif /* __CONSOLE_H__ */
+68
View File
@@ -0,0 +1,68 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 H_MODLOG_
#define H_MODLOG_
#include <stdio.h>
#include <stdint.h>
#include "log_common/log_common.h"
#define MODLOG_MODULE_DFLT 255
#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_DEBUG || defined __DOXYGEN__
#define MODLOG_DEBUG(ml_mod_, ml_msg_, ...) \
printf((ml_msg_), ##__VA_ARGS__)
#else
#define MODLOG_DEBUG(ml_mod_, ...) IGNORE(__VA_ARGS__)
#endif
#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_INFO || defined __DOXYGEN__
#define MODLOG_INFO(ml_mod_, ml_msg_, ...) \
printf((ml_msg_), ##__VA_ARGS__)
#else
#define MODLOG_INFO(ml_mod_, ...) IGNORE(__VA_ARGS__)
#endif
#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_WARN || defined __DOXYGEN__
#define MODLOG_WARN(ml_mod_, ml_msg_, ...) \
printf((ml_msg_), ##__VA_ARGS__)
#else
#define MODLOG_WARN(ml_mod_, ...) IGNORE(__VA_ARGS__)
#endif
#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_ERROR || defined __DOXYGEN__
#define MODLOG_ERROR(ml_mod_, ml_msg_, ...) \
printf((ml_msg_), ##__VA_ARGS__)
#else
#define MODLOG_ERROR(ml_mod_, ...) IGNORE(__VA_ARGS__)
#endif
#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_CRITICAL || defined __DOXYGEN__
#define MODLOG_CRITICAL(ml_mod_, ml_msg_, ...) \
printf((ml_msg_), ##__VA_ARGS__)
#else
#define MODLOG_CRITICAL(ml_mod_, ...) IGNORE(__VA_ARGS__)
#endif
#define MODLOG(ml_lvl_, ml_mod_, ...) \
MODLOG_ ## ml_lvl_((ml_mod_), __VA_ARGS__)
#endif
@@ -0,0 +1,71 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 _NIMBLE_NPL_OS_H_
#define _NIMBLE_NPL_OS_H_
#include <nuttx/config.h>
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include "os_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define BLE_NPL_OS_ALIGNMENT 4
#define BLE_NPL_TIME_FOREVER INT32_MAX
#define SYSINIT_PANIC_MSG(msg) { fprintf(stderr, "%s\n", msg); abort(); }
#define SYSINIT_PANIC_ASSERT_MSG(rc, msg) do \
{ \
if (!(rc)) { \
SYSINIT_PANIC_MSG(msg); \
} \
} while (0)
#ifdef __cplusplus
}
#endif
/* Define some variables since nimBLE is designed to be built ignoring
* undefined macros and we do not ignore warnings on NuttX.
*
* Note: MYNEWT will give undefined warning, but some parts of the code
* interpret !defined(MYNEWT) as MYNEWT=0, so we shouldn't define it to zero
* either.
*
* Note 2: default_RNG_defined could probably set to 1 but this requires
* testing
*/
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PRIVACY 0
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_EXT_ADV 0
#define MYNEWT_VAL_BLE_LL_DTM_EXTENSIONS 0
#define MYNEWT_VAL_BLE_CONTROLLER 0
#define default_RNG_defined 0
#define BLETEST_THROUGHPUT_TEST 0
#define MYNEWT_VAL_TRNG 0
#define MYNEWT_VAL_SELFTEST 0
#endif /* _NPL_H_ */
@@ -0,0 +1,90 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 _NPL_OS_TYPES_H
#define _NPL_OS_TYPES_H
#include <nuttx/config.h>
#include <time.h>
#include <signal.h>
#include <stdbool.h>
#include <pthread.h>
#include <semaphore.h>
#include <sched.h>
#include <mqueue.h>
/* The highest and lowest task priorities */
#define OS_TASK_PRI_HIGHEST (sched_get_priority_max(SCHED_RR))
#define OS_TASK_PRI_LOWEST (sched_get_priority_min(SCHED_RR))
typedef uint32_t ble_npl_time_t;
typedef int32_t ble_npl_stime_t;
//typedef int os_sr_t;
typedef int ble_npl_stack_t;
struct ble_npl_event {
uint8_t ev_queued;
ble_npl_event_fn *ev_cb;
void *ev_arg;
};
struct ble_npl_eventq {
mqd_t mq;
};
struct ble_npl_callout {
struct ble_npl_event c_ev;
struct ble_npl_eventq *c_evq;
uint32_t c_ticks;
timer_t c_timer;
bool c_active;
};
struct ble_npl_mutex {
pthread_mutex_t lock;
pthread_mutexattr_t attr;
struct timespec wait;
};
struct ble_npl_sem {
sem_t lock;
};
struct ble_npl_task {
pthread_t handle;
pthread_attr_t attr;
struct sched_param param;
const char* name;
};
typedef void *(*ble_npl_task_func_t)(void *);
int ble_npl_task_init(struct ble_npl_task *t, const char *name, ble_npl_task_func_t func,
void *arg, uint8_t prio, ble_npl_time_t sanity_itvl,
ble_npl_stack_t *stack_bottom, uint16_t stack_size);
int ble_npl_task_remove(struct ble_npl_task *t);
uint8_t ble_npl_task_count(void);
void ble_npl_task_yield(void);
#endif // _NPL_OS_TYPES_H
+39
View File
@@ -0,0 +1,39 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
#include <nuttx/config.h>
#include <stdint.h>
#include <pthread.h>
#include "nimble/nimble_npl.h"
static pthread_mutex_t s_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
uint32_t
ble_npl_hw_enter_critical(void)
{
pthread_mutex_lock(&s_mutex);
return 0;
}
void
ble_npl_hw_exit_critical(uint32_t ctx)
{
pthread_mutex_unlock(&s_mutex);
}
+166
View File
@@ -0,0 +1,166 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
#include <nuttx/config.h>
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#include "nimble/nimble_npl.h"
static void
ble_npl_callout_timer_cb(union sigval sv)
{
struct ble_npl_callout *c = (struct ble_npl_callout *)sv.sival_ptr;
assert(c);
if (c->c_evq) {
ble_npl_eventq_put(c->c_evq, &c->c_ev);
} else {
c->c_ev.ev_cb(&c->c_ev);
}
}
void
ble_npl_callout_init(struct ble_npl_callout *c,
struct ble_npl_eventq *evq,
ble_npl_event_fn *ev_cb,
void *ev_arg)
{
struct sigevent event;
/* Initialize the callout. */
memset(c, 0, sizeof(*c));
c->c_ev.ev_cb = ev_cb;
c->c_ev.ev_arg = ev_arg;
c->c_evq = evq;
c->c_active = false;
event.sigev_notify = SIGEV_THREAD;
event.sigev_value.sival_ptr = c; // put callout obj in signal args
event.sigev_notify_function = ble_npl_callout_timer_cb;
event.sigev_notify_attributes = NULL;
timer_create(CLOCK_REALTIME, &event, &c->c_timer);
}
bool
ble_npl_callout_is_active(struct ble_npl_callout *c)
{
/* TODO: seek native posix method to determine whether timer_t is active.
TODO: fix bug where one-shot timer is still active after fired. */
return c->c_active;
}
int
ble_npl_callout_inited(struct ble_npl_callout *c)
{
return (c->c_timer != NULL);
}
ble_npl_error_t
ble_npl_callout_reset(struct ble_npl_callout *c,
ble_npl_time_t ticks)
{
struct itimerspec its;
if (ticks < 0) {
return BLE_NPL_EINVAL;
}
if (ticks == 0) {
ticks = 1;
}
c->c_ticks = ble_npl_time_get() + ticks;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0; /* one shot */
its.it_value.tv_sec = (ticks / 1000);
its.it_value.tv_nsec = (ticks % 1000) * 1000000; /* expiration */
its.it_value.tv_nsec %= 1000000000;
c->c_active = true;
timer_settime(c->c_timer, 0, &its, NULL);
return BLE_NPL_OK;
}
int
ble_npl_callout_queued(struct ble_npl_callout *c)
{
struct itimerspec its;
timer_gettime(c->c_timer, &its);
return ((its.it_value.tv_sec > 0) ||
(its.it_value.tv_nsec > 0));
}
void
ble_npl_callout_stop(struct ble_npl_callout *c)
{
if (!ble_npl_callout_inited(c)) {
return;
}
struct itimerspec its;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0;
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 0;
timer_settime(c->c_timer, 0, &its, NULL);
c->c_active = false;
}
ble_npl_time_t
ble_npl_callout_get_ticks(struct ble_npl_callout *co)
{
return co->c_ticks;
}
void
ble_npl_callout_set_arg(struct ble_npl_callout *co, void *arg)
{
co->c_ev.ev_arg = arg;
}
uint32_t
ble_npl_callout_remaining_ticks(struct ble_npl_callout *co,
ble_npl_time_t now)
{
ble_npl_time_t rt;
uint32_t exp;
struct itimerspec its;
timer_gettime(co->c_timer, &its);
exp = its.it_value.tv_sec * 1000;
if (exp > now) {
rt = exp - now;
} else {
rt = 0;
}
return rt;
}
+177
View File
@@ -0,0 +1,177 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
#include <nuttx/config.h>
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include "nimble/nimble_npl.h"
static struct ble_npl_eventq dflt_evq =
{
.mq = (mqd_t)-1
};
int qnum = 0;
struct ble_npl_eventq *
ble_npl_eventq_dflt_get(void)
{
return &dflt_evq;
}
void
ble_npl_eventq_init(struct ble_npl_eventq *evq)
{
char path[PATH_MAX];
struct mq_attr attr;
attr.mq_maxmsg = 16;
attr.mq_msgsize = sizeof(struct ble_npl_event*);
attr.mq_flags = 0;
qnum++;
sprintf(path, "/nimbleq%i", qnum);
evq->mq = mq_open(path, O_CREAT | O_RDWR, 0, &attr);
DEBUGASSERT((intptr_t)evq->mq >= 0);
}
bool
ble_npl_eventq_is_empty(struct ble_npl_eventq *evq)
{
struct mq_attr attr;
mq_getattr(evq->mq, &attr);
return (attr.mq_curmsgs == 0);
}
int
ble_npl_eventq_inited(const struct ble_npl_eventq *evq)
{
return (evq->mq != ((mqd_t)-1));
}
void
ble_npl_eventq_put(struct ble_npl_eventq *evq, struct ble_npl_event *ev)
{
if (ev->ev_queued)
{
return;
}
ev->ev_queued = 1;
mq_send(evq->mq, (const char*)&ev, sizeof(ev), 0);
}
struct ble_npl_event *
ble_npl_eventq_get(struct ble_npl_eventq *evq,
ble_npl_time_t tmo)
{
struct ble_npl_event *ev = NULL;
if (tmo == BLE_NPL_TIME_FOREVER)
{
do
{
mq_receive(evq->mq, (char*)&ev, sizeof(ev), NULL);
} while (ev && ev->ev_queued == 0);
}
else
{
struct timespec now, t;
clock_gettime(CLOCK_REALTIME, &now);
t.tv_sec += tmo / USEC_PER_SEC;
t.tv_nsec = (tmo - t.tv_sec) * NSEC_PER_MSEC;
clock_timespec_add(&now, &t, &t);
do
{
mq_timedreceive(evq->mq, (char*)&ev, sizeof(ev), NULL, &t);
} while (ev && ev->ev_queued == 0);
}
if (ev) {
ev->ev_queued = 0;
}
return ev;
}
void
ble_npl_eventq_run(struct ble_npl_eventq *evq)
{
struct ble_npl_event *ev;
ev = ble_npl_eventq_get(evq, BLE_NPL_TIME_FOREVER);
ble_npl_event_run(ev);
}
// ========================================================================
// Event Implementation
// ========================================================================
void
ble_npl_event_init(struct ble_npl_event *ev, ble_npl_event_fn *fn,
void *arg)
{
memset(ev, 0, sizeof(*ev));
ev->ev_cb = fn;
ev->ev_arg = arg;
}
bool
ble_npl_event_is_queued(struct ble_npl_event *ev)
{
return ev->ev_queued;
}
void *
ble_npl_event_get_arg(struct ble_npl_event *ev)
{
return ev->ev_arg;
}
void
ble_npl_event_set_arg(struct ble_npl_event *ev, void *arg)
{
ev->ev_arg = arg;
}
void
ble_npl_event_run(struct ble_npl_event *ev)
{
assert(ev->ev_cb != NULL);
ev->ev_cb(ev);
}
void
ble_npl_eventq_remove(struct ble_npl_eventq *evq, struct ble_npl_event *ev)
{
/* we simply mark the event as unqueued. we will ignore these elements
* when receiving from the queue */
ev->ev_queued = 0;
}
+82
View File
@@ -0,0 +1,82 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
#include <nuttx/config.h>
#include <errno.h>
#include <pthread.h>
#include "os/os.h"
#include "nimble/nimble_npl.h"
ble_npl_error_t
ble_npl_mutex_init(struct ble_npl_mutex *mu)
{
if (!mu) {
return BLE_NPL_INVALID_PARAM;
}
pthread_mutexattr_init(&mu->attr);
pthread_mutexattr_settype(&mu->attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mu->lock, &mu->attr);
return BLE_NPL_OK;
}
ble_npl_error_t
ble_npl_mutex_release(struct ble_npl_mutex *mu)
{
if (!mu) {
return BLE_NPL_INVALID_PARAM;
}
if (pthread_mutex_unlock(&mu->lock)) {
return BLE_NPL_BAD_MUTEX;
}
return BLE_NPL_OK;
}
ble_npl_error_t
ble_npl_mutex_pend(struct ble_npl_mutex *mu, uint32_t timeout)
{
int err;
if (!mu) {
return BLE_NPL_INVALID_PARAM;
}
if (timeout == BLE_NPL_TIME_FOREVER) {
err = pthread_mutex_lock(&mu->lock);
} else {
err = clock_gettime(CLOCK_REALTIME, &mu->wait);
if (err) {
return BLE_NPL_ERROR;
}
mu->wait.tv_sec += timeout / 1000;
mu->wait.tv_nsec += (timeout % 1000) * 1000000;
err = pthread_mutex_timedlock(&mu->lock, &mu->wait);
if (err == ETIMEDOUT) {
return BLE_NPL_TIMEOUT;
}
}
return (err) ? BLE_NPL_ERROR : BLE_NPL_OK;
}
+100
View File
@@ -0,0 +1,100 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
#include <nuttx/config.h>
#include <assert.h>
#include <errno.h>
#include <semaphore.h>
#include "os/os.h"
#include "nimble/nimble_npl.h"
ble_npl_error_t
ble_npl_sem_init(struct ble_npl_sem *sem, uint16_t tokens)
{
if (!sem) {
return BLE_NPL_INVALID_PARAM;
}
sem_init(&sem->lock, 0, tokens);
return BLE_NPL_OK;
}
ble_npl_error_t
ble_npl_sem_release(struct ble_npl_sem *sem)
{
int err;
if (!sem) {
return BLE_NPL_INVALID_PARAM;
}
err = sem_post(&sem->lock);
return (err) ? BLE_NPL_ERROR : BLE_NPL_OK;
}
ble_npl_error_t
ble_npl_sem_pend(struct ble_npl_sem *sem, uint32_t timeout)
{
int err = 0;
struct timespec wait;
if (!sem) {
return BLE_NPL_INVALID_PARAM;
}
if (timeout == BLE_NPL_TIME_FOREVER) {
err = sem_wait(&sem->lock);
} else {
err = clock_gettime(CLOCK_REALTIME, &wait);
if (err) {
return BLE_NPL_ERROR;
}
wait.tv_sec += timeout / 1000;
wait.tv_nsec += (timeout % 1000) * 1000000;
err = sem_timedwait(&sem->lock, &wait);
if (err && errno == ETIMEDOUT) {
return BLE_NPL_TIMEOUT;
}
}
return (err) ? BLE_NPL_ERROR : BLE_NPL_OK;
}
uint16_t
ble_npl_sem_get_count(struct ble_npl_sem *sem)
{
int count;
assert(sem);
assert(&sem->lock);
sem_getvalue(&sem->lock, &count);
/* NuttX can return negative value, return 0 in that case */
if (count < 0) {
count = 0;
}
return count;
}
+117
View File
@@ -0,0 +1,117 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
#include <nuttx/config.h>
#include "os/os.h"
#include "nimble/nimble_npl.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Initialize a task.
*
* This function initializes the task structure pointed to by t,
* clearing and setting it's stack pointer, provides sane defaults
* and sets the task as ready to run, and inserts it into the operating
* system scheduler.
*
* @param t The task to initialize
* @param name The name of the task to initialize
* @param func The task function to call
* @param arg The argument to pass to this task function
* @param prio The priority at which to run this task
* @param sanity_itvl The time at which this task should check in with the
* sanity task. OS_WAIT_FOREVER means never check in
* here.
* @param stack_bottom A pointer to the bottom of a task's stack
* @param stack_size The overall size of the task's stack.
*
* @return 0 on success, non-zero on failure.
*/
int
ble_npl_task_init(struct ble_npl_task *t, const char *name, ble_npl_task_func_t func,
void *arg, uint8_t prio, ble_npl_time_t sanity_itvl,
ble_npl_stack_t *stack_bottom, uint16_t stack_size)
{
int err;
if ((t == NULL) || (func == NULL)) {
return OS_INVALID_PARM;
}
err = pthread_attr_init(&t->attr);
if (err) return err;
err = pthread_attr_getschedparam (&t->attr, &t->param);
if (err) return err;
err = pthread_attr_setschedpolicy(&t->attr, SCHED_RR);
if (err) return err;
t->param.sched_priority = prio;
err = pthread_attr_setschedparam (&t->attr, &t->param);
if (err) return err;
t->name = name;
err = pthread_create(&t->handle, &t->attr, func, arg);
return err;
}
/*
* Removes specified task
* XXX
* NOTE: This interface is currently experimental and not ready for common use
*/
int
ble_npl_task_remove(struct ble_npl_task *t)
{
return pthread_cancel(t->handle);
}
/**
* Return the number of tasks initialized.
*
* @return number of tasks initialized
*/
uint8_t
ble_npl_task_count(void)
{
return 0;
}
void *
ble_npl_get_current_task_id(void)
{
return (void *)(uintptr_t)pthread_self();
}
bool
ble_npl_os_started(void)
{
return true;
}
void
ble_npl_task_yield(void)
{
pthread_yield();
}
#ifdef __cplusplus
}
#endif
+85
View File
@@ -0,0 +1,85 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
#include <nuttx/config.h>
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include "os/os.h"
#include "nimble/nimble_npl.h"
#include <unistd.h>
#include <time.h>
/**
* Return ticks [ms] since system start as uint32_t.
*/
ble_npl_time_t
ble_npl_time_get(void)
{
struct timespec now;
if (clock_gettime(CLOCK_MONOTONIC, &now)) {
return 0;
}
return now.tv_sec * 1000.0 + now.tv_nsec / 1000000.0;
}
ble_npl_error_t
ble_npl_time_ms_to_ticks(uint32_t ms, ble_npl_time_t *out_ticks)
{
*out_ticks = ms;
return BLE_NPL_OK;
}
ble_npl_error_t
ble_npl_time_ticks_to_ms(ble_npl_time_t ticks, uint32_t *out_ms)
{
*out_ms = ticks;
return BLE_NPL_OK;
}
ble_npl_time_t
ble_npl_time_ms_to_ticks32(uint32_t ms)
{
return ms;
}
uint32_t
ble_npl_time_ticks_to_ms32(ble_npl_time_t ticks)
{
return ticks;
}
void
ble_npl_time_delay(ble_npl_time_t ticks)
{
struct timespec sleep_time;
long ms = ble_npl_time_ticks_to_ms32(ticks);
uint32_t s = ms / 1000;
ms -= s * 1000;
sleep_time.tv_sec = s;
sleep_time.tv_nsec = ms * 1000000;
nanosleep(&sleep_time, NULL);
}
+104
View File
@@ -0,0 +1,104 @@
/*
wqueue.h
Worker thread queue based on the Standard C++ library list
template class.
------------------------------------------
Copyright (c) 2013 Vic Hargrave
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.
*/
// https://vichargrave.github.io/articles/2013-01/multithreaded-work-queue-in-cpp
// https://github.com/vichargrave/wqueue/blob/master/wqueue.h
#ifndef __wqueue_h__
#define __wqueue_h__
#include <nuttx/config.h>
#include <pthread.h>
#include <queue.h>
struct wqueue_s
{
dq_queue_s m_queue;
pthread_mutex_t m_mutex;
pthread_mutexattr_t m_mutex_attr;
pthread_cond_t m_condv;
};
using namespace std;
template <typename T> class wqueue
{
dq_queue_s m_queue;
pthread_mutex_t m_mutex;
pthread_mutexattr_t m_mutex_attr;
pthread_cond_t m_condv;
public:
wqueue()
{
dq_init(m_queue);
pthread_mutexattr_init(&m_mutex_attr);
pthread_mutexattr_settype(&m_mutex_attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&m_mutex, &m_mutex_attr);
pthread_cond_init(&m_condv, NULL);
}
~wqueue() {
pthread_mutex_destroy(&m_mutex);
pthread_cond_destroy(&m_condv);
}
void put(T item) {
dq_entry_t* entry = malloc(sizeof(T));
pthread_mutex_lock(&m_mutex);
dq_addlast(entry, &m_queue);
m_queue.push_back(item);
pthread_cond_signal(&m_condv);
pthread_mutex_unlock(&m_mutex);
}
T get(uint32_t tmo) {
pthread_mutex_lock(&m_mutex);
if (tmo) {
while (m_queue.size() == 0) {
pthread_cond_wait(&m_condv, &m_mutex);
}
}
T item = NULL;
if (m_queue.size() != 0) {
item = m_queue.front();
m_queue.pop_front();
}
pthread_mutex_unlock(&m_mutex);
return item;
}
void remove(T item) {
pthread_mutex_lock(&m_mutex);
m_queue.remove(item);
pthread_mutex_unlock(&m_mutex);
}
int size() {
pthread_mutex_lock(&m_mutex);
int size = m_queue.size();
pthread_mutex_unlock(&m_mutex);
return size;
}
};
#endif
+58
View File
@@ -0,0 +1,58 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
#
CFLAGS += \
-I. \
-I$(NIMBLE_ROOT)/nimble/include \
-I$(NIMBLE_ROOT)/porting/npl/nuttx/include \
-I$(NIMBLE_ROOT)/porting/npl/nuttx/src \
-I$(NIMBLE_ROOT)/porting/nimble/include
OSAL_PATH = $(NIMBLE_ROOT)/porting/npl/nuttx/src
CSRCS = $(wildcard $(OSAL_PATH)/*.c) \
$(wildcard $(OSAL_PATH)/*.cc) \
$(NIMBLE_ROOT)/porting/nimble/src/os_mempool.c
CXXOBJS += $($(wildcard *.cxx):$(CXXEXT)=$(SUFFIX)$(OBJEXT))
CFLAGS += -DNIMBLE_CFG_CONTROLLER=0 -DOS_CFG_ALIGN_4=4 -DOS_CFG_ALIGNMENT=4
DEPPATH += --dep-path $(NIMBLE_ROOT)/porting/npl/nuttx/test
VPATH += :$(NIMBLE_ROOT)/porting/npl/nuttx/test
VPATH += :$(NIMBLE_ROOT)/porting/nimble/src
VPATH += :$(OSAL_PATH)
PROGNAME = test_npl_task test_npl_eventq test_npl_callout test_npl_sem
MAINSRC = $(wildcard $(NIMBLE_ROOT)/porting/npl/nuttx/test/*.c)
clean::
(cd $(NIMBLE_ROOT)/porting/npl/nuttx/test && rm -f *.o)
(cd $(NIMBLE_ROOT)/porting/nimble/src && rm -f *.o)
(cd $(OSAL_PATH) && rm -f *.o)
test_npl_task.exe: test_npl_task.o $(OBJS)
$(LD) -o $@ $^ $(LDFLAGS) $(LIBS)
test_npl_eventq.exe: test_npl_eventq.o $(OBJS)
$(LD) -o $@ $^ $(LDFLAGS) $(LIBS)
test_npl_callout.exe: test_npl_callout.o $(OBJS)
$(LD) -o $@ $^ $(LDFLAGS) $(LIBS)
test_npl_sem.exe: test_npl_sem.o $(OBJS)
$(LD) -o $@ $^ $(LDFLAGS) $(LIBS)
+116
View File
@@ -0,0 +1,116 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/**
Unit tests for the ble_npl_callout api:
void ble_npl_callout_init(struct ble_npl_callout *cf, struct ble_npl_eventq *evq,
ble_npl_event_fn *ev_cb, void *ev_arg);
int ble_npl_callout_reset(struct ble_npl_callout *, int32_t);
int ble_npl_callout_queued(struct ble_npl_callout *c);
void ble_npl_callout_stop(struct ble_npl_callout *c);
*/
#include "test_util.h"
#include "nimble/nimble_npl.h"
#define TEST_ARGS_VALUE (55)
#define TEST_INTERVAL (100)
static bool s_tests_running = true;
static struct ble_npl_task s_task;
static struct ble_npl_callout s_callout;
static int s_callout_args = TEST_ARGS_VALUE;
static struct ble_npl_eventq s_eventq;
void on_callout(struct ble_npl_event *ev)
{
VerifyOrQuit(ev->ev_arg == &s_callout_args,
"callout: wrong args passed");
VerifyOrQuit(*(int*)ev->ev_arg == TEST_ARGS_VALUE,
"callout: args corrupted");
s_tests_running = false;
}
/**
* ble_npl_callout_init(struct ble_npl_callout *c, struct ble_npl_eventq *evq,
* ble_npl_event_fn *ev_cb, void *ev_arg)
*/
int test_init(void)
{
ble_npl_callout_init(&s_callout,
&s_eventq,
on_callout,
&s_callout_args);
return PASS;
}
int test_queued(void)
{
//VerifyOrQuit(ble_npl_callout_queued(&s_callout),
// "callout: not queued when expected");
return PASS;
}
int test_reset(void)
{
return ble_npl_callout_reset(&s_callout, TEST_INTERVAL);
}
int test_stop(void)
{
return PASS;
}
/**
* ble_npl_callout_init(struct ble_npl_callout *c, struct ble_npl_eventq *evq,
* ble_npl_event_fn *ev_cb, void *ev_arg)
*/
void *test_task_run(void *args)
{
SuccessOrQuit(test_init(), "callout_init failed");
SuccessOrQuit(test_queued(), "callout_queued failed");
SuccessOrQuit(test_reset(), "callout_reset failed");
while (s_tests_running)
{
ble_npl_eventq_run(&s_eventq);
}
printf("All tests passed\n");
exit(PASS);
return NULL;
}
int main(void)
{
ble_npl_eventq_init(&s_eventq);
SuccessOrQuit(ble_npl_task_init(&s_task, "s_task", test_task_run,
NULL, 1, 0, NULL, 0),
"task: error initializing");
while (1) {}
}
+131
View File
@@ -0,0 +1,131 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/**
Unit tests for the ble_npl_eventq api:
void ble_npl_eventq_init(struct ble_npl_eventq *);
void ble_npl_eventq_put(struct ble_npl_eventq *, struct ble_npl_event *);
struct ble_npl_event *ble_npl_eventq_get_no_wait(struct ble_npl_eventq *evq);
struct ble_npl_event *ble_npl_eventq_get(struct ble_npl_eventq *);
void ble_npl_eventq_run(struct ble_npl_eventq *evq);
struct ble_npl_event *ble_npl_eventq_poll(struct ble_npl_eventq **, int, ble_npl_time_t);
void ble_npl_eventq_remove(struct ble_npl_eventq *, struct ble_npl_event *);
struct ble_npl_eventq *ble_npl_eventq_dflt_get(void);
*/
#include <assert.h>
#include <pthread.h>
#include "test_util.h"
#include "nimble/nimble_npl.h"
#define TEST_ARGS_VALUE (55)
#define TEST_STACK_SIZE (1024)
static bool s_tests_running = true;
static struct ble_npl_task s_task_runner;
static struct ble_npl_task s_task_dispatcher;
static struct ble_npl_eventq s_eventq;
static struct ble_npl_event s_event;
static int s_event_args = TEST_ARGS_VALUE;
void on_event(struct ble_npl_event *ev)
{
VerifyOrQuit(ev->ev_arg == &s_event_args,
"callout: wrong args passed");
VerifyOrQuit(*(int*)ev->ev_arg == TEST_ARGS_VALUE,
"callout: args corrupted");
s_tests_running = false;
}
int test_init(void)
{
//VerifyOrQuit(!ble_npl_eventq_inited(&s_eventq), "eventq: empty q initialized");
ble_npl_eventq_init(&s_eventq);
//VerifyOrQuit(ble_npl_eventq_inited(&s_eventq), "eventq: not initialized");
return PASS;
}
int test_run(void)
{
while (s_tests_running)
{
ble_npl_eventq_run(&s_eventq);
}
return PASS;
}
int test_put(void)
{
s_event.ev_cb = on_event;
s_event.ev_arg = &s_event_args;
ble_npl_eventq_put(&s_eventq, &s_event);
return PASS;
}
int test_get_no_wait(void)
{
//struct ble_npl_event *ev = ble_npl_eventq_get_no_wait(&s_eventq);
return FAIL;
}
int test_get(void)
{
struct ble_npl_event *ev = ble_npl_eventq_get(&s_eventq,
BLE_NPL_TIME_FOREVER);
VerifyOrQuit(ev == &s_event,
"callout: wrong event passed");
return PASS;
}
void *task_test_runner(void *args)
{
int count = 1000000000;
SuccessOrQuit(test_init(), "eventq_init failed");
SuccessOrQuit(test_put(), "eventq_put failed");
SuccessOrQuit(test_get(), "eventq_get failed");
SuccessOrQuit(test_put(), "eventq_put failed");
SuccessOrQuit(test_run(), "eventq_run failed");
printf("All tests passed\n");
exit(PASS);
return NULL;
}
int main(void)
{
SuccessOrQuit(ble_npl_task_init(&s_task_runner,
"task_test_runner",
task_test_runner,
NULL, 1, 0, NULL, 0),
"task: error initializing");
while (1) {}
}
+111
View File
@@ -0,0 +1,111 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
#include "test_util.h"
#include "nimble/nimble_npl.h"
#define TEST_MEMPOOL_BLOCKS 4
#define TEST_MEMPOOL_BLOCK_SIZE 128
static struct ble_npl_mempool s_mempool;
static os_membuf_t s_mempool_mem[OS_MEMPOOL_SIZE(TEST_MEMPOOL_BLOCKS,
TEST_MEMPOOL_BLOCK_SIZE)];
static void *s_memblock[TEST_MEMPOOL_BLOCKS];
/**
* Unit test for initializing a mempool.
*
* ble_npl_error_t ble_npl_mempool_init(struct ble_npl_mempool *mp, int blocks,
* int block_size, void *membuf, char *name);
*
*/
int test_init(void)
{
int err;
err = ble_npl_mempool_init(NULL,
TEST_MEMPOOL_BLOCKS,
TEST_MEMPOOL_BLOCK_SIZE,
NULL,
"Null mempool");
VerifyOrQuit(err, "ble_npl_mempool_init accepted NULL parameters.");
err = ble_npl_mempool_init(&s_mempool,
TEST_MEMPOOL_BLOCKS,
TEST_MEMPOOL_BLOCK_SIZE,
s_mempool_mem,
"s_mempool");
return err;
}
/**
* Test integrity check of a mempool.
*
* bool ble_npl_mempool_is_sane(const struct ble_npl_mempool *mp);
*/
int test_is_sane(void)
{
return (ble_npl_mempool_is_sane(&s_mempool)) ? PASS : FAIL;
}
/**
* Test getting a memory block from the pool, putting it back,
* and checking if it is still valid.
*
* void *ble_npl_memblock_get(struct ble_npl_mempool *mp);
*
* ble_npl_error_t ble_npl_memblock_put(struct ble_npl_mempool *mp, void *block_addr);
*
* int ble_npl_memblock_from(const struct ble_npl_mempool *mp, const void *block_addr);
*/
int test_stress(void)
{
int loops = 3;
while(loops--)
{
for (int i = 0; i < 4; i++)
{
s_memblock[i] = ble_npl_memblock_get(&s_mempool);
VerifyOrQuit(ble_npl_memblock_from(&s_mempool, s_memblock[i]),
"ble_npl_memblock_get return invalid block.");
}
for (int i = 0; i < 4; i++)
{
SuccessOrQuit(ble_npl_memblock_put(&s_mempool, s_memblock[i]),
"ble_npl_memblock_put refused to take valid block.");
//VerifyOrQuit(!ble_npl_memblock_from(&s_mempool, s_memblock[i]),
// "Block still valid after ble_npl_memblock_put.");
}
}
return PASS;
}
int main(void)
{
SuccessOrQuit(test_init(), "Failed: ble_npl_mempool_init");
SuccessOrQuit(test_is_sane(), "Failed: ble_npl_mempool_is_sane");
SuccessOrQuit(test_stress(), "Failed: ble_npl_mempool stree test");
SuccessOrQuit(test_is_sane(), "Failed: ble_npl_mempool_is_sane");
printf("All tests passed\n");
return PASS;
}
+155
View File
@@ -0,0 +1,155 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/**
Unit tests for the Semaphore api (ble_npl_sem):
ble_npl_error_t ble_npl_sem_init(struct ble_npl_sem *sem, uint16_t tokens);
ble_npl_error_t ble_npl_sem_release(struct ble_npl_sem *sem);
ble_npl_error_t ble_npl_sem_pend(struct ble_npl_sem *sem, uint32_t timeout);
uint16_t ble_npl_sem_get_count(struct ble_npl_sem *sem);
*/
#include "test_util.h"
#include "nimble/nimble_npl.h"
//#include "os/os.h"
#define TEST_ITERATIONS 10
#define TASK1_PRIO 1
#define TASK2_PRIO 1
#define TASK1_STACK_SIZE 1028
#define TASK2_STACK_SIZE 1028
static struct ble_npl_task task1;
static struct ble_npl_task task2;
static ble_npl_stack_t task1_stack[TASK1_STACK_SIZE];
static ble_npl_stack_t task2_stack[TASK2_STACK_SIZE];
struct ble_npl_sem task1_sem;
struct ble_npl_sem task2_sem;
/* Task 1 handler function */
void *
task1_handler(void *arg)
{
for (int i = 0; i < TEST_ITERATIONS; i++)
{
/* Release semaphore to task 2 */
SuccessOrQuit(ble_npl_sem_release(&task1_sem),
"ble_npl_sem_release: error releasing task2_sem.");
/* Wait for semaphore from task 2 */
SuccessOrQuit(ble_npl_sem_pend(&task2_sem, BLE_NPL_TIME_FOREVER),
"ble_npl_sem_pend: error waiting for task2_sem.");
}
printf("All tests passed\n");
exit(PASS);
return NULL;
}
/* Task 2 handler function */
void *
task2_handler(void *arg)
{
while(1)
{
/* Wait for semaphore from task1 */
SuccessOrQuit(ble_npl_sem_pend(&task1_sem, BLE_NPL_TIME_FOREVER),
"ble_npl_sem_pend: error waiting for task1_sem.");
/* Release task2 semaphore */
SuccessOrQuit(ble_npl_sem_release(&task2_sem),
"ble_npl_sem_release: error releasing task1_sem.");
}
return NULL;
}
/* Initialize task 1 exposed data objects */
void
task1_init(void)
{
/* Initialize task1 semaphore */
SuccessOrQuit(ble_npl_sem_init(&task1_sem, 0),
"ble_npl_sem_init: task1 returned error.");
}
/* Initialize task 2 exposed data objects */
void
task2_init(void)
{
/* Initialize task1 semaphore */
SuccessOrQuit(ble_npl_sem_init(&task2_sem, 0),
"ble_npl_sem_init: task2 returned error.");
}
/**
* init_app_tasks
*
* This function performs initializations that are required before tasks run.
*
* @return int 0 success; error otherwise.
*/
static int
init_app_tasks(void)
{
/*
* Call task specific initialization functions to initialize any shared objects
* before initializing the tasks with the OS.
*/
task1_init();
task2_init();
/*
* Initialize tasks 1 and 2 with the OS.
*/
ble_npl_task_init(&task1, "task1", task1_handler, NULL, TASK1_PRIO,
BLE_NPL_TIME_FOREVER, task1_stack, TASK1_STACK_SIZE);
ble_npl_task_init(&task2, "task2", task2_handler, NULL, TASK2_PRIO,
BLE_NPL_TIME_FOREVER, task2_stack, TASK2_STACK_SIZE);
return 0;
}
/**
* main
*
* The main function for the application. This function initializes the system and packages,
* calls the application specific task initialization function, then waits and dispatches
* events from the OS default event queue in an infinite loop.
*/
int
main(int argc, char **arg)
{
/* Initialize application specific tasks */
init_app_tasks();
while (1)
{
ble_npl_eventq_run(ble_npl_eventq_dflt_get());
}
/* main never returns */
}
+98
View File
@@ -0,0 +1,98 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
#include "test_util.h"
#include "nimble/nimble_npl.h"
#include <pthread.h>
#define TASK0_ARG 55
#define TASK1_ARG 66
static struct ble_npl_task s_task[2];
static int s_task_arg[2] =
{
TASK0_ARG, TASK1_ARG
};
void *task0_run(void *args)
{
int i = 10000;
VerifyOrQuit(args == &s_task_arg[0], "Wrong args passed to task0");
while (i--)
{
}
return NULL;
}
void *task1_run(void *args)
{
int i = 10000;
VerifyOrQuit(args == &s_task_arg[1], "Wrong args passed to task0");
while (i--)
{
}
printf("All tests passed\n");
exit(PASS);
return NULL;
}
/**
* Unit test for initializing a task.
*
* int ble_npl_task_init(struct ble_npl_task *t, const char *name, ble_npl_task_func_t func,
* void *arg, uint8_t prio, ble_npl_time_t sanity_itvl,
* ble_npl_stack_t *stack_bottom, uint16_t stack_size)
*
*/
int test_init(void)
{
int err;
err = ble_npl_task_init(NULL,
"Null task",
NULL, NULL, 1, 0, NULL, 0);
VerifyOrQuit(err, "ble_npl_task_init accepted NULL parameters.");
err = ble_npl_task_init(&s_task[0],
"s_task[0]",
task0_run, &s_task_arg[0], 1, 0, NULL, 0);
SuccessOrQuit(err, "ble_npl_task_init failed.");
err = ble_npl_task_init(&s_task[1],
"s_task[1]",
task1_run, &s_task_arg[1], 1, 0, NULL, 0);
return err;
}
int main(void)
{
int ret = PASS;
SuccessOrQuit(test_init(), "Failed: ble_npl_task_init");
pthread_exit(&ret);
return ret;
}
+56
View File
@@ -0,0 +1,56 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 _TEST_UTIL_H_
#define _TEST_UTIL_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdlib.h>
#define PASS (0)
#define FAIL (-1)
#define SuccessOrQuit(ERR, MSG) \
do { \
if ((ERR)) \
{ \
fprintf(stderr, "\nFAILED %s:%d - %s\n", __FUNCTION__, __LINE__, MSG); \
exit(-1); \
} \
} while (false)
#define VerifyOrQuit(TST, MSG) \
do { \
if (!(TST)) \
{ \
fprintf(stderr, "\nFAILED %s:%d - %s\n", __FUNCTION__, __LINE__, MSG); \
exit(-1); \
} \
} while (false)
#ifdef __cplusplus
}
#endif
#endif /* _TEST_UTIL_H_ */
+40
View File
@@ -0,0 +1,40 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
#
pkg.name: "porting/targets/nuttx"
pkg.type: "target"
pkg.description: This target is used to generate syscfg.h file and other artifacts for nuttx example app.
pkg.author:
pkg.homepage:
pkg.deps:
- "@apache-mynewt-core/kernel/os"
- "@apache-mynewt-core/sys/console/stub"
- "@apache-mynewt-core/sys/log/stub"
- "@apache-mynewt-core/sys/stats/stub"
- "@apache-mynewt-nimble/nimble/host"
- "@apache-mynewt-nimble/nimble/transport/socket"
- "@apache-mynewt-nimble/nimble/host/services/ans"
- "@apache-mynewt-nimble/nimble/host/services/bas"
- "@apache-mynewt-nimble/nimble/host/services/dis"
- "@apache-mynewt-nimble/nimble/host/services/gap"
- "@apache-mynewt-nimble/nimble/host/services/gatt"
- "@apache-mynewt-nimble/nimble/host/services/ias"
- "@apache-mynewt-nimble/nimble/host/services/ipss"
- "@apache-mynewt-nimble/nimble/host/services/lls"
- "@apache-mynewt-nimble/nimble/host/services/tps"
+28
View File
@@ -0,0 +1,28 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
#
syscfg.vals:
BLE_SOCK_USE_TCP: 0
BLE_SOCK_USE_NUTTX: 1
BLE_SOCK_TASK_PRIO: 3
BLE_SOCK_STACK_SIZE: 1028
BLE_LL_CFG_FEAT_LL_PRIVACY: 0
LOG_LEVEL: 2
BLE_SM_LEGACY: 1
BLE_SM_SC: 1
+20
View File
@@ -0,0 +1,20 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
#
target.app: "porting/targets/dummy_app"
target.bsp: "porting/targets/dummy_bsp"
target.build_profile: "debug"
+1
View File
@@ -23,6 +23,7 @@ if [ ! -f "project.yml" ]; then
fi
declare -A targets=(
["nuttx"]="repos/apache-mynewt-nimble/porting/examples/nuttx/"
["linux"]="repos/apache-mynewt-nimble/porting/examples/linux/"
["linux_blemesh"]="repos/apache-mynewt-nimble/porting/examples/linux_blemesh/"
["porting_default"]="repos/apache-mynewt-nimble/porting/nimble"