• Linux UWB Stack实现——MCPS接口


    本专栏主要介绍在Linux内核中的UWB Stack的实现,整体基于IEEE 802.15.4框架,采用Qorvo UWB芯片DW3000,开源协议版本为GPLv2。
    在本篇文章中,主要介绍MCPS接口的定义,MCPS(MAC Common Part Sublayer,MAC公共部分子层)。

    关于mcps802154.h

    为MCPS接口相关定义,主要包括一些一些结构体的定义,主要包括底层驱动的连接,收发数据帧等,相关结构体定义如下:

    • struct mcps802154_llhw,不带MCPS的底层硬件,必须使用mcps802154_alloc_llhw()函数进行分配,然后底层驱动程序应对其进行初始化。
    • struct mcps802154_tx_frame_info,用于传输帧的信息。
    • struct mcps802154_rx_info ,使能接收机的信息。
    • struct mcps802154_rx_frame_info,接收到数据帧的信息。
    • struct mcps802154_sts_params,HPR UWB的STS参数。
    • struct mcps802154_ops,MCPS从底层驱动程序的回调函数。

    mcps802154_llhw

    struct mcps802154_llhw {
    	/**
    	 * @dtu_freq_hz: Inverse of device time unit duration, in Hz.
    	 */
    	int dtu_freq_hz;
    	/**
    	 * @symbol_dtu: Symbol duration in device time unit, can change if radio
    	 * parameters are changed. Can be set to 1 if device time unit is the
    	 * symbol.
    	 */
    	int symbol_dtu;
    	/**
    	 * @cca_dtu: CCA duration in device time unit, can change if radio
    	 * parameters or CCA modes are changed.
    	 */
    	int cca_dtu;
    	/**
    	 * @shr_dtu: Synchronisation header duration in device time unit, can
    	 * change if radio parameters are changed. If ranging is supported, this
    	 * is the difference between the RMARKER and the first frame symbol.
    	 */
    	int shr_dtu;
    	/**
    	 * @dtu_rctu: Duration of one device time unit in ranging counter time
    	 * unit (RDEV only).
    	 */
    	int dtu_rctu;
    	/**
    	 * @rstu_dtu: Duration of ranging slot time unit in device time unit
    	 * (ERDEV only).
    	 */
    	int rstu_dtu;
    	/**
    	 * @anticip_dtu: Reasonable delay between reading the current timestamp
    	 * and doing an operation in device time unit.
    	 */
    	int anticip_dtu;
    	/**
    	 * @idle_dtu: Duration long enough to prefer entering the idle mode
    	 * rather than trying to find a valid access.
    	 */
    	int idle_dtu;
    	/**
    	 * @flags: Low-level hardware flags, see &enum mcps802154_llhw_flags.
    	 */
    	u32 flags;
    	/**
    	 * @hw: Pointer to IEEE802154 hardware exposed by MCPS. The low-level
    	 * driver needs to update this and hw->phy according to supported
    	 * hardware features and radio parameters. More specifically:
    	 *
    	 * * &ieee802154_hw.extra_tx_headroom
    	 * * in &ieee802154_hw.flags:
    	 *
    	 *     * IEEE802154_HW_TX_OMIT_CKSUM
    	 *     * IEEE802154_HW_RX_OMIT_CKSUM
    	 *     * IEEE802154_HW_RX_DROP_BAD_CKSUM
    	 *
    	 * * &wpan_phy.flags
    	 * * &wpan_phy_supported
    	 * * &wpan_phy.symbol_duration
    	 */
    	struct ieee802154_hw *hw;
    	/**
    	 * @priv: Driver private data.
    	 */
    	void *priv;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    mcps802154_tx_frame_info

    enum mcps802154_tx_frame_info_flags {
    	MCPS802154_TX_FRAME_TIMESTAMP_DTU = BIT(0),
    	MCPS802154_TX_FRAME_CCA = BIT(1),
    	MCPS802154_TX_FRAME_RANGING = BIT(2),
    	MCPS802154_TX_FRAME_KEEP_RANGING_CLOCK = BIT(3),
    	MCPS802154_TX_FRAME_SP1 = BIT(4),
    	MCPS802154_TX_FRAME_SP2 = BIT(5),
    	MCPS802154_TX_FRAME_SP3 = BIT(4) | BIT(5),
    	MCPS802154_TX_FRAME_STS_MODE_MASK = BIT(4) | BIT(5),
    };
    
    struct mcps802154_tx_frame_info {
    	/**
    	 * @timestamp_dtu: If timestamped, date of transmission start.
    	 */
    	u32 timestamp_dtu;
    	/**
    	 * @rx_enable_after_tx_dtu: If positive, enable receiver this number of
    	 * device time unit after the end of the transmitted frame.
    	 */
    	int rx_enable_after_tx_dtu;
    	/**
    	 * @rx_enable_after_tx_timeout_dtu: When receiver is enabled after the
    	 * end of the transmitted frame: if negative, no timeout, if zero, use
    	 * a default timeout value, else this is the timeout value in device
    	 * time unit.
    	 */
    	int rx_enable_after_tx_timeout_dtu;
    	/**
    	 * @flags: See &enum mcps802154_tx_frame_info_flags.
    	 */
    	u8 flags;
    	/**
    	 * @ant_id: antenna index to use for transmit.
    	 */
    	int ant_id;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    mcps802154_rx_info

    enum mcps802154_rx_info_flags {
    	MCPS802154_RX_INFO_TIMESTAMP_DTU = BIT(0),
    	MCPS802154_RX_INFO_AACK = BIT(1),
    	MCPS802154_RX_INFO_RANGING = BIT(2),
    	MCPS802154_RX_INFO_KEEP_RANGING_CLOCK = BIT(3),
    	MCPS802154_RX_INFO_SP1 = BIT(4),
    	MCPS802154_RX_INFO_SP2 = BIT(5),
    	MCPS802154_RX_INFO_SP3 = BIT(4) | BIT(5),
    	MCPS802154_RX_INFO_STS_MODE_MASK = BIT(4) | BIT(5),
    };
    
    struct mcps802154_rx_info {
    	/**
    	 * @timestamp_dtu: If timestamped, date to enable the receiver.
    	 */
    	u32 timestamp_dtu;
    	/**
    	 * @timeout_dtu: 负数,无超时;0,默认超时;正数为设定的超时时间
    	 */
    	int timeout_dtu;
    	/**
    	 * @flags: See &enum mcps802154_rx_info_flags.
    	 */
    	u8 flags;
    	/**
    	 * @ant_pair_id: 用于接收的天线配对索引
    	 */
    	u8 ant_pair_id;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    mcps802154_rx_frame_info

    接收帧信息相关。
    接收帧信息标志包括测距时间戳、LQI、RSSI、测距FOM、PDOA、STS等相关的接收帧标志。

    • RCTU(Ranging Count Time Unit,测距计数单元),用于测距应用,基础时间单位约为15 ps,仅支持测距的设备支持。
    • DTU,Device Time Unit,设备时钟单元。
    enum mcps802154_rx_frame_info_flags {
    	MCPS802154_RX_FRAME_INFO_TIMESTAMP_DTU = BIT(0),
    	MCPS802154_RX_FRAME_INFO_TIMESTAMP_RCTU = BIT(1),
    	MCPS802154_RX_FRAME_INFO_LQI = BIT(2),
    	MCPS802154_RX_FRAME_INFO_RSSI = BIT(3),
    	MCPS802154_RX_FRAME_INFO_RANGING_FOM = BIT(4),
    	MCPS802154_RX_FRAME_INFO_RANGING_OFFSET = BIT(5),
    	MCPS802154_RX_FRAME_INFO_RANGING_PDOA = BIT(6),
    	MCPS802154_RX_FRAME_INFO_RANGING_PDOA_FOM = BIT(7),
    	MCPS802154_RX_FRAME_INFO_RANGING_STS_TIMESTAMP_RCTU = BIT(8),
    	MCPS802154_RX_FRAME_INFO_RANGING_STS_FOM = BIT(9),
    	MCPS802154_RX_FRAME_INFO_AACK = BIT(10),
    };
    
    struct mcps802154_rx_frame_info {
    	/**
    	 * @timestamp_dtu: Timestamp of start of frame in device time unit.
    	 */
    	u32 timestamp_dtu;
    	/**
    	 * @timestamp_rctu: Timestamp of RMARKER in ranging count time unit
    	 * (RDEV only).
    	 */
    	u64 timestamp_rctu;
    	/**
    	 * @frame_duration_dtu: Duration of the whole frame in device time unit
    	 * or 0 if unknown.
    	 */
    	int frame_duration_dtu;
    
    	int rssi;
    	/**
    	 * @ranging_tracking_interval_rctu: Interval on which tracking offset
    	 * was measured (RDEV only).
    	 */
    	int ranging_tracking_interval_rctu;
    	/**
    	 * @ranging_offset_rctu: Difference between the transmitter and the
    	 * receiver clock measure over the tracking interval, if positive, the
    	 * transmitter operates at a higher frequency (RDEV only).
    	 */
    	int ranging_offset_rctu;
    	/**
    	 * @ranging_pdoa_rad_q11: Phase difference of arrival, unit is radian
    	 * multiplied by 2048 (RDEV only).
    	 */
    	int ranging_pdoa_rad_q11;
    	/**
    	 * @ranging_pdoa_spacing_mm_q11: Spacing between antennas, unit is mm
    	 * multiplied by 2048 (RDEV only).
    	 */
    	int ranging_pdoa_spacing_mm_q11;
    	/**
    	 * @ranging_sts_timestamp_diffs_rctu: For each SRMARKERx, difference
    	 * between the measured timestamp and the expected timestamp relative to
    	 * RMARKER in ranging count time unit (ERDEV only). When STS mode is
    	 * 1 or 3, SRMARKER0 is the same as RMARKER and difference is always 0.
    	 */
    	s16 ranging_sts_timestamp_diffs_rctu[MCPS802154_STS_N_SEGS_MAX + 1];
    	/**
    	 * @lqi: Link quality indicator (LQI).
    	 */
    	u8 lqi;
    	/**
    	 * @ranging_fom: Ranging figure of merit (FoM, RDEV only). Should be
    	 * formatted according to 802.15.4.
    	 */
    	u8 ranging_fom;
    	/**
    	 * @ranging_pdoa_fom: Phase difference of arrival figure of merit (FoM,
    	 * RDEV only). Range is 0 to 255, with 0 being an invalid measure and
    	 * 255 being a 100% confidence.
    	 */
    	u8 ranging_pdoa_fom;
    	/**
    	 * @ranging_sts_fom: Table of figures of merit measuring the correlation
    	 * strength between the received STS segment and the expected one (FoM,
    	 * ERDEV only). Range is 0 to 255, with 0 being an invalid measure and
    	 * 255 being a 100% confidence.
    	 */
    	u8 ranging_sts_fom[MCPS802154_STS_N_SEGS_MAX];
    	/**
    	 * @flags: See &enum mcps802154_rx_frame_info_flags.
    	 */
    	u16 flags;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    mcps802154_sts_params

    HRP UWB的STS参数,包括用在DRBG中生成STS的Value与key,以及STS段的数量以及每个段内STS的长度(FiRa、CCC的标准中通常使用1个STS段,长度为64个Symbol)。
    另外,针对SP2模式帧格式,定义了STS与payload之间的附加gap信息。

    struct mcps802154_sts_params {
    	/**
    	 * @v: Value V used in DRBG for generating the STS. The 32 LSB are the
    	 * VCounter which is incremented every 128 generated pulse.
    	 */
    	u8 v[AES_BLOCK_SIZE];
    	/**
    	 * @key: STS AES key used in DRBG for generating the STS.
    	 */
    	u8 key[AES_KEYSIZE_128];
    
    	int n_segs;
    
    	int seg_len;
    	/**
    	 * @sp2_tx_gap_4chips: For SP2 frame format, additional gap in unit of
    	 * 4 chips between the end of the payload and the start of the STS, used
    	 * for TX.
    	 */
    	int sp2_tx_gap_4chips;
    	/**
    	 * @sp2_rx_gap_4chips: For SP2 frame format, additional gap in unit of
    	 * 4 chips between the end of the payload and the start of the STS, used
    	 * for RX. A0 and A1 bits in PHR are used to index the array.
    	 */
    	int sp2_rx_gap_4chips[MCPS802154_STS_N_SEGS_MAX];
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    mcps802154_ops

    定义了底层驱动相关的实现接口回调,包括初始化底层设备、停止、发送、接收等常规操作接口。

    struct mcps802154_ops {
    	/**
    	 * @start: Initialize device. Reception should not be activated.
    	 */
    	int (*start)(struct mcps802154_llhw *llhw);
    	/**
    	 * @stop: Stop device. Should stop any transmission or reception and put
    	 * the device in a low power mode.
    	 */
    	void (*stop)(struct mcps802154_llhw *llhw);
    	/**
    	 * @tx_frame: Transmit a frame. skb应包含从IEEE 802.15.4帧头开始的数据。底层驱动将根据设定发送帧信息发送。接收机应在没有收到帧的情况下自动关闭。
    	 *
    	 * @next_delay_dtu : 表示预期发送帧开始和下一动作之间的延迟时间
    	 *
    	 */
    	int (*tx_frame)(struct mcps802154_llhw *llhw, struct sk_buff *skb,
    			const struct mcps802154_tx_frame_info *info,
    			int next_delay_dtu);
    	/**
    	 * @rx_enable: 使能接收机。
    	 * @next_delay_dtu: 表示预期从开始接受帧或帧接收超时之间的时间。
    	 */
    	int (*rx_enable)(struct mcps802154_llhw *llhw,
    			 const struct mcps802154_rx_info *info,
    			 int next_delay_dtu);
    	/**
    	 * @rx_disable: Disable receiver
    	 */
    	int (*rx_disable)(struct mcps802154_llhw *llhw);
    	/**
    	 * @rx_get_frame: Get previously received frame. MCPS calls this handler
    	 * after a frame reception has been signaled by the low-level driver.
    	 *
    	 * The received buffer is owned by MCPS after this call. Only the
    	 * requested information need to be filled in the information structure.
    	 *
    	 */
    	int (*rx_get_frame)(struct mcps802154_llhw *llhw, struct sk_buff **skb,
    			    struct mcps802154_rx_frame_info *info);
    	/**
    	 * @rx_get_error_frame: Get information on rejected frame. MCPS can call
    	 * this handler after a frame rejection has been signaled by the
    	 * low-level driver.
    	 */
    	int (*rx_get_error_frame)(struct mcps802154_llhw *llhw,
    				  struct mcps802154_rx_frame_info *info);
    	/**
    	 * @idle: Put the device into idle mode without time limit or until the
    	 * given timestamp.  The driver should call &mcps802154_timer_expired()
    	 * before the given timestamp so that an action can be programmed at the
    	 * given timestamp.
    	 *
    	 * The &mcps802154_timer_expired() function must not be called
    	 * immediately from this callback, but should be scheduled to be called
    	 * later.
    	 *
    	 * If the driver is late, the regular handling of late actions will take
    	 * care of the situation.
    	 */
    	int (*idle)(struct mcps802154_llhw *llhw, bool timestamp,
    		    u32 timestamp_dtu);
    	/**
    	 * @reset: Reset device after an unrecoverable error.
    	 */
    	int (*reset)(struct mcps802154_llhw *llhw);
    	/**
    	 * @get_current_timestamp_dtu: Get current timestamp in device time
    	 * unit.
    	 *
    	 * If the device is currently in a low power state, the eventual wake up
    	 * delay should be added to the returned timestamp.
    	 *
    	 * If the current timestamp can not be determined precisely, it should
    	 * return a pessimistic value, i.e. rounded up.
    	 */
    	int (*get_current_timestamp_dtu)(struct mcps802154_llhw *llhw,
    					 u32 *timestamp_dtu);
    	/**
    	 * @timestamp_dtu_to_rctu: Convert a timestamp in device time unit to
    	 * a timestamp in ranging counter time unit.
    	 */
    	u64 (*timestamp_dtu_to_rctu)(struct mcps802154_llhw *llhw,
    				     u32 timestamp_dtu);
    	/**
    	 * @timestamp_rctu_to_dtu: Convert a timestamp in ranging counter time
    	 * unit to a timestamp in device time unit.
    	 */
    	u32 (*timestamp_rctu_to_dtu)(struct mcps802154_llhw *llhw,
    				     u64 timestamp_rctu);
    	/**
    	 * @tx_timestamp_dtu_to_rmarker_rctu: Compute the RMARKER timestamp in
    	 * ranging counter time unit for a frame transmitted at given timestamp
    	 * in device time unit (RDEV only).
    	 *
    	 * Return: The RMARKER timestamp.
    	 */
    	u64 (*tx_timestamp_dtu_to_rmarker_rctu)(struct mcps802154_llhw *llhw,
    						u32 tx_timestamp_dtu,
    						int ant_id);
    	/**
    	 * @difference_timestamp_rctu: Compute the difference between two
    	 * timestamp values.
    	 *
    	 * Return: The difference between A and B.
    	 */
    	s64 (*difference_timestamp_rctu)(struct mcps802154_llhw *llhw,
    					 u64 timestamp_a_rctu,
    					 u64 timestamp_b_rctu);
    	/**
    	 * @compute_frame_duration_dtu: Compute the duration of a frame with
    	 * given payload length (header and checksum included) using the current
    	 * radio parameters.
    	 *
    	 * Return: The duration in device time unit.
    	 */
    	int (*compute_frame_duration_dtu)(struct mcps802154_llhw *llhw,
    					  int payload_bytes);
    	/**
    	 * @set_channel: Set channel parameters.
    	 */
    	int (*set_channel)(struct mcps802154_llhw *llhw, u8 page, u8 channel,
    			   u8 preamble_code);
    	/**
    	 * @set_hrp_uwb_params: Set radio parameters for HRP UWB.
    	 *
    	 * The parameters in &mcps802154_llhw can change according to radio
    	 * parameters.
    	 */
    	int (*set_hrp_uwb_params)(struct mcps802154_llhw *llhw, int prf,
    				  int psr, int sfd_selector, int phr_rate,
    				  int data_rate);
    	/**
    	 * @set_sts_params: Set STS parameters (ERDEV only).
    	 */
    	int (*set_sts_params)(struct mcps802154_llhw *llhw,
    			      const struct mcps802154_sts_params *params);
    	/**
    	 * @set_hw_addr_filt: Set hardware filter parameters.
    	 */
    	int (*set_hw_addr_filt)(struct mcps802154_llhw *llhw,
    				struct ieee802154_hw_addr_filt *filt,
    				unsigned long changed);
    	/**
    	 * @set_txpower: Set transmission power.
    	 */
    	int (*set_txpower)(struct mcps802154_llhw *llhw, s32 mbm);
    	/**
    	 * @set_cca_mode: Set CCA mode.
    	 *
    	 * The CCA duration in &mcps802154_llhw can change according to CCA
    	 * mode.
    	 */
    	int (*set_cca_mode)(struct mcps802154_llhw *llhw,
    			    const struct wpan_phy_cca *cca);
    	/**
    	 * @set_cca_ed_level: Set CCA energy detection threshold.
    	 */
    	int (*set_cca_ed_level)(struct mcps802154_llhw *llhw, s32 mbm);
    	/**
    	 * @set_promiscuous_mode: Set promiscuous mode.
    	 */
    	int (*set_promiscuous_mode)(struct mcps802154_llhw *llhw, bool on);
    	/**
    	 * @set_scanning_mode: Set SW scanning mode.
    	 */
    	int (*set_scanning_mode)(struct mcps802154_llhw *llhw, bool on);
    	/**
    	 * @set_calibration: Set calibration value.
    	 *
    	 * Set the calibration parameter specified by the key string with the
    	 * value specified in the provided buffer. The provided length must
    	 * match the length returned by the @get_calibration() callback.
    	 */
    	int (*set_calibration)(struct mcps802154_llhw *llhw, const char *key,
    			       void *value, size_t length);
    	/**
    	 * @get_calibration: Get calibration value.
    	 *
    	 * Get the calibration parameter specified by the key string into the
    	 * provided buffer.
    	 *
    	 * Return: size of parameter written in buffer or error.
    	 */
    	int (*get_calibration)(struct mcps802154_llhw *llhw, const char *key,
    			       void *value, size_t length);
    	/**
    	 * @list_calibration: Returns list of accepted calibration key strings.
    	 */
    	const char *const *(*list_calibration)(struct mcps802154_llhw *llhw);
    	/**
    	 * @vendor_cmd: 运行一个供应商特定命令。Run a vendor specific command.
    	 */
    	int (*vendor_cmd)(struct mcps802154_llhw *llhw, u32 vendor_id,
    			  u32 subcmd, void *data, size_t data_len);
    #ifdef CONFIG_MCPS802154_TESTMODE
    	/**
    	 * @testmode_cmd: Run a testmode command.
    	 */
    	int (*testmode_cmd)(struct mcps802154_llhw *llhw, void *data, int len);
    #endif
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
  • 相关阅读:
    Java 序列化和反序列化为什么要实现 Serializable 接口呢?
    家居行业如何借助AI营销数智化转型?《2023 家居行业AI营销第一课(重庆站)》给你答案
    LAST论文翻译
    es搜索功能——DSL查询文档——搜索结果处理
    HTML静态网页成品作业(HTML+CSS)——花主题介绍网页设计制作(1个页面)
    集合——list
    使用 Sealos 构建低成本、高效能的私有云
    先进的人工智能促进更好的业务沟通
    vcs与verdi学习记录
    【GCN基础学习】GCN基本模型概述,图卷积的基本计算方法,邻接矩阵的变换,GCN变换原理
  • 原文地址:https://blog.csdn.net/luo58614013/article/details/133548295