当前位置: 首页 > news >正文

WordPress高端主题 熊/南昌seo搜索排名

WordPress高端主题 熊,南昌seo搜索排名,服装设计师需要什么学历,建筑招聘网站哪个好RK3568 CAN问题:同时收发数据一段时间(几秒钟)can出现错误收发功能异常,必须重新down、up恢复正常 内核更新rockchip_canfd.c、iopoll.h,配置Networking support --->CAN bus subsystem support --->CAN Devic…
RK3568 CAN问题:同时收发数据一段时间(几秒钟)can出现错误收发功能异常,必须重新down、up恢复正常
内核更新rockchip_canfd.c、iopoll.h,配置Networking support  --->CAN bus subsystem support  --->CAN Device Drivers  --->Rockchip CANFD controller, make ARCH=arm64 menuconfig;内核配置后将.config覆盖到arch/arm64/configs/rockchip_linux_defconfig
修改设备树can节点.arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-linux.dts
compatible = "rockchip,rk3568-can-2.0",assigned-clock-rates = <300000000>;//如果CAN的比特率1M建议修改CAN时钟到300M,信号更稳定
./build.sh kernerl
注意:测试时两个节点帧ID不能相同,否则会发生数据错误,且负载率宜控制在30%以内
【负载率计算】
假设报文以定周期发送,总线上的报文只有数据帧一种类型,不存在远程帧、错误帧和过载帧这三种类型。因此每帧报文包括:帧起始(1bit)、仲裁域(29bit)、控制域(6bit)、数据域(8×8bit)、循环冗余码域(15bit)、应答域(2bit)和帧结尾(7bit),共124位。
假设每秒发送的数据帧数为185帧
对于高速CAN总线(500kbps)的负载率 = frac{185*124}\{500*1000}*100\% = 4.58\%
对于低速CAN总线(250kbps)的负载率 = frac{185*124}\{250*1000}*100\% = 9.16\%
【rockchip_canfd.c】
// SPDX-License-Identifier: GPL-2.0
/** Copyright (c) 2020 Rockchip Electronics Co. Ltd.* Rockchip CANFD driver*/#include <linux/delay.h>
#include <linux/iopoll.h>
#include <linux/pinctrl/consumer.h>
#include <linux/clk.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/can/dev.h>
#include <linux/can/error.h>
#include <linux/can/led.h>
#include <linux/reset.h>
#include <linux/pm_runtime.h>/* registers definition */
enum rockchip_canfd_reg {CAN_MODE = 0x00,CAN_CMD = 0x04,CAN_STATE = 0x08,CAN_INT = 0x0c,CAN_INT_MASK = 0x10,CAN_LOSTARB_CODE = 0x28,CAN_ERR_CODE = 0x2c,CAN_RX_ERR_CNT = 0x34,CAN_TX_ERR_CNT = 0x38,CAN_IDCODE = 0x3c,CAN_IDMASK = 0x40,CAN_TX_CHECK_FIC = 0x50,CAN_NBTP = 0x100,CAN_DBTP = 0x104,CAN_TDCR = 0x108,CAN_TSCC = 0x10c,CAN_TSCV = 0x110,CAN_TXEFC = 0x114,CAN_RXFC = 0x118,CAN_AFC = 0x11c,CAN_IDCODE0 = 0x120,CAN_IDMASK0 = 0x124,CAN_IDCODE1 = 0x128,CAN_IDMASK1 = 0x12c,CAN_IDCODE2 = 0x130,CAN_IDMASK2 = 0x134,CAN_IDCODE3 = 0x138,CAN_IDMASK3 = 0x13c,CAN_IDCODE4 = 0x140,CAN_IDMASK4 = 0x144,CAN_TXFIC = 0x200,CAN_TXID = 0x204,CAN_TXDAT0 = 0x208,CAN_TXDAT1 = 0x20c,CAN_TXDAT2 = 0x210,CAN_TXDAT3 = 0x214,CAN_TXDAT4 = 0x218,CAN_TXDAT5 = 0x21c,CAN_TXDAT6 = 0x220,CAN_TXDAT7 = 0x224,CAN_TXDAT8 = 0x228,CAN_TXDAT9 = 0x22c,CAN_TXDAT10 = 0x230,CAN_TXDAT11 = 0x234,CAN_TXDAT12 = 0x238,CAN_TXDAT13 = 0x23c,CAN_TXDAT14 = 0x240,CAN_TXDAT15 = 0x244,CAN_RXFIC = 0x300,CAN_RXID = 0x304,CAN_RXTS = 0x308,CAN_RXDAT0 = 0x30c,CAN_RXDAT1 = 0x310,CAN_RXDAT2 = 0x314,CAN_RXDAT3 = 0x318,CAN_RXDAT4 = 0x31c,CAN_RXDAT5 = 0x320,CAN_RXDAT6 = 0x324,CAN_RXDAT7 = 0x328,CAN_RXDAT8 = 0x32c,CAN_RXDAT9 = 0x330,CAN_RXDAT10 = 0x334,CAN_RXDAT11 = 0x338,CAN_RXDAT12 = 0x33c,CAN_RXDAT13 = 0x340,CAN_RXDAT14 = 0x344,CAN_RXDAT15 = 0x348,CAN_RXFRD = 0x400,CAN_TXEFRD = 0x500,
};enum {ROCKCHIP_CANFD_MODE = 0,ROCKCHIP_CAN_MODE,ROCKCHIP_RK3568_CAN_MODE,
};#define DATE_LENGTH_12_BYTE     (0x9)
#define DATE_LENGTH_16_BYTE     (0xa)
#define DATE_LENGTH_20_BYTE     (0xb)
#define DATE_LENGTH_24_BYTE     (0xc)
#define DATE_LENGTH_32_BYTE     (0xd)
#define DATE_LENGTH_48_BYTE     (0xe)
#define DATE_LENGTH_64_BYTE     (0xf)#define CAN_TX0_REQ             BIT(0)
#define CAN_TX1_REQ             BIT(1)
#define CAN_TX_REQ_FULL         ((CAN_TX0_REQ) | (CAN_TX1_REQ))#define MODE_FDOE               BIT(15)
#define MODE_BRSD               BIT(13)
#define MODE_SPACE_RX           BIT(12)
#define MODE_AUTO_RETX          BIT(10)
#define MODE_RXSORT             BIT(7)
#define MODE_TXORDER            BIT(6)
#define MODE_RXSTX              BIT(5)
#define MODE_LBACK              BIT(4)
#define MODE_SILENT             BIT(3)
#define MODE_SELF_TEST          BIT(2)
#define MODE_SLEEP              BIT(1)
#define RESET_MODE              0
#define WORK_MODE               BIT(0)#define RX_FINISH_INT           BIT(0)
#define TX_FINISH_INT           BIT(1)
#define ERR_WARN_INT            BIT(2)
#define RX_BUF_OV_INT           BIT(3)
#define PASSIVE_ERR_INT         BIT(4)
#define TX_LOSTARB_INT          BIT(5)
#define BUS_ERR_INT             BIT(6)
#define RX_FIFO_FULL_INT        BIT(7)
#define RX_FIFO_OV_INT          BIT(8)
#define BUS_OFF_INT             BIT(9)
#define BUS_OFF_RECOVERY_INT    BIT(10)
#define TSC_OV_INT              BIT(11)
#define TXE_FIFO_OV_INT         BIT(12)
#define TXE_FIFO_FULL_INT       BIT(13)
#define WAKEUP_INT              BIT(14)#define ERR_TYPE_MASK           GENMASK(28, 26)
#define ERR_TYPE_SHIFT          26
#define BIT_ERR                 0
#define STUFF_ERR               1
#define FORM_ERR                2
#define ACK_ERR                 3
#define CRC_ERR                 4
#define ERR_DIR_RX              BIT(25)
#define ERR_LOC_MASK            GENMASK(15, 0)/* Nominal Bit Timing & Prescaler Register (NBTP) */
#define NBTP_MODE_3_SAMPLES     BIT(31)
#define NBTP_NSJW_SHIFT         24
#define NBTP_NSJW_MASK          (0x7f << NBTP_NSJW_SHIFT)
#define NBTP_NBRP_SHIFT         16
#define NBTP_NBRP_MASK          (0xff << NBTP_NBRP_SHIFT)
#define NBTP_NTSEG2_SHIFT       8
#define NBTP_NTSEG2_MASK        (0x7f << NBTP_NTSEG2_SHIFT)
#define NBTP_NTSEG1_SHIFT       0
#define NBTP_NTSEG1_MASK        (0x7f << NBTP_NTSEG1_SHIFT)/* Data Bit Timing & Prescaler Register (DBTP) */
#define DBTP_MODE_3_SAMPLES     BIT(21)
#define DBTP_DSJW_SHIFT         17
#define DBTP_DSJW_MASK          (0xf << DBTP_DSJW_SHIFT)
#define DBTP_DBRP_SHIFT         9
#define DBTP_DBRP_MASK          (0xff << DBTP_DBRP_SHIFT)
#define DBTP_DTSEG2_SHIFT       5
#define DBTP_DTSEG2_MASK        (0xf << DBTP_DTSEG2_SHIFT)
#define DBTP_DTSEG1_SHIFT       0
#define DBTP_DTSEG1_MASK        (0x1f << DBTP_DTSEG1_SHIFT)/* Transmitter Delay Compensation Register (TDCR) */
#define TDCR_TDCO_SHIFT         1
#define TDCR_TDCO_MASK          (0x3f << TDCR_TDCO_SHIFT)
#define TDCR_TDC_ENABLE         BIT(0)#define TX_FD_ENABLE            BIT(5)
#define TX_FD_BRS_ENABLE        BIT(4)#define FIFO_ENABLE             BIT(0)
#define RX_FIFO_CNT0_SHIFT      4
#define RX_FIFO_CNT0_MASK       (0x7 << RX_FIFO_CNT0_SHIFT)
#define RX_FIFO_CNT1_SHIFT      5
#define RX_FIFO_CNT1_MASK       (0x7 << RX_FIFO_CNT1_SHIFT)#define FORMAT_SHIFT            7
#define FORMAT_MASK             (0x1 << FORMAT_SHIFT)
#define RTR_SHIFT               6
#define RTR_MASK                (0x1 << RTR_SHIFT)
#define FDF_SHIFT               5
#define FDF_MASK                (0x1 << FDF_SHIFT)
#define BRS_SHIFT               4
#define BRS_MASK                (0x1 << BRS_SHIFT)
#define DLC_SHIFT               0
#define DLC_MASK                (0xF << DLC_SHIFT)#define CAN_RF_SIZE             0x48
#define CAN_TEF_SIZE            0x8
#define CAN_TXEFRD_OFFSET(n)    (CAN_TXEFRD + CAN_TEF_SIZE * (n))
#define CAN_RXFRD_OFFSET(n)     (CAN_RXFRD + CAN_RF_SIZE * (n))#define CAN_RX_FILTER_MASK      0x1fffffff#define DRV_NAME        "rockchip_canfd"/* rockchip_canfd private data structure */struct rockchip_canfd {struct can_priv can;struct device *dev;struct clk_bulk_data *clks;int num_clks;struct reset_control *reset;void __iomem *base;u32 irqstatus;unsigned long mode;int rx_fifo_shift;u32 rx_fifo_mask;bool txtorx;u32 tx_invalid[4];struct delayed_work tx_err_work;
};static inline u32 rockchip_canfd_read(const struct rockchip_canfd *priv,enum rockchip_canfd_reg reg)
{return readl(priv->base + reg);
}static inline void rockchip_canfd_write(const struct rockchip_canfd *priv,enum rockchip_canfd_reg reg, u32 val)
{writel(val, priv->base + reg);
}static const struct can_bittiming_const rockchip_canfd_bittiming_const = {.name = DRV_NAME,.tseg1_min = 1,.tseg1_max = 128,.tseg2_min = 1,.tseg2_max = 128,.sjw_max = 128,.brp_min = 1,.brp_max = 256,.brp_inc = 2,
};static const struct can_bittiming_const rockchip_canfd_data_bittiming_const = {.name = DRV_NAME,.tseg1_min = 1,.tseg1_max = 32,.tseg2_min = 1,.tseg2_max = 16,.sjw_max = 16,.brp_min = 1,.brp_max = 256,.brp_inc = 2,
};static int set_reset_mode(struct net_device *ndev)
{struct rockchip_canfd *rcan = netdev_priv(ndev);reset_control_assert(rcan->reset);udelay(2);reset_control_deassert(rcan->reset);rockchip_canfd_write(rcan, CAN_MODE, 0);netdev_dbg(ndev, "%s MODE=0x%08x\n", __func__,rockchip_canfd_read(rcan, CAN_MODE));return 0;
}static int set_normal_mode(struct net_device *ndev)
{struct rockchip_canfd *rcan = netdev_priv(ndev);u32 val;val = rockchip_canfd_read(rcan, CAN_MODE);val |= WORK_MODE;rockchip_canfd_write(rcan, CAN_MODE, val);netdev_dbg(ndev, "%s MODE=0x%08x\n", __func__,rockchip_canfd_read(rcan, CAN_MODE));return 0;
}/* bittiming is called in reset_mode only */
static int rockchip_canfd_set_bittiming(struct net_device *ndev)
{struct rockchip_canfd *rcan = netdev_priv(ndev);const struct can_bittiming *bt = &rcan->can.bittiming;const struct can_bittiming *dbt = &rcan->can.data_bittiming;u16 brp, sjw, tseg1, tseg2;u32 reg_btp;brp = (bt->brp >> 1) - 1;sjw = bt->sjw - 1;tseg1 = bt->prop_seg + bt->phase_seg1 - 1;tseg2 = bt->phase_seg2 - 1;reg_btp = (brp << NBTP_NBRP_SHIFT) | (sjw << NBTP_NSJW_SHIFT) |(tseg1 << NBTP_NTSEG1_SHIFT) |(tseg2 << NBTP_NTSEG2_SHIFT);if (rcan->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)reg_btp |= NBTP_MODE_3_SAMPLES;rockchip_canfd_write(rcan, CAN_NBTP, reg_btp);if (rcan->can.ctrlmode & CAN_CTRLMODE_FD) {reg_btp = 0;brp = (dbt->brp >> 1) - 1;sjw = dbt->sjw - 1;tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1;tseg2 = dbt->phase_seg2 - 1;if (dbt->bitrate > 2200000) {u32 tdco;/* Equation based on Bosch's ROCKCHIP_CAN User Manual's* Transmitter Delay Compensation Section*/tdco = (rcan->can.clock.freq / dbt->bitrate) * 2 / 3;/* Max valid TDCO value is 63 */if (tdco > 63)tdco = 63;rockchip_canfd_write(rcan, CAN_TDCR,(tdco << TDCR_TDCO_SHIFT) |TDCR_TDC_ENABLE);}reg_btp |= (brp << DBTP_DBRP_SHIFT) |(sjw << DBTP_DSJW_SHIFT) |(tseg1 << DBTP_DTSEG1_SHIFT) |(tseg2 << DBTP_DTSEG2_SHIFT);if (rcan->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)reg_btp |= DBTP_MODE_3_SAMPLES;rockchip_canfd_write(rcan, CAN_DBTP, reg_btp);}netdev_dbg(ndev, "%s NBTP=0x%08x, DBTP=0x%08x, TDCR=0x%08x\n", __func__,rockchip_canfd_read(rcan, CAN_NBTP),rockchip_canfd_read(rcan, CAN_DBTP),rockchip_canfd_read(rcan, CAN_TDCR));return 0;
}static int rockchip_canfd_get_berr_counter(const struct net_device *ndev,struct can_berr_counter *bec)
{struct rockchip_canfd *rcan = netdev_priv(ndev);int err;err = pm_runtime_get_sync(rcan->dev);if (err < 0) {netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n",__func__, err);return err;}bec->rxerr = rockchip_canfd_read(rcan, CAN_RX_ERR_CNT);bec->txerr = rockchip_canfd_read(rcan, CAN_TX_ERR_CNT);pm_runtime_put(rcan->dev);netdev_dbg(ndev, "%s RX_ERR_CNT=0x%08x, TX_ERR_CNT=0x%08x\n", __func__,rockchip_canfd_read(rcan, CAN_RX_ERR_CNT),rockchip_canfd_read(rcan, CAN_TX_ERR_CNT));return 0;
}static int rockchip_canfd_start(struct net_device *ndev)
{struct rockchip_canfd *rcan = netdev_priv(ndev);u32 val;/* we need to enter the reset mode */set_reset_mode(ndev);rockchip_canfd_write(rcan, CAN_INT_MASK, 0);/* RECEIVING FILTER, accept all */rockchip_canfd_write(rcan, CAN_IDCODE, 0);rockchip_canfd_write(rcan, CAN_IDMASK, CAN_RX_FILTER_MASK);rockchip_canfd_write(rcan, CAN_IDCODE0, 0);rockchip_canfd_write(rcan, CAN_IDMASK0, CAN_RX_FILTER_MASK);rockchip_canfd_write(rcan, CAN_IDCODE1, 0);rockchip_canfd_write(rcan, CAN_IDMASK1, CAN_RX_FILTER_MASK);rockchip_canfd_write(rcan, CAN_IDCODE2, 0);rockchip_canfd_write(rcan, CAN_IDMASK2, CAN_RX_FILTER_MASK);rockchip_canfd_write(rcan, CAN_IDCODE3, 0);rockchip_canfd_write(rcan, CAN_IDMASK3, CAN_RX_FILTER_MASK);rockchip_canfd_write(rcan, CAN_IDCODE4, 0);rockchip_canfd_write(rcan, CAN_IDMASK4, CAN_RX_FILTER_MASK);/* set mode */val = rockchip_canfd_read(rcan, CAN_MODE);/* rx fifo enable */rockchip_canfd_write(rcan, CAN_RXFC,rockchip_canfd_read(rcan, CAN_RXFC) | FIFO_ENABLE);/* Mode */val |= MODE_FDOE;/* Loopback Mode */if (rcan->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)val |= MODE_SELF_TEST | MODE_LBACK;val |= MODE_AUTO_RETX;rockchip_canfd_write(rcan, CAN_MODE, val);rockchip_canfd_set_bittiming(ndev);set_normal_mode(ndev);rcan->can.state = CAN_STATE_ERROR_ACTIVE;netdev_dbg(ndev, "%s MODE=0x%08x, INT_MASK=0x%08x\n", __func__,rockchip_canfd_read(rcan, CAN_MODE),rockchip_canfd_read(rcan, CAN_INT_MASK));return 0;
}static int rockchip_canfd_stop(struct net_device *ndev)
{struct rockchip_canfd *rcan = netdev_priv(ndev);rcan->can.state = CAN_STATE_STOPPED;/* we need to enter reset mode */set_reset_mode(ndev);/* disable all interrupts */rockchip_canfd_write(rcan, CAN_INT_MASK, 0xffff);netdev_dbg(ndev, "%s MODE=0x%08x, INT_MASK=0x%08x\n", __func__,rockchip_canfd_read(rcan, CAN_MODE),rockchip_canfd_read(rcan, CAN_INT_MASK));return 0;
}static int rockchip_canfd_set_mode(struct net_device *ndev,enum can_mode mode)
{int err;switch (mode) {case CAN_MODE_START:err = rockchip_canfd_start(ndev);if (err) {netdev_err(ndev, "starting CAN controller failed!\n");return err;}if (netif_queue_stopped(ndev))netif_wake_queue(ndev);break;default:return -EOPNOTSUPP;}return 0;
}static void rockchip_canfd_tx_err_delay_work(struct work_struct *work)
{struct rockchip_canfd *rcan =container_of(work, struct rockchip_canfd, tx_err_work.work);u32 mode, err_code, id;id = rockchip_canfd_read(rcan, CAN_TXID);err_code = rockchip_canfd_read(rcan, CAN_ERR_CODE);if (err_code & 0x1fe0000) {mode = rockchip_canfd_read(rcan, CAN_MODE);rockchip_canfd_write(rcan, CAN_MODE, 0);rockchip_canfd_write(rcan, CAN_MODE, mode);rockchip_canfd_write(rcan, CAN_CMD, CAN_TX1_REQ);schedule_delayed_work(&rcan->tx_err_work, 1);} else if (rcan->txtorx && rcan->mode >= ROCKCHIP_CAN_MODE && id & CAN_EFF_FLAG) {schedule_delayed_work(&rcan->tx_err_work, 1);}
}/* transmit a CAN message* message layout in the sk_buff should be like this:* xx xx xx xx         ff         ll 00 11 22 33 44 55 66 77* [ can_id ] [flags] [len] [can data (up to 8 bytes]*/
static int rockchip_canfd_start_xmit(struct sk_buff *skb,struct net_device *ndev)
{struct rockchip_canfd *rcan = netdev_priv(ndev);struct canfd_frame *cf = (struct canfd_frame *)skb->data;u32 id, dlc;u32 cmd = CAN_TX0_REQ;int i;unsigned long flags;if (can_dropped_invalid_skb(ndev, skb))return NETDEV_TX_OK;netif_stop_queue(ndev);if (rockchip_canfd_read(rcan, CAN_CMD) & CAN_TX0_REQ)cmd = CAN_TX1_REQ;/* Watch carefully on the bit sequence */if (cf->can_id & CAN_EFF_FLAG) {/* Extended CAN ID format */id = cf->can_id & CAN_EFF_MASK;dlc = can_len2dlc(cf->len) & DLC_MASK;dlc |= FORMAT_MASK;/* Extended frames remote TX request */if (cf->can_id & CAN_RTR_FLAG)dlc |= RTR_MASK;} else {/* Standard CAN ID format */id = cf->can_id & CAN_SFF_MASK;dlc = can_len2dlc(cf->len) & DLC_MASK;/* Standard frames remote TX request */if (cf->can_id & CAN_RTR_FLAG)dlc |= RTR_MASK;}if ((rcan->can.ctrlmode & CAN_CTRLMODE_FD) && can_is_canfd_skb(skb)) {dlc |= TX_FD_ENABLE;if (cf->flags & CANFD_BRS)dlc |= TX_FD_BRS_ENABLE;}if (rcan->txtorx && rcan->mode >= ROCKCHIP_CAN_MODE && cf->can_id & CAN_EFF_FLAG)rockchip_canfd_write(rcan, CAN_MODE, rockchip_canfd_read(rcan, CAN_MODE) | MODE_RXSTX);elserockchip_canfd_write(rcan, CAN_MODE, rockchip_canfd_read(rcan, CAN_MODE) & (~MODE_RXSTX));if (!rcan->txtorx && rcan->mode >= ROCKCHIP_CAN_MODE && cf->can_id & CAN_EFF_FLAG) {/* Two frames are sent consecutively.* Before the first frame is tx finished,* the register of the second frame is configured.* Don't be interrupted in the middle.*/local_irq_save(flags);rockchip_canfd_write(rcan, CAN_TXID, rcan->tx_invalid[1]);rockchip_canfd_write(rcan, CAN_TXFIC, rcan->tx_invalid[0]);rockchip_canfd_write(rcan, CAN_TXDAT0, rcan->tx_invalid[2]);rockchip_canfd_write(rcan, CAN_TXDAT1, rcan->tx_invalid[3]);rockchip_canfd_write(rcan, CAN_CMD, CAN_TX0_REQ);rockchip_canfd_write(rcan, CAN_TXID, id);rockchip_canfd_write(rcan, CAN_TXFIC, dlc);for (i = 0; i < cf->len; i += 4)rockchip_canfd_write(rcan, CAN_TXDAT0 + i,*(u32 *)(cf->data + i));rockchip_canfd_write(rcan, CAN_CMD, CAN_TX1_REQ);local_irq_restore(flags);can_put_echo_skb(skb, ndev, 0);return NETDEV_TX_OK;}rockchip_canfd_write(rcan, CAN_TXID, id);rockchip_canfd_write(rcan, CAN_TXFIC, dlc);for (i = 0; i < cf->len; i += 4)rockchip_canfd_write(rcan, CAN_TXDAT0 + i,*(u32 *)(cf->data + i));rockchip_canfd_write(rcan, CAN_CMD, CAN_TX0_REQ);if (rcan->txtorx && rcan->mode >= ROCKCHIP_CAN_MODE && cf->can_id & CAN_EFF_FLAG)schedule_delayed_work(&rcan->tx_err_work, 1);can_put_echo_skb(skb, ndev, 0);return NETDEV_TX_OK;
}static int rockchip_canfd_rx(struct net_device *ndev)
{struct rockchip_canfd *rcan = netdev_priv(ndev);struct net_device_stats *stats = &ndev->stats;struct canfd_frame *cf;struct sk_buff *skb;u32 id_rockchip_canfd, dlc;int i = 0;u32 __maybe_unused ts, ret;u32 data[16] = {0};dlc = rockchip_canfd_read(rcan, CAN_RXFRD);id_rockchip_canfd = rockchip_canfd_read(rcan, CAN_RXFRD);ts = rockchip_canfd_read(rcan, CAN_RXFRD);for (i = 0; i < 16; i++)data[i] = rockchip_canfd_read(rcan, CAN_RXFRD);if (rcan->mode >= ROCKCHIP_CAN_MODE) {/* may be an empty frame */if (!dlc && !id_rockchip_canfd)return 1;if (rcan->txtorx) {if (rockchip_canfd_read(rcan, CAN_TX_CHECK_FIC) & FORMAT_MASK) {ret = rockchip_canfd_read(rcan, CAN_TXID) & CAN_SFF_MASK;if ((id_rockchip_canfd == ret) && !(dlc & FORMAT_MASK)) {rockchip_canfd_write(rcan, CAN_TX_CHECK_FIC,ts | CAN_TX0_REQ);return 1;} else {return 1;}}}}/* create zero'ed CAN frame buffer */if (dlc & FDF_MASK)skb = alloc_canfd_skb(ndev, &cf);elseskb = alloc_can_skb(ndev, (struct can_frame **)&cf);if (!skb) {stats->rx_dropped++;return 1;}/* Change CAN data length format to socketCAN data format */if (dlc & FDF_MASK)cf->len = can_dlc2len(dlc & DLC_MASK);elsecf->len = get_can_dlc(dlc & DLC_MASK);/* Change CAN ID format to socketCAN ID format */if (dlc & FORMAT_MASK) {/* The received frame is an Extended format frame */cf->can_id = id_rockchip_canfd;cf->can_id |= CAN_EFF_FLAG;if (dlc & RTR_MASK)cf->can_id |= CAN_RTR_FLAG;} else {/* The received frame is a standard format frame */cf->can_id = id_rockchip_canfd;if (dlc & RTR_MASK)cf->can_id |= CAN_RTR_FLAG;}if (dlc & BRS_MASK)cf->flags |= CANFD_BRS;if (!(cf->can_id & CAN_RTR_FLAG)) {/* Change CAN data format to socketCAN data format */for (i = 0; i < cf->len; i += 4)*(u32 *)(cf->data + i) = data[i / 4];}stats->rx_packets++;stats->rx_bytes += cf->len;netif_rx(skb);can_led_event(ndev, CAN_LED_EVENT_RX);return 1;
}static int rockchip_canfd_err(struct net_device *ndev, u32 isr)
{struct rockchip_canfd *rcan = netdev_priv(ndev);struct net_device_stats *stats = &ndev->stats;struct can_frame *cf;struct sk_buff *skb;unsigned int rxerr, txerr;u32 sta_reg;skb = alloc_can_err_skb(ndev, &cf);rxerr = rockchip_canfd_read(rcan, CAN_RX_ERR_CNT);txerr = rockchip_canfd_read(rcan, CAN_TX_ERR_CNT);sta_reg = rockchip_canfd_read(rcan, CAN_STATE);if (skb) {cf->data[6] = txerr;cf->data[7] = rxerr;}if (isr & BUS_OFF_INT) {rcan->can.state = CAN_STATE_BUS_OFF;rcan->can.can_stats.bus_off++;cf->can_id |= CAN_ERR_BUSOFF;} else if (isr & ERR_WARN_INT) {rcan->can.can_stats.error_warning++;rcan->can.state = CAN_STATE_ERROR_WARNING;/* error warning state */if (likely(skb)) {cf->can_id |= CAN_ERR_CRTL;cf->data[1] = (txerr > rxerr) ?CAN_ERR_CRTL_TX_WARNING :CAN_ERR_CRTL_RX_WARNING;cf->data[6] = txerr;cf->data[7] = rxerr;}} else if (isr & PASSIVE_ERR_INT) {rcan->can.can_stats.error_passive++;rcan->can.state = CAN_STATE_ERROR_PASSIVE;/* error passive state */cf->can_id |= CAN_ERR_CRTL;cf->data[1] = (txerr > rxerr) ?CAN_ERR_CRTL_TX_WARNING :CAN_ERR_CRTL_RX_WARNING;cf->data[6] = txerr;cf->data[7] = rxerr;}if (rcan->can.state >= CAN_STATE_BUS_OFF ||((sta_reg & 0x20) == 0x20)) {can_bus_off(ndev);}stats->rx_packets++;stats->rx_bytes += cf->can_dlc;netif_rx(skb);return 0;
}static irqreturn_t rockchip_canfd_interrupt(int irq, void *dev_id)
{struct net_device *ndev = (struct net_device *)dev_id;struct rockchip_canfd *rcan = netdev_priv(ndev);struct net_device_stats *stats = &ndev->stats;u32 err_int = ERR_WARN_INT | RX_BUF_OV_INT | PASSIVE_ERR_INT |TX_LOSTARB_INT | BUS_ERR_INT | BUS_OFF_INT;u32 isr;u32 dlc = 0;u32 quota, work_done = 0;isr = rockchip_canfd_read(rcan, CAN_INT);if (isr & TX_FINISH_INT) {dlc = rockchip_canfd_read(rcan, CAN_TXFIC);/* transmission complete interrupt */if (dlc & FDF_MASK)stats->tx_bytes += can_dlc2len(dlc & DLC_MASK);elsestats->tx_bytes += (dlc & DLC_MASK);stats->tx_packets++;if (rcan->txtorx && rcan->mode >= ROCKCHIP_CAN_MODE && dlc & FORMAT_MASK) {cancel_delayed_work(&rcan->tx_err_work);rockchip_canfd_write(rcan, CAN_TX_CHECK_FIC, FORMAT_MASK);do {quota = (rockchip_canfd_read(rcan, CAN_RXFC) &rcan->rx_fifo_mask) >>rcan->rx_fifo_shift;} while (quota == 0); if (quota) {while (work_done < quota)work_done += rockchip_canfd_rx(ndev);}if (rockchip_canfd_read(rcan, CAN_TX_CHECK_FIC) & CAN_TX0_REQ) {rockchip_canfd_write(rcan, CAN_CMD, CAN_TX1_REQ);read_poll_timeout_atomic(rockchip_canfd_read, quota,(quota & 0x3),0, 5000000, false, rcan, CAN_CMD);}rockchip_canfd_write(rcan, CAN_TX_CHECK_FIC, 0);}rockchip_canfd_write(rcan, CAN_CMD, 0);can_get_echo_skb(ndev, 0);netif_wake_queue(ndev);can_led_event(ndev, CAN_LED_EVENT_TX);}if (isr & RX_FINISH_INT) {quota = (rockchip_canfd_read(rcan, CAN_RXFC) & rcan->rx_fifo_mask) >>rcan->rx_fifo_shift;if (quota) {while (work_done < quota)work_done += rockchip_canfd_rx(ndev);}}if (isr & err_int) {/* error interrupt */if (rockchip_canfd_err(ndev, isr))netdev_err(ndev, "can't allocate buffer - clearing pending interrupts\n");}rockchip_canfd_write(rcan, CAN_INT, isr);return IRQ_HANDLED;
}static int rockchip_canfd_open(struct net_device *ndev)
{struct rockchip_canfd *rcan = netdev_priv(ndev);int err;/* common open */err = open_candev(ndev);if (err)return err;err = pm_runtime_get_sync(rcan->dev);if (err < 0) {netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n",__func__, err);goto exit;}err = rockchip_canfd_start(ndev);if (err) {netdev_err(ndev, "could not start CAN peripheral\n");goto exit_can_start;}can_led_event(ndev, CAN_LED_EVENT_OPEN);netif_start_queue(ndev);netdev_dbg(ndev, "%s\n", __func__);return 0;exit_can_start:pm_runtime_put(rcan->dev);
exit:close_candev(ndev);return err;
}static int rockchip_canfd_close(struct net_device *ndev)
{struct rockchip_canfd *rcan = netdev_priv(ndev);netif_stop_queue(ndev);rockchip_canfd_stop(ndev);close_candev(ndev);can_led_event(ndev, CAN_LED_EVENT_STOP);pm_runtime_put(rcan->dev);cancel_delayed_work_sync(&rcan->tx_err_work);netdev_dbg(ndev, "%s\n", __func__);return 0;
}static const struct net_device_ops rockchip_canfd_netdev_ops = {.ndo_open = rockchip_canfd_open,.ndo_stop = rockchip_canfd_close,.ndo_start_xmit = rockchip_canfd_start_xmit,.ndo_change_mtu = can_change_mtu,
};/*** rockchip_canfd_suspend - Suspend method for the driver* @dev:        Address of the device structure** Put the driver into low power mode.* Return: 0 on success and failure value on error*/
static int __maybe_unused rockchip_canfd_suspend(struct device *dev)
{struct net_device *ndev = dev_get_drvdata(dev);if (netif_running(ndev)) {netif_stop_queue(ndev);netif_device_detach(ndev);rockchip_canfd_stop(ndev);}return pm_runtime_force_suspend(dev);
}/*** rockchip_canfd_resume - Resume from suspend* @dev:        Address of the device structure** Resume operation after suspend.* Return: 0 on success and failure value on error*/
static int __maybe_unused rockchip_canfd_resume(struct device *dev)
{struct net_device *ndev = dev_get_drvdata(dev);int ret;ret = pm_runtime_force_resume(dev);if (ret) {dev_err(dev, "pm_runtime_force_resume failed on resume\n");return ret;}if (netif_running(ndev)) {ret = rockchip_canfd_start(ndev);if (ret) {dev_err(dev, "rockchip_canfd_chip_start failed on resume\n");return ret;}netif_device_attach(ndev);netif_start_queue(ndev);}return 0;
}/*** rockchip_canfd_runtime_suspend - Runtime suspend method for the driver* @dev:        Address of the device structure** Put the driver into low power mode.* Return: 0 always*/
static int __maybe_unused rockchip_canfd_runtime_suspend(struct device *dev)
{struct net_device *ndev = dev_get_drvdata(dev);struct rockchip_canfd *rcan = netdev_priv(ndev);clk_bulk_disable_unprepare(rcan->num_clks, rcan->clks);return 0;
}/*** rockchip_canfd_runtime_resume - Runtime resume from suspend* @dev:        Address of the device structure** Resume operation after suspend.* Return: 0 on success and failure value on error*/
static int __maybe_unused rockchip_canfd_runtime_resume(struct device *dev)
{struct net_device *ndev = dev_get_drvdata(dev);struct rockchip_canfd *rcan = netdev_priv(ndev);int ret;ret = clk_bulk_prepare_enable(rcan->num_clks, rcan->clks);if (ret) {dev_err(dev, "Cannot enable clock.\n");return ret;}return 0;
}static const struct dev_pm_ops rockchip_canfd_dev_pm_ops = {SET_SYSTEM_SLEEP_PM_OPS(rockchip_canfd_suspend, rockchip_canfd_resume)SET_RUNTIME_PM_OPS(rockchip_canfd_runtime_suspend,rockchip_canfd_runtime_resume, NULL)
};static const struct of_device_id rockchip_canfd_of_match[] = {{.compatible = "rockchip,canfd-1.0",.data = (void *)ROCKCHIP_CANFD_MODE},{.compatible = "rockchip,can-2.0",.data = (void *)ROCKCHIP_CAN_MODE},{.compatible = "rockchip,rk3568-can-2.0",.data = (void *)ROCKCHIP_RK3568_CAN_MODE},{},
};
MODULE_DEVICE_TABLE(of, rockchip_canfd_of_match);static int rockchip_canfd_probe(struct platform_device *pdev)
{struct net_device *ndev;struct rockchip_canfd *rcan;struct resource *res;void __iomem *addr;int err, irq;irq = platform_get_irq(pdev, 0);if (irq < 0) {dev_err(&pdev->dev, "could not get a valid irq\n");return -ENODEV;}res = platform_get_resource(pdev, IORESOURCE_MEM, 0);addr = devm_ioremap_resource(&pdev->dev, res);if (IS_ERR(addr))return -EBUSY;ndev = alloc_candev(sizeof(struct rockchip_canfd), 1);if (!ndev) {dev_err(&pdev->dev, "could not allocate memory for CANFD device\n");return -ENOMEM;}rcan = netdev_priv(ndev);/* register interrupt handler */err = devm_request_irq(&pdev->dev, irq, rockchip_canfd_interrupt,0, ndev->name, ndev);if (err) {dev_err(&pdev->dev, "request_irq err: %d\n", err);return err;}rcan->reset = devm_reset_control_array_get(&pdev->dev, false, false);if (IS_ERR(rcan->reset)) {if (PTR_ERR(rcan->reset) != -EPROBE_DEFER)dev_err(&pdev->dev, "failed to get canfd reset lines\n");return PTR_ERR(rcan->reset);}rcan->num_clks = devm_clk_bulk_get_all(&pdev->dev, &rcan->clks);if (rcan->num_clks < 1)return -ENODEV;rcan->mode = (unsigned long)of_device_get_match_data(&pdev->dev);rcan->base = addr;rcan->can.clock.freq = clk_get_rate(rcan->clks[0].clk);rcan->dev = &pdev->dev;rcan->can.state = CAN_STATE_STOPPED;switch (rcan->mode) {case ROCKCHIP_CANFD_MODE:rcan->can.bittiming_const = &rockchip_canfd_bittiming_const;rcan->can.data_bittiming_const = &rockchip_canfd_data_bittiming_const;rcan->can.do_set_mode = rockchip_canfd_set_mode;rcan->can.do_get_berr_counter = rockchip_canfd_get_berr_counter;rcan->can.do_set_bittiming = rockchip_canfd_set_bittiming;rcan->can.do_set_data_bittiming = rockchip_canfd_set_bittiming;rcan->can.ctrlmode = CAN_CTRLMODE_FD;/* IFI CANFD can do both Bosch FD and ISO FD */rcan->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |CAN_CTRLMODE_FD;rcan->rx_fifo_shift = RX_FIFO_CNT0_SHIFT;rcan->rx_fifo_mask = RX_FIFO_CNT0_MASK;break;case ROCKCHIP_CAN_MODE:case ROCKCHIP_RK3568_CAN_MODE:rcan->can.bittiming_const = &rockchip_canfd_bittiming_const;rcan->can.do_set_mode = rockchip_canfd_set_mode;rcan->can.do_get_berr_counter = rockchip_canfd_get_berr_counter;rcan->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING |CAN_CTRLMODE_LISTENONLY |CAN_CTRLMODE_LOOPBACK |CAN_CTRLMODE_3_SAMPLES;rcan->rx_fifo_shift = RX_FIFO_CNT0_SHIFT;rcan->rx_fifo_mask = RX_FIFO_CNT0_MASK;break;default:return -EINVAL;}if (rcan->mode == ROCKCHIP_CAN_MODE) {rcan->rx_fifo_shift = RX_FIFO_CNT1_SHIFT;rcan->rx_fifo_mask = RX_FIFO_CNT1_MASK;}if (device_property_read_u32_array(&pdev->dev,"rockchip,tx-invalid-info",rcan->tx_invalid, 4))rcan->txtorx = 1;ndev->netdev_ops = &rockchip_canfd_netdev_ops;ndev->irq = irq;ndev->flags |= IFF_ECHO;rcan->can.restart_ms = 1;INIT_DELAYED_WORK(&rcan->tx_err_work, rockchip_canfd_tx_err_delay_work);platform_set_drvdata(pdev, ndev);SET_NETDEV_DEV(ndev, &pdev->dev);pm_runtime_enable(&pdev->dev);err = pm_runtime_get_sync(&pdev->dev);if (err < 0) {dev_err(&pdev->dev, "%s: pm_runtime_get failed(%d)\n",__func__, err);goto err_pmdisable;}err = register_candev(ndev);if (err) {dev_err(&pdev->dev, "registering %s failed (err=%d)\n",DRV_NAME, err);goto err_disableclks;}devm_can_led_init(ndev);return 0;err_disableclks:pm_runtime_put(&pdev->dev);
err_pmdisable:pm_runtime_disable(&pdev->dev);free_candev(ndev);return err;
}static int rockchip_canfd_remove(struct platform_device *pdev)
{struct net_device *ndev = platform_get_drvdata(pdev);unregister_netdev(ndev);pm_runtime_disable(&pdev->dev);free_candev(ndev);return 0;
}static struct platform_driver rockchip_canfd_driver = {.driver = {.name = DRV_NAME,.pm = &rockchip_canfd_dev_pm_ops,.of_match_table = rockchip_canfd_of_match,},.probe = rockchip_canfd_probe,.remove = rockchip_canfd_remove,
};
module_platform_driver(rockchip_canfd_driver);MODULE_AUTHOR("Elaine Zhang <zhangqing@rock-chips.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Rockchip CANFD Drivers");

【iopoll.h】
/* SPDX-License-Identifier: GPL-2.0-only */
/** Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.*/#ifndef _LINUX_IOPOLL_H
#define _LINUX_IOPOLL_H#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/ktime.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/io.h>/*** read_poll_timeout - Periodically poll an address until a condition is*                      met or a timeout occurs* @op: accessor function (takes @args as its arguments)* @val: Variable to read the value into* @cond: Break condition (usually involving @val)* @sleep_us: Maximum time to sleep between reads in us (0*            tight-loops).  Should be less than ~20ms since usleep_range*            is used (see Documentation/timers/timers-howto.rst).* @timeout_us: Timeout in us, 0 means never timeout* @sleep_before_read: if it is true, sleep @sleep_us before read.* @args: arguments for @op poll** Returns 0 on success and -ETIMEDOUT upon a timeout. In either* case, the last read value at @args is stored in @val. Must not* be called from atomic context if sleep_us or timeout_us are used.** When available, you'll probably want to use one of the specialized* macros defined below rather than this macro directly.*/
#define read_poll_timeout(op, val, cond, sleep_us, timeout_us, \sleep_before_read, args...) \
({ \u64 __timeout_us = (timeout_us); \unsigned long __sleep_us = (sleep_us); \ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \might_sleep_if((__sleep_us) != 0); \if (sleep_before_read && __sleep_us) \usleep_range((__sleep_us >> 2) + 1, __sleep_us); \for (;;) { \(val) = op(args); \if (cond) \break; \if (__timeout_us && \ktime_compare(ktime_get(), __timeout) > 0) { \(val) = op(args); \break; \} \if (__sleep_us) \usleep_range((__sleep_us >> 2) + 1, __sleep_us); \} \(cond) ? 0 : -ETIMEDOUT; \
})/*** read_poll_timeout_atomic - Periodically poll an address until a condition is*                              met or a timeout occurs* @op: accessor function (takes @args as its arguments)* @val: Variable to read the value into* @cond: Break condition (usually involving @val)* @delay_us: Time to udelay between reads in us (0 tight-loops).  Should*            be less than ~10us since udelay is used (see*            Documentation/timers/timers-howto.rst).* @timeout_us: Timeout in us, 0 means never timeout* @delay_before_read: if it is true, delay @delay_us before read.* @args: arguments for @op poll** Returns 0 on success and -ETIMEDOUT upon a timeout. In either* case, the last read value at @args is stored in @val.** When available, you'll probably want to use one of the specialized* macros defined below rather than this macro directly.*/
#define read_poll_timeout_atomic(op, val, cond, delay_us, timeout_us, \delay_before_read, args...) \
({ \u64 __timeout_us = (timeout_us); \unsigned long __delay_us = (delay_us); \ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \if (delay_before_read && __delay_us) \udelay(__delay_us); \for (;;) { \(val) = op(args); \if (cond) \break; \if (__timeout_us && \ktime_compare(ktime_get(), __timeout) > 0) { \(val) = op(args); \break; \} \if (__delay_us) \udelay(__delay_us); \} \(cond) ? 0 : -ETIMEDOUT; \
})/*** readx_poll_timeout - Periodically poll an address until a condition is met or a timeout occurs* @op: accessor function (takes @addr as its only argument)* @addr: Address to poll* @val: Variable to read the value into* @cond: Break condition (usually involving @val)* @sleep_us: Maximum time to sleep between reads in us (0*            tight-loops).  Should be less than ~20ms since usleep_range*            is used (see Documentation/timers/timers-howto.rst).* @timeout_us: Timeout in us, 0 means never timeout** Returns 0 on success and -ETIMEDOUT upon a timeout. In either* case, the last read value at @addr is stored in @val. Must not* be called from atomic context if sleep_us or timeout_us are used.** When available, you'll probably want to use one of the specialized* macros defined below rather than this macro directly.*/
#define readx_poll_timeout(op, addr, val, cond, sleep_us, timeout_us)   \read_poll_timeout(op, val, cond, sleep_us, timeout_us, false, addr)/*** readx_poll_timeout_atomic - Periodically poll an address until a condition is met or a timeout occurs* @op: accessor function (takes @addr as its only argument)* @addr: Address to poll* @val: Variable to read the value into* @cond: Break condition (usually involving @val)* @delay_us: Time to udelay between reads in us (0 tight-loops).  Should*            be less than ~10us since udelay is used (see*            Documentation/timers/timers-howto.rst).* @timeout_us: Timeout in us, 0 means never timeout** Returns 0 on success and -ETIMEDOUT upon a timeout. In either* case, the last read value at @addr is stored in @val.** When available, you'll probably want to use one of the specialized* macros defined below rather than this macro directly.*/
#define readx_poll_timeout_atomic(op, addr, val, cond, delay_us, timeout_us) \read_poll_timeout_atomic(op, val, cond, delay_us, timeout_us, false, addr)#define readb_poll_timeout(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout(readb, addr, val, cond, delay_us, timeout_us)#define readb_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout_atomic(readb, addr, val, cond, delay_us, timeout_us)#define readw_poll_timeout(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout(readw, addr, val, cond, delay_us, timeout_us)#define readw_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout_atomic(readw, addr, val, cond, delay_us, timeout_us)#define readl_poll_timeout(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout(readl, addr, val, cond, delay_us, timeout_us)#define readl_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout_atomic(readl, addr, val, cond, delay_us, timeout_us)#define readq_poll_timeout(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout(readq, addr, val, cond, delay_us, timeout_us)#define readq_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout_atomic(readq, addr, val, cond, delay_us, timeout_us)#define readb_relaxed_poll_timeout(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout(readb_relaxed, addr, val, cond, delay_us, timeout_us)#define readb_relaxed_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout_atomic(readb_relaxed, addr, val, cond, delay_us, timeout_us)#define readw_relaxed_poll_timeout(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout(readw_relaxed, addr, val, cond, delay_us, timeout_us)#define readw_relaxed_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout_atomic(readw_relaxed, addr, val, cond, delay_us, timeout_us)#define readl_relaxed_poll_timeout(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout(readl_relaxed, addr, val, cond, delay_us, timeout_us)#define readl_relaxed_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout_atomic(readl_relaxed, addr, val, cond, delay_us, timeout_us)#define readq_relaxed_poll_timeout(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout(readq_relaxed, addr, val, cond, delay_us, timeout_us)#define readq_relaxed_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \readx_poll_timeout_atomic(readq_relaxed, addr, val, cond, delay_us, timeout_us)#endif /* _LINUX_IOPOLL_H */

相关文章:

RK3568 CAN驱动更新说明

RK3568 CAN问题&#xff1a;同时收发数据一段时间&#xff08;几秒钟&#xff09;can出现错误收发功能异常&#xff0c;必须重新down、up恢复正常 内核更新rockchip_canfd.c、iopoll.h&#xff0c;配置Networking support --->CAN bus subsystem support --->CAN Devic…...

day47:C++ day7,异常处理、using的第三种用法、类型转换、lambda表达式、STL标准模板库

my_vectoers.h: #ifndef MY_VECTORS_H #define MY_VECTORS_H #include <iostream>using namespace std;template<typename TYPE> class my_vectors { private:TYPE* ptr;int num;int cnum;TYPE* start_ptrNULL;TYPE* end_ptrNULL; public://无参构造my_vectors(){…...

function—— Verilog的函数

文章目录 前言function写法语法举例说明调用 前言 function用法说明。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 function写法 function的标准写法如下&#xff1a; function <返回值的类型或范围>(函数名);<端口说明语句> // in…...

runtime过程中,常见jar问题解决

io.netty java.lang.NoSuchMethodError: io.netty.buffer.PooledByteBufAllocator.<init>此类问题报错&#xff0c;主要是io.netty 多个jar 冲突导致。、 使用以下命令查看同一个jar 有哪些版本 mvn dependency:resolve -Dclassifiersources对一些不愿意引入的依赖加上…...

ElementPlus· banner轮播图实现

功能&#xff0c;①通用型&#xff0c;三方组件完成&#xff08;如&#xff0c;elementPlus&#xff09; ②自己写 轮播图 本文使用vue3中的UI框架——elementPlus——三方组件中的 <el-carousel> 实现轮播图 // 组件静态模板 <template><div class"hom…...

Linux自动化构建项目工具——Makefile/makefile

目录 一&#xff0c;背景知识 二&#xff0c;makefile/Makefile的编写 1.创建makefile/Makefile文件 2.在Makefile文件里写编译代码 3.伪目标——.PHONY 1.伪目标的特点 2.怎样实现总是被执行 4.Makefile/makefile文件的不同编写风格 1.背景知识 2.改写 一&#xff0c;背…...

第11章 字符串和字符串函数

本章介绍以下内容&#xff1a; 函数&#xff1a;gets()、gets_s()、fgets()、puts()、fputs()、strcat()、strncat()、strcmp()、strncmp()、strcpy()、strncpy()、sprintf()、strchr() 创建并使用字符串 使用C库中的字符和字符串函数&#xff0c;并创建自定义的字符串函数 使用…...

TypeScript项目配置

前言 我们需要建立tsconfig.json 作用 用于标识 TypeScript 项目的根路径&#xff1b; 用于配置 TypeScript 编译器&#xff1b; 用于指定编译的文件。 重要字段 files - 设置要编译的文件的名称&#xff1b; include - 设置需要进行编译的文件&#xff0c;支持…...

【Spring面试】二、BeanFactory与IoC容器的加载

文章目录 Q1、BeanFactory的作用是什么&#xff1f;Q2、BeanDefinition的作用是什么&#xff1f;Q3、BeanFactory和ApplicationContext有什么区别&#xff1f;Q4、BeanFactory和FactoryBean有什么区别&#xff1f;Q5、说下Spring IoC容器的加载过程&#xff08;※&#xff09;Q…...

Android嵌套事务

这时候旋转设备还是会重置秒表。旋转设备时Android会重新创建活动。如果你的活动包含一个 < fragment >元素&#xff0c;每次重新创建活动时&#xff0c;它会重新插入片段的一个新版本。老片段被丢掉&#xff0c;所有实例变量会设置其初始值。在这个特定的例子中&#xf…...

如何让项目准时上线?

项目为什么容易延期&#xff1f; 1、软件研发是一项创造性工作 项目延期是一种普遍现象&#xff0c;管理者最为头疼的一个问题。但是外人并不理解。明明是你们自己做的计划&#xff0c;怎么总会出现这么多问题。说到底&#xff0c;这是由于我们的工作特性决定的。我们做的是一…...

ChatGPT 和 Elasticsearch:APM 工具、性能和成本分析

作者&#xff1a;LUCA WINTERGERST 在本博客中&#xff0c;我们将测试一个使用 OpenAI 的 Python 应用程序并分析其性能以及运行该应用程序的成本。 使用从应用程序收集的数据&#xff0c;我们还将展示如何将 LLMs 成到你的应用程序中。 在之前的博客文章中&#xff0c;我们构建…...

不使用辅助变量的前提下实现两个变量的交换

package operator; //不用第三个辅助变量&#xff0c;实现两个数的交换 public class Demo08 {public static void change(int a, int b){a ab;b a-b;a a-b;System.out.println(a);System.out.println(b);}public static void main(String[] args) {change(900,3000);} }后续…...

SV-DJS-i13电梯对讲网关

SV-DJS-i13电梯对讲网关 DJS-I13 是一款主要应用于电梯场景的对讲设备&#xff0c;可以将电梯原有模拟通话器的模拟信号转换成数字信号&#xff0c;不仅有稳定性好、电信级音质的优点&#xff0c;且完美兼容当下所有基于SIP的主流IPPBX/软交换/IMS平台,如Asterisk, Broadsoft,…...

论文解析-基因序列编码算法DeepSEA

论文解析-DeepSEA 参考亮点功能 方法数据集来源数据 实验评估评估DeepSEA预测染色质特征的性能评估DeepSEA在变异序列上的DHS预测性能数据集结果 参考 Zhou, J., Troyanskaya, O. Predicting effects of noncoding variants with deep learning–based sequence model. Nat Me…...

计组与操作系统

非科班出身的程序员&#xff0c;还是得补一下相关理论课程&#xff0c;最近看了下九曲阑干关于CSAPP的视频&#xff0c;学习了一下计算机组成原理&#xff0c;这里列一下相关知识点。 计算机组成原理&#xff1a; 数的表示与运算&#xff1a;CSAPP第二章 指令系统&#xff0…...

Pytorch中张量矩阵乘法函数(mm, bmm, matmul)使用说明,含高维张量实例及运行结果

Pytorch中张量矩阵乘法函数使用说明 1 torch.mm() 函数1.1 torch.mm() 函数定义及参数1.2 torch.bmm() 官方示例 2 torch.bmm() 函数2.1 torch.bmm() 函数定义及参数2.2 torch.bmm() 官方示例 3 torch.matmul() 函数3.1 torch.matmul() 函数定义及参数3.2 torch.matmul() 规则约…...

如何在matlab绘图的标题中添加变量?变量的格式化字符串输出浅析

文章目录 matlab的格式化输出控制符字段宽度、精度和对齐方式的控制matlab的格式化输出总结 matlab的格式化输出控制符 Matlab在画图的时候&#xff0c;采用title函数可以增加标题&#xff0c;该函数的输入是一个字符串&#xff0c;有时候我们想在字符串中添加一些变量&#x…...

Spring MVC 八 - 内置过滤器

SpringMVC内置如下过滤器&#xff1a; Form DataForwarded HeadersShallow ETagCORS Form Data 浏览器可以通过HTTP GET或HTTP POST提交form data&#xff08;表单数据&#xff09;&#xff0c;但是非浏览器客户端可以通过HTTP PUT、HTTP DELETE、HTTP PATCH提交表单数据。但…...

@Change监听事件与vue监听属性:watch的区别?

change 和 watch 是 Vue 中用于处理数据变化的两种不同方式。 1. change: - change 是一个事件监听器&#xff0c;用于监听特定DOM元素的变化事件&#xff0c;通常用于表单元素&#xff08;如输入框、下拉框等&#xff09;的值变化。 - 它在用户与表单元素交互并提交了变化时触…...

C++面试记录之中望软件

上次面试体验不好&#xff0c;记录了&#xff0c;这次同样记录一次体验不好的面试&#xff0c;中望软件…直接写了名字&#xff0c;因为真的很无语&#x1f613; 记录一下我不知道的问题 忘记录音了&#x1f622; 1. main函数之前做了什么&#xff1f; 我&#xff1a;实话我…...

多功能翻译工具:全球翻译、润色和摘要生成 | 开源日报 0914

openai-translator/openai-translator Stars: 18.1k License: AGPL-3.0 这个项目是一个多功能翻译工具&#xff0c;由 OpenAI 提供支持。 可以进行全球单词翻译、单词润色和摘要生成等操作提供三种模式&#xff1a;翻译、润色和摘要支持 55 种不同语言的互相转换支持流模式允…...

在 Vue.js 中,使用 watch 监听data变量如:对象属性/data变量

watch 监听对象属性 在 Vue.js 中&#xff0c;使用 watch 监听对象属性的变化时&#xff0c;应该将属性名作为字符串传递给 watch 选项。 示例如下&#xff1a; javascript watch: {addform.isCheck1: function(newValue) {console.log(newValue);var quantity this.addform…...

vue中预览xml并高亮显示

项目中有需要将接口返回的数据流显示出来&#xff0c;并高亮显示&#xff1b; 1.后端接口返回blob,类型为xml,如图 2.页面中使用pre code标签&#xff1a; <pre v-if"showXML"><code class"language-xml">{{xml}}</code></pre> …...

MFC中嵌入显示opencv窗口

在MFC窗体中建立一个Picture Control控件,用于显示opencv窗口 在属性中设置图片控件的资源ID为IDC_PIC1 主要的思路: 使用GetWindowRect可以获取图片控件的区域 使用cv::resizeWindow可以设置opencv窗口的大小,适合图片控件的大小 使用cvGetWindowHandle函数可以获取到ope…...

金鸣识别网页版:轻松实现表格识别的神器

来百度APP畅享高清图片 金鸣识别网页版是一款功能强大的在线识别工具&#xff0c;它可对图片或PDF中的表格文本内容进行识别&#xff0c;还支持各种证票的结构化识别。以下是以表格识别为例&#xff0c;对金鸣识别网页版的操作说明进行详细介绍&#xff1a; 首先&#xff0c;打…...

DasViewer可以设置打开指定文件吗?

答&#xff1a;会员可以。工具里面选择坐标转换&#xff0c;输入源数据&#xff0c;设置好源坐标和目标坐标以及路径。根据两张坐标系的性质选择转换方式。 DasViewer是由大势智慧自主研发的免费的实景三维模型浏览器,采用多细节层次模型逐步自适应加载技术,让用户在极低的电脑…...

uniapp微信小程序用户隐私保护指引弹窗组件

<template><view v-if"showPrivacy" :class"privacyClass"><view :class"contentClass"><view class"title">用户隐私保护指引</view><view class"des">感谢您选择使用我们的小程序&am…...

Java的反射应用(Method和Class)

记录&#xff1a;473 场景&#xff1a;使用java.lang.reflect.Method和java.lang.Class类&#xff0c;根据Java反射原理实现使用指定字符串类名和方法名称&#xff0c;调用对应对象和对应方法。 版本&#xff1a;JDK 1.8。 1.使用Java反射调用指定类的指定方法 (1)参数说明…...

Java之泛型系列--Class使用泛型的方法(有示例)

原文网址&#xff1a;Java之泛型系列--Class使用泛型的方法(有示例)_IT利刃出鞘的博客-CSDN博客 简介 本文用示例介绍Java在方法前加泛型的使用。 类类型的写法 对象所对应的类的泛型写法 Class classAClass<T> classAClass<?> classB Class与Class<?&g…...