解决RTC内核驱动的问题bm8563

ops/2024/9/19 18:51:35/ 标签: RTC, 实时时钟, linux驱动, 软件开发, c语言

常用pcf-8563 , 国产平替BM8563(驱动管脚一致);

        实时时钟是很常用的一个外设,通过实时时钟我们就可以知道年、月、日和时间等信息。
因此在需要记录时间的场合就需要实时时钟,可以使用专用的实时时钟芯片来完成此功能
        
        RTC 设备驱动是一个标准的字符设备驱动,应用程序通过 open release read write ioctl 等函数完成对 RTC 设备的操作

测试平台:君正x2600;

makefile文件:

# 开发板Linux内核的实际路径 
# KDIR变量
KDIR:=/mnt/new_disk/x2600_linux/src/kernel/kernel/#  获取当前目录
PWD:=$(shell pwd)# obj-m表示将 chrdevbase.c这个文件 编译为 chrdevbase.ko模块。
obj-m += rtc-bm8563.o# 编译成模块
all:make -C $(KDIR) M=$(PWD) modulesclean:make -C $(KDIR) M=$(PWD) clean

驱动编译代码:

// SPDX-License-Identifier: GPL-2.0-only
/** An I2C driver for the Philips BM8563 RTC* Copyright 2005-06 Tower Technologies** Author: Alessandro Zummo <a.zummo@towertech.it>* Maintainers: http://www.nslu2-linux.org/** based on the other drivers in this same directory.** http://www.semiconductors.philips.com/acrobat/datasheets/BM8563-04.pdf*/#include <linux/clk-provider.h>
#include <linux/i2c.h>
#include <linux/bcd.h>
#include <linux/rtc.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/err.h>
#include <linux/of_gpio.h>#define BM8563_REG_ST1		0x00 /* status */
#define BM8563_REG_ST2		0x01
#define BM8563_BIT_AIE		BIT(1)
#define BM8563_BIT_AF		BIT(3)
#define BM8563_BITS_ST2_N	(7 << 5)#define BM8563_REG_SC		0x02 /* datetime */
#define BM8563_REG_MN		0x03
#define BM8563_REG_HR		0x04
#define BM8563_REG_DM		0x05
#define BM8563_REG_DW		0x06
#define BM8563_REG_MO		0x07
#define BM8563_REG_YR		0x08#define BM8563_REG_AMN		0x09 /* alarm */#define BM8563_REG_CLKO		0x0D /* clock out */
#define BM8563_REG_CLKO_FE		0x80 /* clock out enabled */
#define BM8563_REG_CLKO_F_MASK		0x03 /* frequenc mask */
#define BM8563_REG_CLKO_F_32768HZ	0x00
#define BM8563_REG_CLKO_F_1024HZ	0x01
#define BM8563_REG_CLKO_F_32HZ		0x02
#define BM8563_REG_CLKO_F_1HZ		0x03#define BM8563_REG_TMRC	0x0E /* timer control */
#define BM8563_TMRC_ENABLE	BIT(7)
#define BM8563_TMRC_4096	0
#define BM8563_TMRC_64		1
#define BM8563_TMRC_1		2
#define BM8563_TMRC_1_60	3
#define BM8563_TMRC_MASK	3#define BM8563_REG_TMR		0x0F /* timer */#define BM8563_SC_LV		0x80 /* low voltage */
#define BM8563_MO_C			0x80 /* century */static struct i2c_driver bm8563_driver;struct bm8563 {struct rtc_device *rtc;/** The meaning of MO_C bit varies by the chip type.* From BM8563 datasheet: this bit is toggled when the years* register overflows from 99 to 00*   0 indicates the century is 20xx*   1 indicates the century is 19xx* From RTC8564 datasheet: this bit indicates change of* century. When the year digit data overflows from 99 to 00,* this bit is set. By presetting it to 0 while still in the* 20th century, it will be set in year 2000, ...* There seems no reliable way to know how the system use this* bit.  So let's do it heuristically, assuming we are live in* 1970...2069.*/int c_polarity;	/* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */struct i2c_client *client;
#ifdef CONFIG_COMMON_CLKstruct clk_hw		clkout_hw;
#endif
};static int bm8563_read_block_data(struct i2c_client *client, unsigned char reg,unsigned char length, unsigned char *buf)
{struct i2c_msg msgs[] = {{/* setup read ptr */.addr = client->addr,.len = 1,.buf = &reg,},{.addr = client->addr,.flags = I2C_M_RD,.len = length,.buf = buf},};if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {dev_err(&client->dev, "%s: read error\n", __func__);return -EIO;}return 0;
}static int bm8563_write_block_data(struct i2c_client *client,unsigned char reg, unsigned char length,unsigned char *buf)
{int i, err;for (i = 0; i < length; i++) {unsigned char data[2] = { reg + i, buf[i] };err = i2c_master_send(client, data, sizeof(data));if (err != sizeof(data)) {dev_err(&client->dev,"%s: err=%d addr=%02x, data=%02x\n",__func__, err, data[0], data[1]);return -EIO;}}return 0;
}static int bm8563_set_alarm_mode(struct i2c_client *client, bool on)
{unsigned char buf;int err;err = bm8563_read_block_data(client, BM8563_REG_ST2, 1, &buf);if (err < 0)return err;if (on)buf |= BM8563_BIT_AIE;elsebuf &= ~BM8563_BIT_AIE;buf &= ~(BM8563_BIT_AF | BM8563_BITS_ST2_N);err = bm8563_write_block_data(client, BM8563_REG_ST2, 1, &buf);if (err < 0) {dev_err(&client->dev, "%s: write error\n", __func__);return -EIO;}return 0;
}static int bm8563_get_alarm_mode(struct i2c_client *client, unsigned char *en,unsigned char *pen)
{unsigned char buf;int err;err = bm8563_read_block_data(client, BM8563_REG_ST2, 1, &buf);if (err)return err;if (en)*en = !!(buf & BM8563_BIT_AIE);if (pen)*pen = !!(buf & BM8563_BIT_AF);return 0;
}static irqreturn_t bm8563_irq(int irq, void *dev_id)
{struct bm8563 *bm8563 = i2c_get_clientdata(dev_id);int err;char pending;err = bm8563_get_alarm_mode(bm8563->client, NULL, &pending);if (err)return IRQ_NONE;if (pending) {rtc_update_irq(bm8563->rtc, 1, RTC_IRQF | RTC_AF);bm8563_set_alarm_mode(bm8563->client, 1);return IRQ_HANDLED;}return IRQ_NONE;
}/** In the routines that deal directly with the bm8563 hardware, we use* rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.*/
static int bm8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
{struct i2c_client *client = to_i2c_client(dev);struct bm8563 *bm8563 = i2c_get_clientdata(client);unsigned char buf[9];int err;err = bm8563_read_block_data(client, BM8563_REG_ST1, 9, buf);if (err)return err;if (buf[BM8563_REG_SC] & BM8563_SC_LV) {dev_err(&client->dev,"low voltage detected, date/time is not reliable.\n");return -EINVAL;}dev_dbg(&client->dev,"%s: raw data is st1=%02x, st2=%02x, sec=%02x, min=%02x, hr=%02x, ""mday=%02x, wday=%02x, mon=%02x, year=%02x\n",__func__,buf[0], buf[1], buf[2], buf[3],buf[4], buf[5], buf[6], buf[7],buf[8]);tm->tm_sec = bcd2bin(buf[BM8563_REG_SC] & 0x7F);tm->tm_min = bcd2bin(buf[BM8563_REG_MN] & 0x7F);tm->tm_hour = bcd2bin(buf[BM8563_REG_HR] & 0x3F); /* rtc hr 0-23 */tm->tm_mday = bcd2bin(buf[BM8563_REG_DM] & 0x3F);tm->tm_wday = buf[BM8563_REG_DW] & 0x07;tm->tm_mon = bcd2bin(buf[BM8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */tm->tm_year = bcd2bin(buf[BM8563_REG_YR]) + 100;/* detect the polarity heuristically. see note above. */bm8563->c_polarity = (buf[BM8563_REG_MO] & BM8563_MO_C) ?(tm->tm_year >= 100) : (tm->tm_year < 100);dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, ""mday=%d, mon=%d, year=%d, wday=%d\n",__func__,tm->tm_sec, tm->tm_min, tm->tm_hour,tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);return 0;
}static int bm8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
{struct i2c_client *client = to_i2c_client(dev);struct bm8563 *bm8563 = i2c_get_clientdata(client);unsigned char buf[9];dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, ""mday=%d, mon=%d, year=%d, wday=%d\n",__func__,tm->tm_sec, tm->tm_min, tm->tm_hour,tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);/* hours, minutes and seconds */buf[BM8563_REG_SC] = bin2bcd(tm->tm_sec);buf[BM8563_REG_MN] = bin2bcd(tm->tm_min);buf[BM8563_REG_HR] = bin2bcd(tm->tm_hour);buf[BM8563_REG_DM] = bin2bcd(tm->tm_mday);/* month, 1 - 12 */buf[BM8563_REG_MO] = bin2bcd(tm->tm_mon + 1);/* year and century */buf[BM8563_REG_YR] = bin2bcd(tm->tm_year - 100);if (bm8563->c_polarity ? (tm->tm_year >= 100) : (tm->tm_year < 100))buf[BM8563_REG_MO] |= BM8563_MO_C;buf[BM8563_REG_DW] = tm->tm_wday & 0x07;return bm8563_write_block_data(client, BM8563_REG_SC,9 - BM8563_REG_SC, buf + BM8563_REG_SC);
}static int bm8563_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{struct i2c_client *client = to_i2c_client(dev);int ret;switch (cmd) {case RTC_VL_READ:ret = i2c_smbus_read_byte_data(client, BM8563_REG_SC);if (ret < 0)return ret;return put_user(ret & BM8563_SC_LV ? RTC_VL_DATA_INVALID : 0,(unsigned int __user *)arg);default:return -ENOIOCTLCMD;}
}static int bm8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm)
{struct i2c_client *client = to_i2c_client(dev);unsigned char buf[4];int err;err = bm8563_read_block_data(client, BM8563_REG_AMN, 4, buf);if (err)return err;dev_dbg(&client->dev,"%s: raw data is min=%02x, hr=%02x, mday=%02x, wday=%02x\n",__func__, buf[0], buf[1], buf[2], buf[3]);tm->time.tm_sec = 0;tm->time.tm_min = bcd2bin(buf[0] & 0x7F);tm->time.tm_hour = bcd2bin(buf[1] & 0x3F);tm->time.tm_mday = bcd2bin(buf[2] & 0x3F);tm->time.tm_wday = bcd2bin(buf[3] & 0x7);err = bm8563_get_alarm_mode(client, &tm->enabled, &tm->pending);if (err < 0)return err;dev_dbg(&client->dev, "%s: tm is mins=%d, hours=%d, mday=%d, wday=%d,"" enabled=%d, pending=%d\n", __func__, tm->time.tm_min,tm->time.tm_hour, tm->time.tm_mday, tm->time.tm_wday,tm->enabled, tm->pending);return 0;
}static int bm8563_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm)
{struct i2c_client *client = to_i2c_client(dev);unsigned char buf[4];int err;/* The alarm has no seconds, round up to nearest minute */if (tm->time.tm_sec) {time64_t alarm_time = rtc_tm_to_time64(&tm->time);alarm_time += 60 - tm->time.tm_sec;rtc_time64_to_tm(alarm_time, &tm->time);}dev_dbg(dev, "%s, min=%d hour=%d wday=%d mday=%d ""enabled=%d pending=%d\n", __func__,tm->time.tm_min, tm->time.tm_hour, tm->time.tm_wday,tm->time.tm_mday, tm->enabled, tm->pending);buf[0] = bin2bcd(tm->time.tm_min);buf[1] = bin2bcd(tm->time.tm_hour);buf[2] = bin2bcd(tm->time.tm_mday);buf[3] = tm->time.tm_wday & 0x07;err = bm8563_write_block_data(client, BM8563_REG_AMN, 4, buf);if (err)return err;return bm8563_set_alarm_mode(client, !!tm->enabled);
}static int bm8563_irq_enable(struct device *dev, unsigned int enabled)
{dev_dbg(dev, "%s: en=%d\n", __func__, enabled);return bm8563_set_alarm_mode(to_i2c_client(dev), !!enabled);
}#ifdef CONFIG_COMMON_CLK
/** Handling of the clkout*/#define clkout_hw_to_bm8563(_hw) container_of(_hw, struct bm8563, clkout_hw)static const int clkout_rates[] = {32768,1024,32,1,
};static unsigned long bm8563_clkout_recalc_rate(struct clk_hw *hw,unsigned long parent_rate)
{struct bm8563 *bm8563 = clkout_hw_to_bm8563(hw);struct i2c_client *client = bm8563->client;unsigned char buf;int ret = bm8563_read_block_data(client, BM8563_REG_CLKO, 1, &buf);if (ret < 0)return 0;buf &= BM8563_REG_CLKO_F_MASK;return clkout_rates[buf];
}static long bm8563_clkout_round_rate(struct clk_hw *hw, unsigned long rate,unsigned long *prate)
{int i;for (i = 0; i < ARRAY_SIZE(clkout_rates); i++)if (clkout_rates[i] <= rate)return clkout_rates[i];return 0;
}static int bm8563_clkout_set_rate(struct clk_hw *hw, unsigned long rate,unsigned long parent_rate)
{struct bm8563 *bm8563 = clkout_hw_to_bm8563(hw);struct i2c_client *client = bm8563->client;unsigned char buf;int ret = bm8563_read_block_data(client, BM8563_REG_CLKO, 1, &buf);int i;if (ret < 0)return ret;for (i = 0; i < ARRAY_SIZE(clkout_rates); i++)if (clkout_rates[i] == rate) {buf &= ~BM8563_REG_CLKO_F_MASK;buf |= i;ret = bm8563_write_block_data(client,BM8563_REG_CLKO, 1,&buf);return ret;}return -EINVAL;
}static int bm8563_clkout_control(struct clk_hw *hw, bool enable)
{struct bm8563 *bm8563 = clkout_hw_to_bm8563(hw);struct i2c_client *client = bm8563->client;unsigned char buf;int ret = bm8563_read_block_data(client, BM8563_REG_CLKO, 1, &buf);if (ret < 0)return ret;if (enable)buf |= BM8563_REG_CLKO_FE;elsebuf &= ~BM8563_REG_CLKO_FE;ret = bm8563_write_block_data(client, BM8563_REG_CLKO, 1, &buf);return ret;
}static int bm8563_clkout_prepare(struct clk_hw *hw)
{return bm8563_clkout_control(hw, 1);
}static void bm8563_clkout_unprepare(struct clk_hw *hw)
{bm8563_clkout_control(hw, 0);
}static int bm8563_clkout_is_prepared(struct clk_hw *hw)
{struct bm8563 *bm8563 = clkout_hw_to_bm8563(hw);struct i2c_client *client = bm8563->client;unsigned char buf;int ret = bm8563_read_block_data(client, BM8563_REG_CLKO, 1, &buf);if (ret < 0)return ret;return !!(buf & BM8563_REG_CLKO_FE);
}static const struct clk_ops bm8563_clkout_ops = {.prepare = bm8563_clkout_prepare,.unprepare = bm8563_clkout_unprepare,.is_prepared = bm8563_clkout_is_prepared,.recalc_rate = bm8563_clkout_recalc_rate,.round_rate = bm8563_clkout_round_rate,.set_rate = bm8563_clkout_set_rate,
};static struct clk *bm8563_clkout_register_clk(struct bm8563 *bm8563)
{struct i2c_client *client = bm8563->client;struct device_node *node = client->dev.of_node;struct clk *clk;struct clk_init_data init;int ret;unsigned char buf;/* disable the clkout output */buf = 0;ret = bm8563_write_block_data(client, BM8563_REG_CLKO, 1, &buf);if (ret < 0)return ERR_PTR(ret);init.name = "bm8563-clkout";init.ops = &bm8563_clkout_ops;init.flags = 0;init.parent_names = NULL;init.num_parents = 0;bm8563->clkout_hw.init = &init;/* optional override of the clockname */of_property_read_string(node, "clock-output-names", &init.name);/* register the clock */clk = devm_clk_register(&client->dev, &bm8563->clkout_hw);if (!IS_ERR(clk))of_clk_add_provider(node, of_clk_src_simple_get, clk);return clk;
}
#endifstatic const struct rtc_class_ops bm8563_rtc_ops = {.ioctl		= bm8563_rtc_ioctl,.read_time	= bm8563_rtc_read_time,.set_time	= bm8563_rtc_set_time,.read_alarm	= bm8563_rtc_read_alarm,.set_alarm	= bm8563_rtc_set_alarm,.alarm_irq_enable = bm8563_irq_enable,
};static int bm8563_probe(struct i2c_client *client,const struct i2c_device_id *id)
{struct bm8563 *bm8563;int err, value;unsigned char buf;unsigned int vdd_en_gpio;enum of_gpio_flags flags;vdd_en_gpio = of_get_named_gpio_flags(client->dev.of_node, "ingenic,vdd-en-gpio", 0, &flags);if(gpio_is_valid(vdd_en_gpio)) {if(devm_gpio_request(&client->dev, vdd_en_gpio, "rtc-vdd-en") < 0) {printk("Failed to request rtc-vdd-en-gpio pin!\n");}value = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1;gpio_direction_output(vdd_en_gpio, value);printk("Set rtc enable gpio %u, value %d\n", vdd_en_gpio, value);} else {dev_warn(&client->dev, "invalid gpio rtc-vdd-en-gpio: %d\n", vdd_en_gpio);}if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))return -ENODEV;bm8563 = devm_kzalloc(&client->dev, sizeof(struct bm8563),GFP_KERNEL);if (!bm8563)return -ENOMEM;i2c_set_clientdata(client, bm8563);bm8563->client = client;device_set_wakeup_capable(&client->dev, 1);/* Set timer to lowest frequency to save power (ref Haoyu datasheet) */buf = BM8563_TMRC_1_60;err = bm8563_write_block_data(client, BM8563_REG_TMRC, 1, &buf);if (err < 0) {dev_err(&client->dev, "%s: write error\n", __func__);return err;}/* Clear flags and disable interrupts */buf = 0;err = bm8563_write_block_data(client, BM8563_REG_ST2, 1, &buf);if (err < 0) {dev_err(&client->dev, "%s: write error\n", __func__);return err;}bm8563->rtc = devm_rtc_allocate_device(&client->dev);if (IS_ERR(bm8563->rtc))return PTR_ERR(bm8563->rtc);bm8563->rtc->ops = &bm8563_rtc_ops;/* the bm8563 alarm only supports a minute accuracy */bm8563->rtc->uie_unsupported = 1;bm8563->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;bm8563->rtc->range_max = RTC_TIMESTAMP_END_2099;bm8563->rtc->set_start_time = true;if (client->irq > 0) {err = devm_request_threaded_irq(&client->dev, client->irq,NULL, bm8563_irq,IRQF_SHARED | IRQF_ONESHOT | IRQF_TRIGGER_LOW,bm8563_driver.driver.name, client);if (err) {dev_err(&client->dev, "unable to request IRQ %d\n",client->irq);return err;}}err = rtc_register_device(bm8563->rtc);if (err)return err;#ifdef CONFIG_COMMON_CLK/* register clk in common clk framework */bm8563_clkout_register_clk(bm8563);
#endifreturn 0;
}static const struct i2c_device_id bm8563_id[] = {{ "bm8563", 0 },{ }
};static const struct of_device_id bm8563_of_match[] = {{ .compatible = "belling,bm8563" },{}
};static struct i2c_driver bm8563_driver = {.driver		= {.name	= "rtc_bm8563",.of_match_table = of_match_ptr(bm8563_of_match),},.probe		= bm8563_probe,.id_table	= bm8563_id,
};module_i2c_driver(bm8563_driver);MODULE_AUTHOR("<xxl@163.com>");
MODULE_DESCRIPTION("belling BM8563 RTC8564 RTC driver");
MODULE_LICENSE("GPL");

