Linux中tty與8250-uart的虐戀(包括雙中斷發送接收機制)

串口通用驅動文件在哪里?

drivers/tty/serial/

哪一個是正確的compatible

  • arch/arm64/boot/dts/rockchip/rk3568.dtsi
uart3: serial@fe670000 {compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart";reg = <0x0 0xfe670000 0x0 0x100>;interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;clock-names = "baudclk", "apb_pclk";reg-shift = <2>;reg-io-width = <4>;dmas = <&dmac0 6>, <&dmac0 7>;pinctrl-names = "default";pinctrl-0 = <&uart3m0_xfer>;status = "disabled";
};
static const struct of_device_id dw8250_of_match[] = {{ .compatible = "snps,dw-apb-uart" },{ .compatible = "cavium,octeon-3860-uart" },{ .compatible = "marvell,armada-38x-uart" },{ .compatible = "renesas,rzn1-uart" },{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, dw8250_of_match);
  • dw8250_platform_driver 屬于platform_driver,相當于drv->probe
static struct platform_driver dw8250_platform_driver = {.driver = {.name		= "dw-apb-uart",.pm		= &dw8250_pm_ops,.of_match_table	= dw8250_of_match,.acpi_match_table = dw8250_acpi_match,},.probe			= dw8250_probe,.remove			= dw8250_remove,
};module_platform_driver(dw8250_platform_driver)

dw8250_probe

  • uart_add_one_port 把一個 已經初始化好的 uart_port 結構體 綁定到 已經注冊好的 uart_driver 上,從而讓它成為 Linux 內核可見的一個串口設備(/dev/ttySx/dev/ttyAMA0 等)
dw8250_probeuart_8250_port uartresource *regs = platform_get_resource//從設備樹中獲取 8250 控制器寄存器物理基地址uart_port *p = &uart.portdw8250_data *datap->handle_irq  = dw8250_handle_irqp->serial_in    = dw8250_serial_in;p->serial_out   = dw8250_serial_out;p->membase = devm_ioremap(dev, regs->start, resource_size(regs))//內存映射得在Linux用虛擬地址device_property_read_u32device_property_read_booldevm_clk_getdw8250_quirks(p, data)//特定平臺配置和兼容性問題of_alias_get_id(np, "serial")p->serial_inp->serial_outdata->line = serial8250_register_8250_port(&uart)uart_add_one_portplatform_set_drvdata(pdev, data)

serial8250_init

  • uart_register_driver 先注冊 driver
  • uart_register_driver “先填申報戶口資料”,uart_add_one_port 是“依照資料給每塊 UART 上戶口”;只有上完戶口,內核里才會出現對應的 /dev/tty* 設備
  • tty_register_driver創建 tty 設備節點(/dev/ttyS0ttyS1 …)
module_init(serial8250_init)serial8250_isa_init_ports//實現請求端口、添加和注冊串口端口serial8250_init_portuart_8250_port port->ops = &serial8250_popsuart_register_driver(&serial8250_reg)//uart_driver 轉 tty_driver 注冊ttynormal = alloc_tty_driver(drv->nr)tty_set_operations(normal, &uart_ops)port->ops = &uart_port_ops//tty_port *port = &uart_state->porttty_register_driver(normal)put_tty_driver(normal)serial8250_isa_devs = platform_device_alloc("serial8250",PLAT8250_DEV_LEGACY)platform_device_add(serial8250_isa_devs)serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);platform_driver_register(&serial8250_isa_driver)
uart_driverstruct uart_state	*state;struct tty_port        portstruct uart_port   *uart_portstruct tty_driver	*tty_driver;
static struct uart_driver serial8250_reg = {.owner			= THIS_MODULE,.driver_name		= "serial",.dev_name		= "ttyS",.major			= TTY_MAJOR,.minor			= 64,.cons			= SERIAL8250_CONSOLE,
};
static const struct tty_operations uart_ops = {.install	= uart_install,.open		= uart_open,.close		= uart_close,.write		= uart_write,.put_char	= uart_put_char,.flush_chars	= uart_flush_chars,.write_room	= uart_write_room,.chars_in_buffer= uart_chars_in_buffer,.flush_buffer	= uart_flush_buffer,.ioctl		= uart_ioctl,.throttle	= uart_throttle,.unthrottle	= uart_unthrottle,.send_xchar	= uart_send_xchar,.set_termios	= uart_set_termios,.set_ldisc	= uart_set_ldisc,.stop		= uart_stop,.start		= uart_start,.hangup		= uart_hangup,.break_ctl	= uart_break_ctl,.wait_until_sent= uart_wait_until_sent,
#ifdef CONFIG_PROC_FS.proc_show	= uart_proc_show,
#endif.tiocmget	= uart_tiocmget,.tiocmset	= uart_tiocmset,.get_icount	= uart_get_icount,
#ifdef CONFIG_CONSOLE_POLL.poll_init	= uart_poll_init,.poll_get_char	= uart_poll_get_char,.poll_put_char	= uart_poll_put_char,
#endif
};
static const struct tty_port_operations uart_port_ops = {.carrier_raised = uart_carrier_raised,.dtr_rts	= uart_dtr_rts,.activate	= uart_port_activate,.shutdown	= uart_tty_port_shutdown,
};

uart_ops serial8250_popsuart_port 什么區別

uart_8250_portuart_8250_dma *dmauart_8250_ops *opsuart_port port(*serial_in)(*serial_out)(*set_termios)(*set_ldisc)(*handle_irq)uart_state  *statetty_port   portuart_port   *uart_portuart_ops *ops(*startup)(*start_tx)(*stop_tx)(*stop_rx)(*ioctl)
static const struct uart_ops serial8250_pops = {.tx_empty	= serial8250_tx_empty,.set_mctrl	= serial8250_set_mctrl,.get_mctrl	= serial8250_get_mctrl,.stop_tx	= serial8250_stop_tx,.start_tx	= serial8250_start_tx,.throttle	= serial8250_throttle,.unthrottle	= serial8250_unthrottle,.stop_rx	= serial8250_stop_rx,.enable_ms	= serial8250_enable_ms,.break_ctl	= serial8250_break_ctl,.startup	= serial8250_startup,.shutdown	= serial8250_shutdown,.set_termios	= serial8250_set_termios,.set_ldisc	= serial8250_set_ldisc,.pm		= serial8250_pm,.type		= serial8250_type,.release_port	= serial8250_release_port,.request_port	= serial8250_request_port,.config_port	= serial8250_config_port,.verify_port	= serial8250_verify_port,
#ifdef CONFIG_CONSOLE_POLL.poll_get_char = serial8250_get_poll_char,.poll_put_char = serial8250_put_poll_char,
#endif
};
  • univ8250_setup_irq硬件中斷號都沒有(port->irq == 0,常見于早期板級代碼或虛擬端口),則完全采用 純輪詢
  • 如果硬件中斷號有效,就調用 serial_link_irq_chain() 把普通中斷處理鏈掛到該 IRQ 上,包括注冊 serial8250_interrupt()
static const struct uart_8250_ops univ8250_driver_ops = {.setup_irq	= univ8250_setup_irq,.release_irq	= univ8250_release_irq,
};

serial_in serial_out 讀取發送 如何 實現的?

  • ALTERNATIVE 是內核提供的一個宏,利用 ELF .altinstructions 段 機制
  • 在內核啟動早期 會掃描這個段,根據 ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE 的布爾值,把 ldrb 原地 patchldarb,或者在不需要時保持 ldrb,保證 讀操作之前的所有讀寫都不能重排到它之后,用于解決 Device-nGRE/Device-nGnRE 映射上可能出現的加載亂序或重試 bug
serial_in(struct uart_8250_port *up, int offset)up->port.serial_in(&up->port, offset);dw8250_serial_inreadb(p->membase + (offset << p->regshift))readb_relaxedasm volatile(ALTERNATIVE("ldrb %w0, [%1]","ldarb %w0,[%1]",ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE): "=r" (val) : "r" (addr));serial_out(struct uart_8250_port *up, int offset, int value)up->port.serial_out(&up->port, offset, value);dw8250_serial_outwriteb(value, p->membase + (offset << p->regshift))writeb_relaxedasm volatile("strb %w0, [%1]" : : "rZ" (val), "r" (addr))

dw8250_handle_irq -> serial8250_handle_irq

  • serial8250_handle_irq 真正處理函數
univ8250_setup_irqrequest_irqserial8250_interruptp->handle_irq  = dw8250_handle_irqdw8250_handle_irqserial8250_handle_irqif (iir & UART_IIR_NO_INT) //  把假中斷擋在門外serial_port_in(port, UART_LSR) //一次讀出所有線路/錯誤狀態位skip_rx = true //自動 RTS/CTS 硬件流控把 RX 堵住//只要有數據 (`DR`) 或 Break (`BI`) 并且未被上一階段跳過,就處理接收dma_err = handle_rx_dma(up, iir) //先嘗試 DMA 接收 status = serial8250_rx_chars(up, status) //DMA 失敗或無 DMA落到 PIO 接收serial8250_modem_status(up)//讀取 `UART_MSR` 寄存器,檢測 CTS/DSR/RI/DCD 變化  //CTS 變高/低、載波丟失等事件上報 TTYserial8250_tx_chars(up)//serial8250_tx_chars把 TTY 環形緩沖區里的字節寫入UART TXFIFOpr_err //現 Overrun/Parity/Frame/Break 錯誤,就打印一行提示

UART_LSR 是什么寄存器?

  • Line Status Register(線路狀態寄存器)一次讀即可得到發送/接收單元當前狀態
#define UART_LSR	5	/* In:  Line Status Register */
bit7  UART_LSR_FIFOE  FIFO 數據錯誤
bit6  UART_LSR_TEMT   發送移位器+發送保持器都空
bit5  UART_LSR_THRE   發送保持器 空(可繼續寫下一個字節)
bit4  UART_LSR_BI     Break 中斷
bit3  UART_LSR_FE     幀錯誤
bit2  UART_LSR_PE     奇偶錯誤
bit1  UART_LSR_OE     Overrun 錯誤
bit0  UART_LSR_DR     接收數據就緒

up->dma->txchan 是什么?

  • 發送 DMA 通道:由 dma_request_slave_channel_compat()DMA Engine 子系統 申請得到
  • 不為 NULL → 用 DMA 搬數據到 UART
  • NULL → 退回到傳統 PIOCPU 輪詢)方式發送

