From dccbbaaa5d464c11dc232f5fce7ff756238f8fcf Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 12 Feb 2020 14:01:13 +0100 Subject: [PATCH 1/4] hw/hal: Add generic API to retrieve provisioned data Currently we only have dedicated API to retrieve HW ID from BSP. However, there are more data that can be provisioned to device and it would be nice to be able to retrieve it in a consistent way regardless of BSP used. This patch adds generic API to retrieve provisioned data. Note that it does not specify how these data should be provisioned to device, it's just about reading them. There are few predefined data identifiers and this list can be extended as there are more data that are usable by various packages. Also there is separate range for user-defined identifiers. In general provisioned data are BSP-specific but application can provide own callback to override some data or support custom data identifiers via the same common API. --- hw/hal/include/hal/hal_bsp.h | 50 +++++++++++++++++++ hw/hal/include/hal/hal_bsp_int.h | 40 ++++++++++++++++ hw/hal/src/hal_bsp.c | 82 ++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 hw/hal/include/hal/hal_bsp_int.h create mode 100644 hw/hal/src/hal_bsp.c diff --git a/hw/hal/include/hal/hal_bsp.h b/hw/hal/include/hal/hal_bsp.h index d141f28791..fd4d72466f 100644 --- a/hw/hal/include/hal/hal_bsp.h +++ b/hw/hal/include/hal/hal_bsp.h @@ -122,6 +122,56 @@ int hal_bsp_power_state(int state); */ uint32_t hal_bsp_get_nvic_priority(int irq_num, uint32_t pri); +/* Provisioned data identifiers */ +#define HAL_BSP_PROV_HW_ID 0x0001 +#define HAL_BSP_PROV_BLE_PUBLIC_ADDR 0x0002 +#define HAL_BSP_PROV_BLE_STATIC_ADDR 0x0003 +#define HAL_BSP_PROV_BLE_IRK 0x0004 +/* First id for user-defined data identifiers */ +#define HAL_BSP_PROV_USER 0x8000 + +/** + * Get provisioned data + * + * \p length input value shall be set to size of buffer pointer by \p data. + * + * If provided buffer is too small, SYS_ENOMEM is returned and \p length is set + * to minimum required buffer size. + * + * On success \p length is is updated to length of data written to buffer. + * + * @param id provisioned data identifier + * @param data output buffer to store data + * @param length length + * + * @return 0 on success + * SYS_EINVAL if \p data or \p length is NULL + * SYS_ENOMEM if provided buffer size it too small + * SYS_ENOENT if requested data is not provisioned + * SYS_ENOTSUP if requested data identifier is not supported + */ +int hal_bsp_prov_data_get(uint16_t id, void *data, uint16_t *length); + +typedef int (* hal_bsp_prov_data_cb)(uint16_t id, void *data, uint16_t *length); + +/** + * Set custom callback to override provisioned data + * + * Sets callback which is called prior to BSP code and can override handling + * for selected data identifiers. + * + * Callback parameters and behavior shall be the same as hal_bsp_prov_data(). + * + * Callback can be registered only once. + * + * @param cb Data callback + * + * @return 0 on success + * SYS_EINVAL if \p cb is NULL + * SYS_EALREADY if callback is already registered + */ +int hal_bsp_prov_data_set_cb(hal_bsp_prov_data_cb cb); + #ifdef __cplusplus } #endif diff --git a/hw/hal/include/hal/hal_bsp_int.h b/hw/hal/include/hal/hal_bsp_int.h new file mode 100644 index 0000000000..9fcd6620e8 --- /dev/null +++ b/hw/hal/include/hal/hal_bsp_int.h @@ -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. + */ + +#ifndef __HAL_BSP_INT_H_ +#define __HAL_BSP_INT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * Below API shall be defined by BSP to provide provisioned data. It will be + * called by generic hal_bsp_prov_data_get(). + */ + +int hal_bsp_prov_data_get_int(uint16_t id, void *data, uint16_t *length); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/hal/src/hal_bsp.c b/hw/hal/src/hal_bsp.c new file mode 100644 index 0000000000..a6d3024b98 --- /dev/null +++ b/hw/hal/src/hal_bsp.c @@ -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 +#include "hal/hal_bsp.h" +#include "hal/hal_bsp_int.h" +#include "defs/error.h" + +static hal_bsp_prov_data_cb g_hal_bsp_prov_data_cb; + +int +hal_bsp_prov_data_get(uint16_t id, void *data, uint16_t *length) +{ + int rc; + + if (!data || !length) { + return SYS_EINVAL; + } + + /* + * Check length for well-known data. Also adjust length so data providers + * do not need to check this again. + */ + switch (id) { + case HAL_BSP_PROV_BLE_PUBLIC_ADDR: + case HAL_BSP_PROV_BLE_STATIC_ADDR: + if (*length < 6) { + *length = 6; + return SYS_ENOMEM; + } + *length = 6; + break; + case HAL_BSP_PROV_BLE_IRK: + if (*length < 16) { + *length = 16; + return SYS_ENOMEM; + } + *length = 16; + break; + } + + if (g_hal_bsp_prov_data_cb) { + rc = g_hal_bsp_prov_data_cb(id, data, length); + if (rc != SYS_ENOTSUP) { + return rc; + } + } + + return hal_bsp_prov_data_get_int(id, data, length); +} + +int +hal_bsp_prov_data_set_cb(hal_bsp_prov_data_cb cb) +{ + if (!cb) { + return SYS_EINVAL; + } + + if (g_hal_bsp_prov_data_cb) { + return SYS_EALREADY; + } + + g_hal_bsp_prov_data_cb = cb; + + return 0; +} From e9d6b2f2272d82518c8f82f68eb54a97031aba30 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 12 Feb 2020 14:02:22 +0100 Subject: [PATCH 2/4] hw/mcu: Add nrf52_hw_id API This converts existing hal_bsp APIs to get hw id into MCU APIs. The hal_bsp APIs are still there for backwards compatibility and they just are wrappers for MCU APIs. --- .../nordic/nrf52xxx/include/mcu/nrf52_hw_id.h | 36 +++++++++++++++++++ hw/mcu/nordic/nrf52xxx/src/nrf52_hw_id.c | 17 +++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 hw/mcu/nordic/nrf52xxx/include/mcu/nrf52_hw_id.h diff --git a/hw/mcu/nordic/nrf52xxx/include/mcu/nrf52_hw_id.h b/hw/mcu/nordic/nrf52xxx/include/mcu/nrf52_hw_id.h new file mode 100644 index 0000000000..58d2110362 --- /dev/null +++ b/hw/mcu/nordic/nrf52xxx/include/mcu/nrf52_hw_id.h @@ -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 H_NRF52_HW_ID_ +#define H_NRF52_HW_ID_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +int nrf52_hw_id_len(void); +int nrf52_hw_id(uint8_t *id, int max_len); + +#ifdef __cplusplus +} +#endif + +#endif /* H_NRF52_HW_ID_ */ diff --git a/hw/mcu/nordic/nrf52xxx/src/nrf52_hw_id.c b/hw/mcu/nordic/nrf52xxx/src/nrf52_hw_id.c index ca916bf22b..95b19e5913 100644 --- a/hw/mcu/nordic/nrf52xxx/src/nrf52_hw_id.c +++ b/hw/mcu/nordic/nrf52xxx/src/nrf52_hw_id.c @@ -20,6 +20,7 @@ #include #include #include +#include "mcu/nrf52_hw_id.h" #include "nrf.h" #ifndef min @@ -27,7 +28,7 @@ #endif int -hal_bsp_hw_id_len(void) +nrf52_hw_id_len(void) { return sizeof(NRF_FICR->DEVICEID) + sizeof(NRF_FICR->DEVICEADDR); } @@ -37,7 +38,7 @@ hal_bsp_hw_id_len(void) * DEVICEID[0-1] and DEVICEADDR[0-1]. */ int -hal_bsp_hw_id(uint8_t *id, int max_len) +nrf52_hw_id(uint8_t *id, int max_len) { int len, cnt; @@ -50,3 +51,15 @@ hal_bsp_hw_id(uint8_t *id, int max_len) return len + cnt; } + +int +hal_bsp_hw_id_len(void) +{ + return nrf52_hw_id_len(); +} + +int +hal_bsp_hw_id(uint8_t *id, int max_len) +{ + return nrf52_hw_id(id, max_len); +} From 0e3b57e421d8bcc1c3045dbfe23406367625a2c0 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 12 Feb 2020 14:02:36 +0100 Subject: [PATCH 3/4] hw/bsp/nordic: Implement new hal_bsp API for provisioned data --- hw/bsp/nordic_pca10056/src/hal_bsp.c | 58 ++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/hw/bsp/nordic_pca10056/src/hal_bsp.c b/hw/bsp/nordic_pca10056/src/hal_bsp.c index 9f8ba8da12..827b8fa059 100644 --- a/hw/bsp/nordic_pca10056/src/hal_bsp.c +++ b/hw/bsp/nordic_pca10056/src/hal_bsp.c @@ -27,6 +27,7 @@ #include "hal/hal_flash.h" #include "hal/hal_system.h" #include "mcu/nrf52_hal.h" +#include "mcu/nrf52_hw_id.h" #include "mcu/nrf52_periph.h" #include "bsp/bsp.h" @@ -95,6 +96,63 @@ hal_bsp_get_nvic_priority(int irq_num, uint32_t pri) return cfg_pri; } +static int +prov_data_hw_id(void *data, uint16_t *length) +{ + uint16_t len = nrf52_hw_id_len(); + + if (*length < len) { + *length = len; + return SYS_ENOMEM; + } + + *length = nrf52_hw_id(data, *length); + + return 0; +} + +static int +prov_data_ble_public_addr(void *data, uint16_t *length) +{ + if ((NRF_FICR->DEVICEADDRTYPE & 1) != 0) { + return SYS_ENOENT; + } + + memcpy(data, (void *)&NRF_FICR->DEVICEADDR[0], 6); + + return 0; +} + +static int +prov_data_ble_static_addr(void *data, uint16_t *length) +{ + uint8_t *addr = data; + + if ((NRF_FICR->DEVICEADDRTYPE & 1) == 0) { + return SYS_ENOENT; + } + + memcpy(data, (void *)&NRF_FICR->DEVICEADDR[0], 6); + addr[5] |= 0xc0; + + return 0; +} + +int +hal_bsp_prov_data_get_int(uint16_t id, void *data, uint16_t *length) +{ + switch (id) { + case HAL_BSP_PROV_HW_ID: + return prov_data_hw_id(data, length); + case HAL_BSP_PROV_BLE_PUBLIC_ADDR: + return prov_data_ble_public_addr(data, length); + case HAL_BSP_PROV_BLE_STATIC_ADDR: + return prov_data_ble_static_addr(data, length); + } + + return SYS_ENOTSUP; +} + void hal_bsp_init(void) { From d73f885098bbd672d9bb64ff7887900076b059a7 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 12 Feb 2020 14:04:38 +0100 Subject: [PATCH 4/4] hw/hal: Make hal_bsp_hw_id APIs deprecated Use hal_bsp_prov_data instead. --- hw/hal/include/hal/hal_bsp.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/hal/include/hal/hal_bsp.h b/hw/hal/include/hal/hal_bsp.h index fd4d72466f..b7043223c2 100644 --- a/hw/hal/include/hal/hal_bsp.h +++ b/hw/hal/include/hal/hal_bsp.h @@ -68,6 +68,7 @@ const struct hal_bsp_mem_dump *hal_bsp_core_dump(int *area_cnt); * * @return The length of the hardware ID. */ +__attribute__((deprecated)) int hal_bsp_hw_id_len(void); /** @@ -79,6 +80,7 @@ int hal_bsp_hw_id_len(void); * * @return 0 on success, non-zero error code on failure */ +__attribute__((deprecated)) int hal_bsp_hw_id(uint8_t *id, int max_len); /** Full System On */