Linux I2C(二) - I2C软硬件架构

news2024/10/6 0:34:53

1,I2C的总线拓扑

2,I2C S/W topology

linux kernel I2C framework使用如下的软件拓扑抽象I2C硬件(我们可以一起领会一下其中的“设备模型”思想):

1)platform bus(/sys/bus/platform)是驱动工程师常见的bus,用于挂载和CPU通过系统总线连接的各类外设。在I2C framework中,I2C控制器直接从属于platform bus,我们在linux kernel中常说的I2C driver,都是指I2C controller driver,都是以platform driver的形式存在,当然,对应的控制器是platform device。

2)与此同时,kernel抽象出I2C bus(/sys/bus/i2c),用于挂载和I2C controller通过I2C总线连接的各个I2C slave device。

3)比较特殊的地方是,I2C core使用一个虚拟实体----I2C adapter,抽象I2C controller有关的功能(主要是数据的收发),I2C adapter也挂载在I2C bus上。

4)I2C adapter和I2C slave device都挂载在I2C bus上,就可以方便的进行Master(I2C adapter)和Slave之间的匹配操作,并通过I2C core提供的统一接口,访问I2C salve device,进行数据的收发。

5)以上各实体在sysfs中的位置,已经在“图片2”中通过红色字体标注,大家可自行理解。

3,软件框架

1)I2C framework的最终目标,是提供一种“访问I2C slave devices”的方法。由于这些slave devices由I2C controller控制,因而主要由I2C controller驱动实现这一目标。

2)经过I2C framework的抽象,consumer可以不用关心I2C总线的技术细节,只需要通过简单的API,就可以与slave devices进行数据交互。正常情况下,consumer是位于内核态的其它driver(如HDMI driver、touch screen driver等等)。与此同时,I2C framework也通过字符设备向用户空间提供类似的接口,用户空间程序可以通过该接口访问slave devices。

3)在I2C framework内部,有I2C core、I2C busses、I2C algos和I2C muxes四个模块。

4)I2C core使用I2C adapter和I2C algorithm两个子模块抽象I2C controller的功能,使用I2C client和I2C driver抽象I2C slave device的功能(对应设备模型中的device和device driver)。另外,基于I2C协议,通过smbus模块实现SMBus(System Management Bus,系统管理总线)的功能。

5)I2C busses是各个I2C controller drivers的集合,位于drivers/i2c/busses/目录下,驱动工程师常说的“I2C driver”就是指它们。

6)I2C algos包含了一些通用的I2C algorithm,所谓的algorithm,是指I2C协议包的生成方法,进而组合成I2C的read/write指令,一般情况下,都是由硬件实现,不需要特别关注该目录。

7)I2C muxes用于实现I2C bus的多路复用功能,属于奇葩的冷门功能,暂不过多介绍。

4,源码目录结构

在Linux内核源代码中的drivers目录下有一个i2c目录,而在i2c目录下又包含如下文件和文件夹。

(1)i2c-core.c

    这个文件实现了i2c核心的功能以及/proc/bus/i2c*接口。

(2)i2c-dev.c

    实现了i2c适配器设备文件的功能,每一个i2c适配器都被分配一个设备。通过适配器访问设备时的主设备号都为89,次设备号为0 ~ 255。应用程序通过“i2c-%d”(i2c-0,i2c-1,... ,i2c-10,...)文件名并使用文件操作接口open(),write(),read(), ioctl()和close()等来访问这个设备。

    i2c-dev.c并不是针对特定的设备而设计的,只是提供了通用的read()、write()和ioctl()等接口,应用层可以借用这些接访问挂接在适配器上的i2c设备的存储空间或寄存器,并控制i2c设备的工作方式。

(3)busses文件夹

    这个文件夹包含了一些i2c主机控制器驱动,如i2c-tegra.c、i2c-omap.c、i2c-versatile.c、i2c-s3c2410.c等。

(4)algos文件夹

    实现了一些i2c总线适配器的通信方法。

5,i2c_adapter/i2c_algorithm/i2c_driver/i2c_client结构体之间的关系

    内核中的i2c.h头文件中对i2c_adapter、i2c_algorithm、i2c_driver和i2c_client这4个数据结构进行了定义。他们的定义位于include/linux/i2c.h文件中。

i2c_adapter结构体:

/*
* i2c_adapter is the structure used to identify a physical i2c bus along
* with the access algorithms necessary to access it.
*/
struct i2c_adapter {
    struct module *owner;
    unsigned int class;          /* classes to allow probing for */
    const struct i2c_algorithm *algo; /* the algorithm to access the bus */
    void *algo_data;

