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

建设企业网站的/seo推广编辑

建设企业网站的,seo推广编辑,合肥设计工作室,现在新手做电商能做好吗一、RTC 概述 RTC(real-time clock) 为操作系统中的实时时钟设备,为操作系统提供精准的实时时间和定时报警功能。当设备下电后,通过外置电池供电,RTC 继续记录操作系统时间;设备上电后,RTC 提供实时时钟给操作系统&am…

一、RTC 概述

RTC(real-time clock) 为操作系统中的实时时钟设备,为操作系统提供精准实时时间定时报警功能。当设备下电后,通过外置电池供电,RTC 继续记录操作系统时间;设备上电后,RTC 提供实时时钟给操作系统,确保断电后系统时间的连续性。

二、iMX6ULL 的 RTC 原理

三、Linux 内核中 RTC 驱动原理

参考:内核驱动 (三)Linux系统时钟RTC_LouisGou的博客-CSDN博客_linux rtc。

RTC 设备驱动是一个标准的字符设备驱动,应用程序通过 openreleasereadwriteioctl 等函数完成对 RTC 设备的操作。

Linux 内核使用 rtc_device 结构体描述 RTC 设备,因此 RTC 设备驱动就是申请并初始化 rtc_device,最后将 rtc_device 注册到 Linux 内核里面。rtc_device 结构体中 rtc_class_ops 结构体描述 RTC 设备底层操作函数。 rtc_class_ops 结构体函数集包括从 RTC 设备中读取时间、向 RTC 设备写入新的时间等。
值等。

struct rtc_device 结构体定义如下:

struct rtc_device
{struct device dev;struct module *owner;int id;char name[RTC_DEVICE_NAME_SIZE];const struct rtc_class_ops *ops;struct mutex ops_lock;struct cdev char_dev;unsigned long flags;unsigned long irq_data;spinlock_t irq_lock;wait_queue_head_t irq_queue;struct fasync_struct *async_queue;struct rtc_task *irq_task;spinlock_t irq_task_lock;int irq_freq;int max_user_freq;struct timerqueue_head timerqueue;struct rtc_timer aie_timer;struct rtc_timer uie_rtctimer;struct hrtimer pie_timer; /* sub second exp, so needs hrtimer */int pie_enabled;struct work_struct irqwork;/* Some hardware can't support UIE mode */int uie_unsupported;#ifdef CONFIG_RTC_INTF_DEV_UIE_EMULstruct work_struct uie_task;struct timer_list uie_timer;/* Those fields are protected by rtc->irq_lock */unsigned int oldsecs;unsigned int uie_irq_active:1;unsigned int stop_uie_polling:1;unsigned int uie_task_active:1;unsigned int uie_timer_active:1;
#endif
};
  • dev:设备;
  • idID
  • name:名字;
  • opsRTC 设备底层操作函数;
  • char_dev:字符设备;

struct rtc_class_ops 结构体定义如下:

/** For these RTC methods the device parameter is the physical device* on whatever bus holds the hardware (I2C, Platform, SPI, etc), which* was passed to rtc_device_register().  Its driver_data normally holds* device state, including the rtc_device pointer for the RTC.** Most of these methods are called with rtc_device.ops_lock held,* through the rtc_*(struct rtc_device *, ...) calls.** The (current) exceptions are mostly filesystem hooks:*   - the proc() hook for procfs*   - non-ioctl() chardev hooks:  open(), release(), read_callback()** REVISIT those periodic irq calls *do* have ops_lock when they're* issued through ioctl() ...*/
struct rtc_class_ops {int (*open)(struct device *);void (*release)(struct device *);int (*ioctl)(struct device *, unsigned int, unsigned long);int (*read_time)(struct device *, struct rtc_time *);int (*set_time)(struct device *, struct rtc_time *);int (*read_alarm)(struct device *, struct rtc_wkalrm *);int (*set_alarm)(struct device *, struct rtc_wkalrm *);int (*proc)(struct device *, struct seq_file *);int (*set_mmss64)(struct device *, time64_t secs);int (*set_mmss)(struct device *, unsigned long secs);int (*read_callback)(struct device *, int data);int (*alarm_irq_enable)(struct device *, unsigned int enabled);
};

