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

python做网站多么慧聪网seo页面优化

python做网站多么,慧聪网seo页面优化,自媒体平台注册方法,深圳网站建设认准乐云践新前言 开组会,感觉全部门的人都会网络,看以太网和 WIFI 体系又过于庞大,看的头昏脑涨。既然那些东西太难了,那就曲线救国,看 CAN 驱动。在 Linux 中 CAN 也是属于网络驱动一部分。但是 CAN 的硬件设计非常的优秀&#…

前言

  1. 开组会,感觉全部门的人都会网络,看以太网和 WIFI 体系又过于庞大,看的头昏脑涨。
  2. 既然那些东西太难了,那就曲线救国,看 CAN 驱动。在 Linux 中 CAN 也是属于网络驱动一部分。
  3. 但是 CAN 的硬件设计非常的优秀,直接把硬件层和数据链路层的活都搞好了,而应用层又不是驱动工程师该做的事情,因此个人感觉 CAN 驱动还是相对简单的。(叠甲:刚接触,小白的莫名其妙自信)
  4. 对于 I2C、SPI 这类驱动程序,是被分为了适配器驱动层和设备驱动层,因为这两种协议通常用于主从模式的板级通信,针对具体设备(如传感器、存储器、转换器等)的通信。而每个设备可能有不同的初始化、读写和中断处理需求。因此,设计有设备驱动层,用于处理与每个设备特有的通信协议。
  5. 而对于 CAN 这类设备,是不会区分主从设备的(可以软件实现,例如 CANopen),他更多的是倾向于传输原始的数据流,因此不进行设备驱动层设计。
  6. 这个时候有人又要说了,UART 不也是倾向于传输原始数据吗?为什么 UART 适配器驱动层上面还有一个 TTY 和字符设备层呢?这是因为,UART 是传输原始数据没错,但是 UART 多用于控制台。而控制台可以是串口,也可以是 LCD 或键盘等多种形式,为了统一标准输入和标准输出,弄了一个 TTY抽象层。
  7. 综上所述,CAN 的设计是相对简单的,基本是原厂适配好 CAN 控制器,那么就可以直接移交给应用层进行数据交互了。
  8. 个人邮箱:zhangyixu02@gmail.com
  9. 微信公众号:风正豪

在这里插入图片描述

正文

Linux 网络通讯设计

  1. 在 Linux 中,所有的网络通讯采用统一的接口,对于底层实现,数据包发送都是调用的 net_device_ops.ndo_start_xmit 函数。
  2. 在网络通讯中,所有的数据接收都是采用中断实现(后面又一个 NAPI 机制,即中断 + 轮询,但 CAN 似乎没有采用该机制)。