    /* data fields that are valid for all devices    */
    const struct i2c_lock_operations *lock_ops;
    struct rt_mutex bus_lock;
    struct rt_mutex mux_lock;

    int timeout;            /* in jiffies */
    int retries;
    struct device dev;        /* the adapter device */
    unsigned long locked_flags;    /* owned by the I2C core */
#define I2C_ALF_IS_SUSPENDED        0
#define I2C_ALF_SUSPEND_REPORTED    1

    int nr;
    char name[48];
    struct completion dev_released;

    struct mutex userspace_clients_lock;
    struct list_head userspace_clients;

    struct i2c_bus_recovery_info *bus_recovery_info;
    const struct i2c_adapter_quirks *quirks;

    struct irq_domain *host_notify_domain;
};
#define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)

i2c_algorithm结构体:

/**
* struct i2c_algorithm - represent I2C transfer method
* @master_xfer: Issue a set of i2c transactions to the given I2C adapter
*   defined by the msgs array, with num messages available to transfer via
*   the adapter specified by adap.
* @master_xfer_atomic: same as @master_xfer. Yet, only using atomic context
*   so e.g. PMICs can be accessed very late before shutdown. Optional.
* @smbus_xfer: Issue smbus transactions to the given I2C adapter. If this
*   is not present, then the bus layer will try and convert the SMBus calls
*   into I2C transfers instead.
* @smbus_xfer_atomic: same as @smbus_xfer. Yet, only using atomic context
*   so e.g. PMICs can be accessed very late before shutdown. Optional.
* @functionality: Return the flags that this algorithm/adapter pair supports
*   from the ``I2C_FUNC_*`` flags.
* @reg_slave: Register given client to I2C slave mode of this adapter
* @unreg_slave: Unregister given client from I2C slave mode of this adapter
*
* The following structs are for those who like to implement new bus drivers:
* i2c_algorithm is the interface to a class of hardware solutions which can
* be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584
* to name two of the most common.
*
* The return codes from the ``master_xfer{_atomic}`` fields should indicate the
* type of error code that occurred during the transfer, as documented in the
* Kernel Documentation file Documentation/i2c/fault-codes.rst.
*/
struct i2c_algorithm {
    /*
     * If an adapter algorithm can't do I2C-level access, set master_xfer
     * to NULL. If an adapter algorithm can do SMBus access, set
     * smbus_xfer. If set to NULL, the SMBus protocol is simulated
     * using common I2C messages.
     *
     * master_xfer should return the number of messages successfully
     * processed, or a negative value on error
     */
    int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
               int num);
    int (*master_xfer_atomic)(struct i2c_adapter *adap,
                   struct i2c_msg *msgs, int num);
    int (*smbus_xfer)(struct i2c_adapter *adap, u16 addr,
              unsigned short flags, char read_write,
              u8 command, int size, union i2c_smbus_data *data);
    int (*smbus_xfer_atomic)(struct i2c_adapter *adap, u16 addr,
                 unsigned short flags, char read_write,
                 u8 command, int size, union i2c_smbus_data *data);

    /* To determine what the adapter supports */
    u32 (*functionality)(struct i2c_adapter *adap);

#if IS_ENABLED(CONFIG_I2C_SLAVE)
    int (*reg_slave)(struct i2c_client *client);
    int (*unreg_slave)(struct i2c_client *client);
#endif
};

i2c_driver结构体:

/**
* struct i2c_driver - represent an I2C device driver
* @class: What kind of i2c device we instantiate (for detect)
* @probe: Callback for device binding - soon to be deprecated
* @probe_new: New callback for device binding
* @remove: Callback for device unbinding
* @shutdown: Callback for device shutdown
* @alert: Alert callback, for example for the SMBus alert protocol
* @command: Callback for bus-wide signaling (optional)
* @driver: Device driver model driver
* @id_table: List of I2C devices supported by this driver
* @detect: Callback for device detection
* @address_list: The I2C addresses to probe (for detect)
* @clients: List of detected clients we created (for i2c-core use only)
*
* The driver.owner field should be set to the module owner of this driver.
* The driver.name field should be set to the name of this driver.
*
* For automatic device detection, both @detect and @address_list must
* be defined. @class should also be set, otherwise only devices forced
* with module parameters will be created. The detect function must
* fill at least the name field of the i2c_board_info structure it is
* handed upon successful detection, and possibly also the flags field.
*
* If @detect is missing, the driver will still work fine for enumerated
* devices. Detected devices simply won't be supported. This is expected
* for the many I2C/SMBus devices which can't be detected reliably, and
* the ones which can always be enumerated in practice.
*
* The i2c_client structure which is handed to the @detect callback is
* not a real i2c_client. It is initialized just enough so that you can
* call i2c_smbus_read_byte_data and friends on it. Don't do anything
* else with it. In particular, calling dev_dbg and friends on it is
* not allowed.
*/
struct i2c_driver {
    unsigned int class;