注意:struct rtc_device 结构体和 struct rtc_class_ops 结构体定义在 include/linux/rtc.h

Linux 内核提供了一个 RTC 通用字符设备驱动文件,定义在 drivers/rtc/rtc-dev.c 文件中, rtc-dev.c 文件提供了所有 RTC 设备向应用层提供的 file_operations 函数操作集,如下所示:

static const struct file_operations rtc_dev_fops = {.owner		= THIS_MODULE,.llseek		= no_llseek,.read		= rtc_dev_read,.poll		= rtc_dev_poll,.unlocked_ioctl	= rtc_dev_ioctl,.open		= rtc_dev_open,.release	= rtc_dev_release,.fasync		= rtc_dev_fasync,
};

四、Linux 中 RTC 驱动分析

file_operationsrtc_devicertc_class_ops 结构体建立联系过程如下:

1、通过设备树确定驱动源码,设备树内容如下:

snvs_rtc: snvs-rtc-lp {compatible = "fsl,sec-v4.0-mon-rtc-lp";regmap = <&snvs>;offset = <0x34>;interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
};

通过 fsl,sec-v4.0-mon-rtc-lp 字符串确定驱动相关源码。

2、驱动源码确定

static const struct of_device_id snvs_dt_ids[] = {{ .compatible = "fsl,sec-v4.0-mon-rtc-lp", },{ /* sentinel */ }
};

驱动源码路径:linux\drivers\rtc\rtc-snvs.c

3、驱动源码分析

static struct platform_driver snvs_rtc_driver = {.driver = {.name	= "snvs_rtc",.pm	= SNVS_RTC_PM_OPS,.of_match_table = snvs_dt_ids,},.probe		= snvs_rtc_probe,
};
module_platform_driver(snvs_rtc_driver);

通过以上信息,可以确定 RTC 驱动框架为 platform,当设备和驱动匹配成功后,snvs_rtc_probe 函数执行。

4、snvs_rtc_probe 函数分析

struct snvs_rtc_data {struct rtc_device *rtc;struct regmap *regmap;int offset;int irq;struct clk *clk;
};
static int snvs_rtc_probe(struct platform_device *pdev)
{struct snvs_rtc_data *data;struct resource *res;int ret;void __iomem *mmio;data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);if (!data)return -ENOMEM;data->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "regmap");if (IS_ERR(data->regmap)) {dev_warn(&pdev->dev, "snvs rtc: you use old dts file, please update it\n");res = platform_get_resource(pdev, IORESOURCE_MEM, 0);mmio = devm_ioremap_resource(&pdev->dev, res);if (IS_ERR(mmio))return PTR_ERR(mmio);data->regmap = devm_regmap_init_mmio(&pdev->dev, mmio, &snvs_rtc_config);} else {data->offset = SNVS_LPREGISTER_OFFSET;of_property_read_u32(pdev->dev.of_node, "offset", &data->offset);}if (!data->regmap) {dev_err(&pdev->dev, "Can't find snvs syscon\n");return -ENODEV;}data->irq = platform_get_irq(pdev, 0);if (data->irq < 0)return data->irq;data->clk = devm_clk_get(&pdev->dev, "snvs-rtc");if (IS_ERR(data->clk)) {data->clk = NULL;} else {ret = clk_prepare_enable(data->clk);if (ret) {dev_err(&pdev->dev,"Could not prepare or enable the snvs clock\n");return ret;}}platform_set_drvdata(pdev, data);/* Initialize glitch detect */regmap_write(data->regmap, data->offset + SNVS_LPPGDR, SNVS_LPPGDR_INIT);/* Clear interrupt status */regmap_write(data->regmap, data->offset + SNVS_LPSR, 0xffffffff);/* Enable RTC */snvs_rtc_enable(data, true);device_init_wakeup(&pdev->dev, true);ret = devm_request_irq(&pdev->dev, data->irq, snvs_rtc_irq_handler,IRQF_SHARED, "rtc alarm", &pdev->dev);if (ret) {dev_err(&pdev->dev, "failed to request irq %d: %d\n",data->irq, ret);goto error_rtc_device_register;}data->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,&snvs_rtc_ops, THIS_MODULE);if (IS_ERR(data->rtc)) {ret = PTR_ERR(data->rtc);dev_err(&pdev->dev, "failed to register rtc: %d\n", ret);goto error_rtc_device_register;}return 0;error_rtc_device_register:if (data->clk)clk_disable_unprepare(data->clk);return ret;
}
  • 分配并初始化 rtc_device

  • 调用 devm_rtc_device_register 向内核注册 RTC 设备。

  • devm_rtc_device_register 中调用 rtc_device_register 完成 RTC 设备注册。

