当前位置: 首页 > article >正文

【Zephyr】【一】学习笔记

Zephyr RTOS 示例代码集

1. 基础示例

1.0 基础配置

每个示例都需要一个 prj.conf 文件来配置项目。以下是各个示例所需的配置:

基础示例 prj.conf
# 控制台输出
CONFIG_PRINTK=y
CONFIG_SERIAL=y
CONFIG_UART_CONSOLE=y# 日志系统
CONFIG_LOG=y
CONFIG_LOG_DEFAULT_LEVEL=3# 内核配置
CONFIG_KERNEL_BIN_NAME="app"
线程示例 prj.conf
# 基础配置
CONFIG_PRINTK=y
CONFIG_SERIAL=y
CONFIG_UART_CONSOLE=y# 线程配置
CONFIG_THREAD_NAME=y
CONFIG_THREAD_MONITOR=y
CONFIG_THREAD_STACK_INFO=y

1.1 Hello World

int main(void)
{const struct device *uart_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));if (!device_is_ready(uart_dev)) {printk("UART device not ready\n");return -ENODEV;}char tx_buf[] = "Hello World!\r\n";for (int i = 0; i < sizeof(tx_buf); i++) {uart_poll_out(uart_dev, tx_buf[i]);}return 0;
}return ret;}while (1) {gpio_pin_set(dev, PIN, (int)led_is_on);led_is_on = !led_is_on;k_sleep(K_MSEC(1000));}return 0;
}
{while (1) {printk("Thread 1 running\n");k_msleep(1000);}
}void thread2_entry(void *p1, void *p2, void *p3)
{while (1) {printk("Thread 2 running\n");k_msleep(1500);}
}int main(void)
{k_thread_create(&thread1_data, thread1_stack,STACK_SIZE, thread1_entry,NULL, NULL, NULL,THREAD_PRIORITY, 0, K_NO_WAIT);k_thread_create(&thread2_data, thread2_stack,STACK_SIZE, thread2_entry,NULL, NULL, NULL,THREAD_PRIORITY, 0, K_NO_WAIT);return 0;
}

2. 通信示例

2.0 通信示例配置

信号量示例 prj.conf
# 基础配置
CONFIG_PRINTK=y
CONFIG_SERIAL=y
CONFIG_UART_CONSOLE=y# 内核配置
CONFIG_KERNEL_BIN_NAME="app"# 线程配置
CONFIG_THREAD_NAME=y
CONFIG_THREAD_MONITOR=y
CONFIG_THREAD_STACK_INFO=y
消息队列示例 prj.conf
# 基础配置
CONFIG_PRINTK=y
CONFIG_SERIAL=y
CONFIG_UART_CONSOLE=y# 内核配置
CONFIG_KERNEL_BIN_NAME="app"# 线程配置
CONFIG_THREAD_NAME=y
CONFIG_THREAD_MONITOR=y
CONFIG_THREAD_STACK_INFO=y# 消息队列配置
CONFIG_HEAP_MEM_POOL_SIZE=256

2.1 信号量

#include <zephyr/kernel.h>#define STACK_SIZE 1024
#define THREAD_PRIORITY 7K_SEM_DEFINE(my_sem, 0, 1);K_THREAD_STACK_DEFINE(producer_stack, STACK_SIZE);
K_THREAD_STACK_DEFINE(consumer_stack, STACK_SIZE);struct k_thread producer_thread_data;
struct k_thread consumer_thread_data;void producer_entry(void *p1, void *p2, void *p3)
{while (1) {k_msleep(1000);printk("Giving semaphore\n");k_sem_give(&my_sem);}
}void consumer_entry(void *p1, void *p2, void *p3)
{while (1) {printk("Taking semaphore\n");k_sem_take(&my_sem, K_FOREVER);printk("Got semaphore\n");}
}void main(void)
{k_thread_create(&producer_thread_data, producer_stack,STACK_SIZE, producer_entry,NULL, NULL, NULL,THREAD_PRIORITY, 0, K_NO_WAIT);k_thread_create(&consumer_thread_data, consumer_stack,STACK_SIZE, consumer_entry,NULL, NULL, NULL,THREAD_PRIORITY, 0, K_NO_WAIT);
}

2.2 消息队列

