Custom BSP
The following section explains what is the purpose of the custom BSP and how to use it.
Description
GAP SDK’s custom BSP is a mechanism that allows you to define and integrate custom boards and drivers based on GAP SDK resources. The custom BSP currently supports the following features :
Create kconfig options to define your board
Link your board to an existing GAP chip and already supported drivers from the SDK
Add new drivers
Describe how your board is implemented with devicetree.
Create board’s dedicated BSP files to handle specific implementation.
To simplify this process, GAP SDK offers a way to define the whole content of your custom BSP into a directory which is independant from the SDK. This directory is expected to be rigorously organized.
Custom BSP directory organization
A custom BSP directory is expected to contain specific subfolders and files. Here is a tree view of it :
custom_bsp_folder
--> bsp
--> boards
# Board's related BSP files (.c/.h)
--> drivers
# Drivers implementation (.c/.h)
--> devicetree
# Devicetree source files
--> kconfig
--> board.kconfig # Board definition
--> drivers.kconfig # Drivers definition
--> CMakeLists.txt # A custom BSP requires a CMakeLists file to build its sources.
The folder and files name exposed here need to remain unchanged to get properly linked to the SDK. To facilitate the creation of a custom BSP, the SDK provides a template generator here :
${GAP_SDK_HOME}/utils/custom_bsp/custom_bsp_generate.py
This script allows you to create the basics of the custom BSP, here are its arguments :
--path
: Custom BSP desired location
--name
: Custom BSP folder name
--boards
: A list a board name
--drivers
: A list of driver name
--override
: An empty option that allow to override an existing custom BSP. If this option is not set and if the folder already exists, the creation will abort.
Here is an example :
python custom_bsp_generate.py --path . --name my_first_bsp --boards BOARD_DEV BOARD_CUSTOMER --drivers driver_a driver_b driver_c
my_first_custom_bsp
bsp
bsp_board_customer.h
bsp_board_customer.c
bsp_board_dev.h
bsp_board.c
drivers
device_a.c
device_a.h
device_b.c
device_b.h
device_c.c
device_c.h
devicetree
board_customer.dts
board_dev.dts
kconfig
board.kconfig
drivers.kconfig
CMakeLists.txt
#
# Copyright (C) 2022 GreenWaves Technologies
#
# 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.
#
config BOARD_BOARD_DEV
bool "board_dev"
# Select a chip here
# select CHIP_
# List hardware here
# HAS_ _HARDWARE
config BOARD_BOARD_CUSTOMER
bool "board_customer"
# Select a chip here
# select CHIP_
# List hardware here
# HAS_ _HARDWARE
#
# Copyright (C) 2022 GreenWaves Technologies
#
# 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.
#
config HAS_DEVICE_A_HARDWARE
bool
help
Select this option from a Board definition to indicate that device_a hardware is implemented.
config HAS_DEVICE_B_HARDWARE
bool
help
Select this option from a Board definition to indicate that device_b hardware is implemented.
config HAS_DEVICE_C_HARDWARE
bool
help
Select this option from a Board definition to indicate that device_c hardware is implemented.
menu "Custom BSP Drivers"
config DRIVER_DEVICE_A
bool "device_a"
depends on HAS_DEVICE_A_HARDWARE
# Add low level driver dependencies here
# select DRIVER_
config DRIVER_DEVICE_B
bool "device_b"
depends on HAS_DEVICE_B_HARDWARE
# Add low level driver dependencies here
# select DRIVER_
config DRIVER_DEVICE_C
bool "device_c"
depends on HAS_DEVICE_C_HARDWARE
# Add low level driver dependencies here
# select DRIVER_
endmenu
Customer board devicetree
/dts-v1/;
/plugin/;
/{
board_customer
{
compatible = "gwt, gap9";
target-path = "/";
__overlay__
{
// Insert nodes here.
// node_label: node_name
// {
// status = "okay";
// sys
// {
// device_name = "";
// driver_name = "";
// device_type = "";
// device_board = "";
// device_driver = "";
// };
// conf
// {
// bsp_open = "NULL";
// bsp_close = "NULL";
// bsp_conf = "NULL";
// };
// pads
// {
// };
// defs
// {
// };
// }
};
};
};
Dev board devicetree
/dts-v1/;
/plugin/;
/{
board_dev
{
compatible = "gwt, gap9";
target-path = "/";
__overlay__
{
// Insert nodes here.
// node_label: node_name
// {
// status = "okay";
// sys
// {
// device_name = "";
// driver_name = "";
// device_type = "";
// device_board = "";
// device_driver = "";
// };
// conf
// {
// bsp_open = "NULL";
// bsp_close = "NULL";
// bsp_conf = "NULL";
// };
// pads
// {
// };
// defs
// {
// };
// }
};
};
};
#
# Copyright (C) 2022 GreenWaves Technologies
#
# 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.
#
macro(setup_custom_bsp)
# Board options
if(CONFIG_BOARD_BOARD_DEV)
list(APPEND CUSTOM_BSP_SRCS "${GAP_CUSTOM_BSP}/bsp/boards/bsp_board_dev.c")
list(APPEND CUSTOM_BSP_COMPILE_OPTIONS "-D__GAP_BOARD_BOARD_DEV__=1")
endif()
if(CONFIG_BOARD_BOARD_CUSTOMER)
list(APPEND CUSTOM_BSP_SRCS "${GAP_CUSTOM_BSP}/bsp/boards/bsp_board_customer.c")
list(APPEND CUSTOM_BSP_COMPILE_OPTIONS "-D__GAP_BOARD_BOARD_CUSTOMER__=1")
endif()
# Driver options
if(CONFIG_DRIVER_DEVICE_A)
list(APPEND CUSTOM_BSP_SRCS "${GAP_CUSTOM_BSP}/bsp/drivers/device_a.c")
list(APPEND CUSTOM_BSP_COMPILE_OPTIONS "-D__GAP_DRIVER_DEVICE_A__=1")
endif()
if(CONFIG_DRIVER_DEVICE_B)
list(APPEND CUSTOM_BSP_SRCS "${GAP_CUSTOM_BSP}/bsp/drivers/device_b.c")
list(APPEND CUSTOM_BSP_COMPILE_OPTIONS "-D__GAP_DRIVER_DEVICE_B__=1")
endif()
if(CONFIG_DRIVER_DEVICE_C)
list(APPEND CUSTOM_BSP_SRCS "${GAP_CUSTOM_BSP}/bsp/drivers/device_c.c")
list(APPEND CUSTOM_BSP_COMPILE_OPTIONS "-D__GAP_DRIVER_DEVICE_C__=1")
endif()
if(CUSTOM_BSP_SRCS)
add_library(custom_bsp STATIC ${CUSTOM_BSP_SRCS})
target_include_directories(custom_bsp PUBLIC ${GAP_CUSTOM_BSP})
target_compile_options(custom_bsp PUBLIC ${CUSTOM_BSP_COMPILE_OPTIONS})
endif()
endmacro()
Header
//
// Copyright (C) 2022 GreenWaves Technologies
//
// 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.
//
#ifndef __DEVICE_A_H__
#define __DEVICE_A_H__
#include "pmsis.h"
#include "bsp/bsp.h"
/// @brief device_a configuration structure
typedef struct
{
int32_t (*bsp_open)(pi_device_t*); //!< Open function to call to initialize the BSP part of the module
int32_t (*bsp_close)(pi_device_t*); //!< Close function to call to deinitialize the BSP part of the module
void* bsp_conf; //!< BSP related data (May vary depending on the board used)
}pi_device_a_conf_t;
/// @brief device_a data structure
typedef struct
{
uint8_t reentrance_cnt; //!< Open counter
}pi_device_a_data_t;
/// @brief device_a API instance
extern pi_device_api_t device_a_api;
#endif
Source
//
// Copyright (C) 2022 GreenWaves Technologies
//
// 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.
//
#include "device_a.h"
/// @brief Driver's open function.
///
/// @param device Pointer to the device instance.
/// @return pi_err_t Error management
/// @arg PI_OK The driver is correctly opened
/// @arg PI_FAIL Failed to open the driver.
static pi_err_t pi_device_a_open(pi_device_t* device)
{
pi_assert(device);
pi_assert(device->config);
pi_assert(device->data);
pi_err_t err = PI_OK;
pi_device_a_conf_t* device_a_conf = (pi_device_a_conf_t*)device->config;
pi_device_a_data_t* device_a_data = (pi_device_a_data_t*)device->data;
if(device_a_data->reentrance_cnt)
{
device_a_data->reentrance_cnt++;
}
else
{
// Execute BSP open function if it has been set in the device tree
if(NULL != device_a_conf->bsp_open)
{
if(PI_OK != device_a_conf->bsp_open(device))
{
PI_LOG_ERR("device_a", "Failed to open bsp\n");
err = PI_FAIL;
}
}
if(PI_OK == err)
{
// Implement your driver open process here
}
}
return err
}
/// @brief Driver's close function.
///
/// @param device Pointer to the device instance.
/// @return pi_err_t Error management
/// @arg PI_OK The driver is correctly closed
/// @arg PI_FAIL Failed to close the driver.
static pi_err_t pi_device_a_close(pi_device_t* device)
{
pi_assert(device);
pi_assert(device->config);
pi_assert(device->data);
pi_err_t err = PI_OK;
pi_device_a_data_t* device_a_data = (pi_device_a_data_t*)device->data;
pi_device_a_conf_t* device_a_conf = (pi_device_a_conf_t*)device->config;
if(device_a_data->reentrance_cnt > 0)
{
device_a_data->reentrance_cnt--;
if(device_a_data->reentrance_cnt == 0)
{
// Implement your driver close process here
// Execute BSP close function if it has been set in the device tree
if(NULL != device_a_conf->bsp_close)
{
if(PI_OK != device_a_conf->bsp_close(device))
{
PI_LOG_ERR("device_a", "Failed to close bsp\n");
err = PI_FAIL;
}
}
}
}
return err;
}
/// @brief Driver API definition'
pi_device_api_t device_a_api
{
.open = &pi_device_a_open,
.close = &pi_device_a_close,
};
Header
//
// Copyright (C) 2022 GreenWaves Technologies
//
// 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.
//
#ifndef __BSP_BOARD_CUSTOMER_H__
#define __BSP_BOARD_CUSTOMER_H__
// Implement here any specific code related to your board such as BSP open and
// close functions to fully support GAP drivers or your owns
#endif
Source
//
// Copyright (C) 2022 GreenWaves Technologies
//
// 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.
//
#include "bsp_board_customer.h"
// Implement here any specific code related to your board such as BSP open and
// close functions to fully support GAP drivers or your owns
Header
python custom_bsp_generate.py --path . --name my_first_custom_bsp --boards BOARD_DEV BOARD_CUSTOMER --drivers device_a device_b device_c
To link this custom BSP to GAP SDK, set GAP_CUSTOM_BSP variable at the begining your application CMakeList.txt with your custom_bsp path.
As en example "set(GAP_CUSTOM_BSP /path/to/your/custom_bsp)"
If your custom BSP is located in your application source directory, consider using ${CMAKE_CURRENT_SOURCE_DIR} variable as a path
Adding a board to the custom BSP
First, read the following tutorial How to integrate a new GWT board into the GAP SDK to understand how GAP SDK implements devicetree feature.
The following step describes how to add your own board in the custom bsp :
Create your board option in board.kconfig file. Select which chip and drivers it embbeds.
If needed, implement required drivers unknwown from GAP SDK in bsp/drivers folder.
Create your board’s devicetree file.
Write your board’s BSP implementation in bsp/board folder.
Write the custom BSP’s CMakeList.txt file
The CMakeList.txt file need to create a “custom_bsp” library. This library aims to provide the location of header directories and required C files to compile depending on selected kconfig options.
Check GWT examples for more details : custom_bsp_example
Linking a custom BSP to the SDK
Set the GAP_CUSTOM_BSP cmake variable in your applciation CMakeLists.txt file to the path of your custom BSP to establish the link between the two.
set(GAP_CUSTOM_BSP /path/to/your/custom_bsp)
SDK CMake process include a general check about your custom BSP folder organization. If it respects the conditions explained here, the link will be successful.
The linking process consists in merging the board.kconfig and drivers.kconfig file’s options definition newt to GAP SDK’s board.kconfig and drivers.kconfig ones to appear in the menuconfig interface and to be selectable as valid boards and drivers from an application.
Example
Please, ask an access to GWT’s custom_bsp_helloworld.git project to get an example of a custom BSP implementation.