UART_IIR_THRI 是什么?

  • UART_IIR_THRI = “Transmit Holding Register Empty Interrupt”
  • 當發送 FIFO(或保持寄存器)里的最后一個字節被移位器取走后,硬件置位 THREUART_LSR bit5),并同時把 UART_IIR_THRI 填進 IIR,表示“你可以繼續寫下一個字節了”

為什么 p->handle_irq dw8250_handle_irq 要兼顧 DesignWare UART “假超時”和“BUSY”處理?什么是 DesignWare UART ?

  • DesignWare UART(官方文檔中稱為 DW_apb_uart)是 Synopsys公司推出的、基于 AMBA APB 總線的可綜合 IP 核,目標是給 SoC 提供一套 兼容傳統 16550/8250 的通用異步串行收發器(UART
  • dw8250_handle_irq 復用了 8250 核心邏輯,又補上了芯片特有的“假超時”和“BUSY”處理
階段作用
讀取 IIR獲知當前中斷類型
DesignWare UART RX TIMEHO?UT 假中斷檢查USR/LSR/RFL,必要時空讀 UART_RX 清假超時
標準中斷交給 serial8250_handle_irq()
DesignWare UART BUSY 中斷USRBUSY狀態
結束返回已處理標志

自動 RTS/CTS 流控是什么?

自動 RTS/CTS 流控 = 硬件級雙向握手,用兩根線 RTS(Request To Send) CTS(Clear To Send)自動啟停對方的發送,防止 FIFO 溢出。

  • RTS 由 本地 UART 輸出:
    “我準備好接收了,你可以發”。
  • CTS 由 對方 UART 輸出:
    “我準備好了,你可以發”。

工作方式(全雙工場景):

  • 本地接收側

    • 當本地 RX FIFO 快滿(可編程閾值)時,UART 自動把 RTS 拉高 → 對方看到 RTS=1 就 暫停發送
    • FIFO 被讀空后,RTS 自動拉低 → 對方繼續發。
  • 本地發送側

    • 只有檢測到 CTS=0(對方準備好)時,UART 才會把 TX FIFO 里的數據真正發出;
    • CTS=1 則硬件暫停發送

dma初始化位置在哪里?兩個函數是什么?

serial8250_startupserial8250_do_startupserial8250_request_dmadma->txchan = dma_request_slave_channel_compatdma->tx_addr = dma_map_single
serial8250_initserial8250_isa_init_portsserial8250_set_defaultsup->dma->tx_dma = serial8250_tx_dmaup->dma->rx_dma = serial8250_rx_dma
  • serial8250_tx_dma
struct uart_8250_dma *dma = p->dma;                // 拿到 DMA 私有結構
struct circ_buf *xmit = &p->port.state->xmit;      // 指向 TTY 層的發送環形緩沖區
struct dma_async_tx_descriptor *desc;               // DMA 描述符
int ret;                                            // 返回值if (dma->tx_running)                                // 如果上一次 DMA 還沒完成,直接退出return 0;if (uart_tx_stopped(&p->port) || uart_circ_empty(xmit)) {   // 上層已暫停或緩沖區為空serial8250_rpm_put_tx(p);                       // 發送端置空閑,降低功耗return 0;
}dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);  // 計算本次可搬的字節數
#ifdef CONFIG_ARCH_ROCKCHIP
if (dma->tx_size < MAX_TX_BYTES) {                  // Rockchip:字節數太少就別 DMA,用 PIOret = -EBUSY;goto err;
}
#endifdesc = dmaengine_prep_slave_single(                 // 構造 DMA 描述符dma->txchan,                                // 發送通道dma->tx_addr + xmit->tail,                  // 源地址:環形緩沖區尾指針dma->tx_size,                               // 長度DMA_MEM_TO_DEV,                             // 方向:內存 -> 設備DMA_PREP_INTERRUPT | DMA_CTRL_ACK);         // 完成后中斷 + 立即應答
if (!desc) {                                        // 描述符申請失敗ret = -EBUSY;goto err;
}dma->tx_running = 1;                                // 置標志:DMA 正在跑
desc->callback = __dma_tx_complete;                 // DMA 完成回調
desc->callback_param = p;                           // 回調參數:uart_8250_port 指針dma->tx_cookie = dmaengine_submit(desc);            // 把描述符提交給 DMA 引擎dma_sync_single_for_device(                         // 刷新 cache,確保 DMA 看到最新數據dma->txchan->device->dev,dma->tx_addr, UART_XMIT_SIZE, DMA_TO_DEVICE);dma_async_issue_pending(dma->txchan);               // 真正啟動 DMA 傳輸if (dma->tx_err) {                                  // 如果之前出過錯dma->tx_err = 0;                                // 清錯誤if (p->ier & UART_IER_THRI) {                   // 關 THRE 中斷,避免 PIO 與 DMA 沖突p->ier &= ~UART_IER_THRI;
#ifdef CONFIG_ARCH_ROCKCHIPp->ier &= ~UART_IER_PTIME;
#endifserial_out(p, UART_IER, p->ier);}
}
return 0;                                           // 成功啟動 DMAerr:
dma->tx_err = 1;                                    // 記錄錯誤,下次退到 PIO
return ret;
  • serial8250_rx_dma