#include <zephyr/kernel.h>#define STACK_SIZE 1024
#define THREAD_PRIORITY 7
#define MAX_MSG_SIZE 32K_MSGQ_DEFINE(my_msgq, MAX_MSG_SIZE, 10, 4);K_THREAD_STACK_DEFINE(producer_stack, STACK_SIZE);
K_THREAD_STACK_DEFINE(consumer_stack, STACK_SIZE);struct k_thread producer_thread_data;
struct k_thread consumer_thread_data;void producer_entry(void *p1, void *p2, void *p3)
{char tx_str[MAX_MSG_SIZE];int count = 0;while (1) {snprintf(tx_str, sizeof(tx_str), "message %d", count++);k_msgq_put(&my_msgq, tx_str, K_FOREVER);k_msleep(1000);}
}void consumer_entry(void *p1, void *p2, void *p3)
{char rx_str[MAX_MSG_SIZE];while (1) {k_msgq_get(&my_msgq, &rx_str, K_FOREVER);printk("Received: %s\n", rx_str);}
}void main(void)
{k_thread_create(&producer_thread_data, producer_stack,STACK_SIZE, producer_entry,NULL, NULL, NULL,THREAD_PRIORITY, 0, K_NO_WAIT);k_thread_create(&consumer_thread_data, consumer_stack,STACK_SIZE, consumer_entry,NULL, NULL, NULL,THREAD_PRIORITY, 0, K_NO_WAIT);
}

3. 硬件操作示例

3.0 硬件操作配置

GPIO示例 prj.conf
# 基础配置
CONFIG_PRINTK=y
CONFIG_SERIAL=y
CONFIG_UART_CONSOLE=y# GPIO配置
CONFIG_GPIO=y# 设备树配置
CONFIG_GPIO_INIT_PRIORITY=40
UART示例 prj.conf
# 基础配置
CONFIG_PRINTK=y
CONFIG_SERIAL=y
CONFIG_UART_CONSOLE=y# UART配置
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_UART_LINE_CTRL=y

3.1 GPIO控制

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>/* 获取LED设备树信息 */
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios);void main(void)
{int ret;if (!device_is_ready(led.port)) {printk("Error: LED device %s is not ready\n", led.port->name);return;}ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);if (ret < 0) {printk("Error %d: Failed to configure LED pin\n", ret);return;}while (1) {gpio_pin_toggle_dt(&led);k_msleep(1000);}
}

3.2 UART通信

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/uart.h>void main(void)
{const struct device *const uart_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));if (!device_is_ready(uart_dev)) {printk("UART device not ready\n");return;}char tx_buf[] = "Hello World!\r\n";for (int i = 0; i < sizeof(tx_buf); i++) {uart_poll_out(uart_dev, tx_buf[i]);}
}

4. 传感器示例

4.0 传感器配置

温度传感器示例 prj.conf
# 基础配置
CONFIG_PRINTK=y
CONFIG_SERIAL=y
CONFIG_UART_CONSOLE=y# I2C配置(如果传感器使用I2C)
CONFIG_I2C=y# 传感器配置
CONFIG_SENSOR=y
CONFIG_BME280=y
CONFIG_BME280_MODE_FORCED=y

4.1 温度传感器

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>int main(void)
{const struct device *const dev = DEVICE_DT_GET_ANY(bosch_bme280);if (!device_is_ready(dev)) {printk("Device %s is not ready\n", dev->name);return -ENODEV;}while (1) {struct sensor_value temp;int ret = sensor_sample_fetch(dev);if (ret < 0) {printk("sensor_sample_fetch failed: %d\n", ret);continue;}ret = sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp);if (ret < 0) {printk("sensor_channel_get failed: %d\n", ret);continue;}printk("Temperature: %.2f °C\n", sensor_value_to_double(&temp));k_msleep(1000);}return 0;
}

5. 网络示例

5.0 网络配置

TCP Echo服务器示例 prj.conf
# 基础配置
CONFIG_PRINTK=y
CONFIG_SERIAL=y
CONFIG_UART_CONSOLE=y# 网络配置
CONFIG_NETWORKING=y
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=y
CONFIG_NET_TCP=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y# 网络缓冲区配置
CONFIG_NET_PKT_RX_COUNT=16
CONFIG_NET_PKT_TX_COUNT=16
CONFIG_NET_BUF_RX_COUNT=64
CONFIG_NET_BUF_TX_COUNT=64# 网络shell(可选,用于调试)
CONFIG_NET_SHELL=y# DHCP客户端(可选)
CONFIG_NET_DHCPV4=y# 日志配置
CONFIG_NET_LOG=y
CONFIG_NET_SOCKETS_LOG_LEVEL_DBG=y

5.1 TCP Echo服务器