5、rtc_device_register

/*** rtc_device_register - register w/ RTC class* @dev: the device to register** rtc_device_unregister() must be called when the class device is no* longer needed.** Returns the pointer to the new struct class device.*/
struct rtc_device *rtc_device_register(const char *name, struct device *dev,const struct rtc_class_ops *ops,struct module *owner)
{struct rtc_device *rtc;struct rtc_wkalrm alrm;int of_id = -1, id = -1, err;if (dev->of_node)of_id = of_alias_get_id(dev->of_node, "rtc");else if (dev->parent && dev->parent->of_node)of_id = of_alias_get_id(dev->parent->of_node, "rtc");if (of_id >= 0) {id = ida_simple_get(&rtc_ida, of_id, of_id + 1,GFP_KERNEL);if (id < 0)dev_warn(dev, "/aliases ID %d not available\n",of_id);}if (id < 0) {id = ida_simple_get(&rtc_ida, 0, 0, GFP_KERNEL);if (id < 0) {err = id;goto exit;}}rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL);if (rtc == NULL) {err = -ENOMEM;goto exit_ida;}rtc->id = id;rtc->ops = ops;rtc->owner = owner;rtc->irq_freq = 1;rtc->max_user_freq = 64;rtc->dev.parent = dev;rtc->dev.class = rtc_class;rtc->dev.release = rtc_device_release;mutex_init(&rtc->ops_lock);spin_lock_init(&rtc->irq_lock);spin_lock_init(&rtc->irq_task_lock);init_waitqueue_head(&rtc->irq_queue);/* Init timerqueue */timerqueue_init_head(&rtc->timerqueue);INIT_WORK(&rtc->irqwork, rtc_timer_do_work);/* Init aie timer */rtc_timer_init(&rtc->aie_timer, rtc_aie_update_irq, (void *)rtc);/* Init uie timer */rtc_timer_init(&rtc->uie_rtctimer, rtc_uie_update_irq, (void *)rtc);/* Init pie timer */hrtimer_init(&rtc->pie_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);rtc->pie_timer.function = rtc_pie_update_irq;rtc->pie_enabled = 0;strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE);dev_set_name(&rtc->dev, "rtc%d", id);/* Check to see if there is an ALARM already set in hw */err = __rtc_read_alarm(rtc, &alrm);if (!err && !rtc_valid_tm(&alrm.time))rtc_initialize_alarm(rtc, &alrm);rtc_dev_prepare(rtc);err = device_register(&rtc->dev);if (err) {put_device(&rtc->dev);goto exit_kfree;}rtc_dev_add_device(rtc);rtc_sysfs_add_device(rtc);rtc_proc_add_device(rtc);dev_info(dev, "rtc core: registered %s as %s\n",rtc->name, dev_name(&rtc->dev));return rtc;exit_kfree:kfree(rtc);exit_ida:ida_simple_remove(&rtc_ida, id);exit:dev_err(dev, "rtc core: unable to register %s, err = %d\n",name, err);return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(rtc_device_register);
  • rtc_dev_prepare 函数中调用 cdev_init 完成 rtc_dev_fopsstruct file_operations) 操作集注册。
  • rtc_dev_add_device 函数中调用 cdev_add 完成字符设备驱动注册。

五、Linux 下 RTC 时间相关操作

1、确定 RTC 是否启动

在这里插入图片描述

2、查看 RTC 时间

Linux 内核通过 RTC 为系统提供时钟,通过 date 命令即可查看 Linux 系统时钟:

# date
Thu Jan  1 00:04:34 UTC 1970
#

3、设置 RTC 时间