make之后,生产了ko文件;

测试结果:

问题和解决:

 1.i2c和pcf8563的内核启动失败

根据问题,我在make menucofig上取消i2c的驱动

开启君正RTC的驱动

 然后将编译好的内核烧录进去,程序启动:

不再看到pcf8563的报错信息,但是我调用hwclock的指令时,会报错
can't open '/dev/misc/rtc': No such file or directory

这个表示--rtc驱动没有加载成功!

我去查了网上一下资料:
比如hwclock: can't open '/dev/misc/rtc': No such file or directory_读行四海_新浪博客

我确定,我已经加载了君正官方的RTC支持,并且启动的iic的配置; 

2.hwclock报错:

 做了横向对比,查出如下问题:设备树没有做对应的设置
加入代码:

rtc: rtc@0x10003000 {compatible = "ingenic,rtc";reg = <0x10003000 0x4c>;interrupt-parent = <&core_intc>;interrupts = <IRQ_RTC>;system-power-controller;power-on-press-ms = <1000>;status = "ok";
};


http://www.ppmy.cn/ops/25649.html

相关文章

Solana未来的费用市场是什么样?

编者按&#xff1a;在 DeFi 领域迅速扩张的今天&#xff0c;Solana 区块链凭借其高性能的架构和创新技术&#xff0c;正在成为去中心化应用的新热点。然而&#xff0c;随着经济活动的激增&#xff0c;Solana 的费用市场和最大可提取价值&#xff08;MEV&#xff09;问题逐渐成为…

