opensbi串口驱动详解

原创 嵌入式Lee 2024-10-01 23:48

一. 前言

本文分享OpenSBI串口驱动相关的实现,并实践添加自己的串口驱动。

整个框架如下

二. 串口驱动相关KconfigMakefile

2.1 Kconfig

要了解串口驱动的相关结构,最好的方式是从KconfigMakefile入手,看到底编译了哪些文件,结构是怎么样的。https://mp.weixin.qq.com/s/941A4li9L6kq1QB-fuyuVA opensbi单独构建与GDB仿真调试一文中介绍了Kconfig的结构。这里重点关注串口驱动相关的。

输入如下命令进入配置界面:

make PLATFORM=generic menuconfig

如下路径

Utils and Drivers Support --->

Serial Device Support--->

对应的文件就是lib/utils/serial/Kconfig

Kconfig下,首先有个总的配置FDT_SERIAL,该配置选中,下面才会有各个driver选择。

FDT_SERIAL依赖于FDT配置。

FDT配置是在platform/generic/Kconfig中,选中平台时自动选中的(make PLATFORM=generic menuconfig时自动选择的是platform/generic/Kconfig)

Platform options --->

选中某个driver配置时,自动会select对应的串口底层实现

比如选中config FDT_SERIAL_CADENCE时自动选择select SERIAL_CADENCE

2.2. Makefile

lib/utils/serial/objects.mk中就会根据上述Kconfig配置,是否添加对应的c文件进行编译。

libsbiutils-objs-$(CONFIG_FDT_SERIAL) += serial/fdt_serial.o

libsbiutils-objs-$(CONFIG_FDT_SERIAL) += serial/fdt_serial_drivers.carray.o

fdt_serial.c始终会编译

fdt_serial_drivers.carray.c是脚本自动生成的,后面介绍

如下驱动代码按照配置添加

carray-fdt_serial_drivers-$(CONFIG_FDT_SERIAL_CADENCE) += fdt_serial_cadence

libsbiutils-objs-$(CONFIG_FDT_SERIAL_CADENCE) += serial/fdt_serial_cadence.o

......

如下再根据配置添加串口底层实现文件

libsbiutils-objs-$(CONFIG_SERIAL_CADENCE) += serial/cadence-uart.o

......

上面提到的build/platform/generic/lib/utils/serial/fdt_serial_drivers.carray.c

Makefile中如下实现

$(platform_build_dir)/%.carray.c: $(platform_src_dir)/%.carray

  $(call compile_carray,$@,$<)

实现如下

compile_carray = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \

       echo " CARRAY    $(subst $(build_dir)/,,$(1))"; \

       $(eval CARRAY_VAR_LIST := $(carray-$(subst .carray.c,,$(shell basename $(1)))-y)) \

       $(src_dir)/scripts/carray.sh -i $(2) -l "$(CARRAY_VAR_LIST)" > $(1)

即调用的脚本

scripts/carray.sh

根据

lib/utils/serial/fdt_serial_drivers.carray

HEADER: sbi_utils/serial/fdt_serial.h  //头文件

TYPE: struct fdt_serial     //数组类型

NAME: fdt_serial_drivers   //指定数组结构名字,可以通过该全局变量索引指定的驱动

生成

build/platform/generic/lib/utils/serial/fdt_serial_drivers.carray.c

实际就是生成了全局数组 fdt_serial_drivers ,这个数组的成员即各个串口驱动的实现