unsigned int rfl, i = 0, fcr = 0, cur_index = 0;    // 局部變量
unsigned char buf[MAX_FIFO_SIZE];                   // 臨時緩存,放本次接收字節
struct uart_port *port = &p->port;                  // 方便引用
struct tty_port *tty_port = &p->port.state->port;   // TTY 端口
struct dma_tx_state state;                          // DMA 狀態結構
struct uart_8250_dma *dma = p->dma;                 // DMA 私有結構fcr = UART_FCR_ENABLE_FIFO | UART_FCR_T_TRIG_10 | UART_FCR_R_TRIG_11; // 開 FIFO,設高觸發
serial_port_out(port, UART_FCR, fcr);               // 立即寫到硬件do {                                                // 輪詢直到 DMA 余量是整 burst 倍數dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);cur_index = dma->rx_size - state.residue;       // 已搬運字節
} while (cur_index % dma->rxconf.src_maxburst);     // 對齊到 burst 大小rfl = serial_port_in(port, UART_RFL_16550A);        // 讀出 FIFO 當前字節數
while (i < rfl)                                     // 把 FIFO 里剩余字節全部讀出buf[i++] = serial_port_in(port, UART_RX);__dma_rx_complete(p);                               // 復位 DMA 描述符,準備下一輪tty_insert_flip_string(tty_port, buf, i);           // 把 i 個字節塞進 TTY flip buffer
p->port.icount.rx += i;                             // 統計接收字節
tty_flip_buffer_push(tty_port);                     // 通知上層“有數據可讀”if (fcr)                                            // 恢復原始 FCR 設置serial_port_out(port, UART_FCR, p->fcr);
return 0;