SV-7041T IP网络有源音箱 教室广播多媒体音箱(带本地扩音功能)教学广播音箱 办公室背景音乐广播音箱 2.0声道壁挂式网络有源音箱

SV-7041T IP网络有源音箱 教室广播多媒体音箱&#xff08;带本地扩音功能&#xff09; 教学广播音箱 办公室背景音乐广播音箱 一、描述 SV-7041T是深圳锐科达电子有限公司的一款2.0声道壁挂式网络有源音箱&#xff0c;具有10/100M以太网接口&#xff0c;可将网络音源通过自带…

笔记:编写程序,分别采用面向对象和 pyplot 快捷函数的方式绘制正弦曲线 和余弦曲线。 提示:使用 sin()或 cos()函数生成正弦值或余弦值。

文章目录 前言一、面向对象和 pyplot 快捷函数的方式是什么&#xff1f;二、编写代码面向对象的方法&#xff1a;使用 pyplot 快捷函数的方法&#xff1a; 总结 前言 本文将探讨如何使用编程语言编写程序&#xff0c;通过两种不同的方法绘制正弦曲线和余弦曲线。我们将分别采用…

从伊利金领冠逆势增长,看国产奶粉新「气象」

【潮汐商业评论/文】 2023年&#xff0c;“升级”成为国内婴幼儿奶粉消费市场的关键词&#xff0c;这是行业最严“新国标”正式实施后的硬性要求&#xff0c;也是市场转向存量竞争后的现实所需。 在这场大浪潮的洗礼下&#xff0c;市场清晰可见谁是“裸泳者”&#xff0c;谁又…