// Generated with carray.sh from fdt_serial_drivers.carray#include 
extern struct fdt_serial fdt_serial_cadence;extern struct fdt_serial fdt_serial_gaisler;extern struct fdt_serial fdt_serial_htif;extern struct fdt_serial fdt_serial_renesas_scif;extern struct fdt_serial fdt_serial_shakti;extern struct fdt_serial fdt_serial_sifive;extern struct fdt_serial fdt_serial_litex;extern struct fdt_serial fdt_serial_uart8250;extern struct fdt_serial fdt_serial_xlnx_uartlite;
struct fdt_serial *fdt_serial_drivers[] = {    &fdt_serial_cadence,    &fdt_serial_gaisler,    &fdt_serial_htif,    &fdt_serial_renesas_scif,    &fdt_serial_shakti,    &fdt_serial_sifive,    &fdt_serial_litex,    &fdt_serial_uart8250,    &fdt_serial_xlnx_uartlite,};
unsigned long fdt_serial_drivers_size = sizeof(fdt_serial_drivers) / sizeof(struct fdt_serial *);

2.3 设备树

串口驱动上面可以选择同时支持多个,根据设备树来匹配具体是哪一个

sudo apt-get install device-tree-compiler

获取c-sky/buildroot的设备树。

dump设备树,注意逗号

./host/csky-qemu/bin/qemu-system-riscv64 -M virt,dumpdtb=dump.dtb

反编译

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

dtb文件放置于platform/generic目录下

make PLATFORM=generic FW_TEXT_START=0x80000000 FW_FDT_PATH=/home/qinyunti/opensbi/platform/generic/dump.dtb

Dts串口相关内容如下,这是qemu的串口,根据实际平台修改。

chosenuart两个节点必须要有。