    /* Standard driver model interfaces */
    int (*probe)(struct i2c_client *client, const struct i2c_device_id *id);
    int (*remove)(struct i2c_client *client);

    /* New driver model interface to aid the seamless removal of the
     * current probe()'s, more commonly unused than used second parameter.
     */
    int (*probe_new)(struct i2c_client *client);

    /* driver model interfaces that don't relate to enumeration  */
    void (*shutdown)(struct i2c_client *client);

    /* Alert callback, for example for the SMBus alert protocol.
     * The format and meaning of the data value depends on the protocol.
     * For the SMBus alert protocol, there is a single bit of data passed
     * as the alert response's low bit ("event flag").
     * For the SMBus Host Notify protocol, the data corresponds to the
     * 16-bit payload data reported by the slave device acting as master.
     */
    void (*alert)(struct i2c_client *client, enum i2c_alert_protocol protocol,
              unsigned int data);

    /* a ioctl like command that can be used to perform specific functions
     * with the device.
     */
    int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);

    struct device_driver driver;
    const struct i2c_device_id *id_table;

    /* Device detection callback for automatic device creation */
    int (*detect)(struct i2c_client *client, struct i2c_board_info *info);
    const unsigned short *address_list;
    struct list_head clients;
};
#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)

i2c_client结构体:

/**
* struct i2c_client - represent an I2C slave device
* @flags: see I2C_CLIENT_* for possible flags
* @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.
* @init_irq: IRQ that was set at initialization
* @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        */
#define I2C_CLIENT_PEC        0x04    /* Use Packet Error Checking */
#define I2C_CLIENT_TEN        0x10    /* we have a ten bit chip address */
                    /* Must equal I2C_M_TEN below */
#define I2C_CLIENT_SLAVE    0x20    /* we are the slave */
#define I2C_CLIENT_HOST_NOTIFY    0x40    /* We want to use I2C host notify */
#define I2C_CLIENT_WAKE        0x80    /* for board_info; true iff can wake */
#define I2C_CLIENT_SCCB        0x9000    /* Use Omnivision SCCB protocol */
                    /* Must match I2C_M_STOP|IGNORE_NAK */

    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 init_irq;            /* irq set at initialization    */
    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
};
#define to_i2c_client(d) container_of(d, struct i2c_client, dev)

下面分析i2c_adapter、i2c_algorithm、i2c_driver、i2c_client这4个数据结构的作用及其关系。

(1)i2c_adapter 与 i2c_algorithm

    i2c_adapter对应于物理上的一个适配器,而i2c_algorithm对应一套通信方法。一个i2c适配器需要i2c_algorithm提供的通信函数来控制适配器产生特定的访问周期。缺少i2c_algorithm的i2c_adapter什么也做不了,因此i2c_adapter中包含所使用的i2c_algorithm的指针。

    i2c_algorithm中的关键函数是master_xfer()用于产生i2c访问周期需要的信号,以i2c_msg(即i2c消息)为单位。i2c_msg结构体也非常重要,它定义于include/uapi/linux/i2c.h(在uapi目录下,证明用户空间也可能使用这个结构体)中该结构体的成员表明了i2c的传输地址、方向、缓冲区、缓冲区长度等信息。

i2c_msg结构体的定义:

