Linkage Zephyr V1.13 versus V2.X


frv
 
Edited

Hi all,
 
Recently I have moved from Zephyr 1.13 to V2.
 
I ported my simple BLE peripheral application based on the sample code peripheral_hr from  V1.13 to V2.
 
However I can't seem to get it build anymore due to a linkage issue.
As far as I can see the sources are well compiled but for some reason the linker reports an undefined reference.
 
"/home/frv/develop/zephyrproject/zephyr/samples/bluetooth/peripheral_hrORIGI/src/button.c:78: undefined reference to `bt_gatt_service_register'"
 
In my setup the GATT services are still defined in separate files. 
So next to my main.c that calls the init function (button_init()) I have the sources button.c and button.h file where I define my own GATT service (cfr. hrs.c, hrs.h as done in V1.13) to follow up a button press.
 
src/main.c
    /button.c
 
The CMakeLists.txt has as content (which is pretty simple): 
 
# SPDX-License-Identifier: Apache-2.0
 
cmake_minimum_required(VERSION 3.13.1)
 
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(peripheral_hr)
 
FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE
  ${app_sources}
  )
 
zephyr_library_include_directories($ENV{ZEPHYR_BASE}/samples/bluetooth)
//has the button.h file
zephyr_library_include_directories($ENV{ZEPHYR_BASE}/samples/bluetooth/gatt)
 
In the button.c  code snippet:
...
static struct bt_gatt_service button_svc = BT_GATT_SERVICE(attrs);
 
void button_init(void)
{
   int result = bt_gatt_service_register(&button_svc);
}
...
 
I have spend some time on looking at the boilerplate concepts but so far without any luck to prevent the linker error.
I also had a look at this : https://github.com/zephyrproject-rtos/zephyr/issues/8851
 
Any idea's what the issue could be and how to solve this properly. Linkage order?
 
BTW when I do the call, bt_gatt_service_register,  in the main.c this is not seen as an undefined reference.
 
Thanks,
Best regards,
Frank


Lawrence King
 

I had the same issue when moving forward kernel versions. The API for

 

At the top level get rid of the bt_gatt_ccc_cfg variables (my code has two characteristics) :

 

#ifndef NEW_BT_STACK

static struct bt_gatt_ccc_cfg iks_atom_ccc_cfg[BT_GATT_CCC_MAX];

static struct bt_gatt_ccc_cfg iks_mtoa_ccc_cfg[BT_GATT_CCC_MAX];

#endif

 

And inside the bt_gatt_attr change the parameters to the BT_GATT_CCC macro, delete the first parameter it is no longer needed, and add a new 3rd parameter (same thing in two places for me):

 

#ifdef  NEW_BT_STACK

        BT_GATT_CCC(iks_atom_ccc_cfg_changed,BT_GATT_PERM_WRITE_ENCRYPT),

        // BT_GATT_CCC(iks_atom_ccc_cfg_changed,BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

        // BT_GATT_CCC(iks_atom_ccc_cfg_changed,BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT),

#else   //NEW_BT_STACK

        BT_GATT_CCC(iks_atom_ccc_cfg, iks_atom_ccc_cfg_changed),

#endif  //NEW_BT_STACK

 

Lawrence King

Principal Developer

+1(416)627-7302

 

From: devel@... <devel@...> On Behalf Of frv
Sent: Wednesday, December 4, 2019 2:19 AM
To: devel@...
Subject: [Zephyr-devel] Linkage Zephyr V1.13 versus V2.X

 

[Edited Message Follows]

Hi all,

 

Recently I have moved from Zephyr 1.13 to V2.

 

I ported my simple BLE peripheral application based on the sample code peripheral_hr from  V1.13 to V2.

 

However I can't seem to get it build anymore due to a linkage issue.

As far as I can see the sources are well compiled but for some reason the linker reports an undefined reference.

 