為什么叫“8250”驅動?

  • 歷史原因:Intel1981 年推出了 NMOS 8250 UART 芯片,用來給早期 IBM PC/XT 提供串口 COM1/COM2
  • 后續 1645016550A1675016850 等芯片都把 寄存器布局 做成了 8250 的超集,于是 Linux 就把支持這一系列芯片的驅動統稱為 8250 驅動

tty8250驅動是什么關系?

  • 用戶空間對 tty 設備文件進行操作時,實際上是在調用對應的 tty_fops 中的操作函數
應用層│├── read()/write()/ioctl()│
tty 層(tty_io.c, n_tty.c, tty_port.c)│   ① 負責線路規程、回顯、緩沖、termios├── tty_struct├── tty_port└── tty_ldisc│
serial_core(serial_core.c)│   ② 把“tty 端口”與“uart_driver”粘合在一起└── uart_driver / uart_port│
8250 驅動族(8250_core.c, 8250_port.c, 8250_dw.c …)│   ③ 真正把字節寫進 UART 寄存器└── struct uart_ops│
硬件 UART(16550, DesignWare, QCOM …)

tty 如何調用 8250

open("/dev/ttyS0",)tty_open()tty_port_open(struct tty_port *port, struct tty_struct *tty,struct file *filp)port->ops->activateuart_port_activateuart_startupretval = uport->ops->startup(uport);uart_state->uart_port->ops->startupuart_ops.startupserial8250_startup

