Custom BSP
Overview
“Custom BSP” stands for Custom Board Support Package. It is the SDK entry point for adding your custom board definitions and any drivers not yet supported by the SDK.
With a custom BSP, you can:
Create a Kconfig option for your board and select it among GWT options.
Create a devicetree file to describe the devices implemented on your board.
Associate your board with supported boards and drivers.
Integrate new hardware drivers with the SDK.
The custom BSP is simply an external folder with specific constraints. Its contents must be organized precisely, as described in the next section.
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-specific implementations. (.c/.h files)
--> drivers
# Drivers implementation (.c/.h files)
--> devicetree
# Board content definition. Devicetree source files
--> kconfig
--> board.kconfig # Board options
--> drivers.kconfig # Drivers options
--> CMakeLists.txt # Compilation and link rules
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 :
# From GAP_SDK top-level directory
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 names
--drivers
: A list of driver names
--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 :
# From GAP_SDK top-level directory
python utils/custom_bsp/custom_bsp_generate.py --path . --name my_custom_bsp --boards customer_1 customer_2 --drivers driver_a driver_b driver_c
my_first_custom_bsp
bsp
bsp_customer_1.c
bsp_customer_1.h
bsp_customer_2.c
bsp_customer_2.h
drivers
device_a.c
device_a.h
device_b.c
device_b.h
device_c.c
device_c.h
devicetree
customer_1.dts
customer_2.dts
kconfig
board.kconfig
drivers.kconfig
CMakeLists.txt
#
# Copyright (C) 2024 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_CUSTOMER_1
bool "customer_1"
# Create a dependency to a GAP chip
# depends on CHIP_
# List board hardware here
# select HAS_ _HARDWARE
config BOARD_CUSTOMER_2
bool "customer_2"
# Create a dependency to a GAP chip
# depends on CHIP_
# List board hardware here
# select HAS_ _HARDWARE
#
# Copyright (C) 2024 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_DRIVER_A_HARDWARE
bool
help
Select this option from a Board definition to indicate that driver_a hardware is implemented.
config HAS_DRIVER_B_HARDWARE
bool
help
Select this option from a Board definition to indicate that driver_b hardware is implemented.
config HAS_DRIVER_C_HARDWARE
bool
help
Select this option from a Board definition to indicate that driver_c hardware is implemented.
menu "Custom BSP Drivers"
config DRIVER_DRIVER_A
bool "driver_a"
depends on HAS_DRIVER_A_HARDWARE
# Add low level driver dependencies here
# select DRIVER_
config DRIVER_DRIVER_B
bool "driver_b"
depends on HAS_DRIVER_B_HARDWARE
# Add low level driver dependencies here
# select DRIVER_
config DRIVER_DRIVER_C
bool "driver_c"
depends on HAS_DRIVER_C_HARDWARE
# Add low level driver dependencies here
# select DRIVER_
endmenu
/dts-v1/;
/plugin/;
/{
customer_1
{
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
// {
// };
// };
};
};
};
/dts-v1/;
/plugin/;
/{
customer_2
{
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) 2024 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.
#
set(ENV{CUSTOM_BSP_TARGET} pmsis)
# Board options
if(CONFIG_BOARD_CUSTOMER_1)
list(APPEND CUSTOM_BSP_SRCS "${GAP_CUSTOM_BSP}/bsp/boards/bsp_customer_1.c")
list(APPEND CUSTOM_BSP_COMPILE_OPTIONS "-DCONFIG_BOARD_CUSTOMER_1")
endif()
if(CONFIG_BOARD_CUSTOMER_2)
list(APPEND CUSTOM_BSP_SRCS "${GAP_CUSTOM_BSP}/bsp/boards/bsp_customer_2.c")
list(APPEND CUSTOM_BSP_COMPILE_OPTIONS "-DCONFIG_BOARD_CUSTOMER_2")
endif()
# Driver options
if(CONFIG_DRIVER_DRIVER_A)
list(APPEND CUSTOM_BSP_SRCS "${GAP_CUSTOM_BSP}/bsp/drivers/driver_a.c")
list(APPEND CUSTOM_BSP_COMPILE_OPTIONS "-DCONFIG_DRIVER_DRIVER_A")
endif()
if(CONFIG_DRIVER_DRIVER_B)
list(APPEND CUSTOM_BSP_SRCS "${GAP_CUSTOM_BSP}/bsp/drivers/driver_b.c")
list(APPEND CUSTOM_BSP_COMPILE_OPTIONS "-DCONFIG_DRIVER_DRIVER_B")
endif()
if(CONFIG_DRIVER_DRIVER_C)
list(APPEND CUSTOM_BSP_SRCS "${GAP_CUSTOM_BSP}/bsp/drivers/driver_c.c")
list(APPEND CUSTOM_BSP_COMPILE_OPTIONS "-DCONFIG_DRIVER_DRIVER_C")
endif()
if(CUSTOM_BSP_SRCS)
target_sources($ENV{CUSTOM_BSP_TARGET} PRIVATE ${CUSTOM_BSP_SRCS})
target_include_directories($ENV{CUSTOM_BSP_TARGET} PUBLIC ${GAP_CUSTOM_BSP}/bsp/drivers)
target_include_directories($ENV{CUSTOM_BSP_TARGET} PUBLIC ${GAP_CUSTOM_BSP}/bsp/boards)
target_compile_options($ENV{CUSTOM_BSP_TARGET} PUBLIC ${CUSTOM_BSP_COMPILE_OPTIONS})
endif()
//
// Copyright (C) 2024 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.
//
#pragma once
#include "pmsis.h"
#include "bsp/bsp.h"
/// @brief driver_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_driver_a_conf_t;
/// @brief driver_a data structure
typedef struct
{
uint8_t reentrance_cnt; //!< Open counter
}pi_driver_a_data_t;
/// @brief driver_a API instance
extern pi_device_api_t driver_a_api;
//
// Copyright (C) 2024 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 "driver_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_driver_a_open(pi_device_t* device)
{
pi_assert(device);
pi_assert(device->config);
pi_assert(device->data);
pi_err_t err = PI_OK;
pi_driver_a_conf_t* driver_a_conf = (pi_driver_a_conf_t*)device->config;
pi_driver_a_data_t* driver_a_data = (pi_driver_a_data_t*)device->data;
if(driver_a_data->reentrance_cnt)
{
driver_a_data->reentrance_cnt++;
}
else
{
// Execute BSP open function if it has been set in the device tree
if(NULL != driver_a_conf->bsp_open)
{
if(PI_OK != driver_a_conf->bsp_open(device))
{
PI_LOG_ERR("driver_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_driver_a_close(pi_device_t* device)
{
pi_assert(device);
pi_assert(device->config);
pi_assert(device->data);
pi_err_t err = PI_OK;
pi_driver_a_data_t* driver_a_data = (pi_driver_a_data_t*)device->data;
pi_driver_a_conf_t* driver_a_conf = (pi_driver_a_conf_t*)device->config;
if(driver_a_data->reentrance_cnt > 0)
{
driver_a_data->reentrance_cnt--;
if(driver_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 != driver_a_conf->bsp_close)
{
if(PI_OK != driver_a_conf->bsp_close(device))
{
PI_LOG_ERR("driver_a", "Failed to close bsp\n");
err = PI_FAIL;
}
}
}
}
return err;
}
/// @brief Driver API definition'
pi_device_api_t driver_a_api
{
.open = &pi_driver_a_open,
.close = &pi_driver_a_close,
};
//
// Copyright (C) 2024 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.
//
#pragma once
// Implement here any specific code related to your board such as BSP open and
// close functions to fully support GAP drivers or your owns
//
// Copyright (C) 2024 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_customer_1.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 utils/custom_bsp/custom_bsp_generate.py --path . --name my_custom_bsp --boards customer_1 customer_2 --drivers driver_a driver_b driver_c
Custom BSP has been created!
To link this custom BSP to GAP SDK, set GAP_CUSTOM_BSP variable at the begining your application's CMakeList.txt with your custom_bsp path.
As an example:
set(GAP_CUSTOM_BSP /home/mickael/gwt/sdk/gapple/my_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 unknown 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
Link 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.
Source compilation and CMake target
Custom BSP sources should be compiled within the pmsis
CMake target.
To enable this, the following line is required at the beginning of the CMake file:
set(ENV{CUSTOM_BSP_TARGET} pmsis)
Use boards and drivers from your custom BSP
Options defined in board.kconfig and drivers.kconfig file can be now selected
either from a configuration file sdk.config
or from menuconfig interface.
sdk.config file example
CONFIG_BOARD_CUSTOMER_1=y
CONFIG_DRIVER_A=y
CONFIG_DRIVER_C=y
In the menuconfig interface:
Custom BSP board options appear under
GAP_SDK → Board → GWT Board
Custom BSP drivers appear under
GAP_SDK → Drivers → Custom BSP Drivers
.
Example
A simple custom BSP example can be found here in GAP SDK
examples/gap9/basic/bsp/custom_bsp