#include <zephyr/kernel.h>
#include <zephyr/net/socket.h>
#include <zephyr/net/net_ip.h>#define PORT 4242
#define BUFFER_SIZE 1024int main(void)
{int serv_sock, client_sock;struct sockaddr_in server_addr, client_addr;socklen_t client_addr_len = sizeof(client_addr);char rx_buf[BUFFER_SIZE];int ret;/* 创建socket */serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (serv_sock < 0) {printk("Failed to create socket: %d\n", errno);return -errno;}/* 配置服务器地址 */server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = htonl(INADDR_ANY);server_addr.sin_port = htons(PORT);ret = bind(serv_sock, (struct sockaddr *)&server_addr,sizeof(server_addr));if (ret < 0) {printk("Failed to bind: %d\n", errno);close(serv_sock);return -errno;}ret = listen(serv_sock, 5);if (ret < 0) {printk("Failed to listen: %d\n", errno);close(serv_sock);return -errno;}printk("TCP server listening on port %d\n", PORT);while (1) {client_sock = accept(serv_sock, (struct sockaddr *)&client_addr,&client_addr_len);if (client_sock < 0) {printk("Accept failed: %d\n", errno);continue;}printk("Client connected\n");while (1) {ret = recv(client_sock, rx_buf, sizeof(rx_buf), 0);if (ret < 0) {printk("Receive failed: %d\n", errno);break;}if (ret == 0) {printk("Client disconnected\n");break;}ret = send(client_sock, rx_buf, ret, 0);if (ret < 0) {printk("Send failed: %d\n", errno);break;}}close(client_sock);}close(serv_sock);return 0;
}

6. 蓝牙示例

6.0 蓝牙配置

BLE广播示例 prj.conf
# 基础配置
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y# 蓝牙配置
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="Zephyr"
CONFIG_BT_DEVICE_NAME_DYNAMIC=n
CONFIG_BT_DEVICE_APPEARANCE=0
CONFIG_BT_MAX_CONN=1# 蓝牙服务配置
CONFIG_BT_DIS=y
CONFIG_BT_DIS_PNP=n
CONFIG_BT_DIS_MODEL="Zephyr Model"
CONFIG_BT_DIS_MANUF="Zephyr Manufacturer"# 调试配置(可选)
#CONFIG_BT_DEBUG_LOG=y

6.1 BLE广播

prj.conf
# 基础配置
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y# 蓝牙配置
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="Zephyr Test"# 调试配置(可选)
CONFIG_BT_DEBUG_LOG=y
src/main.c
#include <zephyr/kernel.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>static const struct bt_data ad[] = {BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),BT_DATA_BYTES(BT_DATA_NAME_COMPLETE, 'Z', 'e', 'p', 'h', 'y', 'r', ' ', 'T', 'e', 's', 't'),
};void start_advertising(void)
{int err;err = bt_le_adv_start(BT_LE_ADV_NCONN, ad, ARRAY_SIZE(ad), NULL, 0);if (err) {printk("Advertising failed to start (err %d)\n", err);return;}printk("Advertising successfully started\n");
}int main(void)
{int err;printk("Starting Bluetooth Peripheral example\n");/* 初始化蓝牙 */err = bt_enable(NULL);if (err) {printk("Bluetooth init failed (err %d)\n", err);return err;}printk("Bluetooth initialized\n");/* 开始广播 */start_advertising();return 0;
}

CONFIG_BT_DIS=y
CONFIG_BT_DIS_PNP=n
CONFIG_BT_DIS_MODEL=“Zephyr Model”
CONFIG_BT_DIS_MANUF=“Zephyr Manufacturer”

调试配置(可选)

CONFIG_BT_DEBUG_LOG=y