cat /proc/interrupts

![[Pasted image 20250814173636.png]]

cat /proc/tty/drivers

![[Pasted image 20250814145902.png]]

cat /proc/tty/ldiscs

  • 行規程

![[Pasted image 20250814152218.png]]

有了early boot of_platform_default_populate_init,為什么serial8250_init需要platform_device_add?

  • 因為serial8250_isa_devs 并不是“從設備樹里解析出來的普通串口”,而是 8250/16550 驅動為了兼容 ISA/Legacy UART 專門創建的一個“虛擬”平臺設備

  • 給“非設備樹、非 ACPI”的老式串口一個統一的 platform_device 句柄

  • 那些固定地址(0x3F8、0x2F8…)的 ISA UART 在設備樹里往往根本沒有節點,或者節點被禁用

  • 驅動必須手動把它們包裝成一個 platform_device,才能繼續沿用 platform_driverprobe 流程

  • 驅動注冊時如果找不到任何 device 就會無事可做;因此驅動自己先 platform_device_alloc() / platform_device_add() 創建一個名字為 "serial8250"、ID 為 PLAT8250_DEV_LEGACY 的設備,確保 serial8250_isa_driver 能匹配到它并進入 probe

platform_device_add調用 bus 匹配,drv 進行 probe

  • serial8250_initplatform_device_add()device_add()bus_probe_device()__device_attach()bus_for_each_drv()__device_attach_driver()driver_match_device()bus_type->match()
  • __device_attach_driver()driver_probe_device -> really_probe -> drv->probe
__device_attach_driverdriver_match_devicebus_type->match()driver_probe_devicedrv->probe
  • 參考文檔43
    module_platform_driver 與 module_init_module platform driver-CSDN博客

  • 參考文檔44
    uart驅動學習-CSDN博客

  • 參考45
    深入淺出UART驅動開發與調試:從基礎調試到虛擬驅動實現-CSDN博客

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/918802.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/918802.shtml
英文地址,請注明出處:http://en.pswp.cn/news/918802.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

GitHub 倉庫代碼上傳指南

