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

consumer 角度讲一下i2c外设

往期内容

I2C子系统专栏:

  1. I2C(IIC)协议讲解-CSDN博客
  2. SMBus 协议详解-CSDN博客
  3. I2C相关结构体讲解:i2c_adapter、i2c_algorithm、i2c_msg-CSDN博客
  4. 内核提供的通用I2C设备驱动I2c-dev.c分析:注册篇
  5. 内核提供的通用I2C设备驱动I2C-dev.c分析:file_ops篇
  6. 设备驱动与设备树匹配机制详解
  7. 编写一个通用的i2c设备驱动框架
  8. 编写一个通用的i2c控制器驱动框架

总线和设备树专栏:

  1. 总线和设备树_憧憬一下的博客-CSDN博客
  2. 设备树与 Linux 内核设备驱动模型的整合-CSDN博客

前言

在上一章节(编写一个通用的i2c控制器驱动框架)讲了i2c_adapter。这里再继之前的文章( 编写一个通用的i2c设备驱动框架)进行补充,讲一下l2c_cleint的设备形态等

1. 两种设备形态

img

可以看出是有两种你描述的这两种设备形态反映了设备通过不同的总线进行交互的差异,并且在设备树(DTS)和驱动程序的编写上有不同的表现。根据设备的主要功能和数据传输方式,它们在 Linux 设备模型中的位置不同,从而影响了 DTS 文件中的结构和驱动程序的设计。我们来分析这两种设备形态。

形态 1: I2C-only 设备(图左侧):

  • 特点:这类设备和 CPU 之间的所有数据交互都是通过 I2C 总线完成的,没有其他传输方式。
  • DTS 描述:设备直接作为 I2C 控制器的子节点存在。在 DTS 中,设备的定义紧随其所在的 I2C 总线节点之后。例如 PMIC,它是 I2C 总线上的一个设备,因此直接在 I2C 节点的子节点中定义。
&i2c1 {clock-frequency = <100000>;pinctrl-names = "default";pinctrl-0 = <&pinctrl_i2c1>;status = "okay";pmic: pf0100@08 {compatible = "fsl,pfuze100";reg = <0x08>;...};
};
  • 驱动模型:I2C 核心负责处理设备的创建和注册。驱动程序是以 I2C slave 设备的方式来实现,I2C 驱动框架通过 i2c_driver 结构和 i2c_device_id 来与设备匹配。设备的 proberemove 等函数由 I2C 核心进行管理。
static const struct i2c_device_id pmic_i2c_ids[] = {{ "pfuze100", 0 },{ /* sentinel */ }
};static struct i2c_driver pmic_driver = {.driver = {.name = "pfuze100",.of_match_table = pmic_of_match,},.probe = pmic_probe,.remove = pmic_remove,.id_table = pmic_i2c_ids,
};

I2C 是主数据交互总线,设备完全依赖 I2C,所有操作通过 I2C 完成。

驱动注册流程通过 I2C 子系统的 i2c_driver 完成,设备由 I2C 核心管理。


形态 2: 复合设备(I2C 作为辅助接口,图右侧):

  • 特点:这类设备通过多种方式与 CPU 交互,例如,主要的数据传输(如音视频数据)通过 TDMS 接口,而配置信息或控制信息通过 I2C(DDC)接口。这类设备的核心功能决定了它们的主要位置在其他总线(如平台总线 platform bus)上,而 I2C 只是作为一个辅助接口。
  • DTS 描述:HDMI 设备作为 platform device 定义,并且通过 ddc-i2c-bus 属性引用 I2C 总线,用于 DDC(Display Data Channel)接口的 I2C 通信。
&hdmi {ddc-i2c-bus = <&i2c2>;status = "okay";
};
  • 驱动模型:在这种情况下,HDMI 控制器是主要设备,注册为 platform_device。I2C 通信是 HDMI 控制器的一部分,用来处理 EDID 等信息读取。在驱动程序中,I2C 总线是通过 DTS 中的 ddc-i2c-bus 属性传递给 HDMI 驱动的,驱动程序会通过 of_find_i2c_adapter_by_node() 获取并绑定 I2C 控制器。
