LINKER_SORT_BY_ALIGNMENT causing crash in start-up code

Hello,

I am working in ncs1.5.0 on a nrf52840dk based custom board. I have found an issue where adding a certain number of characteristics in a single BLE service causing my code to crash during start-up. I ran the debugger and see code hitting a Zephyr Fatal Error in SystemInit() as shown in the debugger screenshot.

I have investigated the issue and found that if I remove one of the Client Characteristic Configuration Declarations, everything works fine. The firmware will also work fine with all the characteristics are included and CONFIG_LINKER_SORT_BY_ALIGNMENT is disabled.

I compared the generated map files and found that the failing code results in a fill of 0x3 bytes that the working code does not have. The working code has one less Client Characteristic Configuration Declaration.

I also tried to add attribute ((aligned (4))) to the BLE service definition which had no effect on the issue and still crashed.

For now, I have removed one of the characteristics in the problematic BLE service to avoid this crash. I do not want to disable CONFIG_LINKER_SORT_BY_ALIGNMENT because that results in using too much memory for padding. Please see the attached code and screenshots for more info.

`/* The following code will cause a crash. */

BT_GATT_SERVICE_DEFINE(
    new_service,
    BT_GATT_PRIMARY_SERVICE(BT_UUID_EXAMPLE_SRV),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE1,
                           BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY,
                           BT_GATT_PERM_WRITE,
                           NULL, CommandReceived, NULL),
        BT_GATT_CCC(new_ccc_ex1_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE2,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_INDICATE,
                           BT_GATT_PERM_READ,
                           ReadStatusRequested, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex2_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE3,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
                           BT_GATT_PERM_READ,
                           ReadStatusHeartbeatRequested, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex3_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE4,
                           EXAMPLE_CHAR_PACKET_TYPE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex4_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE5,
                           BT_GATT_CHRC_INDICATE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex5_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE6,
                           EXAMPLE_CHAR_PACKET_TYPE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex6_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE7,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
                           BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
                           SerialRead, SerialWrite, NULL),
);
`

`/* One of the Client Characteristic Configuration Declarations has been
commented out (line 36). This change resolves the firmware crash.*/

BT_GATT_SERVICE_DEFINE(
    new_service,
    BT_GATT_PRIMARY_SERVICE(BT_UUID_EXAMPLE_SRV),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE1,
                           BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY,
                           BT_GATT_PERM_WRITE,
                           NULL, CommandReceived, NULL),
        BT_GATT_CCC(new_ccc_ex1_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE2,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_INDICATE,
                           BT_GATT_PERM_READ,
                           ReadStatusRequested, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex2_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE3,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
                           BT_GATT_PERM_READ,
                           ReadStatusHeartbeatRequested, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex3_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE4,
                           EXAMPLE_CHAR_PACKET_TYPE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex4_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE5,
                           BT_GATT_CHRC_INDICATE,
                           0,
                           NULL, NULL, NULL),
        // BT_GATT_CCC(new_ccc_ex5_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE6,
                           EXAMPLE_CHAR_PACKET_TYPE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex6_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE7,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
                           BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
                           SerialRead, SerialWrite, NULL),
);

/* One of the Client Characteristic Configuration Declarations has been
    commented out (line 36). This change resolves the firmware crash.*/
	
BT_GATT_SERVICE_DEFINE(
    new_service,
    BT_GATT_PRIMARY_SERVICE(BT_UUID_EXAMPLE_SRV),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE1,
                           BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY,
                           BT_GATT_PERM_WRITE,
                           NULL, CommandReceived, NULL),
        BT_GATT_CCC(new_ccc_ex1_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE2,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_INDICATE,
                           BT_GATT_PERM_READ,
                           ReadStatusRequested, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex2_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE3,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
                           BT_GATT_PERM_READ,
                           ReadStatusHeartbeatRequested, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex3_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE4,
                           EXAMPLE_CHAR_PACKET_TYPE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex4_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE5,
                           BT_GATT_CHRC_INDICATE,
                           0,
                           NULL, NULL, NULL),
        // BT_GATT_CCC(new_ccc_ex5_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE6,
                           EXAMPLE_CHAR_PACKET_TYPE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex6_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE7,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
                           BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
                           SerialRead, SerialWrite, NULL),
);
/* The following code will cause a crash. */

BT_GATT_SERVICE_DEFINE(
    new_service,
    BT_GATT_PRIMARY_SERVICE(BT_UUID_EXAMPLE_SRV),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE1,
                           BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY,
                           BT_GATT_PERM_WRITE,
                           NULL, CommandReceived, NULL),
        BT_GATT_CCC(new_ccc_ex1_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE2,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_INDICATE,
                           BT_GATT_PERM_READ,
                           ReadStatusRequested, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex2_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE3,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
                           BT_GATT_PERM_READ,
                           ReadStatusHeartbeatRequested, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex3_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE4,
                           EXAMPLE_CHAR_PACKET_TYPE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex4_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE5,
                           BT_GATT_CHRC_INDICATE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex5_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE6,
                           EXAMPLE_CHAR_PACKET_TYPE,
                           0,
                           NULL, NULL, NULL),
        BT_GATT_CCC(new_ccc_ex6_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),

    BT_GATT_CHARACTERISTIC(BT_UUID_EXAMPLE7,
                           BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
                           BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
                           SerialRead, SerialWrite, NULL),
);

Parents Reply Children
  • Hi Kamal,

    Maybe you could try to add an alignment directive that minimizes padding but avoids misaligned accesses, i.e. modify the linker script to improve memory alignment without disabling CONFIG_LINKER_SORT_BY_ALIGNMENT . Also, if you can reduce the size of your characteristics or CCCs to better fit within memory constraints this can help. You can also try to increase the stack or heap size of your application. 

    -Priyanka

Related