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

视频主持网站建设怎么做记步数的程序到网站

视频主持网站建设,怎么做记步数的程序到网站,移动应用开发难学吗,设计网站公司linux kernel 引入 dts 的背景 http://www.wowotech.net/linux_kenrel/why-dt.html 什么是 device tree ​ device tree 是一种描述硬件资源的数据结构。device tree 可以描述的信息包括 cpu 的数量和类别、内存基地址和大小、clock 控制器和 clock 使用情况、外设基地址以及…

linux kernel 引入 dts 的背景

http://www.wowotech.net/linux_kenrel/why-dt.html

什么是 device tree

​ device tree 是一种描述硬件资源的数据结构。device tree 可以描述的信息包括 cpu 的数量和类别、内存基地址和大小、clock 控制器和 clock 使用情况、外设基地址以及配置信息、中断控制器和中断使用情况。

设备树解决了什么问题

​ 本质上,device tree 改变了原来用 hardcode 方式将 HW 配置信息嵌入到内核代码(驱动程序)的方法,改用 bootloader 传递一个 DB 的形式。对于基于 ARM CPU 的嵌入式系统,我们习惯于针对每一个 platform 进行内核的编译,但是随着 ARM 在消费电子上的广泛应用,我们期望 ARM 能够像 x86 那样用一个 kernel image 来支持多个 platform。

​ 其实,就是将驱动程序中硬编码的定义改为由设备树来描述,优化了驱动程序,同时,让 kernel image 相对独立,同一份 image 可在不同的 soc 上运行。

​ 总之,设备树是为 kernel 服务的,让内核与设备尽可能的保持独立。

Linux 与 Zephyr 的 dts

linux

以下是 at5050_codec.c

// 通过 platform 驱动框架,将驱动注册到系统中去.
// 驱动程序解析 dts, 避免硬编码到该文件中
static struct platform_driver at5k_codec_driver = {.driver = {.name = "at5050-codec",.owner = THIS_MODULE,.of_match_table = of_match_ptr(of_at5k_codec_match),},.probe = at5k_codec_probe,.remove = at5k_codec_remove,
};module_platform_driver(at5k_codec_driver);

linux 中的驱动程序会通过 一套设备树接口获取设备树节点,通过这些节点的描述实现驱动程序,注意,这里驱动程序是强依赖设备树的,驱动程序不可能做到通用(不同的 soc 之间,寄存器操作存在差异),通用的是驱动框架,如上述 platform 框架,或者字符设备、块设备、mtd 设备框架等等。

驱动程序需要有一套 设备树解析接口 。注册到系统中之后,应用程序就能够使用设备了。

zephyr

以下是 gpio_stm32.c :