struct i2c_adapter *ddc;
struct device_node *ddc_node;ddc_node = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);
if (!ddc_node) {dev_err(dev, "failed to find ddc-i2c-bus node\n");return -ENODEV;
}ddc = of_find_i2c_adapter_by_node(ddc_node);
of_node_put(ddc_node);
if (!ddc)return -EPROBE_DEFER;/* Use ddc for I2C transactions */

I2C 是辅助总线,用于少量数据交互(如 EDID、配置信息传输),主要功能通过其他总线(如 TDMS)完成。

驱动以 platform_device 形式注册,I2C 仅作为其中一个通信接口,I2C 控制器通过设备树中的引用绑定。

2. 驱动编写

根据上面所说的形态去编写设备不同的i2c_driver

形态1: 完全依赖I2C的设备(如PMIC)

  1. 确定I2C adapter
    根据设备硬件连接的实际情况,确定该设备所从属的I2C controller,即I2C adapter(在I2C framework中,I2C controller通常被称为I2C adapter)。例如,PMIC设备可能连接在 i2c1 总线上。
  2. 在DTS中添加设备描述
    在设备树的I2C adapter节点中,添加I2C从设备的描述。这个从设备的定义格式与普通的platform device一致,例如:
&i2c1 {pmic: pfuze100@08 {compatible = "fsl,pfuze100";reg = <0x08>;// 其他字段...};
};
  1. compatible 字段的使用
    DTS 中的 compatible 字段用于设备驱动的匹配和 probe。I2C驱动会根据 compatible 字段匹配到合适的驱动程序,例如 "compatible = "fsl,pfuze100";"
  2. 编写I2C设备的驱动程序

示例:

static const struct of_device_id pmic_of_match[] = {{ .compatible = "fsl,pfuze100", },{ /* sentinel */ }
};static struct i2c_driver pmic_driver = {.driver = {.name = "pfuze100",.of_match_table = pmic_of_match,},.probe = pmic_probe,.remove = pmic_remove,
};
static int __init i2c_driver_XXX_init(void)
{printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);return i2c_add_driver(&i2c_XXX_driver);
}
module_init(i2c_driver_XXX_init);
    • 定义并注册 i2c_driver:编写一个 struct i2c_driver 结构体,并使用 i2c_add_driver将其注册到I2C core中。
    • 匹配设备:在 i2c_driver 结构体中,定义 of_match_table,使其可以通过 compatible 字段进行匹配。
    • 实现 probe 回调:编写 probe 函数,用于设备初始化。
  1. I2C core处理设备注册
    当I2C adapter注册时,I2C framework的核心代码会自动为其下的所有I2C从设备创建 struct i2c_client 结构体,并根据设备树中的 compatible 字段,匹配合适的 i2c_driver,然后调用驱动程序的 probe 函数。
  2. probe
    当设备被I2C framework匹配到时,调用此函数进行设备初始化。主要负责获取设备资源(如设备地址、I2C Adapter),设置硬件寄存器,或者初始化其他系统资源(如注册字符设备)。
static int ap3216c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{// 打印日志确认 probe 触发printk(KERN_INFO "ap3216c i2c device probe.\n");// 设置I2C client指针ap3216c_client = client;// 执行设备初始化:如设置初始寄存器值i2c_smbus_write_byte_data(client, 0x00, 0x03);  // 设置某些寄存器// 注册字符设备或其他资源major = register_chrdev(0, "ap3216c", &ap3216c_ops);ap3216c_class = class_create(THIS_MODULE, "ap3216c_class");device_create(ap3216c_class, NULL, MKDEV(major, 0), NULL, "ap3216c");return 0;
}

在注册的ap3216c_ops中,有关read和write的函数,使用到I2C数据有关的接口就有两类:

  • 一类是以i2c client为参数,进行简单的数据收发。该方法只可以通过标准方式,发送或者接收一定数量的数据。
  • 另一类是以i2c adapter和i2c msg为参数,可以更为灵活的read或者write数据,包括i2c_transfer。使用该方法可以以struct i2c_msg为参数,一次读取、或者写入、或者读取加写入,一定数量的数据。
  • 具体的函数去看\Linux-4.9.88\include\linux\i2c.h

形态2: 复合型设备(如HDMI)

  1. 确定I2C adapter
    根据设备硬件的连接方式,找到设备使用的I2C adapter。例如,HDMI 设备可以使用 i2c2 作为其 DDC 通道。
  2. 将设备作为平台设备描述
    将设备作为平台设备(platform device)进行描述。其 DTS 节点并不是直接位于I2C adapter下,而是位于根目录。例如:
