第 2 课 - 输入(按键)控制输出(LED)-驱动模型和GPIO通用API

Zephyr 设备模型

从这张图可以看到Zephyr 设备驱动模型可以分为4层:

  • APP应用
  • API接口
  • 设备驱动实例
  • 设备驱动实现

可以看出,在 nRF Connect SDK 中,驱动程序与 API 是高度解耦的。这基本上意味着我们能够在不修改应用程序的情况下切换出低级驱动程序实现,因为使用的是相同的通用 API。

这种解耦有很多好处,包括高可移植性,因为它可以在不同的板上使用相同的代码,而无需手动修改底层驱动。
对于开发者来说,大部分时候只需要关注API就可以了。

驱动程序通过使用宏DEVICE_DT_GET()或相关宏获取相关硬件的设备指针。

应用程序通过使用通用 API 与硬件进行交互。Zephyr 中的一些通用 API 具有特定于 API 的结构,其中包含前面提到的设备指针,以及有关设备的一些其他信息。在 GPIO API 中,gpio_dt_spec结构包括设备指针、设备上的引脚号和设备的配置标志.

/**
 * @brief Container for GPIO pin information specified in devicetree
 *
 * This type contains a pointer to a GPIO device, pin number for a pin
 * controlled by that device, and the subset of pin configuration
 * flags which may be given in devicetree.
 *
 * @see GPIO_DT_SPEC_GET_BY_IDX
 * @see GPIO_DT_SPEC_GET_BY_IDX_OR
 * @see GPIO_DT_SPEC_GET
 * @see GPIO_DT_SPEC_GET_OR
 */
struct gpio_dt_spec {
	/** GPIO device controlling the pin */
	const struct device *port;
	/** The pin's number on the device */
	gpio_pin_t pin;
	/** The pin's configuration flags as specified in devicetree */
	gpio_dt_flags_t dt_flags;
};

看一下第一课LED闪灯例程中是如何通过GPIO的API来控制输出的:

/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE DT_ALIAS(led0) //通过别名获取设备树的 led0 节点

/*
 * A build error on this line means your board is unsupported.
 * See the sample documentation for information on how to fix this.
 */
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios); //通过节点获取一个 gpio 的实例
.
.
.
//在使用gpio外设之前判断是否可用
if (!gpio_is_ready_dt(&led))
{
	return 0;
}
//配置为输出模式
ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
if (ret < 0)
{
	return 0;
}
while (1)
{
	ret = gpio_pin_toggle_dt(&led);
	if (ret < 0)
	{
		return 0;
	}

	led_state = !led_state;
	printf("LED state: %s\n", led_state ? "ON" : "OFF");
	k_msleep(SLEEP_TIME_MS);
}
posted @ 2025-03-04 14:29  NEIKOO  阅读(168)  评论(0)    收藏  举报