/**
* struct i2c_msg - an I2C transaction segment beginning with START
* @addr: Slave address, either seven or ten bits.  When this is a ten
*    bit address, I2C_M_TEN must be set in @flags and the adapter
*    must support I2C_FUNC_10BIT_ADDR.
* @flags: I2C_M_RD is handled by all adapters.  No other flags may be
*    provided unless the adapter exported the relevant I2C_FUNC_*
*    flags through i2c_check_functionality().
* @len: Number of data bytes in @buf being read from or written to the
*    I2C slave address.  For read transactions where I2C_M_RECV_LEN
*    is set, the caller guarantees that this buffer can hold up to
*    32 bytes in addition to the initial length byte sent by the
*    slave (plus, if used, the SMBus PEC); and this value will be
*    incremented by the number of block data bytes received.
* @buf: The buffer into which data is read, or from which it's written.
*
* An i2c_msg is the low level representation of one segment of an I2C
* transaction.  It is visible to drivers in the @i2c_transfer() procedure,
* to userspace from i2c-dev, and to I2C adapter drivers through the
* @i2c_adapter.@master_xfer() method.
*
* Except when I2C "protocol mangling" is used, all I2C adapters implement
* the standard rules for I2C transactions.  Each transaction begins with a
* START.  That is followed by the slave address, and a bit encoding read
* versus write.  Then follow all the data bytes, possibly including a byte
* with SMBus PEC.  The transfer terminates with a NAK, or when all those
* bytes have been transferred and ACKed.  If this is the last message in a
* group, it is followed by a STOP.  Otherwise it is followed by the next
* @i2c_msg transaction segment, beginning with a (repeated) START.
*
* Alternatively, when the adapter supports I2C_FUNC_PROTOCOL_MANGLING then
* passing certain @flags may have changed those standard protocol behaviors.
* Those flags are only for use with broken/nonconforming slaves, and with
* adapters which are known to support the specific mangling options they
* need (one or more of IGNORE_NAK, NO_RD_ACK, NOSTART, and REV_DIR_ADDR).
*/
struct i2c_msg {
    __u16 addr;    /* slave address            */
    __u16 flags;
#define I2C_M_RD        0x0001    /* read data, from slave to master */
                    /* I2C_M_RD is guaranteed to be 0x0001! */
#define I2C_M_TEN        0x0010    /* this is a ten bit chip address */
#define I2C_M_DMA_SAFE        0x0200    /* the buffer of this message is DMA safe */
                    /* makes only sense in kernelspace */
                    /* userspace buffers are copied anyway */
#define I2C_M_RECV_LEN        0x0400    /* length will be first received byte */
#define I2C_M_NO_RD_ACK        0x0800    /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_IGNORE_NAK    0x1000    /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_REV_DIR_ADDR    0x2000    /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NOSTART        0x4000    /* if I2C_FUNC_NOSTART */
#define I2C_M_STOP        0x8000    /* if I2C_FUNC_PROTOCOL_MANGLING */
    __u16 len;        /* msg length                */
    __u8 *buf;        /* pointer to msg data            */
};

(2)i2c_driver与i2c_client

    i2c_driver对应于一套驱动方法,其主要成员函数是probe()、remove()、suspend()、resume()等,另外,struct i2c_device_id形式的id_table是该驱动所支持的i2c设备的ID表。i2c_client对应于真实的物理设备,每个i2c设备都需要一个i2c_client来描述。i2c_driver与i2c_client的关系是一对多,一个i2c_driver可以支持多个同类型的i2c_client。

(3)i2c_adapter 与 i2c_client

    i2c_adapter 与 i2c_client的关系与i2c硬件体系中适配器和设备的关系一致,即i2c_client依附于i2c_adapter。由于一个适配器可以连接多个i2c设备,所以一个i2c_adapter也可以被多个i2c_client依附,i2c_adapter中包括依附于它的i2c_client的链表。

I2C驱动的各种数据结构的关系:

6,编写I2C驱动需要完成的工作

    一方面,适配器驱动可能是Linux内核还不包含的;另一方面,挂接在适配器上的具体的设备驱动可能也是Linux内核还不包含的。因此,工程师需要实现的主要工作如下:

(1)提供I2C适配器的硬件驱动,探测、初始化I2C适配器(如申请I2C的I/O地址和中断号)、驱动CPU控制的I2C适配器从硬件上产生各种信号以及处理I2C中断等。

(2)提供I2C适配器的algorithm,用具体适配器的xxx_xfer()函数填充i2c_algorithm的master_xfer指针,并把i2c_algorithm指针赋值给i2c_adapter的algo指针。

(3)实现I2C设备驱动中的i2c_driver接口,用具体设备yyy的yyy_probe()、yyy_remove()、yyy_suspend()、yyy_resume()函数指针和i2c_device_id设备ID表赋值给i2c_driver的probe、remove、suspend、resume和id_table指针。