&hdmi {ddc-i2c-bus = <&i2c2>;status = "okay";
};
  1. 获取I2C adapter的引用
    在DTS描述中使用 ddc-i2c-bus 属性引用I2C adapter节点。该属性通过 of_parse_phandle 来解析,并在驱动中获取相应的I2C adapter的指针。
  2. probe 函数中获取I2C adapter
    在平台设备的 probe 函数中,通过 of_parse_phandle 来获取I2C adapter节点,并通过 of_find_i2c_adapter_by_node() 获取对应的 struct i2c_adapter 指针。如下代码示例:
struct i2c_adapter *ddc;
struct device_node *ddc_node;ddc_node = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);
if (!ddc_node) {dev_err(dev, "failed to find ddc-i2c-bus node\n");return -ENODEV;
}ddc = of_find_i2c_adapter_by_node(ddc_node);
of_node_put(ddc_node);
if (!ddc)return -EPROBE_DEFER;
  1. 使用 i2c_transfer 进行读写操作
    获取I2C adapter之后,便可以使用 i2c_transfer() 接口来进行I2C读写操作。例如,通过DDC接口读取EDID信息时:
struct i2c_msg msgs[] = {{.addr = ddc_addr,.flags = I2C_M_RD,.len = 128,.buf = edid_buf,},
};ret = i2c_transfer(ddc, msgs, 1);  // 读取EDID数据

3. i2c_client

i2c设备中用i2c_client结构体来指代:

/*** struct i2c_client - represent an I2C slave device* @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;*	I2C_CLIENT_PEC indicates it uses SMBus Packet Error Checking* @addr: Address used on the I2C bus connected to the parent adapter.* @name: Indicates the type of the device, usually a chip name that's*	generic enough to hide second-sourcing and compatible revisions.* @adapter: manages the bus segment hosting this I2C device* @dev: Driver model device node for the slave.* @irq: indicates the IRQ generated by this device (if any)* @detected: member of an i2c_driver.clients list or i2c-core's*	userspace_devices list* @slave_cb: Callback when I2C slave mode of an adapter is used. The adapter*	calls it to pass on slave events to the slave driver.** An i2c_client identifies a single device (i.e. chip) connected to an* i2c bus. The behaviour exposed to Linux is defined by the driver* managing the device.*/
struct i2c_client {unsigned short flags;		/* div., see below		*/unsigned short addr;		/* chip address - NOTE: 7bit	*//* addresses are stored in the	*//* _LOWER_ 7 bits		*/char name[I2C_NAME_SIZE];struct i2c_adapter *adapter;	/* the adapter we sit on	*/struct device dev;		/* the device structure		*/int irq;			/* irq issued by device		*/struct list_head detected;
#if IS_ENABLED(CONFIG_I2C_SLAVE)i2c_slave_cb_t slave_cb;	/* callback for slave mode	*/
#endif
};

flags:

  • 表示I2C设备的标志位。可以包含以下选项:

    • I2C_CLIENT_TEN:表示设备使用的是十位地址(而不是常见的七位地址)。
    • I2C_CLIENT_PEC:表示设备使用SMBus包错误校验(Packet Error Checking,PEC),这是一种错误检测机制。

addr:

  • I2C设备的地址。地址位于I2C总线上的低7位或低10位(如果 flags 指示设备使用十位地址的话)。

name:

  • 一个字符数组,表示设备的名称,通常是设备的芯片名称或类型。名称尽可能保持通用,以适应同一设备的不同版本或兼容的设备。

adapter:

  • 指向设备所在的I2C总线适配器(i2c_adapter)的指针。每个I2C设备都挂载在一个I2C适配器上,适配器管理与设备的通信。

dev:

  • Linux驱动模型中的设备节点(struct device),用于表示I2C从设备。这是Linux设备模型的标准数据结构,提供了与设备类、驱动程序以及电源管理等相关的接口。

irq:

  • 表示设备所使用的中断号(如果该设备可以生成中断)。不使用中断的设备此字段可能为0或无效值。

detected:

  • 用于链表结构中的节点。在内核中,这个字段用于将该设备连接到 i2c_driver.clients 列表或 i2c-coreuserspace_devices 列表中。