CAN control 层

  1. 已提供核心代码,各位根据我提供的代码,与 driver/net/can 目录自行学习,不做赘述。
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/can.h>
#include <linux/can/dev.h>
#include <linux/interrupt.h> // 包含中断相关的接口#define DRV_NAME "simple_can"struct simple_can_priv {struct can_priv can; // 继承自 can_priv 用于 CAN 设备的基本设施int custom_data;     // 自定义数据,比如设备状态或配置
};static const struct can_bittiming_const simple_bittiming_const = {.name = DRV_NAME,        // 定义时序的名称,用于标识或调试.tseg1_min = 4,          // 时间段1的最小值,即TSEG1最少包含的时间量.tseg1_max = 16,         // 时间段1的最大值,即TSEG1最多包含的时间量.tseg2_min = 2,          // 时间段2的最小值,即TSEG2最少包含的时间量.tseg2_max = 8,          // 时间段2的最大值,即TSEG2最多包含的时间量.sjw_max = 4,            // 同步跳转宽度的最大值,用于相位缓冲,可提高时钟容忍度.brp_min = 1,            // 波特率预分频器(BRP)的最小值.brp_max = 256,          // 波特率预分频器(BRP)的最大值.brp_inc = 1,            // 波特率预分频器(BRP)的增量,用于调整通信速率
};// CAN 设备指针
static struct net_device *simple_can_dev;// CAN 设备打开
static int simple_can_open(struct net_device *dev) 
{struct simple_can_priv *priv = netdev_priv(dev);open_candev(dev);/* 芯片原厂工程师提供 CAN 通讯启动操作函数* 启动 CAN 时钟* 启动 CAN 控制器*/can_led_event(dev, CAN_LED_EVENT_OPEN);netif_start_queue(dev);printk(KERN_INFO "simple_can: device opened\n");return 0;
}// CAN 设备关闭
static int simple_can_close(struct net_device *dev) 
{struct simple_can_priv *priv = netdev_priv(dev);netif_stop_queue(dev);/* 芯片原厂工程师提供 CAN 通讯停止操作函数* 关闭 CAN 控制器* 关闭时钟*/close_candev(dev);can_led_event(dev, CAN_LED_EVENT_STOP);printk(KERN_INFO "simple_can: device closed\n");return 0;
}static netdev_tx_t simple_can_start_xmit(struct sk_buff *skb, struct net_device *dev) 
{struct simple_can_priv *priv = netdev_priv(dev);struct can_frame *cf = (struct can_frame *)skb->data;// 检查是否为有效数据包,如果不是有效数据包,则直接丢弃并结束函数if (can_dropped_invalid_skb(ndev, skb))return NETDEV_TX_OK;netif_stop_queue(ndev);/* 芯片原厂工程师解析上层的帧信息,将其存入指定寄存器* 根据 cf->can_id 参数获知当前的数据包是远程帧,扩展帧,还是标准帧* 根据 cf->can_dlc 参数获知当前数据报文中有效数据长度*/// 将数据包存入回环缓冲区can_put_echo_skb(skb, dev, 0);/* 芯片原厂工程师向指定寄存器写入指令,让数据包发往 CAN 总线*/printk(KERN_INFO "simple_can: start xmit\n");return NETDEV_TX_OK;
}static const struct net_device_ops simple_can_netdev_ops = {.ndo_open = simple_can_open,    // 定义设备打开操作.ndo_stop = simple_can_close,   // 定义设备关闭操作.ndo_start_xmit = simple_can_start_xmit, // 定义数据发送操作
};static irqreturn_t simple_can_interrupt(int irq, void *dev_id)
{struct net_device *dev =  (struct net_device *)dev_id;struct simple_can_priv *priv = netdev_priv(dev);struct net_device_stats *stats = &ndev->stats;struct can_frame *cf;struct sk_buff *skb;// 读取 CAN 控制器的硬件寄存器,以确定中断原因if (/* 检测对应寄存器,查看是否为接收中断 */) {// 分配skb并设置其为CAN包skb = alloc_can_skb(dev, &cf);// 将接收的数据放入CAN帧(假定从硬件寄存器读取数据)cf->can_id = /* 设置接收的CAN ID */;cf->can_dlc = get_can_dlc(/* 设置数据长度,通常从寄存器读取 */);memcpy(cf->data, /* 来源于硬件寄存器的数据 */, cf->can_dlc);stats->rx_packets++; // 记录设备接收到的数据包总数stats->rx_bytes += cf->can_dlc;  // 记录设备接收到的字节总数// 提交数据包给上层netif_rx(skb);printk(KERN_INFO "simple_can: received a packet\n");}// 处理其他中断引发的事件(如错误、状态更改等)// 函数退出时记得清除中断标志位return IRQ_HANDLED;
}static int simplecan_chip_start(struct net_device *dev)
{/* 芯片原厂工程师初始化和启动 CAN 控制器 */return 0;
}static int simplecan_set_mode(struct net_device *dev, enum can_mode mode)
{int err;switch (mode) {case CAN_MODE_START:err = simplecan_chip_start(dev);if (err)return err;netif_wake_queue(dev);break;default:return -EOPNOTSUPP;}return 0;
}static int simplecan_get_berr_counter(const struct net_device *dev,struct can_berr_counter *bec)
{bec->txerr = 0; // 模拟传输错误计数bec->rxerr = 0; // 模拟接收错误计数return 0;
}static int __init simple_can_init(void) 
{int irq;struct simple_can_priv *priv;/* 1. 获取设备树相关信息* 获取 CAN 控制器的 GIC 中断号 interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;*/irq = platform_get_irq(pdev, 0);// 2. 分配网络设备simple_can_dev = alloc_candev(0, 0);// 3. 配置 CAN 信息,提供操作集simple_can_dev->netdev_ops = &simple_can_netdev_ops;simple_can_dev->irq = irq;simple_can_dev->flags |= IFF_ECHO;priv = netdev_priv(simple_can_dev); // 获取私有数据区指针memset(priv, 0, sizeof(struct simple_can_priv));priv->custom_data = -1;           // 设置初始的私有数据,芯片原厂工程师看情况填充priv->can.clock.freq = 8000000;   // 假设频率为8MHz,CAN 控制器的时钟频率priv->can.bittiming_const = &simple_bittiming_const;        // 定义 CAN 位时序常量priv->can.do_set_mode = simplecan_set_mode;                 // 设置 CAN 模式priv->can.do_get_berr_counter = simplecan_get_berr_counter; // 获取错误计数器// 指示 CAN 控制器支持哪些控制模式priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING |CAN_CTRLMODE_LISTENONLY |CAN_CTRLMODE_LOOPBACK |CAN_CTRLMODE_3_SAMPLES;/* 4. 请求处理中断函数,网络驱动中,所有的接收都是通过中断实现。* 这里 flags 传入 0,表示中断触发类型采用默认设备树中的 interrupts 成员 flags*/devm_request_irq(&pdev->dev, simple_can_dev->irq, simple_can_interrupt,0, DRV_NAME, simple_can_dev);// 5. 将网络设备注册到内核register_candev(simple_can_dev);printk(KERN_INFO "simple_can: module loaded\n");return 0;
}static void __exit simple_can_exit(void) {unregister_candev(simple_can_dev);free_candev(simple_can_dev);printk(KERN_INFO "simple_can: module unloaded\n");
}module_init(simple_can_init);
module_exit(simple_can_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("https://zyxbeyourself.blog.csdn.net/");
MODULE_DESCRIPTION("Simple CAN Driver Example");

CAN 驱动测试

    1. 测试 CAN 接口是否正常
# 查询当前网络设备
ifconfig -a
# 关闭 CAN  
ip link set can0 down
# 设置仲裁段 1M 波特率,数据段3M波特率
ip link set can0 type can bitrate 1000000 dbitrate 3000000 fd on  
# 打印 can0 信息
ip -details link show can0  
# 启动CAN  
ip link set can0 up
# 发送(标准帧,数据帧,ID:123,date:DEADBEEF)
cansend can0 123##1DEADBEEF  
# 发送(扩展帧,数据帧,ID:00000123,date:DEADBEEF)
cansend can0 00000123##1DEADBEEF
# 开启打印,等待接收
candump can0  
http://www.dtcms.com/wzjs/161558.html

相关文章:

  • 清华紫光做网站关键词排名公司
  • 临桂区住房和城乡建设局门户网站自动发外链工具
  • react 手机网站开发手机网站免费客服系统
  • 房地产开发公司招聘岗位开鲁网站seo免费版
  • 做网站去哪里招商外包
  • 兰州网站制作有哪些如何自己做网络推广
  • 网站开发顶岗实践总结百度快速收录教程
  • 济南城市建设学院网站网站广告策划
  • 做网站和优化共多少钱?广东全网推广
  • 服务好的网站建设联系人知乎关键词优化软件
  • 现在由哪些网站可以做外链可以推广网站
  • 免费公司网站建设口碑营销什么意思
  • 网站开发设计制作推广产品故事软文案例
  • 网站上的3d产品展示怎么做竞价销售是什么意思
  • 霸州网站建设提升seo搜索排名
  • notepad做网站技巧seo免费
  • 网站策划书的撰写互联网运营推广是做什么的
  • 学习html 欣赏好的网站优化法治化营商环境
  • dreamweaver 网站地图阿里云域名查询和注册
  • 新建网站做优化培训心得体会
  • 网站建设模板百度seo引流
  • 鸡西网站开发大一html网页制作作业简单
  • 商城网站建设code521seo外链推广工具
  • 单页seo如何优化seo含义
  • 各种网站开发语言的优缺点线上营销方式
  • shopify可以做企业网站嘛关键词优化公司电话
  • 广州电商网站开发公司seo的中文意思
  • vs 2008网站做安装包网络营销推广专员
  • 公司做网站能够带来的好处怎么做网络销售
  • 网页无法访问怎么回事评论优化