// 操作 pin 设备的虚函数表,注册到系统中去(这里是真正意义上的驱动代码,通常是直接操作寄存器或者调用 hal 层提供的接口)
static const struct gpio_driver_api gpio_stm32_driver = {.pin_configure = gpio_stm32_config,.port_get_raw = gpio_stm32_port_get_raw,.port_set_masked_raw = gpio_stm32_port_set_masked_raw,.port_set_bits_raw = gpio_stm32_port_set_bits_raw,.port_clear_bits_raw = gpio_stm32_port_clear_bits_raw,.port_toggle_bits = gpio_stm32_port_toggle_bits,.pin_interrupt_configure = gpio_stm32_pin_interrupt_configure,.manage_callback = gpio_stm32_manage_callback,
};// 注册 pin 设备,系统初始化期间会处理好
DEVICE_DT_DEFINE(__node,					       \gpio_stm32_init,				       \PM_DEVICE_DT_GET(__node),			       \&gpio_stm32_data_## __suffix,		       \&gpio_stm32_cfg_## __suffix,		       \PRE_KERNEL_1,				       \CONFIG_GPIO_INIT_PRIORITY,			       \&gpio_stm32_driver)#define GPIO_DEVICE_INIT_STM32(__suffix, __SUFFIX)			\GPIO_DEVICE_INIT(DT_NODELABEL(gpio##__suffix),	\__suffix,					\DT_REG_ADDR(DT_NODELABEL(gpio##__suffix)),	\STM32_PORT##__SUFFIX,				\DT_CLOCKS_CELL(DT_NODELABEL(gpio##__suffix), bits),\DT_CLOCKS_CELL(DT_NODELABEL(gpio##__suffix), bus))// 根据 dts 文件中对于 gpio 的描述,注册该 pin 设备到系统中
#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpioa), okay)
GPIO_DEVICE_INIT_STM32(a, A);
#endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpioa), okay) */

以下是应用代码 main.c:

// led0 这个名字在设备树文件中定义
#define LED_BLUE DT_ALIAS(led0)
#define LED_RED DT_ALIAS(led1)// 根据设备树中的描述,得到操作该 pin 设备的句柄
static const struct gpio_dt_spec led_blue = GPIO_DT_SPEC_GET(LED_BLUE, gpios);
static const struct gpio_dt_spec led_red = GPIO_DT_SPEC_GET(LED_RED, gpios);int main(void)
{printk("hello zephyr.\n");// 通过统一设备树接口,操作 pin 设备,而不是直接操作 hal 层方法if (!gpio_is_ready_dt(&led_blue) && !gpio_is_ready_dt(&led_red)) {return 0;}if (gpio_pin_configure_dt(&led_blue, GPIO_OUTPUT_ACTIVE) < 0 || gpio_pin_configure_dt(&led_red, GPIO_OUTPUT_ACTIVE) < 0) {return 0;}sdram_test();while (1) {if (gpio_pin_toggle_dt(&led_blue) < 0 || gpio_pin_toggle_dt(&led_red)) {return 0;}k_msleep(SLEEP_TIME_MS);}return 0;
}
// 可以看出,应用程序在使用 pin 设备时,使用的是一套带有 dt 字符的抽象接口,这里让应用程序感受到了设备树的存在
  • zephyr 支持两种设备驱动的注册,一种是使用设备树相关宏 DEVICE_DT_DEFINE,另外一种是不使用设备树相关宏 DEVICE_DEFINE
  • 如果使用设备树,应用程序中操作设备时,需要 依赖设备树,具体操作如下:
    • ADC_DT_SPEC_GET 使用该宏,获取 adc 设备,需要知道该设备在设备树中的命名
    • static inline int adc_read_dt(const struct adc_dt_spec *spec,const struct adc_sequence *sequence),读取 struct adc_dt_spec 设备
    • static inline int adc_channel_setup_dt(const struct adc_dt_spec *spec) 配置 adc 设备
    • 这里略微不合理,我们希望应用程序不要考虑那么多,不要知道设备树的存在。
  • 如果不使用设备树,而是使用 DEVICE_DEFINE 注册设备,那么应用程序对设备的操作如下
    • static inline const struct device * device_get_binding(const char * name),返回一个 device 对象,如果该设备是个 adc 设备,使用如下接口操作设备
    • static inline int adc_read(const struct device * dev, const struct adc_sequence * sequence),读取 adc 设备,会调用到驱动层实现的虚函数表
    • static inline int adc_channel_setup(const struct device * dev, const struct adc_channel_cfg * channel_cfg),配置 adc 设备
    • 这里应用程序通过 binding 接口得到了设备句柄

抛开 linux 历史原因,直接从内核源码来看,目前 dts 目前为什么是 linux 的标配?

  • linux kernel 已经依赖 dts,如 kernel 内部稳定的驱动框架(platform、spi、i2c 等等)。
  • 从驱动框架来看,dts 是必须的,从使用驱动框架的人(linux 驱动开发人员)来看,dts 也是必须的。Linux 驱动开发人员需要使用 dts 中描述的信息来写驱动。

为什么各大主流 rtos 不引入 dts ?

  • 首先 rtos 面向的是小型嵌入式设备,业务逻辑没那么复杂
  • 其次,如果引入 dts,那么 dtb 文件如何放入 mcu / mpu 里面?需要额外引入其他依赖。设备开机重启后,需要保证 dtb 文件依然存在,需要预留持久化存储空间。
  • 这可能也是 zephyr 为什么改变 dts 常规使用方法(编译 dts 成为 dtb,再使用一些工具把 dtb 放到持久化存储的地方),而是改为编译时解析,不用再考虑 dtb 文件放哪里了,系统启动流程不用那么复杂了,甚至系统都没起来(堆都没初始化)都能先初始化设备了。

综上,dts 对于 rtos 来说,意义不大,甚至会引入副作用。

dts 文件如何使用 dtc 工具编译成 dtb

先使用 c / cpp 预处理器展开头文件

cpp -nostdinc -I /home/null/zephyrproject/zephyr/dts/arm/ -I /home/null/zephyrproject/zephyr/dts/common -undef -x assembler-with-cpp  stm32h750_art_pi.dts stm32h750_art_pi.dts.preprocessed

然后使用 dtc 工具

dtc -I dts -O dtb -o example.dtb example.dts

如果 dts 文件中使用了 include 关键字,则需要通过 c/cpp 预处理器来展开头文件,dtc 工具是不负责展开头文件的,只是编译,否则会报错。

http://www.yayakq.cn/news/350621/

相关文章:

  • 陕西建工第五建设集团有限公司官方网站安徽省建设信息管理平台
  • 做网站如何免费制作永久个人网站
  • seo网站诊断书书画网站源码
  • 影视网站建设教程呼叫中心网站建设
  • 上海哪家seo好班级优化大师的功能有哪些
  • 央企网站建设有没有可以免费制作ppt的app
  • 网站设计自已申请如何进入网站后台管理网站
  • ie打不开建设企业网站可以做游戏的网站
  • ps做网站导航条高度淘宝关键词排名查询网站
  • 官方网站哪家做的最好wordpress c
  • 有效果的网站排名泰安有限公司
  • 邯郸 网站建设wordpress图片站教程
  • 网站建设的资金风险asp做网站主要技术
  • 无锡网站制作哪家价格便宜lnmp lamp wordpress
  • 网站运营推广公司淄博专业做网站
  • 网站排名 算法网站开发应用
  • 深圳深圳龙岗网站建设公司淘宝关键词排名优化
  • 做外贸soho网站的公司吗携程旅游电子商务网站策划书
  • 企业网站php模板下载云南昆明网站建设公司
  • 昆明网站建设技术托管电子商务基础网站建设与维护单项选择题
  • asp网站的优点店铺引流推广方案
  • 成都科技网站建设咨询房地产网站模板 下载
  • 电子政务与网站建设经验代码素材网站
  • 小视频网站开发霞山网站开发公司
  • 宁波seo网站排名优化用齐博cms建网站
  • 天津市建设交易中心网站兰州网站制作设计
  • 河北汉佳 做网站的公司品牌战略咨询公司排名
  • 大鹏新区住房和建设局网站wordpress主题 wdone
  • 移动端网站开发流程图设计网页通常用什么语言
  • 网站用模板为什么不利于seo推广网页设计及网站建设的相关概念