"/home/frv/develop/zephyrproject/zephyr/samples/bluetooth/peripheral_hrORIGI/src/button.c:78: undefined reference to `bt_gatt_service_register'"

 

In my setup the GATT services are still defined in separate files. 

So next to my main.c that calls the init function (button_init()) I have the sources button.c and button.h file where I define my own GATT service (cfr. hrs.c, hrs.h as done in V1.13) to follow up a button press.

 

src/main.c

    /button.c

 

The CMakeLists.txt has as content (which is pretty simple): 

 

# SPDX-License-Identifier: Apache-2.0

 

cmake_minimum_required(VERSION 3.13.1)

 

include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)

project(peripheral_hr)

 

FILE(GLOB app_sources src/*.c)

target_sources(app PRIVATE

  ${app_sources}

  )

 

zephyr_library_include_directories($ENV{ZEPHYR_BASE}/samples/bluetooth)

//has the button.h file

zephyr_library_include_directories($ENV{ZEPHYR_BASE}/samples/bluetooth/gatt)

 

In the button.c  code snippet:

...

static struct bt_gatt_service button_svc = BT_GATT_SERVICE(attrs);

 

void button_init(void)

{

   int result = bt_gatt_service_register(&button_svc);

}

...

 

I have spend some time on looking at the boilerplate concepts but so far without any luck to prevent the linker error.
I also had a look at this : https://github.com/zephyrproject-rtos/zephyr/issues/8851

 

Any idea's what the issue could be and how to solve this properly. Linkage order?

 

BTW when I do the call, bt_gatt_service_register,  in the main.c this is not seen as an undefined reference.

 

Thanks,

Best regards,

Frank


frv
 
Edited

Hi Lawrence,

Correct, but this one was quite easy to find as the compiler raised the issue as the function parameters no longer matched. 

Having to specify the option in the prj.conf to support dynamic BT GATT service creation was quite harder :). I had no glue the bt_gatt_service_register code was no longer linked in when the option "CONFIG_BT_GATT_DYNAMIC_DB=y"
was not set in the prj.conf file. 

Thanks for the response,
Frank


frv
 

Hi all,

Sorry replied the solution to myself and not to the group, but solution is to set the option "CONFIG_BT_GATT_DYNAMIC_DB=y"
in the application prj.conf file, otherwise it is no longer possible to call the function bt_gatt_service_register when creating a GATT service (dynamically...).

Best regards,

Frank


Lawrence King
 

This is what I have my prj.conf, yours might be different, an I’m not sure what I have is 100% correct:

 

# BT settings

CONFIG_BT=y

CONFIG_BT_SMP=y

CONFIG_BT_SIGNING=y

CONFIG_BT_BONDABLE=y

CONFIG_BT_PERIPHERAL=y

CONFIG_BT_GATT_DYNAMIC_DB=y

CONFIG_BT_GATT_READ_MULTIPLE=y

CONFIG_BT_GATT_DIS=y

CONFIG_BT_ATT_PREPARE_COUNT=2

CONFIG_BT_PRIVACY=y

CONFIG_BT_DEVICE_NAME="My Device"

CONFIG_BT_DEVICE_APPEARANCE=833

CONFIG_BT_SETTINGS=n

 

Lawrence King

Principal Developer

+1(416)627-7302

 

From: devel@... <devel@...> On Behalf Of frv
Sent: Wednesday, December 4, 2019 11:23 AM
To: devel@...
Subject: Re: [Zephyr-devel] Linkage Zephyr V1.13 versus V2.X

 

Hi Lawrence,

Correct, but this one was quite easy to find as the compiler raised the issue. 

Having to specify the option in the prj.conf to support dynamic service creation was quite harder :).

Thanks for the response,
Frank


frv
 
Edited

Hi Lawrence,

As far as I know this one 
CONFIG_BT_GATT_DYNAMIC_DB=y
did the trick as specified in your prj.conf as well.

Br,
Frank