首页 > 系统相关 >Linux下PCI设备驱动开发详解(五)

Linux下PCI设备驱动开发详解(五)

时间:2023-12-24 15:32:41浏览次数:29  
标签:TX tx cfg rx chnl PCI Linux CHNL 详解

Linux下PCI设备驱动开发详解(五)

本章及其以后的几章,我们将从用户态软件、内核态驱动、FPGA逻辑介绍一个通过PCI Express总线实现CPU和FPGA数据通信的简单框架。

这个框架就是开源界非常有名的RIFFA(reuseable integration framework for FPGA accelerators),它是一个FPGA加速器的一种可重用性集成框架,是一个第三方开源PCIe框架。

该框架要求具备一个支持PCIe的工作站和一个带有PCIe连接器的FPGA板卡。RIFFA支持windows、linux,altera和xilinx,可以通过c/c++、python、matlab、java驱动来实现数据的发送和接收。驱动程序可以在linux或windows上运行,每一个系统最多支持5个FPGA device。

在用户端有独立的发送和接收端口,用户只需要编写几行简单代码即可实现和FPGA IP内核通信。

riffa使用直接存储器访问(DMA)传输和中断信号传输数据。这实现了PCIe链路上的高带宽,运行速率可以达到PCIe链路饱和点。

开源地址:https://github.com/KastnerRG/riffa

一、riffa体系结构

Linux下PCI设备驱动开发详解(五)_Linux

在硬件方面,简化了接口,以便通过FIFO简便的将数据取出或存入。数据的传输由riffa的rx和tx DMA engine模块用分散聚合方法来实现。rx engine模块收集上位机来的有效数据,收集完成发给channel模块,tx engine收集channel模块传送来的数据,打包发给PCI express端点。

在软件方面,PC接收FPGA板卡数据是用户应用程序调用库函数fpga_recv,然后由FPGA端启动。用户应用程序线程进入内核驱动程序,然后开始接收上游FPGA的读请求,将数据分包发送,如果没收到请求,将会等待它达到。

启动发送函数后,服务器将建立一个散列收集元素的列表,将数据存储地址和长度等信息放入其中,将其写入共享缓冲区。用户应用程序将缓冲区地址和数据长度等信息发送给FPGA。FPGA读取散射收集数据,然后发出相应地址的数据写入请求,如果散列收集元素列表的地址有多个,FPGA将通过中断发出多次请求。

TX搬移的数据全部写入缓存区后,驱动程序读取FPGA写入的字节数,确认是否与发送数据长度一致。这样就完成了传输。其过程如下图所示:

Linux下PCI设备驱动开发详解(五)_Linux_02

PC机发送数据到FPGA板卡过程与PC机接收FPGA板卡数据过程相似,下图说明了该流程。 刚开始也是用户应用程序调用库函数fpga_send,传输线程进入内核驱动程序,然后FPGA启动传输。

启动fpga_send,服务器将申请一些空间,将要发送的数据写入其中,然后建立一个分散收集列表,将存储数据的地址和长度放入其中,并将分散收集列表的地址和要发生的数据长度等信息发给FPGA。FPGA 收到列表地址后,读取该列表的信息,然后发出相应地址和长度的读请求,然后将数据存储,最后一起发给FPGA板卡。

Linux下PCI设备驱动开发详解(五)_驱动_03

驱动程序首先调用pci_present()检查PCI总线是否被linux内核支持,如果系统支持PCI总线结构,这个函数的返回值为0,如果驱动程序在调用这个函数时得到一个非0的返回值,那么驱动程序就必须得中止自己的任务。调用pci_register_driver()函数来注册PCI设备的驱动程序,此时需要提供一个“demo_pci_driver”结构,在该结构中给出的probe探测例程负责完成对硬件的检测工作。

下面将从user logic -> PCIe IP -> 驱动层 -> library-> 用户态C++/C按照实例一一进行分析,包括理论基础、实际操作、源代码分析。

首先我们先从FPGA xilinx integrated block for PCI express分析,因为这个有承上启下的作用。