C语言指针和数组的一些笔试题

文章目录 前言一、一维数组二、字符数组-1三、字符数组-2总结 前言 C语言指针和数组的一些笔试题 一、一维数组 #include <stdio.h> int main() {int a[] { 1,2,3,4 };printf("%d\n", sizeof(a));printf("%d\n", sizeof(a 0));printf("%d\n…

RocketMQ快速入门:namesrv、broker、dashboard的作用及消息发送、消费流程(三)

0. 引言 接触rocketmq之后&#xff0c;大家首当其冲的就会发现需要安装3个组件&#xff1a;namesrv, broker, dashboard&#xff0c;其中dashboard也叫console&#xff0c;为选装。而这几个组件之前的关系是什么呢&#xff0c;消息发送和接收的过程是如何传递的呢&#xff0c;…

【Transformer】detr之decoder逐行梳理(三)

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 detr之decoder逐行梳理 1. 整体 decoder由多个decoder layer串联构成 输入 tgt: query是一个shape为(n,bs,embed),内容为0的tensormemory: encoder最…

Docker的介绍及与传统虚拟化技术的区别

docker的介绍 Docker是什么Docker 的核心组件Docker的优点Docker 和传统虚拟化技术的区别为什么使用Docker&#xff1f;docker的运行机制运行机制docker pull 执行过程docker run 执行过程&#xff1a; 基本命令管理命令 Docker是什么 docker官网地址 Docker 是一种开源的容器…