slave_cb:

  • 仅在启用了 I2C Slave 模式(即 CONFIG_I2C_SLAVE 选项启用时)时有效。
  • 这是用于适配器从模式的回调函数指针。当I2C适配器处于从模式时,适配器调用这个回调函数,将从模式的事件传递给从设备的驱动程序。

i2c_client一般是在register adapter的时候,解析adapter的child node自行创建的,这个在对上一章节中对i2c_add_adapte函数进行分析的时候有提到过

相关文章:

consumer 角度讲一下i2c外设

往期内容 I2C子系统专栏&#xff1a; I2C&#xff08;IIC&#xff09;协议讲解-CSDN博客SMBus 协议详解-CSDN博客I2C相关结构体讲解:i2c_adapter、i2c_algorithm、i2c_msg-CSDN博客内核提供的通用I2C设备驱动I2c-dev.c分析&#xff1a;注册篇内核提供的通用I2C设备驱动I2C-dev.…...

面试经典150题刷题记录

数组部分 1. 合并两个有序的子数组 —— 倒序双指针避免覆盖 88. 合并两个有序数组 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使…...

【HarmonyOS NEXT】实现保存base64图片到图库

上篇文章介绍了HarmonyOS NEXT如何保存base64文件到download目录下&#xff0c;本次介绍如何保存base64图片到图库&#xff0c;网络图片保存方式大同小异&#xff0c;先下载图片&#xff0c;然后再保存 phAccessHelper.showAssetsCreationDialog参考官方文档’ ohos.file.pho…...

开题答辩最怕被问什么?教你用ChatGPT轻松准备,稳拿高分!

AIPaperGPT&#xff0c;论文写作神器~ https://www.aipapergpt.com/ 开题答辩是学位论文写作过程中的重要环节&#xff0c;能帮助导师评估你的研究计划是否可行&#xff0c;并对后续写作起到指导作用。很多同学在面对导师提问时会感到紧张&#xff0c;因此提前准备好常见问题的…...

Unity3D功耗和发热分析与优化详解

前言 Unity3D作为广泛使用的游戏开发引擎&#xff0c;在游戏开发过程中&#xff0c;功耗和发热问题一直是开发者需要重点关注的问题。功耗和发热不仅影响用户体验&#xff0c;还可能对设备的硬件寿命造成一定影响。本文将从技术角度详细分析Unity3D游戏在移动设备上的功耗和发…...

深度学习中的掩码介绍

在深度学习中,**掩码(Mask)**通常用于屏蔽掉某些特定部分的数据,以确保模型在训练或推理时不处理无效或无关的输入。掩码的使用场景主要包括处理变长序列、生成模型中的自回归任务、处理填充数据等。掩码可以是二值矩阵(1 表示有效数据,0 表示屏蔽数据),在注意力机制中…...

rust高级进阶总结

文章目录 前言1. Rust生命周期进阶一、不太聪明的生命周期检查&#xff08;一&#xff09;例子1&#xff08;二&#xff09;例子2 二、无界生命周期三、生命周期约束&#xff08;HRTB&#xff09;&#xff08;一&#xff09;语法及含义&#xff08;二&#xff09;综合例子 四、…...

整理—计算机网络

目录 网络OSI模型和TCP/IP模型 应用层有哪些协议 HTTP报文有哪些部分 HTTP常用的状态码 Http 502和 504 的区别 HTTP层请求的类型有哪些&#xff1f; GET和POST的使用场景&#xff0c;有哪些区别&#xff1f; HTTP的长连接 HTTP默认的端口是什么&#xff1f; HTTP1.1怎…...

分布式数据库环境(HBase分布式数据库)的搭建与配置

分布式数据库环境&#xff08;HBase分布式数据库&#xff09;的搭建与配置 1. VMWare安装CentOS7.9.20091.1 下载 CentOS7.9.2009 映像文件1.2启动 VMware WorkstationPro&#xff0c;点击“创建新的虚拟机”1.3在新建虚拟机向导界面选择“典型&#xff08;推荐&#xff09;”1…...

100个JavaWeb(JDBC, Servlet, JSP)毕业设计选题