二、PCIe hard IP分析

1. PCIE IP 核配置

AXI总线时钟选择62.5M,AXI总线接口位宽设置为64bit。

Linux下PCI设备驱动开发详解(五)_FPGA_04

在IDs界面是PCIe设备的相关信息,主机在上电时BIOS系统中识别到的PCIe设备,就是通过这些ID号来进行识别的。

在本实验中,关于ID的设定全部保持为默认值即可,若用户对ID进行了更改,可能导致计算机在启动时不能正确识别设备从而导致蓝屏死机。

Vendor ID是厂商ID,本实验中的厂商ID代值的就是Xilinx;

Device ID代表了PCIe设备,其中7指的是Xilinx 7 系列FPGA,02指的是使用的PCIe 2.0的协议,1指的是含有一个PCIe的传输lane;

Base class Menu指的是PCIe设备的种类,常见的有声卡、显卡、网卡等,各种不同种类的设备都有其对应的驱动,若驱动与其PCIe的种类不对应,就会导致系统的内存访问错误,从而导致蓝屏。

Linux下PCI设备驱动开发详解(五)_FPGA_05

在PCIe的bars配置界面对PCIe的bar进行设置,BAR空间对应的就是在内存中开辟一段空间用于存放PCIe设备的信息。只使用到一个bar0一个bar且将其内存空间的大小设置为1k。

Linux下PCI设备驱动开发详解(五)_Linux_06

IP核的负载选择最大负载长度为512字节,勾选对数据进行缓冲。

Linux下PCI设备驱动开发详解(五)_PCI_07

在中断配置界面,取消勾选传统类型的中断,只选择消息类型的中断。

Linux下PCI设备驱动开发详解(五)_PCI_08

在share logic界面取消勾选包含其他逻辑,这样在PCIe的IP核中就包含了全部功能。

Linux下PCI设备驱动开发详解(五)_FPGA_09

在IP核接口参数配置界面,只选择其中用于配置核控制的参数,这是由于riffa框架的特性所提供的。

Linux下PCI设备驱动开发详解(五)_FPGA_10

下面代码是实际的top level,