# date
Thu Jan  1 00:06:53 UTC 1970
# date -s "2022-11-01 21:44:00"
Tue Nov  1 21:44:00 UTC 2022
# date
Tue Nov  1 21:44:02 UTC 2022
#

使用 “date -s” 命令仅仅是将当前系统时间设置了,此时间还没有写入到 iMX6ULL 内部 RTC 里面或其他的 RTC 芯片里面,因此系统重启以后时间又会丢失。我们需要将当前的时间写入到 RTC 里面,这里要用到 hwclock 命令,输入如下命令将系统时间写入到 RTC 里面:

hwclock -w # 将当前系统时间写入到 RTC 里面

4、date 帮助信息

# date -h
date: invalid option -- 'h'
BusyBox v1.35.0 (2022-09-25 01:42:03 PDT) multi-call binary.Usage: date [OPTIONS] [+FMT] [[-s] TIME]Display time (using +FMT), or set time-u              Work in UTC (don't convert to local time)[-s] TIME       Set time to TIME-d TIME         Display TIME, not 'now'-D FMT          FMT (strptime format) for -s/-d TIME conversion-r FILE         Display last modification time of FILE-R              Output RFC-2822 date-I[SPEC]        Output ISO-8601 dateSPEC=date (default), hours, minutes, seconds or nsRecognized TIME formats:@seconds_since_1970hh:mm[:ss][YYYY.]MM.DD-hh:mm[:ss]YYYY-MM-DD hh:mm[:ss][[[[[YY]YY]MM]DD]hh]mm[.ss]'date TIME' form accepts MMDDhhmm[[YY]YY][.ss] instead
#

5、hwclock 帮助信息

# hwclock -h
hwclock: invalid option -- 'h'
BusyBox v1.35.0 (2022-09-25 01:42:03 PDT) multi-call binary.Usage: hwclock [-swul] [--systz] [-f DEV]Show or set hardware clock (RTC)-s      Set system time from RTC-w      Set RTC from system time--systz Set in-kernel timezone, correct system timeif RTC is kept in local time-f DEV  Use specified device (e.g. /dev/rtc2)-u      Assume RTC is kept in UTC-l      Assume RTC is kept in local time(if neither is given, read from /var/lib/hwclock/adjtime)
#
http://www.jmfq.cn/news/5026951.html

相关文章:

  • 用树莓派做网站/个人网站网页首页
  • 路由器通过域名解析做网站/站长统计官方网站
  • 修改wordpress注册邮件/谷歌seo和百度seo区别
  • 简述如何让网站排名快速提升/网络推广方案的基本思路
  • 深圳网站建设 罗湖/中国百强县市榜单
  • 网站怎么做浏览量才会多/服务器
  • 网站推广链接怎么做/爱站网长尾关键词挖掘工具下载
  • 做网站先用dw还是asp/上海最近3天疫情情况
  • 建建建设网站/友妙招链接怎么弄
  • 怎么做代刷网站教程/域名查询注册商
  • 网站域名解绑/口碑营销案例有哪些
  • gateface能用来做网站吗/网站优化关键词公司
  • 北京学设计去哪个网站/网页搜索关键字
  • asp.net web网站开发/seo运营做什么
  • 做网站 需要买云服务器吗/培训学校资质办理条件
  • 北京网站怎么优化/杭州网站提升排名
  • 商标 做网站 是几类/百度首页的ip地址
  • 大连项目备案网站/搜狗优化排名
  • 企业官网建站系统/最新中高风险地区名单
  • 仙桃做网站的公司有哪些/网站制作公司
  • 济南网站建设(力选聚搜网络)/关键词自动生成器
  • 专门做dnf补丁的网站/竞价托管推广哪家好
  • 文山网站建设哪家好/成都全网推广哪家专业
  • ftp建网站/徐州网络推广服务
  • java做网站代码/怎么做推广赚钱
  • 青岛外贸网站推广/北京网站推广营销服务电话
  • 网站建设要多少费用/公司网站优化
  • 怎么看公司网站建设的时间/百度提交网站
  • 网站制作模板程序/在线推广企业网站的方法有哪些
  • 网站建设产品展示/百度搜索引擎营销如何实现