Java基础 异常传递

概述 项目中经常会在方法A中调方法B&#xff0c;如果B出现了异常&#xff0c;A要获取到B的异常&#xff0c;并且在接口中返回&#xff0c;这是一个例子。大概就是需要发送消息到哪里&#xff0c;仅支持邮件、微信&#xff0c;其他的则出错&#xff0c;错误信息用一个列表装着&…

Opencv_14_多边形填充与绘制

绘制多边形&#xff1a; 1&#xff09;coInvert.polyline_drawing(src); 2&#xff09;void ColorInvert::polyline_drawing(Mat& image) { Mat canvas Mat::zeros(Size(512, 512), CV_8UC3); Point p1(100, 100); Point p2(150, 100); Point p3(200…

Java拓扑排序知识点(含面试大厂题和源码)

在技术面试中&#xff0c;大厂可能会要求候选人实现或优化一些与图相关的算法&#xff0c;比如深度优先搜索&#xff08;DFS&#xff09;、广度优先搜索&#xff08;BFS&#xff09;和拓扑排序等。以下是三道与这些算法相关的面试题目&#xff0c;以及它们的Java源码示例。 1.…

mysql-sql练习-5-行列互转

目录 成绩单 简单互转 需求 多行转多列 分组 判断 聚合 理解 分组 合并 逆向需求 多列转多行 输出 合并 abc 去重 合并 拆分 需求 建表 多行转多列 逆向需求 多列转多行 拆分 按长度 拆分 按个数 成绩单 简单互转 需求 多行转多列 分组 判断 聚合 with tmp as(--…

首页最新 多IP浏览器防关联:如何配置多个独立且稳定的IP地址?

在互联网时代&#xff0c;IP地址的重要性不言而喻。然而&#xff0c;IP关联问题却成为一项令人担忧的隐私和安全挑战。针对这个问题&#xff0c;多IP浏览器是一种解决方案&#xff0c;可以帮助用户单独配置多个独立且稳定的IP地址&#xff0c;有效地防止IP关联。 一、IP关联是…

从曝光到安装:App传参安装的关键步骤与数据指标

随着移动互联网的普及&#xff0c;手游市场日益繁荣&#xff0c;手游推广方式也日新月异。在这个竞争激烈的市场中&#xff0c;如何有效地推广手游&#xff0c;吸引更多的用户&#xff0c;成为了开发者和广告主关注的焦点。而Xinstall作为国内专业的App全渠道统计服务商&#x…

【blender几何节点】制作几何节点生成树

实际上&#xff0c;用pcg功能的工具去搭单个可控制性较强的pcg案例&#xff08;如单个生成树&#xff09;而言&#xff0c;确实难度不大。但是要实现诸如speedtree这样通用性比较强的应用or插件&#xff08;精心设计的诸多可调节参数多带来的强通用性&#xff0c;使其能够适应不…

VGG16简单部署(使用自己的数据集)

一.注意事项 1.本文主要是引用大佬的文章&#xff08;侵权请联系&#xff0c;马上删除&#xff09;&#xff0c;做的工作为简单补充 二.介绍 ①简介&#xff1a;VGG16是一种卷积神经网络模型&#xff0c;由牛津大学视觉几何组&#xff08;Visual Geometry Group&#xff09;开…

分享土地利用/覆被变化长时序遥感解译

土地利用/覆被变化解译 多光谱和全色波段遥感影像结合滨海湿地分类系统、《中国湿地调查纲要》和研究区现状及相关研究&#xff0c;将江苏海岸带滨海湿地解译类型确定为浅海水域、芦苇、互花米草、盐地碱蓬、混生湿地植被、河流、水库坑塘、养殖水域、道路、建筑、裸地、农业用…

Xinlinx FPGA内的存储器BRAM全解

目录 一、总体概述1.7系列FPGA的BRAM特点2.资源情况 二、BRAM分类1.单端口RAM2.简单双端口RAM3.真双端口RAM 三、BRAM的读写1、Primitives Output Registers读操作注意事项2.三种写数据模式&#xff08;1&#xff09;Write_First&#xff08;2&#xff09;Read_First&#xff0…

随手记:vue2 filters this指向undefined

今天在使用filters的时候&#xff0c;需要用到this的数据&#xff0c;结果发现&#xff0c;this打印出来的是undefined 原因: 过滤器注册在vue实例之前&#xff0c;所以this指向了window&#xff0c;但是因为严格模式原因&#xff0c;为 undefined&#xff1b; 所以需要全局声…

Linux系统安全及应用(1)

目录 一.账号安全控制 系统账号清理 二.密码安全控制 密码安全控制 三.命令历史限制 命令历史限制 四.限制su切换用户 1&#xff09;将信任的用户加入到wheel组中 2&#xff09;修改su的PAM认证配置文件 ​编辑五.PAM认证的构成 六.使用sudo机制提升权限…