100个JavaWeb(JDBC, Servlet, JSP)毕业设计选题 教育行业 学生信息管理系统在线考试系统课程管理与选课系统教师评价管理系统图书馆管理系统学生成绩查询系统校园论坛作业提交与批改系统学生考勤管理系统教学资源共享平台 企业管理 员工管理系统考勤打卡系统办公用品申请管…...

05 go语言(golang) - 常量和条件语句

常量 在Go语言中&#xff0c;常量是使用 const 关键字定义的&#xff0c;并且一旦被赋值后&#xff0c;它们的值在程序运行期间不能改变。常量可以是字符、字符串、布尔或数值类型。 基本特性 不可修改&#xff1a;一旦一个常量被定义&#xff0c;它的值就不能被更新。编译时…...

【设计模式】深入理解Python中的适配器模式(Adapter Pattern)

深入理解Python中的适配器模式&#xff08;Adapter Pattern&#xff09; 在软件开发中&#xff0c;常常会遇到需要让不兼容的类或接口协同工作的问题。适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;通过提供一个包装器对象&#xff0c;…...

RuoYi-Vue若依框架-后端设置不登陆访问(白名单)

找到SecurityConfig类 确认自己的需求 /*** anyRequest | 匹配所有请求路径* access | SpringEl表达式结果为true时可以访问* anonymous | 匿名可以访问* denyAll | 用户不能访问* fullyAuthenticated | 用户完全认证可…...

C语言初阶小练习2(三子棋小游戏的实现代码)

这是C语言小游戏三子棋的代码实现 test.c文件是用来测试的部分 game.h文件是用来声明我们说写出的函数 game.c文件是用来编写我们的功能实现函数部分 1.test.c #define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" void menu() {printf("***************…...

金融行业合同管理如何利用AI技术进行风险预警?

2024年以来&#xff0c;金融行业的发展主线被锚定&#xff0c;强调了防风险的基调&#xff0c;尤其是系统性风险的防范。金融工作的重点在于实现六个强大&#xff1a;强大的货币、强大的中央银行、强大的金融机构、强大的国际金融中心、强大的金融监管、强大的金融人才队伍。这…...

世界数字农业盛宴与技术探索,25年3月聚焦世界灌溉科技大会

由中国农业节水和农村供水技术协会、中国农垦节水农业产业技术联盟、北京物联网智能技术应用协会、振威国际会展集团主办的“世界灌溉科技大会”、“第11届北京国际数字农业与灌溉技术博览会”&#xff0c;定于2025年3月31日至4月2日在北京国家会议中心举办。 作为世界三大灌溉…...

二百六十九、Kettle——ClickHouse清洗ODS层原始数据增量导入到DWD层表中

一、目的 清洗ClickHouse的ODS层原始数据&#xff0c;增量导入到DWD层表中 二、实施步骤 2.1 newtime select( select create_time from hurys_jw.dwd_statistics order by create_time desc limit 1) as create_time 2.2 替换NULL值 2.3 clickhouse输入 2.4 字段选择 2.5 …...

Maya---骨骼绑定

调节骨骼大小 回车键确认骨骼 FK子集跟父集走 IK子集不跟父集走 前视图中按shift键添加骨骼 清零、删除历史记录&#xff0c;创建新的物体...

携手并进,智驭教育!和鲸科技与智谱 AI 签署“101 数智领航计划”战略合作协议

近日&#xff0c;上海和今信息科技有限公司&#xff08;以下简称“和鲸科技”&#xff09;与北京智谱华章科技有限公司&#xff08;以下简称“智谱 AI”&#xff09;签署“101 数智领航计划”战略合作协议。双方将携手营造智能化学科教育与科研环境&#xff0c;提供多种大模型工…...

牛客周赛63

https://ac.nowcoder.com/acm/contest/91592 好数 简单的判断两位数&#xff0c;且十位等于个位 #include <bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define int long long using namespace std; using ll long long; using pii …...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

【深度学习新浪潮】什么是credit assignment problem?

Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...

Vue3 PC端 UI组件库我更推荐Naive UI

一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用&#xff0c;前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率&#xff0c;还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库&#xff08;Naive UI、Element …...

高分辨率图像合成归一化流扩展

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 1 摘要 我们提出了STARFlow&#xff0c;一种基于归一化流的可扩展生成模型&#xff0c;它在高分辨率图像合成方面取得了强大的性能。STARFlow的主要构建块是Transformer自回归流&#xff08;TARFlow&am…...