文章目錄 ??? 一、環境準備 ?? 二、創建 GitHub 倉庫 ?? 三、本地代碼上傳流程 首次上傳 更新已有代碼 ?? 四、認證問題解決(必看!) 方案 1:個人訪問令牌(PAT) 方案 2:SSH 密鑰(推薦長期使用) ? 五、常見錯誤處理 ?? 六、最佳實踐建議 ?? 高級技巧 ??…

介紹一下 自動駕駛 感知多任務訓練模型設計

自動駕駛感知多任務訓練模型是指在一個統一的模型架構中&#xff0c;同時完成自動駕駛場景下的多個感知任務&#xff08;如目標檢測、語義分割、深度估計、車道線檢測等&#xff09;的模型設計。其核心目標是通過特征共享和任務協同&#xff0c;在提升單任務性能的同時&#xf…

huggingface文件下載過慢/中斷怎么辦

huggingface上匯集了各個大模型和預訓練模型的權重文件&#xff0c;但是訪問huggingface需要連接外網&#xff0c;即時連接外網之后下載仍然過慢甚至會出現中斷&#xff0c;因此本文將使用兩種方法教你解決上述問題。 文章目錄1.使用國內鏡像下載2.使用Python腳本自動化下載1.使…

Spring Boot + Redis Sentinel (一主兩從)測試案例

&#x1f680; Spring Boot Redis Sentinel 完整測試案例 &#x1f3f7;? 標簽&#xff1a;Redis 、Redis Sentinel、Spring Boot 實戰 &#x1f4da; 目錄導航 &#x1f4dd; 前言&#x1f3d7;? Redis Sentinel 架構說明&#x1f4e6; Docker Compose 搭建 Redis 哨兵環境…

力扣-295.數據流的中位數

