前言
- 继上篇Zephyr开发环境搭建记录(Clion)的基础上去学习驱动外设。
- 从点亮LED开始,熟悉Zephyr的设备树文件的编写。
- 通过示例程序作为参考+通义AI(不懂就问) 的方式进行学习。
- 开发环境使用的是Clion。
- 使用到的外设:串口1和LED
- 示例项目:blinky
- 环境搭建在本文中不在重述,注重实际操作。
项目复制

打开项目(使用Clion)
选择指定的开发板(第一打开时必选或更换开发板)

创建设备树覆盖文件(用于覆盖原有的配置或增加新配置)

关于这个文件命名的确定
- 参考build生成目录下


编写对应的设备驱动配置信息(一般都有可以参考的文件)
1、这里我参考的文件就是stm32f4_disco.dts
json
/*
探索者开发板LED灯驱动
LED0 PF9
LED1 PF10
*/
// 定义根节点,包含整个设备树的主要配置
/ {
// 配置系统选择项,指定控制台和shell使用的UART接口
chosen {
// 指定系统控制台使用USART1
zephyr,console = &usart1;
// 指定shell命令行使用USART1
zephyr,shell-uart = &usart1;
};
// 定义LED设备节点,配置GPIO控制的LED
leds {
// 设置兼容性字符串,表示使用GPIO LED驱动
compatible = "gpio-leds";
// 定义第一个LED设备,别名为led_0
led_0: led_0 {
// 配置GPIO引脚为PF9(GPIOF端口第9号引脚),高电平有效
gpios = <&gpiof 9 GPIO_ACTIVE_HIGH>; // PF9
// 设置LED的标签名称
label = "User LED0";
};
// 定义第二个LED设备,别名为led_1
led_1: led_1 {
// 配置GPIO引脚为PF10(GPIOF端口第10号引脚),高电平有效
gpios = <&gpiof 10 GPIO_ACTIVE_HIGH>; // PF10
// 设置LED的标签名称
label = "User LED1";
};
};
// 定义别名节点,为设备树中的节点提供简短的别名引用
aliases {
// 将"led0"别名指向led_0节点
led0 = &led_0;
// 将"led1"别名指向led_1节点
led1 = &led_1;
};
};
// 引用并修改预定义的usart1节点
&usart1 {
// 配置USART1的引脚控制,TX连接到PA9,RX连接到PA10
pinctrl-0 = <&usart1_tx_pa9>, <&usart1_rx_pa10>;
// 定义引脚控制配置的名称
pinctrl-names = "default";
// 设置串口通信波特率为115200
current-speed = <115200>;
// 启用此UART外设
status = "okay";
};
编写main函数
c
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
// 包含标准输入输出库
#include <stdio.h>
// 包含Zephyr内核API
#include <zephyr/kernel.h>
// 包含GPIO驱动API
#include <zephyr/drivers/gpio.h>
/* 1000毫秒 = 1秒 */
#define SLEEP_TIME_MS 1000
/* 获取设备树中"led0"别名的节点标识符 */
#define LED0_NODE DT_ALIAS(led0)
#define LED1_NODE DT_ALIAS(led1)
/*
* 如果在此行出现构建错误,说明您的开发板不受支持。
* 请参阅示例文档以了解如何修复此问题。
*/
static const struct gpio_dt_spec led0 = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
static const struct gpio_dt_spec led1 = GPIO_DT_SPEC_GET(LED1_NODE, gpios);
int main(void)
{
int ret; // 返回值变量
bool led_state = true; // LED状态标志,true为开启,false为关闭
// 检查GPIO设备是否准备就绪
if (!gpio_is_ready_dt(&led0) || !gpio_is_ready_dt(&led1))
{
return 0; // 如果GPIO未就绪,则退出程序
}
// 配置GPIO引脚为输出模式,活动状态
ret = gpio_pin_configure_dt(&led0, GPIO_OUTPUT_ACTIVE);
ret |= gpio_pin_configure_dt(&led1, GPIO_OUTPUT_ACTIVE);
if (ret < 0)
{
return 0; // 如果配置失败,则退出程序
}
// 设置GPIO默认值
gpio_pin_set_dt(&led0, GPIO_ACTIVE_LOW);
gpio_pin_set_dt(&led1, GPIO_ACTIVE_HIGH);
// 主循环:无限循环以持续闪烁LED
while (1)
{
// 切换LED引脚状态(开/关)
ret = gpio_pin_toggle_dt(&led0);
ret |= gpio_pin_toggle_dt(&led1);
if (ret < 0)
{
return 0; // 如果切换失败,则退出程序
}
// 更新LED状态标志(真变假,假变真)
led_state = !led_state;
// 在控制台打印LED当前状态
printf("LED state: %s\n", led_state ? "ON" : "OFF");
// 延迟指定毫秒数(这里是1秒)
k_msleep(SLEEP_TIME_MS);
}
return 0; // 程序正常退出(实际上不会到达这里,因为是无限循环)
}
下载程序
- 注意如果使用jlink的话需要如下配置


结果测试

总结
- 记录Zephyr的学习过程。