(4)实现i2c设备所对应类型的具体驱动,i2c_driver只是实现设备与总线的挂接,而挂接在总线上的设备则千差万别。例如,如果是字符设备,就实现文件操作接口,即实现具体设备的yyy_read()、yyy_write()和yyy_ioctl()函数等;如果是声卡,就实现ALSA驱动。

上述前两个属于I2C总线驱动,后两个属于I2C设备驱动。

参考链接:

Linux I2C framework(1)_概述

<<Linux设备驱动开发详解>>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1625281.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle导出导入dmp等文件类型的多表数据的常用方法、遇见的常见问题和解决办法(exp无效sql???)

使用PLSQL执行导出表数据的时候有两种方法 1、使用Oracle命令【imp--exp】【impdp--expdp】 但是如果你的本机没有安装有Oracle数据库&#xff0c;使用的instant client远程连接服务器上的Oracle数据库时候&#xff0c;你没有Oracle数据库带有的exp.exe、imp.exe等扩展文件&a…

如何高效跟进项目进度?试试禅道几个功能

禅道提供了一系列功能和工具&#xff0c;可实现项目进度的有效管理和跟进&#xff0c;极大提升项目管理效率。禅道中的项目进度来源于迭代进度&#xff0c;迭代的进度又来源于任务的消耗和剩余工时&#xff0c;可通过以下功能有效跟进项目进展。 一、燃尽图 在禅道里&#xf…

机器学习day1

一、人工智能三大概念 人工智能三大概念 人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&#xff09;和深度学习&#xff08;DL&#xff09; 人工智能&#xff1a;人工智能是研究计算代理的合成和分析的领域。人工智能是使用计算机来模拟&#xff0c;而不是人类…

【办公类-22-14】周计划系列(5-5)“周计划-05 周计划表格内教案部分“节日”清空改成“节日“” (2024年调整版本)Win32

背景需求&#xff1a; 本学期19周&#xff0c;用了近10周的时间&#xff0c;终于把周计划教案部分的内容补全了&#xff08;把所有教案、反思的文字都撑满一个单元格&#xff09;&#xff0c; 一、原始教案 二、新模板内的教案 三、手动添加文字后的样式&#xff08;修改教案…

庐山研习班上介绍的25个LINUX工具

从2013年的第一届算起&#xff0c;庐山研习班走过十余个年头&#xff0c;办了十几次了。但每一次&#xff0c;都有很多不一样。即使是相同的主题&#xff0c;也有很大差异。 今年春季的庐山研习班是在上个周末。周四晚上我和大部分同学都到了五老峰脚下的训练基地。 除了周六下…

【C++ STL序列容器】list 双向链表

文章目录 【 1. 基本原理 】【 2. list 的创建 】2.1 创建1个空的 list2.2 创建一个包含 n 个元素的 list&#xff08;默认值&#xff09;2.3 创建一个包含 n 个元素的 list&#xff08;赋初值&#xff09;2.4 通过1个 list 初始化另一个 list2.5 拷贝其他类型容器的指定元素创…

HNCTF 2022 week1 题解

自由才是生活主旋律。 [HNCTF 2022 Week1] Interesting_include <?php //WEB手要懂得搜索 //flag in ./flag.phpif(isset($_GET[filter])){$file $_GET[filter];if(!preg_match("/flag/i", $file)){die("error");}include($file); }else{highlight_…

CentOS7安装并配置Yearning并实现无公网IP远程SQL审核与数据查询

目录 ​编辑 前言 1. Linux 部署Yearning 2. 本地访问Yearning 3. Linux 安装cpolar 4. 配置Yearning公网访问地址 5. 公网远程访问Yearning管理界面 6. 固定Yearning公网地址 结语 前言 作者简介&#xff1a; 懒大王敲代码&#xff0c;计算机专业应届生 今天给大家聊聊…

Docker 的数据管理 端口映射 容器互联 镜像的创建

目录 概念 概念 管理 Docker 容器中数据主要有两种方式&#xff1a;数据卷&#xff08;Data Volumes&#xff09;和数据卷容器&#xff08;DataVolumes Containers&#xff09;。总结&#xff1a;因为容器数据是临时保存的为了安全&#xff0c;就要让数据保持持久化。 1&#…

qt QTreeWidget 学习

树形控件的节点可以有多层、多个子节点&#xff0c; 如果将子节点全部展开&#xff0c;那么每一行都是一个数据条目。QTreeWidgetItem 比较特殊&#xff0c;一个条目内部可以有多列数据信息&#xff0c;相当于表格控件一整行的表格单元集成为一个条目。 默认情况下&#xff0c;…