題目鏈接 295.數據流的中位數 class MedianFinder {PriorityQueue<Integer> left;//隊頭最大PriorityQueue<Integer> right;//隊頭最小public MedianFinder() {left new PriorityQueue<>(new Comparator<Integer>() {Overridepublic int compare(In…

【數據分享】2014-2023年長江流域 (0.05度)5.5km分辨率的每小時日光誘導葉綠素熒光SIF數據

而今天要說明數據就是2014-2023年長江流域 &#xff08;0.05度&#xff09;5.5km分辨率的每小時日光誘導葉綠素熒光SIF數據。數據介紹一、數據集概況&#xff1a;長江流域植被動態的 “每小時快照”本文分享的核心數據集為2014 年 9 月至 2023 年 9 月長江流域日光誘導葉綠素熒…

計算機二級 Web —— HTML 全面精講(含真題實戰)

例題來源: web.code2ji.cn 0. HTML 基礎與全局常識 0.1 HTML 是什么 HTML&#xff08;HyperText Markup Language&#xff09;是網頁結構語言&#xff0c;用“標簽”描述內容、層次與含義。 0.2 基本文檔骨架&#xff08;必須熟練&#xff09; <!DOCTYPE html> <…

Linux中的日志管理

注&#xff1a;在 centos7/Rocky9 中&#xff0c;系統日志消息由兩個服務負責處理&#xff1a;systemd-journald 和 rsyslog一、常見日志文件的作用實驗一&#xff1a;測試查看暴力破解系統密碼的IP地址步驟一&#xff1a;故意輸錯密碼3次&#xff0c;在日志文件中查看步驟二&a…

C++ 性能優化擂臺:挑戰與突破之路

一、引言&#xff08;一&#xff09;C 在性能關鍵領域的地位在當今數字化時代&#xff0c;C 語言憑借其高效性、靈活性和對硬件的直接操控能力&#xff0c;在眾多對性能要求極高的領域中占據著舉足輕重的地位。無論是構建高性能的游戲引擎&#xff0c;實現金融領域毫秒級響應的…

五、Elasticsearch在Linux的安裝部署

五、Elasticsearch在Linux的安裝部署 文章目錄五、Elasticsearch在Linux的安裝部署1.Elasticsearch的作用2.安裝0. 安裝前準備1.使用包管理器安裝&#xff08;推薦&#xff0c;自動服務化&#xff09;Ubuntu / DebianRHEL / CentOS / Rocky / Alma2. 使用 tar.gz 安裝&#xff…

Kubernetes集群部署全攻略

目錄 一、 服務器環境及初始化 1、架構分析 2、初始化 2.1、清空Iptales默認規則及關閉防火墻 2.2、關閉SELINUX 2.3、關閉Swap交換空間 2.4、設置主機名 2.5、編寫hosts文件 2.6、設置內核參數 二、安裝Docker環境 1、安裝Docker 1.1、配置阿里源 1.2、安裝docke…

Ceph存儲池詳解

Ceph 存儲池&#xff08;Pool&#xff09;詳解 Ceph 的 存儲池&#xff08;Pool&#xff09; 是邏輯存儲單元&#xff0c;用于管理數據的分布、冗余和訪問策略。它是 Ceph 存儲集群的核心抽象&#xff0c;支持 對象存儲&#xff08;RGW&#xff09;、塊存儲&#xff08;RBD&…

使用 Docker 部署 PostgreSQL

通過 Docker 部署 PostgreSQL 是一種快速、高效的方式&#xff0c;適用于開發和測試環境。 步驟 1&#xff1a;拉取 PostgreSQL 鏡像 運行以下命令從 Docker Hub 拉取最新的 PostgreSQL 鏡像&#xff1a; docker pull postgres 如果需要其他的鏡像&#xff0c;可以指定版本…

P1886 滑動窗口 /【模板】單調隊列【題解】

P1886 滑動窗口 /【模板】單調隊列 題目描述 有一個長為 nnn 的序列 aaa&#xff0c;以及一個大小為 kkk 的窗口。現在這個窗口從左邊開始向右滑動&#xff0c;每次滑動一個單位&#xff0c;求出每次滑動后窗口中的最小值和最大值。 例如&#xff0c;對于序列 [1,3,?1,?3,5,3…

河南萌新聯賽2025第(五)場:信息工程大學補題

文章目錄[TOC](文章目錄)前言A.宇宙終極能量調和與多維時空穩定性驗證下的基礎算術可行性研究B.中位數C.中位數1F.中位數4G.簡單題H.簡單題I.Re:從零開始的近世代數復習&#xff08;easy&#xff09;K.狂飆追擊L.防k題前言 這次萌新聯賽考到了很多數學知識 A.宇宙終極能量調和…

SuperMap GIS基礎產品FAQ集錦(20250804)

一、SuperMap iServer 問題1&#xff1a;iServer的名稱和logo怎么自定義&#xff1f; 11.3.0 【解決辦法】參考&#xff1a;https://blog.csdn.net/supermapsupport/article/details/144744640 問題2&#xff1a;iServer 刷新工作空間&#xff0c;當數據庫是 PostGIS 時&#x…

AWS CloudFormation批量刪除指南:清理Clickstream Analytics堆棧

概述 在AWS環境管理中,經常會遇到需要批量刪除CloudFormation堆棧的情況。本文記錄了一次完整的Clickstream Analytics堆棧清理過程,包括遇到的問題和解決方案,希望能為其他開發者提供參考。 背景 我們的AWS賬戶中部署了多個Clickstream Analytics解決方案的CloudFormati…

redis中分布式鎖的應用

我們之前講了秒殺模塊的實現&#xff0c;使用了sychronized互斥鎖&#xff0c;但是在集群模式下因為不同服務器有不同jvm&#xff0c;所以synchronized互斥鎖失效了。 redis實現秒殺超賣問題的解決方案&#xff1a;(僅限于單體項目)-CSDN博客 這時就要找到一個多臺服務器都能…

【科研繪圖系列】R語言繪制微生物豐度和基因表達值的相關性網絡圖

文章目錄 介紹 加載R包 數據下載 導入數據 數據預處理 畫圖 系統信息 參考 介紹 【科研繪圖系列】R語言繪制微生物豐度和基因表達值的相關性網絡圖 加載R包 library(tidyverse) library(ggsignif) library(RColorBrewer) library(dplyr) library(reshape2) library(grid

Pycharm現有conda環境有對應env,但是添加后沒反應

一、系統環境 二、異常現象 Pycharm現有conda環境有對應env&#xff1a; anaconda3的envs下也確實存在這個環境&#xff1a; 但是添加后沒反應&#xff08;點擊確認后&#xff0c;yolov7環境沒有出現在列表中&#xff09;&#xff1a; 但是我之前在別的機子添加是沒問題的。 …