PCIeGen1x4If64 PCIeGen1x4If64_i
        (//---------------------------------------------------------------------
         // PCI Express (pci_exp) Interface                                     
         //---------------------------------------------------------------------
         // Tx
         .pci_exp_txn                               ( PCI_EXP_TXN ),
         .pci_exp_txp                               ( PCI_EXP_TXP ),        
         // Rx
         .pci_exp_rxn                               ( PCI_EXP_RXN ),
         .pci_exp_rxp                               ( PCI_EXP_RXP ),        
         //---------------------------------------------------------------------
         // AXI-S Interface                                                     
         //---------------------------------------------------------------------
         // Common
         .user_clk_out                              ( user_clk ),
         .user_reset_out                            ( user_reset ),
         .user_lnk_up                               ( user_lnk_up ),
         .user_app_rdy                              ( user_app_rdy ),
         // TX
         .s_axis_tx_tready                          ( s_axis_tx_tready ),
         .s_axis_tx_tdata                           ( s_axis_tx_tdata ),
         .s_axis_tx_tkeep                           ( s_axis_tx_tkeep ),
         .s_axis_tx_tuser                           ( s_axis_tx_tuser ),
         .s_axis_tx_tlast                           ( s_axis_tx_tlast ),
         .s_axis_tx_tvalid                          ( s_axis_tx_tvalid ),
         // Rx
         .m_axis_rx_tdata                           ( m_axis_rx_tdata ),
         .m_axis_rx_tkeep                           ( m_axis_rx_tkeep ),
         .m_axis_rx_tlast                           ( m_axis_rx_tlast ),
         .m_axis_rx_tvalid                          ( m_axis_rx_tvalid ),
         .m_axis_rx_tready                          ( m_axis_rx_tready ),
         .m_axis_rx_tuser                           ( m_axis_rx_tuser ),
         .tx_cfg_gnt                                ( tx_cfg_gnt ),
         .rx_np_ok                                  ( rx_np_ok ),
         .rx_np_req                                 ( rx_np_req ),
         .cfg_trn_pending                           ( cfg_trn_pending ),
         .cfg_pm_halt_aspm_l0s                      ( cfg_pm_halt_aspm_l0s ),
         .cfg_pm_halt_aspm_l1                       ( cfg_pm_halt_aspm_l1 ),
         .cfg_pm_force_state_en                     ( cfg_pm_force_state_en ),
         .cfg_pm_force_state                        ( cfg_pm_force_state ),
         .cfg_dsn                                   ( cfg_dsn ),
         .cfg_turnoff_ok                            ( cfg_turnoff_ok ),
         .cfg_pm_wake                               ( cfg_pm_wake ),
         .cfg_pm_send_pme_to                        ( 1'b0 ),
         .cfg_ds_bus_number                         ( 8'b0 ),
         .cfg_ds_device_number                      ( 5'b0 ),
         .cfg_ds_function_number                    ( 3'b0 ),
         //---------------------------------------------------------------------
         // Flow Control Interface                                              
         //---------------------------------------------------------------------
         .fc_cpld                                   ( fc_cpld ),
         .fc_cplh                                   ( fc_cplh ),
         .fc_npd                                    ( fc_npd ),
         .fc_nph                                    ( fc_nph ),
         .fc_pd                                     ( fc_pd ),
         .fc_ph                                     ( fc_ph ),
         .fc_sel                                    ( fc_sel ),
         //---------------------------------------------------------------------
         // Configuration (CFG) Interface                                       
         //---------------------------------------------------------------------
         .cfg_device_number                         ( cfg_device_number ),
         .cfg_dcommand2                             ( cfg_dcommand2 ),
         .cfg_pmcsr_pme_status                      ( cfg_pmcsr_pme_status ),
         .cfg_status                                ( cfg_status ),
         .cfg_to_turnoff                            ( cfg_to_turnoff ),
         .cfg_received_func_lvl_rst                 ( cfg_received_func_lvl_rst ),
         .cfg_dcommand                              ( cfg_dcommand ),
         .cfg_bus_number                            ( cfg_bus_number ),
         .cfg_function_number                       ( cfg_function_number ),
         .cfg_command                               ( cfg_command ),
         .cfg_dstatus                               ( cfg_dstatus ),
         .cfg_lstatus                               ( cfg_lstatus ),
         .cfg_pcie_link_state                       ( cfg_pcie_link_state ),
         .cfg_lcommand                              ( cfg_lcommand ),
         .cfg_pmcsr_pme_en                          ( cfg_pmcsr_pme_en ),
         .cfg_pmcsr_powerstate                      ( cfg_pmcsr_powerstate ),
         //------------------------------------------------//
         // EP Only                                        //
         //------------------------------------------------//
         .cfg_interrupt                             ( cfg_interrupt ),
         .cfg_interrupt_rdy                         ( cfg_interrupt_rdy ),
         .cfg_interrupt_assert                      ( cfg_interrupt_assert ),
         .cfg_interrupt_di                          ( cfg_interrupt_di ),
         .cfg_interrupt_do                          ( cfg_interrupt_do ),
         .cfg_interrupt_mmenable                    ( cfg_interrupt_mmenable ),
         .cfg_interrupt_msienable                   ( cfg_interrupt_msienable ),
         .cfg_interrupt_msixenable                  ( cfg_interrupt_msixenable ),
         .cfg_interrupt_msixfm                      ( cfg_interrupt_msixfm ),
         .cfg_interrupt_stat                        ( cfg_interrupt_stat ),
         .cfg_pciecap_interrupt_msgnum              ( cfg_pciecap_interrupt_msgnum ),
         //---------------------------------------------------------------------
         // System  (SYS) Interface                                             
         //---------------------------------------------------------------------
         .sys_clk                                    ( pcie_refclk ),
         .sys_rst_n                                  ( pcie_reset_n )
         );

从顶层代码接口可以看出来,TX/RX差分信号、AXIS数据common接口信号、tx/rx数据面信号、FC流控信号、configuration(CFG)interface、EP中断信号、系统时钟/复位信号。

详细使用参考xilinx PCIe spec官方文档。

PCIe IP位于整个设计架构的这个位置:

Linux下PCI设备驱动开发详解(五)_PCI_11

2. tx_engine和rx_engine

下面我们分析一下tx_engine和rx_engine这两个核心模块,这两个模块负责转换axis data和tlp data。

我们先看一下top level的源代码:

riffa_wrapper_ac701
        #(/*AUTOINSTPARAM*/
          // Parameters
          .C_LOG_NUM_TAGS               (C_LOG_NUM_TAGS),
          .C_NUM_CHNL                   (C_NUM_CHNL),
          .C_PCI_DATA_WIDTH             (C_PCI_DATA_WIDTH),
          .C_MAX_PAYLOAD_BYTES          (C_MAX_PAYLOAD_BYTES))
    riffa
        (
         // Outputs
         .CFG_INTERRUPT                 (cfg_interrupt),
         .M_AXIS_RX_TREADY              (m_axis_rx_tready),
         .S_AXIS_TX_TDATA               (s_axis_tx_tdata[C_PCI_DATA_WIDTH-1:0]),
         .S_AXIS_TX_TKEEP               (s_axis_tx_tkeep[(C_PCI_DATA_WIDTH/8)-1:0]),
         .S_AXIS_TX_TLAST               (s_axis_tx_tlast),
         .S_AXIS_TX_TVALID              (s_axis_tx_tvalid),
         .S_AXIS_TX_TUSER               (s_axis_tx_tuser[`SIG_XIL_TX_TUSER_W-1:0]),
         .FC_SEL                        (fc_sel[`SIG_FC_SEL_W-1:0]),
         .RST_OUT                       (rst_out),
         .CHNL_RX                       (chnl_rx[C_NUM_CHNL-1:0]),
         .CHNL_RX_LAST                  (chnl_rx_last[C_NUM_CHNL-1:0]),
         .CHNL_RX_LEN                   (chnl_rx_len[(C_NUM_CHNL*`SIG_CHNL_LENGTH_W)-1:0]),
         .CHNL_RX_OFF                   (chnl_rx_off[(C_NUM_CHNL*`SIG_CHNL_OFFSET_W)-1:0]),
         .CHNL_RX_DATA                  (chnl_rx_data[(C_NUM_CHNL*C_PCI_DATA_WIDTH)-1:0]),
         .CHNL_RX_DATA_VALID            (chnl_rx_data_valid[C_NUM_CHNL-1:0]),
         .CHNL_TX_ACK                   (chnl_tx_ack[C_NUM_CHNL-1:0]),
         .CHNL_TX_DATA_REN              (chnl_tx_data_ren[C_NUM_CHNL-1:0]),
         // Inputs
         .M_AXIS_RX_TDATA               (m_axis_rx_tdata[C_PCI_DATA_WIDTH-1:0]),
         .M_AXIS_RX_TKEEP               (m_axis_rx_tkeep[(C_PCI_DATA_WIDTH/8)-1:0]),
         .M_AXIS_RX_TLAST               (m_axis_rx_tlast),
         .M_AXIS_RX_TVALID              (m_axis_rx_tvalid),
         .M_AXIS_RX_TUSER               (m_axis_rx_tuser[`SIG_XIL_RX_TUSER_W-1:0]),
         .S_AXIS_TX_TREADY              (s_axis_tx_tready),
         .CFG_BUS_NUMBER                (cfg_bus_number[`SIG_BUSID_W-1:0]),
         .CFG_DEVICE_NUMBER             (cfg_device_number[`SIG_DEVID_W-1:0]),
         .CFG_FUNCTION_NUMBER           (cfg_function_number[`SIG_FNID_W-1:0]),
         .CFG_COMMAND                   (cfg_command[`SIG_CFGREG_W-1:0]),
         .CFG_DCOMMAND                  (cfg_dcommand[`SIG_CFGREG_W-1:0]),
         .CFG_LSTATUS                   (cfg_lstatus[`SIG_CFGREG_W-1:0]),
         .CFG_LCOMMAND                  (cfg_lcommand[`SIG_CFGREG_W-1:0]),
         .FC_CPLD                       (fc_cpld[`SIG_FC_CPLD_W-1:0]),
         .FC_CPLH                       (fc_cplh[`SIG_FC_CPLH_W-1:0]),
         .CFG_INTERRUPT_MSIEN           (cfg_interrupt_msienable),// TODO: Rename
         .CFG_INTERRUPT_RDY             (cfg_interrupt_rdy),
         .USER_CLK                      (user_clk),
         .USER_RESET                    (user_reset),
         .CHNL_RX_CLK                   (chnl_rx_clk[C_NUM_CHNL-1:0]),
         .CHNL_RX_ACK                   (chnl_rx_ack[C_NUM_CHNL-1:0]),
         .CHNL_RX_DATA_REN              (chnl_rx_data_ren[C_NUM_CHNL-1:0]),
         .CHNL_TX_CLK                   (chnl_tx_clk[C_NUM_CHNL-1:0]),
         .CHNL_TX                       (chnl_tx[C_NUM_CHNL-1:0]),
         .CHNL_TX_LAST                  (chnl_tx_last[C_NUM_CHNL-1:0]),
         .CHNL_TX_LEN                   (chnl_tx_len[(C_NUM_CHNL*`SIG_CHNL_LENGTH_W)-1:0]),
         .CHNL_TX_OFF                   (chnl_tx_off[(C_NUM_CHNL*`SIG_CHNL_OFFSET_W)-1:0]),
         .CHNL_TX_DATA                  (chnl_tx_data[(C_NUM_CHNL*C_PCI_DATA_WIDTH)-1:0]),
         .CHNL_TX_DATA_VALID            (chnl_tx_data_valid[C_NUM_CHNL-1:0]),
         .RX_NP_OK                      (rx_np_ok),
         .TX_CFG_GNT                    (tx_cfg_gnt),
         .RX_NP_REQ                     (rx_np_req)
         /*AUTOINST*/);

这个模块可以通过C_NUM_CHNL配置通道个数,C_PCI_DATA_WIDTH配置PCIe data的位宽,C_LOG_NUM_TAGS配置PCIe tag的个数。

module riffa_wrapper_ac701负责将xilinx PCIe IP的TX、RX、Configuration、flow control、中断信号转换为riffa的输入输出信号。

阅读riffa_wrapper_ac701.v源代码发现这个模块分为两个模块:

· translation_xilinx

· engine_layer

· riffa

transtion_xilinx:负责提供统一的PCIe接口信息,比如altera、xilinx;

engine_layer:负责封装了tx_engine和rx_engine。其中tx engine负责上传DMA通道(写通道),即Interface: TX Classic;rx engine负责下发DMA通道(读通道),即Interface: RX Classic;

riffa:负责将tx/rx engine的信号转换为user logic的通道信号,方便我们使用,接口代码如下:

input [C_NUM_CHNL-1:0]                     CHNL_RX_CLK, 
     output [C_NUM_CHNL-1:0]                    CHNL_RX, 
     input [C_NUM_CHNL-1:0]                     CHNL_RX_ACK, 
     output [C_NUM_CHNL-1:0]                    CHNL_RX_LAST, 
     output [(C_NUM_CHNL*32)-1:0]               CHNL_RX_LEN, 
     output [(C_NUM_CHNL*31)-1:0]               CHNL_RX_OFF, 
     output [(C_NUM_CHNL*C_PCI_DATA_WIDTH)-1:0] CHNL_RX_DATA, 
     output [C_NUM_CHNL-1:0]                    CHNL_RX_DATA_VALID, 
     input [C_NUM_CHNL-1:0]                     CHNL_RX_DATA_REN,
    
     input [C_NUM_CHNL-1:0]                     CHNL_TX_CLK, 
     input [C_NUM_CHNL-1:0]                     CHNL_TX, 
     output [C_NUM_CHNL-1:0]                    CHNL_TX_ACK,
     input [C_NUM_CHNL-1:0]                     CHNL_TX_LAST, 
     input [(C_NUM_CHNL*32)-1:0]                CHNL_TX_LEN, 
     input [(C_NUM_CHNL*31)-1:0]                CHNL_TX_OFF, 
     input [(C_NUM_CHNL*C_PCI_DATA_WIDTH)-1:0]  CHNL_TX_DATA, 
     input [C_NUM_CHNL-1:0]                     CHNL_TX_DATA_VALID, 
     output [C_NUM_CHNL-1:0]                    CHNL_TX_DATA_REN

对应整个实际框架的这一部分,如下图所示:

Linux下PCI设备驱动开发详解(五)_驱动_12

3. user logic

经过tx engine和rx engine模块,输出CHNL_RX_*和CHNL_TX_*信号,下面我们看一下user如何使用的,源代码如下:

generate
    for (chnl = 0; chnl < C_NUM_CHNL; chnl = chnl + 1) begin : test_channels
        chnl_tester 
                #(
                  .C_PCI_DATA_WIDTH(C_PCI_DATA_WIDTH)
                  ) 
        module1 
                (.CLK(user_clk),
                 .RST(rst_out),    // riffa_reset includes riffa_endpoint resets
                 // Rx interface
                 .CHNL_RX_CLK(chnl_rx_clk[chnl]), 
                 .CHNL_RX(chnl_rx[chnl]), 
                 .CHNL_RX_ACK(chnl_rx_ack[chnl]), 
                 .CHNL_RX_LAST(chnl_rx_last[chnl]), 
                 .CHNL_RX_LEN(chnl_rx_len[32*chnl +:32]), 
                 .CHNL_RX_OFF(chnl_rx_off[31*chnl +:31]), 
                 .CHNL_RX_DATA(chnl_rx_data[C_PCI_DATA_WIDTH*chnl +:C_PCI_DATA_WIDTH]), 
                 .CHNL_RX_DATA_VALID(chnl_rx_data_valid[chnl]), 
                 .CHNL_RX_DATA_REN(chnl_rx_data_ren[chnl]),

                 // Tx interface
                 .CHNL_TX_CLK(chnl_tx_clk[chnl]), 
                 .CHNL_TX(chnl_tx[chnl]), 
                 .CHNL_TX_ACK(chnl_tx_ack[chnl]), 
                 .CHNL_TX_LAST(chnl_tx_last[chnl]), 
                 .CHNL_TX_LEN(chnl_tx_len[32*chnl +:32]), 
                 .CHNL_TX_OFF(chnl_tx_off[31*chnl +:31]), 
                 .CHNL_TX_DATA(chnl_tx_data[C_PCI_DATA_WIDTH*chnl +:C_PCI_DATA_WIDTH]), 
                 .CHNL_TX_DATA_VALID(chnl_tx_data_valid[chnl]), 
                 .CHNL_TX_DATA_REN(chnl_tx_data_ren[chnl])
                 );    
    end
endgenerate

这个模块的用于执行RIFFA TX 和 RX 接口。在RX接口上接收数据并保存最后接收的值。在TX接口上发送回相同数量的数据。返回的数据从接收到的最后一个值开始,重置并递增,直到等于TX接口上发回的(4字节)字数的值结束。

Linux下PCI设备驱动开发详解(五)_PCI_13

三、总结

这篇文章通过经典开源项目RIIFA的FPGA部分,结合源代码详细分析了框架部分的Xilinx PCIe hard IP、TX/RX engine和RIFFA模块,最后结合了user logic部分的chnl_tester,介绍了如何使用CHNL_TX_*和CHNL_RX_*接口。

四、未完待续

Linux下PCI设备驱动开发详解(六),将结合经典开源项目RIIFA,详细介绍内核态驱动的设计、开发、安装等。

五、参考资料

https://blog.csdn.net/qq_41332806/article/details/105864632

标签:TX,tx,cfg,rx,chnl,PCI,Linux,CHNL,详解
From: https://blog.51cto.com/u_16419576/8955982

相关文章

  • Linux平台总线
    linuxdrv和dev都会注册进总线的链表,如果设备和驱动匹配,调用驱动程序的probe函数总线类型:bus_type代码分析:注册drv举例说明:分析注册一个平台drvdriver_register(&drv->driver) bus_add_driver(structdevice_driver*drv) klist_add_tail(&priv->knode_bus,&bu......
  • 将windows上socket的client程序修改到linux上运行
    将windows上客户端程序修改到linux上运行记录一下修改哪些地方编译命令文件夹的内容:包含了client.cppmySocket.cppmySocket.huntil.h链接在一起g++-cclient.cppmySocket.cppuntil.h-std=c++11-pthread使用g++编译器将client.cpp、mySocket.cpp和until.h......
  • Python教程(16)——lambda表达式详解
    lambda函数介绍我们平时经常可以在Python的代码中看到一种lambda开头的这种表达式,如果没有学过Python的相关知识,可能会一脸懵逼,不清楚到底这个关键字是干嘛的,用来表示什么。实际上这个就是lambda函数。lambda函数是Python中一种特殊的匿名函数,但不仅仅只存在Python中,它允许我们......
  • Python教程(16)——lambda表达式详解
    lambda函数介绍我们平时经常可以在Python的代码中看到一种lambda开头的这种表达式,如果没有学过Python的相关知识,可能会一脸懵逼,不清楚到底这个关键字是干嘛的,用来表示什么。实际上这个就是lambda函数。lambda函数是Python中一种特殊的匿名函数,但不仅仅只存在Python中,它允许我们......
  • linux中文件的特殊权限setgid-setuid-sbit
    1.SetUID一.SetUID的功能SetUID主要是给命令提供一个root权限,就是命令运行时拥有root用户权限,命令运行结束后root权限消失1.只有执行的二进制程序才能设定SUID权限2.命令执行者要对该程序有用x(执行)权限3.命令执行者在执行该程序时获得该程序文件属主(所有者)的身份(在执行程......
  • windows通过 桥接Usb 电缆连接linux 主机并通信的方法
    在Windows上通过USB转串口线连接Linux主机并进行通信,可以参考以下步骤:首先,插入USB转串口线到电脑的USB接口,此时系统会自动识别设备并安装驱动。检查设备管理器的端口(COM和LPT)中是否出现相应的串口信息。启动USB/IP项目以启用常见的开发人员USB场景,例如访问智能卡读取器等。确保你的......
  • Linux安装无线网卡驱动
    您可以通过以下步骤来实现:首先,将Linux安装盘插入电脑的USB接口。打开电脑的BIOS设置,将启动顺序设置为优先从USB设备启动。重启电脑并进入Linux安装界面。在安装过程中,选择“手动分区”选项,然后为Linux系统分配一个适当的分区。接下来,选择“安装Linux内核”选项,并等待安装完成。安装......
  • linux-网络接口的绑定与组合(bond 网桥的创建)
    网络接口的绑定一、虚拟接口将多个网络逻辑接口连接在一起:1、实现冗余、避免故障2、提高吞吐率原理:非在物理网卡上设置、而是通过多个物理网卡聚合成一个虚拟的网卡(外部网络访问的就是本机的虚拟网卡的地址)二、通过networkmanger实现绑定模式balanceactive-backup--......
  • Typescript 函数详解
    前言虽然JS/TS支持面向对象编程,但大部分时候还是在写函数。函数是一等公民。本文介绍下如何在TypeScript中使用函数,包括:函数类型声明函数参数类型:可选参数、默认参数、剩余参数函数返回值类型this类型函数重载函数类型面试中经常会被问到,JS中有哪几种数据类型。其中就会有函......
  • linux 中正则匹配限制词首和词尾
     001、\<或者\b限制词首[root@pc1test]#lsa.txt[root@pc1test]#cata.txt##测试数据010203040506070809101112131415137831204331617181920212223242524332233443262728293031323334353637383940[root@......