Zephyr k_event_wait problem

Hi.

There is MainThread and MeasureThread.

There are also two events that MainThread sends - BIT(0), BIT(1). These are Start and Stop.

In MeasureThread, we first wait for the Start event K_FOREVER, after which we get into another loop where we wait for Stop K_NO_WAIT.

The idea is to send a Start event when a Client connects via BE, which will wake up the thread.
This Thread will start sending notify via BE until it receives a Stop event when the client disconnects.

My problem is that when I sent the Stop event, it does not arrive, although Start did. What could this be related to?

I do not see the line "WT> Receive WT_STOP_EVENT"

#include <zephyr/types.h>
#include <zephyr/kernel.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/sys/printk.h>

static uint8_t weight_value = 0;

static struct bt_conn *connection_;

#define WT_EXEC_EVENT BIT(0)
#define WT_STOP_EVENT BIT(1)
K_EVENT_DEFINE(measure_thread_event_);

#define WT_STACK_SIZE 4096
K_THREAD_STACK_DEFINE(wt_stack, WT_STACK_SIZE);

extern void wt_thread(void *, void *, void *);
struct k_thread wt_data;

static struct bt_uuid_128 service_uuid = BT_UUID_INIT_128(
    BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef0));

static struct bt_uuid_128 weight_char_uuid = BT_UUID_INIT_128(
    BT_UUID_128_ENCODE(0x87654321, 0x4321, 0x8765, 0x4321, 0xfedcba987654));

static ssize_t read_weight(struct bt_conn *conn, const struct bt_gatt_attr *attr,
                           void *buf, uint16_t len, uint16_t offset)
{
    const uint8_t *value = attr->user_data;
    return bt_gatt_attr_read(conn, attr, buf, len, offset, value, sizeof(weight_value));
}

static void bt_read_weight_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
    bool notif_enabled = (value == BT_GATT_CCC_NOTIFY);
    printk("BT> Notifications %s\n", notif_enabled ? "enabled" : "disabled");
}

BT_GATT_SERVICE_DEFINE(service,
                       BT_GATT_PRIMARY_SERVICE(&service_uuid),
                       BT_GATT_CHARACTERISTIC(&weight_char_uuid.uuid, BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_READ,
                                              BT_GATT_PERM_READ, read_weight, NULL, &weight_value),
                       BT_GATT_CCC(bt_read_weight_cfg_changed,
                                   BT_GATT_PERM_READ | BT_GATT_PERM_WRITE), );

static void connected(struct bt_conn *conn, uint8_t err)
{
    if (err)
    {
        printk("BT> Connection failed (err %u)\n", err);
        return;
    }

    if (connection_)
    {
        printk("BT> Only one connection is allowed at a time.\n");
        return;
    }

    printk("BT> Connected\n");
    connection_ = bt_conn_ref(conn);

    printk("BT> Send WT_EXEC_EVENT\n");
    k_event_set(&measure_thread_event_, WT_EXEC_EVENT);
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
    printk("BT> Disconnected (reason %u)\n", reason);
    if (!connection_)
    {
        printk("BT> No active connection\n");
    }
    else
    {
        printk("BT> Send WT_STOP_EVENT\n");
        k_event_set(&measure_thread_event_, WT_STOP_EVENT);
    }
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
    .connected = connected,
    .disconnected = disconnected,
};

int main(void)
{
    printk("BT> Starting Bluetooth Peripheral\n");

    int error;
    error = bt_enable(NULL);
    if (error)
    {
        printk("BT> Bluetooth init failed (err %d)\n", error);
        return -1;
    }

    printk("BT> Bluetooth initialized\n");

    k_tid_t my_tid = k_thread_create(&wt_data, wt_stack,
                                     K_THREAD_STACK_SIZEOF(wt_stack),
                                     wt_thread,
                                     NULL, NULL, NULL,
                                     /*lowPrio=*/7, /*options=*/0, K_NO_WAIT);

    error = bt_le_adv_start(BT_LE_ADV_CONN, NULL, 0, NULL, 0);
    if (error)
    {
        printk("BT> Advertising failed to start (err %d)\n", error);
        return -1;
    }

    printk("BT> Advertising successfully started\n");

    k_thread_suspend(k_current_get());

    return 0;
}