Methoxy-PEG-PLGA,mPEG-PLGA是一种可生物降解的两亲性嵌段共聚物

【试剂详情】 英文名称 mPEG-PLGA&#xff0c;Methoxy-PEG-Poly(lactide-co-glycolide)&#xff0c;Methoxy-PEG-PLGA&#xff0c; mPEG-Poly(lactide-co-glycolide) 中文名称 聚乙二醇单甲醚聚乳酸&#xff0c;乙醇酸两嵌段共聚物 外观性状 由分子量决定&#xff0c;液体…

调试记录 Flash 芯片 GD25LQ128ESIG 的程序烧录问题

1. 烧录工具 工具型号&#xff1a; VS4000P 2. 烧录问题 1. 烧录器选择烧录型号过程中没有看见 Flash 芯片 GD25LQ128ESIG 的型号。其中有GD25Q128E &#xff0c;但是三个选项的封装不对。 3. 解决过程 1. 尝试别的类型的芯片型号烧录。 A.GD25LQ80E(SOP8_200) B.GD25LQ64E(SOP…

IDEA 2024.1 配置 AspectJ环境

最近Java课设在学习AspectJ&#xff0c;做PPT顺便写一个博客 下载包 首先去AspectJ官网下载一个JAR包并安装 安装完最后可以按照他的建议配置一下 然后找到AspectJ的安装位置的lib目录&#xff0c;把三个包拷到自己项目中的lib目录下 由于最新版的IDEA已经不支持AspectJ了 所…

(八)Servlet教程——创建Web项目以及Servlet的实现

1. 打开Idea编辑器 2. 点击界面上的“新建项目”按钮 3. 设置好项目名称和位置 应用服务器选择之前设置好的Tomcat服务器 构建系统默认选择Maven 4. 点击“下一步”按钮 5. 点击“完成”按钮&#xff0c;Idea就创建好了项目&#xff0c;创建完成后的目录结构如下图所示 6. 此…

脉冲电源的直流斩波板设计总结(RC缓冲电路,输出电容选值)

IC的RC缓冲 总结一下过去电加工所的直流斩波板问题 1&#xff1a;电流突变问题 在独立式电火花脉冲电源里面&#xff0c;用电阻去限制电流&#xff0c;从而抑制当极间突变时的电流突变。 在非独立式的脉冲电源里面&#xff0c;电流平时是稳定在循环电感里面&#xff0c;当击…

ESLlint重大更新后,使用旧版ESLint搭配Prettier的配置方式

概要 就在前几天&#xff0c;ESLint迎来了一次重大更新&#xff0c;9.0.0版本&#xff0c;根据官方文档介绍&#xff0c;使用新版的先决条件是Node.js版本必须是18.18.0、20.9.0&#xff0c;或者是>21.1.0的版本&#xff0c;新版ESLint将不再直接支持以下旧版配置(非扁平化…

USB设备的音频类UAC

一、UAC简介 UAC&#xff08;USB Audio Class&#xff09;是USB设备的音频类&#xff0c;它定义了USB音频设备与主机计算机通信的方式。UAC标准是USB规范的一部分&#xff0c;并受到各种操作系统&#xff08;包括Windows、macOS和Linux&#xff09;的支持。 UAC是基于libusb,实…

抖音智能运营系统源码

这是一个一站式服务的抖音智能运营系统&#xff0c;旨在提升内容创作者和营销人员的工作效率。它是一个综合性的在线服务平台&#xff0c;专为抖音内容创作者和营销人员设计。系统基于高性能、可扩展性强的ThinkPHP框架&#xff0c;整合了视频处理、数据分析、文案生成与配音等…

联网获取不了IP地址:原因分析与解决方案

在数字化时代&#xff0c;网络连接已成为我们日常生活和工作中不可或缺的一部分。然而&#xff0c;有时我们可能会遇到一个问题&#xff1a;设备在尝试连接到网络时&#xff0c;无法获取IP地址。这种情况可能导致我们无法访问互联网或局域网资源。那么&#xff0c;联网获取不了…

PD虚拟机和双系统哪个好 Mac建议装双系统吗

在当今数字化时代&#xff0c;对于部分使用Mac电脑的用户来说&#xff0c;选择如何在系统中运行Windows或其他操作系统能节省大量精力。Parallels Desktop&#xff08;PD&#xff09;虚拟机和双系统是两种常见的选择&#xff0c;它们各自具有优势和限制。下面我们来看看PD虚拟机…