/dts-v1/;
/ { #address-cells = <0x02>; #size-cells = <0x02>; compatible = "riscv-virtio"; model = "riscv-virtio,qemu";
chosen { bootargs = [00]; stdout-path = "/uart@10000000"; };
uart@10000000 { interrupts = <0x0a>; interrupt-parent = <0x03>; clock-frequency = <1000000>; current-speed = <115200>; reg-shift = <0>; reg-io-width = <1>; reg-offset = <0>; reg = <0x00 0x10000000 0x00 0x100>; compatible = "xxx,xxx-uart"; };......

lib/utils/serial/fdt_serial.c

fdt_serial_init

会匹配设备树的串口节点的compatible和驱动中的serial_xxx_match中的compatible

一致则调用该驱动的实现。

三. 添加自定义驱动

以下以添加自定义驱动为例分享整个过程

3.1. 添加源码

lib/utils/serial/下添加fdt_serial_xxx.cxxx_uart.c

前者实现

struct fdt_serial fdt_serial_xxx = {

.match_table = serial_xxx_match,

.init = serial_xxx_init

};

后者实现

int xxx_uart_init(unsigned long base, u32 in_freq, u32 baudrate)

并调用sbi_console_set_device注册标准输入输出接口。

驱动代码以qemu的为例,根据实际修改

lib/utils/serial/xxx-uart.c内容如下

/* * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2019 . * * Authors: *    */
#include #include #include #include #include
/* clang-format off */
#define UART_RBR_OFFSET     0   /* In:  Recieve Buffer Register */#define UART_THR_OFFSET     0   /* Out: Transmitter Holding Register */#define UART_DLL_OFFSET     0   /* Out: Divisor Latch Low */#define UART_IER_OFFSET     1   /* I/O: Interrupt Enable Register */#define UART_DLM_OFFSET     1   /* Out: Divisor Latch High */#define UART_FCR_OFFSET     2   /* Out: FIFO Control Register */#define UART_IIR_OFFSET     2   /* I/O: Interrupt Identification Register */#define UART_LCR_OFFSET     3   /* Out: Line Control Register */#define UART_MCR_OFFSET     4   /* Out: Modem Control Register */#define UART_LSR_OFFSET     5   /* In:  Line Status Register */#define UART_MSR_OFFSET     6   /* In:  Modem Status Register */#define UART_SCR_OFFSET     7   /* I/O: Scratch Register */#define UART_MDR1_OFFSET    8   /* I/O:  Mode Register */
#define UART_LSR_FIFOE      0x80    /* Fifo error */#define UART_LSR_TEMT       0x40    /* Transmitter empty */#define UART_LSR_THRE       0x20    /* Transmit-hold-register empty */#define UART_LSR_BI     0x10    /* Break interrupt indicator */#define UART_LSR_FE     0x08    /* Frame error indicator */#define UART_LSR_PE     0x04    /* Parity error indicator */#define UART_LSR_OE     0x02    /* Overrun error indicator */#define UART_LSR_DR     0x01    /* Receiver data ready */#define UART_LSR_BRK_ERROR_BITS 0x1E    /* BI, FE, PE, OE bits */
/* clang-format on */
static volatile char *xxx_uart_base;static u32 xxx_uart_in_freq;static u32 xxx_uart_baudrate;static u32 xxx_uart_reg_width;static u32 xxx_uart_reg_shift;
static u32 get_reg(u32 num){    u32 offset = num << xxx_uart_reg_shift;
    if (xxx_uart_reg_width == 1)        return readb(xxx_uart_base + offset);    else if (xxx_uart_reg_width == 2)        return readw(xxx_uart_base + offset);    else        return readl(xxx_uart_base + offset);}
static void set_reg(u32 num, u32 val){    u32 offset = num << xxx_uart_reg_shift;
    if (xxx_uart_reg_width == 1)        writeb(val, xxx_uart_base + offset);    else if (xxx_uart_reg_width == 2)        writew(val, xxx_uart_base + offset);    else        writel(val, xxx_uart_base + offset);}
static void xxx_uart_putc(char ch){    while ((get_reg(UART_LSR_OFFSET) & UART_LSR_THRE) == 0)        ;
    set_reg(UART_THR_OFFSET, ch);}
static int xxx_uart_getc(void){    if (get_reg(UART_LSR_OFFSET) & UART_LSR_DR)        return get_reg(UART_RBR_OFFSET);    return -1;}
static struct sbi_console_device xxx_uart_console = {    .name = "xxx_uart",    .console_putc = xxx_uart_putc,    .console_getc = xxx_uart_getc};
int xxx_uart_init(unsigned long base, u32 in_freq, u32 baudrate, u32 reg_shift,          u32 reg_width, u32 reg_offset){    u16 bdiv = 0;    volatile uint32_t* tmp = (uint32_t*)0x10000004;    *tmp = 0x11223344;    if(*tmp != 0x11223344)    {        while(1);    }    xxx_uart_base      = (volatile char *)base + reg_offset;    xxx_uart_reg_shift = reg_shift;    xxx_uart_reg_width = reg_width;    xxx_uart_in_freq   = in_freq;    xxx_uart_baudrate  = baudrate;
    if (xxx_uart_baudrate) {        bdiv = (xxx_uart_in_freq + 8 * xxx_uart_baudrate) /               (16 * xxx_uart_baudrate);    }
    /* Disable all interrupts */    set_reg(UART_IER_OFFSET, 0x00);    /* Enable DLAB */    set_reg(UART_LCR_OFFSET, 0x80);
    if (bdiv) {        /* Set divisor low byte */        set_reg(UART_DLL_OFFSET, bdiv & 0xff);        /* Set divisor high byte */        set_reg(UART_DLM_OFFSET, (bdiv >> 8) & 0xff);    }
    /* 8 bits, no parity, one stop bit */    set_reg(UART_LCR_OFFSET, 0x03);    /* Enable FIFO */    set_reg(UART_FCR_OFFSET, 0x01);    /* No modem control DTR RTS */    set_reg(UART_MCR_OFFSET, 0x00);    /* Clear line status */    get_reg(UART_LSR_OFFSET);    /* Read receive buffer */    get_reg(UART_RBR_OFFSET);    /* Set scratchpad */    set_reg(UART_SCR_OFFSET, 0x00);
    sbi_console_set_device(&xxx_uart_console);
    return sbi_domain_root_add_memrange(base, PAGE_SIZE, PAGE_SIZE,                        (SBI_DOMAIN_MEMREGION_MMIO |                        SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW));}

lib/utils/serial/fdt_serial_xxx.c内容如下

/* * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) . * * Authors: *    */
#include #include #include
static int serial_xxx_init(const void *fdt, int nodeoff,                const struct fdt_match *match){    int rc;    struct platform_uart_data uart = { 0 };
    rc = fdt_parse_uart_node(fdt, nodeoff, &uart);    if (rc)        return rc;
    return xxx_uart_init(uart.addr, uart.freq, uart.baud,                 uart.reg_shift, uart.reg_io_width,                 uart.reg_offset);}
static const struct fdt_match serial_xxx_match[] = {    { .compatible = "xxx,xxx-uart" },    { },};
struct fdt_serial fdt_serial_xxx = {    .match_table = serial_xxx_match,    .init = serial_xxx_init,};

添加include/sbi_utils/serial/xxx-uart.h文件

内容如下

/* * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2022  Technology Co., Ltd. * * Author:  */
#ifndef __SERIAL_XXX_UART_H__#define __SERIAL_XXX_UART_H__
#include
int xxx_uart_init(unsigned long base, u32 in_freq, u32 baudrate);
#endif

1. 配置Kconfig

lib/utils/serial/Kconfig

config FDT_SERIAL_XILINX_UARTLITE后添加

config FDT_SERIAL_XXX

  bool "XXX UART FDT driver"

  select SERIAL_XXX

  default n

config SERIAL_XILINX_UARTLITE后添加

config SERIAL_XXX

  bool "XXX UART support"

  default n

3.配置objects.mk

lib/utils/serial/objects.mk

添加

carray-fdt_serial_drivers-$(CONFIG_FDT_SERIAL_XXX) += fdt_serial_xxx

libsbiutils-objs-$(CONFIG_FDT_SERIAL_XXX) += serial/fdt_serial_xxx.o

libsbiutils-objs-$(CONFIG_SERIAL_XXX) += serial/xxx-uart.o

4.修改设备树

uart@10000000 {

compatible改为和

lib/utils/serial/fdt_serial_xxx.c中的serial_xxx_match一致

static const struct fdt_match serial_xxx_match[] = {

  { .compatible = "xxx,xxx-uart" },

  { },

};

chosen {    bootargs = [00];    stdout-path = "/uart@10000000";  };
uart@10000000 { interrupts = <0x0a>; interrupt-parent = <0x03>; clock-frequency = <1000000>; current-speed = <115200>; reg-shift = <0>; reg-io-width = <32>; reg-offset = <0>; reg = <0x00 0x10000000 0x00 0x100>; compatible = "xxx,xxx-uart"; };

编译设备树

dtc -I dts -O dtb -o xxx-uart.dtb platform/generic/qemu_dump.dts

5.编译

export CROSS_COMPILE=~/buildroot/thead_920v2_enhanced_5.10_glibc_br_defconfig/host/bin/riscv64-unknown-linux-gnu-

export PLATFORM_RISCV_XLEN=64

make PLATFORM=generic menuconfig

Utils and Drivers Support --->

Serial Device Support--->

make PLATFORM=generic FW_TEXT_START=0x80000000 FW_FDT_PATH=/home/qinyunti/opensbi/platform/generic/xxx-uart.dtb

运行即可看到qemu的打印。

四. 标准输入输出重定向

4.1 输入输出接口

前面看到了打印,继续来看下,打印是如何实现的

串口初始化时注册底层读写接口

sbi_console_set_device(&xxx_uart_console);

static struct sbi_console_device xxx_uart_console = {

.name = "xxx_uart",

.console_putc = xxx_uart_putc,

.console_getc = xxx_uart_getc

};

还可以实现console_puts打印字符串可以提高效率。

lib/sbi/sbi_console.c中设置全局变量

console_dev = dev;

sbi_printf->print->printc->sbi_putc->nputs_all->nputs->console_dev->console_putc或者console_dev->console_puts

sbi_ecall_dbcn_handler->sbi_ngets/sbi_gets->sbi_getc->console_dev->console_getc

4.2 打印信息

这里来看下相关信息是在哪打印的

以下BUILD_INFO=y可以打印更多信息

make PLATFORM=generic FW_TEXT_START=0x80000000 FW_FDT_PATH=/home/qinyunti/opensbi/platform/generic/xxx-uart.dtb BUILD_INFO=y

Makefile

# Build Info:# OPENSBI_BUILD_TIME_STAMP -- the compilation time stamp# OPENSBI_BUILD_COMPILER_VERSION -- the compiler version infoBUILD_INFO ?= nifeq ($(BUILD_INFO),y)OPENSBI_BUILD_DATE_FMT = +%Y-%m-%d %H:%M:%S %zifdef SOURCE_DATE_EPOCH    OPENSBI_BUILD_TIME_STAMP ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" \        "$(OPENSBI_BUILD_DATE_FMT)" 2>/dev/null || \        date -u -r "$(SOURCE_DATE_EPOCH)" \        "$(OPENSBI_BUILD_DATE_FMT)" 2>/dev/null || \        date -u "$(OPENSBI_BUILD_DATE_FMT)")else    OPENSBI_BUILD_TIME_STAMP ?= $(shell date "$(OPENSBI_BUILD_DATE_FMT)")endifOPENSBI_BUILD_COMPILER_VERSION=$(shell $(CC) -v 2>&1 | grep ' version ' | \    sed 's/[[:space:]]*$$//')endif

ifeq ($(BUILD_INFO),y)GENFLAGS    +=  -DOPENSBI_BUILD_TIME_STAMP="\"$(OPENSBI_BUILD_TIME_STAMP)\""GENFLAGS    +=  -DOPENSBI_BUILD_COMPILER_VERSION="\"$(OPENSBI_BUILD_COMPILER_VERSION)\""endif
ifeq ($(BUILD_INFO),y)$(build_dir)/lib/sbi/sbi_init.o: $(libsbi_dir)/sbi_init.c FORCE    $(call compile_cc,$@,$<)endif

lib/sbi/sbi_init.c

sbi_boot_print_banner打印LOGO和编译版本信息

OPENSBI_BUILD_TIME_STAMPOPENSBI_BUILD_COMPILER_VERSION就是BUILD_INFO=y时自动生成。

static void sbi_boot_print_banner(struct sbi_scratch *scratch){    if (scratch->options & SBI_SCRATCH_NO_BOOT_PRINTS)        return;
#ifdef OPENSBI_VERSION_GIT    sbi_printf("\nOpenSBI %s\n", OPENSBI_VERSION_GIT);#else    sbi_printf("\nOpenSBI v%d.%d\n", OPENSBI_VERSION_MAJOR,           OPENSBI_VERSION_MINOR);#endif
#ifdef OPENSBI_BUILD_TIME_STAMP    sbi_printf("Build time: %s\n", OPENSBI_BUILD_TIME_STAMP);#endif
#ifdef OPENSBI_BUILD_COMPILER_VERSION    sbi_printf("Build compiler: %s\n", OPENSBI_BUILD_COMPILER_VERSION);#endif
    sbi_printf(BANNER);}

打印如下

五. 总结

串口驱动的实现实际是通过脚本,将各个串口驱动c文件中的struct fdt_serial全局变量,自动组合生成一个全局数组fdt_serial_drivers,该数组的成员就是各个串口驱动的实现struct fdt_serial。通过全局变量fdt_serial_drivers即可索引各个驱动,通过设备树节点的compatible来匹配驱动。







评论 (0)
  • 长期以来,光耦合器一直被人们信赖,因为它能够在电路的不同部分之间提供电气隔离,确保信号的安全传输,同时保护元件免受高压影响。然而,近年来,数字隔离器已成为一种强大的替代品,在速度、寿命和效率方面都具有优势。本文探讨了这两种技术之间日益激烈的竞争,探讨了性能差异以及光耦合器制造商保持竞争力的潜在策略。数字隔离器的兴起数字隔离器的功能类似于光耦合器,可在电路之间提供电气隔离,但它们使用的机制不同。数字隔离器通常使用电容或磁耦合,而不是像光耦合器那样依靠光来传输信号。这种技术转变使数字隔离器在几个关键
    腾恩科技-彭工 2024-10-11 16:29 67浏览
  •  在很多的应用场景都有电池供电,同时也有充电器同时存在的场景,这种供电系统希望在没有充电器的时候,为了保证充电头不带电就需要防止电流倒灌的产品比如肖特基或者是理想二极管,通常在小电流情况下比如1A以及一下的场景,肖特基便宜,不在乎功耗,但是当充电电流比较大的时候,肖特基压降明显的降低了效率,产生了很大的热损耗,给工程师散热造成了很大的挑战,这时候就需要用到理想二极管。无锡明芯微提供了多种选择的理想二极管控制和模块,覆盖不同的电压需求。 当有充电器在的时候,为了不让电池供电,提高电池的使
    王萌 2024-10-12 14:34 104浏览
  • 滚柱导轨是一种重要的传动元件,它由滚柱作为滚动体。用于连接机床的运动部件和床身基座,其设计旨在提供高承载能力和高刚度,适用于重型机床和精密仪器,而滚柱导轨的适配方法对于确保机械设备的高精度运行至关重要。 滚柱导轨的适配方法主要包括安装和调试,首先,选择合适的规格和精度匹配是确保滚柱导轨正常工作的基础,规格的选择应根据具体的应用场景和需求来确定。此外,还需要进行前期的准备。 ①在安装滚柱导轨前,要对滚柱导轨及其安装面进行仔细检查,确保无毛刺、伤痕和杂物。②使用油石或适当的工具清
    高技传动 2024-10-11 17:56 88浏览
  • 2024年10月12日 Global Info Research调研机构发布了《全球射频识别 (RFID) 手术海绵计数系统行业总体规模、主要厂商及IPO上市调研报告,2024-2030》。本报告研究全球射频识别 (RFID) 手术海绵计数系统总体规模,主要地区规模,主要企业规模和份额,主要产品分类规模,下游主要应用规模等。统计维度包括收入和市场份额等。不仅全面分析全球范围内主要企业竞争态势,收入和市场份额等。同时也重点分析全球市场主要厂商(品牌)产品特点、产品规格、收入、毛利率及市场份额、及发
    GIRtina 2024-10-12 09:18 58浏览
  • 光耦合器在确保电路不同部分之间的电气隔离方面起着至关重要的作用。它们对于保护系统免受高压影响、确保信号完整性以及防止敏感应用中的灾难性故障至关重要。鉴于其关键作用,光耦合器中的任何故障都可能造成严重后果,尤其是在汽车、医疗和工业系统等安全敏感领域。然而,由于制造实践的差异,导致性能不一致,质量和可靠性问题仍然是一个问题。本文深入探讨了保持光耦合器质量和可靠性的挑战,并探讨了制造商的潜在解决方案。光耦合器可靠性的重要性在现代电子系统中,光耦合器通常用于通过将输入与输出隔离来保护电路,确保高压尖峰或
    腾恩科技-彭工 2024-10-11 16:31 72浏览
  • 2024年10月12日  Global Info Research行业调研机构发布的《全球无人机自动机库行业总体规模、主要厂商及IPO上市调研报告,2024-2030》分析了全球无人机自动机库总体规模,主要地区规模,主要企业规模和份额,主要产品分类规模,下游主要应用规模等。统计维度包括收入和市场份额等。不仅全面分析全球范围内主要企业竞争态势,收入和市场份额等。同时也重点分析全球市场主要厂商(品牌)产品特点、产品规格、收入、毛利率及市场份额、及发展动态。历史数据为2019至2023年,预
    GIRtina 2024-10-12 11:17 57浏览
  • 2024年10月12日 调研机构Global Info Research出版了《全球全身超声设备行业总体规模、主要厂商及IPO上市调研报告,2024-2030》。本报告主要分析全球全身超声设备总体规模,主要地区规模,主要企业规模和份额,主要产品分类规模,下游主要应用规模等。规模分析包括收入和市场份额等。深入分析了全球范围内主要企业竞争态势,收入和市场份额等,同时也重点分析全球市场主要厂商(品牌)产品特点、产品规格、收入、毛利率及市场份额、及发展动态。历史数据为2019至2023年,预测数据为20
    GIRtina 2024-10-12 10:29 53浏览
  • 2024年10月12日  Global Info Research行业调研机构发布的《全球线性压电平台行业总体规模、主要厂商及IPO上市调研报告,2024-2030》分析了全球线性压电平台总体规模,主要地区规模,主要企业规模和份额,主要产品分类规模,下游主要应用规模等。统计维度包括收入和市场份额等。不仅全面分析全球范围内主要企业竞争态势,收入和市场份额等。同时也重点分析全球市场主要厂商(品牌)产品特点、产品规格、收入、毛利率及市场份额、及发展动态。历史数据为2019至2023年,预测数
    GIRtina 2024-10-12 11:31 52浏览
  • 在电力系统中,高电压和高电流很常见,电气隔离对于保护设备和人员至关重要。光耦合器,也称为光隔离器,在提供这种隔离的同时,确保电力系统不同部分之间的信号平稳传输,起着至关重要的作用。近年来,国产光耦合器由于性能、可靠性和价格的提高,在电力应用中越来越普遍。本文探讨了国产光耦合器在电力系统中的实际应用,强调了它们在提高安全性、确保运行效率和支持新能源技术发展方面的作用。国产光耦合器在电力系统中的实际应用1.电网监控和控制系统电网需要持续的监控和控制,以保持稳定性并防止停电。国产光耦合器通常用于电网监
    克里雅半导体科技 2024-10-11 16:42 96浏览
  • 随着电动自行车市场的蓬勃发展,如何提升其安全性、可靠性和智能化水平已成为行业关注的焦点。在众多关键元件中,光电耦合器(简称光耦)正以其独特的功能,成为电动自行车设计中的关键角色。下面,让我们一同探索光耦在电动自行车中的主要应用:电池管理系统(BMS)的隔离与保护电动自行车的心脏是其电池组,而BMS则扮演着保护电池、延长寿命和优化性能的重要角色。光耦在BMS中发挥了隔离高压电池电路与低压控制电路的关键作用,有效防止电气过载、短路等潜在问题,从而提升了电动自行车的安全性,确保了控制系统的稳定运行。控
    晶台光耦 2024-10-12 10:33 61浏览
  • 近年来,国产光耦在技术和市场覆盖方面都取得了长足进步。随着半导体制造和隔离技术的进步,国产光耦已成为汽车电子、工业自动化、电力系统和医疗设备等行业的关键部件。这些部件因其可靠性、价格合理性和在各种应用中的增强性能而受到关注。本文深入探讨了国产光耦的实际应用和市场进展,展示了它们在推动多个行业技术创新方面的作用。国产光耦的实际应用1.工业自动化:增强控制和安全性工业自动化系统依靠高效的信号传输和隔离来确保组件之间的无缝通信。国产光耦广泛应用于可编程逻辑控制器(PLC)、电机驱动器和工厂自动化设备,
    克里雅半导体科技 2024-10-11 16:39 92浏览
  • 2024年10月12日 Global Info Research调研机构发布了《全球热封式托盘封口机行业总体规模、主要厂商及IPO上市调研报告,2024-2030》。本报告研究全球热封式托盘封口机总体规模,主要地区规模,主要企业规模和份额,主要产品分类规模,下游主要应用规模等。统计维度包括收入和市场份额等。不仅全面分析全球范围内主要企业竞争态势,收入和市场份额等。同时也重点分析全球市场主要厂商(品牌)产品特点、产品规格、收入、毛利率及市场份额、及发展动态。历史数据为2019至2023年,预测数据
    GIRtina 2024-10-12 10:33 54浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