#### src/main.c
```c
#include <zephyr/kernel.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>static const struct bt_data ad[] = {BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR),BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_DIS_VAL)),
};static const struct bt_data sd[] = {BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),
};static void bt_ready(int err)
{if (err) {printk("Bluetooth init failed (err %d)\n", err);return;}printk("Bluetooth initialized\n");/* 开始广播 */err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0);if (err) {printk("Advertising failed to start (err %d)\n", err);return;}printk("Advertising successfully started\n");
}static void connected(struct bt_conn *conn, uint8_t err)
{if (err) {printk("Connection failed (err 0x%02x)\n", err);} else {printk("Connected\n");}
}static void disconnected(struct bt_conn *conn, uint8_t reason)
{printk("Disconnected (reason 0x%02x)\n", reason);
}BT_CONN_CB_DEFINE(conn_callbacks) = {.connected = connected,.disconnected = disconnected,
};int main(void)
{int err;printk("Starting Bluetooth Peripheral example\n");/* 初始化蓝牙 */err = bt_enable(bt_ready);if (err) {printk("Bluetooth init failed (err %d)\n", err);return err;}/* 等待事件 */while (1) {k_msleep(1000);}return 0;
}

6.2 BLE GATT服务

prj.conf
# 基础配置
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y# 蓝牙配置
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="Zephyr GATT"
CONFIG_BT_DEVICE_APPEARANCE=0
CONFIG_BT_MAX_CONN=1# GATT配置
CONFIG_BT_GATT_DYNAMIC_DB=y
CONFIG_BT_GATT_SERVICE_CHANGED=y# 调试配置
CONFIG_BT_DEBUG_LOG=y
src/main.c
#include <zephyr/kernel.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>/* 自定义服务 UUID */
#define BT_UUID_CUSTOM_SERVICE_VAL \BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef0)/* 自定义特征 UUID */
#define BT_UUID_CUSTOM_CHRC_VAL \BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef1)static struct bt_uuid_128 custom_service_uuid = BT_UUID_INIT_128(BT_UUID_CUSTOM_SERVICE_VAL);
static struct bt_uuid_128 custom_characteristic_uuid = BT_UUID_INIT_128(BT_UUID_CUSTOM_CHRC_VAL);static uint8_t custom_value[] = { 0x00 };static ssize_t read_custom_characteristic(struct bt_conn *conn,const struct bt_gatt_attr *attr,void *buf,uint16_t len,uint16_t offset)
{return bt_gatt_attr_read(conn, attr, buf, len, offset,custom_value, sizeof(custom_value));
}static ssize_t write_custom_characteristic(struct bt_conn *conn,const struct bt_gatt_attr *attr,const void *buf,uint16_t len,uint16_t offset,uint8_t flags)
{if (offset + len > sizeof(custom_value)) {return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);}memcpy(custom_value + offset, buf, len);printk("Received data: 0x%02x\n", custom_value[0]);return len;
}/* GATT服务定义 */
BT_GATT_SERVICE_DEFINE(custom_svc,BT_GATT_PRIMARY_SERVICE(&custom_service_uuid),BT_GATT_CHARACTERISTIC(&custom_characteristic_uuid.uuid,BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,read_custom_characteristic,write_custom_characteristic,custom_value),
);static const struct bt_data ad[] = {BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_CUSTOM_SERVICE_VAL),
};static void connected(struct bt_conn *conn, uint8_t err)
{if (err) {printk("Connection failed (err 0x%02x)\n", err);} else {printk("Connected\n");}
}static void disconnected(struct bt_conn *conn, uint8_t reason)
{printk("Disconnected (reason 0x%02x)\n", reason);
}BT_CONN_CB_DEFINE(conn_callbacks) = {.connected = connected,.disconnected = disconnected,
};static void bt_ready(int err)
{if (err) {printk("Bluetooth init failed (err %d)\n", err);return;}printk("Bluetooth initialized\n");/* 开始广播 */err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));if (err) {printk("Advertising failed to start (err %d)\n", err);return;}printk("Advertising successfully started\n");
}int main(void)
{int err;printk("Starting Bluetooth GATT Service example\n");/* 初始化蓝牙 */err = bt_enable(bt_ready);if (err) {printk("Bluetooth init failed (err %d)\n", err);return err;}/* 等待事件 */while (1) {k_msleep(1000);}return 0;
}
prj.conf
# 基础配置
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y# 蓝牙配置
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="Zephyr"
CONFIG_BT_DEVICE_APPEARANCE=0
CONFIG_BT_MAX_CONN=1# 调试配置(可选)
CONFIG_BT_DEBUG_LOG=y
src/main.c
#include <zephyr/kernel.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>#define DEVICE_NAME     CONFIG_BT_DEVICE_NAME
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)/* 广播数据 */
static const struct bt_data ad[] = {BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN)
};/* 扫描响应数据 */
static const struct bt_data sd[] = {BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_DIS_VAL))
};static void bt_ready(int err)
{if (err) {printk("Bluetooth init failed (err %d)\n", err);return;}printk("Bluetooth initialized\n");/* 开始广播 */err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad),sd, ARRAY_SIZE(sd));if (err) {printk("Advertising failed to start (err %d)\n", err);return;}printk("Advertising successfully started\n");
}static void connected(struct bt_conn *conn, uint8_t err)
{if (err) {printk("Connection failed (err %u)\n", err);return;}printk("Connected\n");
}static void disconnected(struct bt_conn *conn, uint8_t reason)
{printk("Disconnected (reason %u)\n", reason);
}BT_CONN_CB_DEFINE(conn_callbacks) = {.connected = connected,.disconnected = disconnected,
};int main(void)
{int err;printk("Starting Bluetooth Peripheral example\n");/* 初始化蓝牙 */err = bt_enable(bt_ready);if (err) {printk("Bluetooth init failed (err %d)\n", err);return err;}/* 无限循环等待事件 */while (1) {k_msleep(1000);}return 0;
}
CMakeLists.txt
# SPDX-License-Identifier: Apache-2.0cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(bluetooth_peripheral)target_sources(app PRIVATE src/main.c)

6.2 BLE服务示例

src/main.c
#include <zephyr/kernel.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>#define DEVICE_NAME     CONFIG_BT_DEVICE_NAME
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)/* 自定义服务 UUID */
#define BT_UUID_CUSTOM_SERVICE_VAL \BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef0)#define BT_UUID_CUSTOM_CHAR_VAL \BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef1)static struct bt_uuid_128 custom_service_uuid = BT_UUID_INIT_128(BT_UUID_CUSTOM_SERVICE_VAL);
static struct bt_uuid_128 custom_char_uuid = BT_UUID_INIT_128(BT_UUID_CUSTOM_CHAR_VAL);static uint8_t custom_value[] = { 0x00 };/* 广播数据 */
static const struct bt_data ad[] = {BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_CUSTOM_SERVICE_VAL)
};/* 特征值读取回调 */
static ssize_t read_custom_value(struct bt_conn *conn,const struct bt_gatt_attr *attr,void *buf, uint16_t len, uint16_t offset)
{return bt_gatt_attr_read(conn, attr, buf, len, offset,custom_value, sizeof(custom_value));
}/* 特征值写入回调 */
static ssize_t write_custom_value(struct bt_conn *conn,const struct bt_gatt_attr *attr,const void *buf, uint16_t len,uint16_t offset, uint8_t flags)
{if (offset + len > sizeof(custom_value)) {return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);}memcpy(custom_value + offset, buf, len);printk("Value updated: %02x\n", custom_value[0]);return len;
}/* 定义GATT服务 */
BT_GATT_SERVICE_DEFINE(custom_svc,BT_GATT_PRIMARY_SERVICE(&custom_service_uuid),BT_GATT_CHARACTERISTIC(&custom_char_uuid.uuid,BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,read_custom_value, write_custom_value,custom_value),
);static void connected(struct bt_conn *conn, uint8_t err)
{if (err) {printk("Connection failed (err %u)\n", err);return;}printk("Connected\n");
}static void disconnected(struct bt_conn *conn, uint8_t reason)
{printk("Disconnected (reason %u)\n", reason);
}BT_CONN_CB_DEFINE(conn_callbacks) = {.connected = connected,.disconnected = disconnected,
};static void bt_ready(int err)
{if (err) {printk("Bluetooth init failed (err %d)\n", err);return;}printk("Bluetooth initialized\n");/* 开始广播 */err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad),NULL, 0);if (err) {printk("Advertising failed to start (err %d)\n", err);return;}printk("Advertising successfully started\n");
}int main(void)
{int err;printk("Starting Bluetooth GATT Service example\n");/* 初始化蓝牙 */err = bt_enable(bt_ready);if (err) {printk("Bluetooth init failed (err %d)\n", err);return err;}/* 无限循环等待事件 */while (1) {k_msleep(1000);}return 0;
}

7. 文件系统示例

7.0 文件系统配置

文件操作示例 prj.conf
# 基础配置
CONFIG_PRINTK=y
CONFIG_SERIAL=y
CONFIG_UART_CONSOLE=y# 文件系统配置
CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_LITTLEFS=y# Flash驱动配置
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_FLASH_PAGE_LAYOUT=y# 日志配置
CONFIG_LOG=y
CONFIG_LOG_DEFAULT_LEVEL=3# 文件系统分区配置示例(需要在设备树中定义具体分区)
CONFIG_FLASH_MAP=y
文件系统分区示例 (boards/xxx.overlay)
/ {fstab {compatible = "zephyr,fstab";lfs1: lfs1 {compatible = "zephyr,fstab,littlefs";mount-point = "/lfs";partition = <&lfs1_part>;read-size = <16>;prog-size = <16>;cache-size = <64>;lookahead-size = <32>;block-cycles = <512>;};};
};&flash0 {partitions {compatible = "fixed-partitions";#address-cells = <1>;#size-cells = <1>;lfs1_part: partition@70000 {label = "storage";reg = <0x70000 0x10000>;};};
};

7.1 文件操作

#include <zephyr/kernel.h>
#include <zephyr/fs/fs.h>int main(void)
{struct fs_file_t file;char buf[128];ssize_t written, read;int ret;/* 初始化文件对象 */fs_file_t_init(&file);/* 写文件 */ret = fs_open(&file, "/lfs/test.txt", FS_O_CREATE | FS_O_WRITE);if (ret < 0) {printk("Failed to open file for writing: %d\n", ret);return ret;}written = fs_write(&file, "Hello, Zephyr!", 13);if (written < 0) {printk("Failed to write file: %d\n", written);fs_close(&file);return written;}ret = fs_close(&file);if (ret < 0) {printk("Failed to close file: %d\n", ret);return ret;}/* 读文件 */ret = fs_open(&file, "/lfs/test.txt", FS_O_READ);if (ret < 0) {printk("Failed to open file for reading: %d\n", ret);return ret;}read = fs_read(&file, buf, sizeof(buf));if (read < 0) {printk("Failed to read file: %d\n", read);fs_close(&file);return read;}if (read > 0) {buf[read] = '\0';printk("Read from file: %s\n", buf);}ret = fs_close(&file);if (ret < 0) {printk("Failed to close file: %d\n", ret);return ret;}return 0;
}

相关文章:

【Zephyr】【一】学习笔记

Zephyr RTOS 示例代码集 1. 基础示例 1.0 基础配置 每个示例都需要一个 prj.conf 文件来配置项目。以下是各个示例所需的配置&#xff1a; 基础示例 prj.conf # 控制台输出 CONFIG_PRINTKy CONFIG_SERIALy CONFIG_UART_CONSOLEy# 日志系统 CONFIG_LOGy CONFIG_LOG_DEFAULT…...

网络安全设备配置与管理-实验4-防火墙AAA服务配置

实验4-p118防火墙AAA服务配置 从这个实验开始&#xff0c;每一个实验都是长篇大论&#x1f613; 不过有好兄弟会替我出手 注意&#xff1a;1. gns3.exe必须以管理员身份打开&#xff0c;否则ping不通虚拟机。 win10虚拟机无法做本次实验&#xff0c;必须用学校给的虚拟机。首…...

后端框架模块化

后端框架的模块化设计旨在简化开发流程、提高可维护性&#xff0c;并通过分层解耦降低复杂性。以下是常见的后端模块及其在不同语言&#xff08;Node.js、Java、Python&#xff09;中的实现方式&#xff1a; 目录 1. 路由&#xff08;Routing&#xff09;2. 中间件&#xff08;…...

【论文阅读】Contrastive Clustering Learning for Multi-Behavior Recommendation

论文地址&#xff1a;Contrastive Clustering Learning for Multi-Behavior Recommendation | ACM Transactions on Information Systems 摘要 近年来&#xff0c;多行为推荐模型取得了显著成功。然而&#xff0c;许多模型未充分考虑不同行为之间的共性与差异性&#xff0c;以…...

视频转音频, 音频转文字

Ubuntu 24 环境准备 # 系统级依赖 sudo apt update && sudo apt install -y ffmpeg python3-venv git build-essential python3-dev# Python虚拟环境 python3 -m venv ~/ai_summary source ~/ai_summary/bin/activate核心工具链 工具用途安装命令Whisper语音识别pip …...

基于协同过滤推荐算法的景点票务数据系统(python-计算机毕设)

摘 要 I ABSTRACT II 第 1 章 引言 1 研究背景及意义 1 研究背景 1研究意义 1 国内外研究现状 2 智慧旅游 3旅游大数据 3 研究内容 4本章小结 4 第 2 章 相关技术概述 5 基于内容的推荐算法 5 基于内容的推荐算法原理 5基于内容的推荐算法实现 5 协同过滤推荐算法 6 协同过…...

QT学习笔记1

** Qt Creator开发环境配置** 安装流程&#xff08;Windows平台&#xff09; 下载与安装 &#xff1a; 访问Qt官网&#xff0c;下载在线安装工具Qt Online Installer。登录或注册Qt账号&#xff0c;选择开源版本&#xff08;需勾选“接受协议”&#xff09;。勾选组件&#xff…...

Ubuntu 24 常用命令方法

文章目录 环境说明1、账号管理1.1、启用 root 2、包管理工具 apt & dpkg2.1、apt 简介 & 阿里源配置2.2、dpkg 简介2.3、apt 和 dpkg 两者之间的关系2.4、常用命令 3、启用 ssh 服务4、防火墙5、开启远程登录6、关闭交换分区7、build-essential&#xff08;编译和开发软…...

Flask多参数模版使用

需要建立目录templates&#xff1b; 把建好的html文件放到templates目录里面&#xff1b; 约定好参数名字&#xff0c;单个名字可以直接使用&#xff1b;多参数使用字典传递&#xff1b; 样例&#xff1a; from flask import render_template # 模板 (Templates) #Flask 使用…...

torcharrow gflags版本问题

问题描述 其实仍然是很简单的编译问题&#xff0c;但是又弄了一整个下午加几乎整个晚上&#xff0c;进度缓慢&#xff0c;又吸取了教训&#xff0c;因而还是来记录一下。 在试图使用torcharrow进行推荐系统模拟的时候&#xff0c;撰写的python程序报错&#xff1a;ERROR: flag…...

自然语言处理|深入解析 PEGASUS:从原理到实践

一、引言 在信息爆炸的时代&#xff0c;互联网上的文本数据以极快的速度增长。无论是新闻资讯、学术论文、社交媒体动态&#xff0c;还是各类报告文档&#xff0c;我们每天接触到的文字信息量巨大。如何快速、准确地提取关键内容成为一项重要任务。文本摘要技术通过将长篇文本…...

Spring AI Alibaba快速使用

AI 时代&#xff0c;Java 程序员也需要与时俱进&#xff0c;这两个框架必须掌握。 一个是 Spring AI一个是 Spring Alibaba AI。 Spring AI 是一个AI工程领域的应用程序框架&#xff0c;它的目标是将 Spring生态系统的设计原则应用于人工智能领域。 但是&#xff0c; Spring…...

socks 协议介绍

SOCKS协议详解 一、基本定义与核心功能 SOCKS&#xff08;Socket Secure&#xff09;是一种网络传输协议&#xff0c;主要用于通过代理服务器转发客户端与目标服务器之间的通信请求。其核心功能包括隐藏用户真实IP地址、穿透防火墙限制以及支持多种网络协议&#xff08;如TCP…...

Linux --centos安装显卡驱动

显卡下载页面 https://www.nvidia.com/en-us/drivers/unix/ 随便下载一个即可 安装过程 查看当前设备的显卡信息 lspci | grep -i vga安装gcc相关依赖 yum update -y yum update gcc yum install build-essential yum install gcc-multilibdkms yum groupinstall "Dev…...

【软件工程】简答题

真题 2024-10 26.需求验证应验证需求规格说明书中每一单一需求是否满足5个性质,这5个性质是什么? 27.简述RUP和UML的关系。 28.简述五种常见的模块间耦合类型。 29.螺旋模型在笛卡尔坐标的4个象限上,分别表达了哪4个方面的活动? 30.为了表达概念模型和软件模型,UML提供了13…...

统信UOS中使用Vscode编程

写在前面&#xff1a;统信UOS其实就是套壳的Linux系统&#xff0c;所以有问题如果搜不到解决方法&#xff0c;可以参考Linux下的解决方法。 1.环境配置 Vscode : 1.85.0 Vscode就直接下载安装就行&#xff0c;然后安装插件&#xff1a;Volar、中文汉化包 node&#xff1a;18…...

K8s认证(CKA/CKAD/CKS)哪家强?主流证书对比

2024年Kubernetes认证全解析&#xff1a;选对证书&#xff0c;薪资翻倍&#xff01; &#xff08;附CKA/CKAD/CKS最新考试攻略&#xff09; 一、K8s认证哪家强&#xff1f;主流证书对比 认证名称颁发机构考试特点适合人群考试费用CKA&#xff08;认证K8s管理员&#xff09;CN…...

HTTP1.0、HTTP1.1、HTTP2.0对比

HTTP 1.0、HTTP 1.1 和 HTTP 2.0 是 HTTP 协议演进中的三个重要版本&#xff0c;每个版本都针对前一代的不足进行了优化和改进。以下是它们的核心区别和关键特性对比&#xff1a; 1. HTTP 1.0&#xff08;1996年&#xff09; 非持久连接 每个请求/响应对都需要单独建立和关闭 T…...

docker安装向量数据库Milvus及可视化工具 Attu

前置条件 1.安装了docker 2.服务器网络正常&#xff0c;可以连接到容器下载地址 3.服务器磁盘空间正常&#xff0c;docker磁盘占用过大&#xff0c;请参考docker容量占用过大解决办法 一、下载yml文件 可在文章资源下载或者自行下载&#xff1a;下载yml 下载这个单机版本的…...

A l密码学(Deepseek)

我&#xff1a;qwertyuiopasdfghjklzxcvbnm deepseek:深度思考中&#xff0e; Okay, lets see. The user input is "qwertyuiopasdfghjklzxcvbnm". At first glance, it looks like a jumbled sequence of letters with some spaces or maybe other characters in …...

DeepSeek + Kimi 自动生成 PPT

可以先用deepseek生成ppt大纲&#xff0c;再把这个大纲复制到Kimi的ppt助手里&#xff1a; https://kimi.moonshot.cn/kimiplus/conpg18t7lagbbsfqksg 选择ppt模板&#xff1a; 点击生成ppt就制作好了。...

Apache Paimon 在抖音集团多场景中的优化实践

资料来源&#xff1a;火山引擎-开发者社区 本文将基于抖音集团内部两大业务的典型实时数仓场景&#xff0c;介绍Paimon在抖音集团内部的生产实践。 作者&#xff1a;李明、苏兴、文杰 抖音集团大数据工程师 目前抖音集团内部主要使用 Lambda 架构进行实时数仓建设&#xff0c;其…...

Uni-App 双栏联动滚动组件开发详解 (电梯导航)

本文基于提供的代码实现一个左右联动的滚动组件&#xff0c;以下是详细的代码解析与实现原理说明&#xff1a; <!--双栏联动滚动组件 - 技术解析功能特性&#xff1a;1. 左侧导航栏与右侧内容区双向联动2. 自适应容器高度3. 平滑滚动定位4. 动态内容位置计算 --> <te…...

当下主流 AI 模型对比:ChatGPT、DeepSeek、Grok 及其他前沿技术

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 1. 引言 人工智能&#xff08;AI&#xff09;领域近年来取得了巨大的突破&#xff0c;特别是在大语言模型&#xff08;LLM&#…...

【自用】NLP算法面经(5)

一、L1、L2正则化 正则化是机器学习中用于防止过拟合并提高模型泛化能力的技术。当模型过拟合时&#xff0c;它已经很好地学习了训练数据&#xff0c;甚至是训练数据中的噪声&#xff0c;所以可能无法在新的、未见过的数据上表现良好。 比如&#xff1a; 其中&#xff0c;x1和…...

体育直播视频源格式解析:M3U8 vs FLV

在体育直播领域&#xff0c;视频源的格式选择直接影响着直播的流畅度、画质以及兼容性。目前&#xff0c;M3U8 和 FLV 是两种最为常见的视频流格式&#xff0c;它们各有优劣&#xff0c;适用于不同的场景。本文将从技术原理、优缺点以及应用场景等方面对 M3U8 和 FLV 进行详细解…...

Ubuntu20.04安装并配置Pycharm2020.2.5

一. 下载pycharm 社区版 1. 下载地址&#xff1a; PyCharm: the Python IDE for data science and web developmentThe Python IDE for data science and web development with intelligent code completion, on-the-fly error checking, quick-fixes, and much more.https:/…...

Filter Solutions学习-02 【高级设计】界面介绍

这是高级界面的各种控件的功能。 其中说一下filter type。这不是根据自己想当然决定的&#xff0c;而是根据实际的需要&#xff0c;比如带外衰减的程度&#xff0c;带内波动&#xff08;平坦&#xff09;如何&#xff0c;还有群时延等等决定的。比如不要求矩形系数选什么。。 …...

用Python实现交互式数据可视化:从基础图表到动态仪表板

用Python实现交互式数据可视化&#xff1a;从基础图表到动态仪表板 一、项目背景 本文将通过一个完整的Python项目&#xff0c;展示如何使用Plotly和ipywidgets构建从基础统计到动态交互的全栈数据可视化方案。 二、核心功能模块 1. 数据生成与预处理 np.random.seed(100)…...

Java面试黄金宝典5

1. ConcurrentHashMap 和 HashTable 有哪些区别 原理 HashTable&#xff1a;它继承自 Dictionary 类&#xff0c;是 Java 早期提供的线程安全哈希表。其线程安全的实现方式是对每个方法都使用 synchronized 关键字进行同步。例如&#xff0c;在调用 put、get 等方法时&#xff…...