void wt_thread(void *, void *, void *)
{
    while (1)
    {
        uint32_t events = k_event_wait(&measure_thread_event_, WT_EXEC_EVENT, true, K_FOREVER);
        if (events & WT_EXEC_EVENT)
        {
            printk("WT> Received WT_EXEC_EVENT\n");
            if (!connection_)
            {
                printk("WT> No active connection\n");
                return;
            }

            exec();

            printk("WT> Completed\n");
            bt_conn_unref(connection_);
            connection_ = NULL;
        }
    }
}

void exec()
{
    while (1)
    {
        uint32_t events = k_event_wait(&measure_thread_event_, WT_STOP_EVENT, false, K_NO_WAIT);
        if (events & WT_STOP_EVENT)
        {
            printk("WT> Receive WT_STOP_EVENT\n");
            return;
        }

        weight_value++;
        printk("WT> Notify %d\n", weight_value);
        //bt_gatt_notify(NULL, &service.attrs[1], &weight_value, sizeof(weight_value));

        k_sleep(K_MSEC(500));
    }
}

Parents
  • Hi!

    What version of nRF Connect SDK are you using?

    Did you see "BT> Send WT_STOP_EVENT" in the log?

  • BT> Bluetooth initialized
    BT> Advertising successfully started
    BT> Connected
    BT> Send WT_EXEC_EVENT
    WT> Received WT_EXEC_EVENT
    WT> Notify 1
    WT> Notify 2
    WT> Notify 3
    WT> Notify 4
    WT> Notify 5
    WT> Notify 6
    WT> Notify 7
    WT> Notify 8
    WT> Notify 9
    BT> Disconnected (reason 19)
    BT> Send WT_STOP_EVENT
    WT> Notify 10
    WT> Notify 11
    WT> Notify 12
    WT> Notify 13
    WT> Notify 14

    My version is 2.6.1

    My config

    CONFIG_GPIO=y
    
    CONFIG_ASSERT=y
    
    CONFIG_CONSOLE=y
    CONFIG_UART_CONSOLE=y
    CONFIG_PRINTK=y
    CONFIG_EARLY_CONSOLE=y
    
    CONFIG_EVENTS=y
    
    CONFIG_LOG=y
    CONFIG_LOG_DEFAULT_LEVEL=3
    
    CONFIG_INIT_STACKS=y
    CONFIG_THREAD_STACK_INFO=y
    
    CONFIG_RESET_ON_FATAL_ERROR=n
    
    CONFIG_USB_DEVICE_VID=0x1234
    
    CONFIG_BT=y
    CONFIG_BT_HCI=y
    CONFIG_BT_CTLR=y
    CONFIG_BT_PERIPHERAL=y

Reply
  • BT> Bluetooth initialized
    BT> Advertising successfully started
    BT> Connected
    BT> Send WT_EXEC_EVENT
    WT> Received WT_EXEC_EVENT
    WT> Notify 1
    WT> Notify 2
    WT> Notify 3
    WT> Notify 4
    WT> Notify 5
    WT> Notify 6
    WT> Notify 7
    WT> Notify 8
    WT> Notify 9
    BT> Disconnected (reason 19)
    BT> Send WT_STOP_EVENT
    WT> Notify 10
    WT> Notify 11
    WT> Notify 12
    WT> Notify 13
    WT> Notify 14

    My version is 2.6.1

    My config

    CONFIG_GPIO=y
    
    CONFIG_ASSERT=y
    
    CONFIG_CONSOLE=y
    CONFIG_UART_CONSOLE=y
    CONFIG_PRINTK=y
    CONFIG_EARLY_CONSOLE=y
    
    CONFIG_EVENTS=y
    
    CONFIG_LOG=y
    CONFIG_LOG_DEFAULT_LEVEL=3
    
    CONFIG_INIT_STACKS=y
    CONFIG_THREAD_STACK_INFO=y
    
    CONFIG_RESET_ON_FATAL_ERROR=n
    
    CONFIG_USB_DEVICE_VID=0x1234
    
    CONFIG_BT=y
    CONFIG_BT_HCI=y
    CONFIG_BT_CTLR=y
    CONFIG_BT_PERIPHERAL=y

Children
Related