AUTOSAR通信篇 - CAN网络通信(二:CanIf)

目录

初始化

数据发送

请求发送

发送数据流

发送缓存

发送确认

数据接收

数据接收提醒

读取接收数据

CAN控制器模式

控制器模式转换

唤醒

PDU通道模式控制

PDU通道组

PDU通道模式

总结


在上一篇,我们介绍了CAN模块,接下来我们介绍在CAN模块之上的模块Can Interface(CanIf)模块。在AUTOSAR软件架构中,CanIf也在BSW层,它处于CAN模块之上紧挨着CAN模块。CanIf是一个硬件独立层,具有到 CAN 驱动程序和 CAN 收发器驱动程序层以及 PDU 路由器、通信管理器和网络管理等上层的标准化接口。 所有需要 CAN 通信的上层都必须与负责 CAN 通信处理的 CanIf通信。 这包括消息的传输和接收以及 CAN 控制器的状态处理。下图显示了 CAN 接口在 AUTOSAR 架构中的位置。

 CanIf 提供的服务可分为以下几大类:

  • 初始化
  • 数据发送
  • 数据接收
  • Can控制器模式控制
  • PDU 模式控制

在介绍CanIf提供的服务之前,我们首先理解几个概念:Hardware Object Handles(HOH)、Hardware Transmit Handle(HTH) 和 Hardware Receive Handle(HRH)。

HOH是CAN Mailbox数据结构的抽象,它包括CanId、DLC和数据等CAN相关的参数。基于CAN硬件buffer抽象出来的在CanIf中被引用的硬件对象是独立于CAN硬件buffer。HOH被用做调用CanDrv的接口服务的传参,它有CanDrv的配置提供,被CanDrv用来识别CAN邮箱的通信buffer。

CanIf作为HOH的使用者,不会根据硬件特定信息对其进行解释。 因此,CanIf 保持独立于硬件

HOH分为两类:HTH和HRH

  • HRH是对一个CAN控制器信箱的逻辑Hardware Receive Object的引用的handle;
  • HTH是对一个CAN控制器信箱的逻辑Hardware Transmit Object的引用的handle;

一个HRH可以被配置用于接收:

  • 一个CanId(FullCan)
  • 一组CanIds(BasicCan)
  • 一个范围/区域 CanIds(BasicCan)
  • 所有CanIds

一个HTH可以被配置用于发送:

  • 一个CanId
  • 固定的一组CanIds

下图是一帧Can报文到硬件对象之间的映射关系

 HTH需要在配置阶段静态分配到一个CanIfBufferCfg,CanIf Tx L-PDU不直接引用HTHs而是引用CanIfBufferCfg。

CanIf 存储有关为传输目的配置的可用硬件对象的信息。 函数CanIf_Transmit()将CanTxPduId映射到对应的HTH,调用函数Can_Write()。

如果全局启用总线镜像并且已通过调用 CAN 控制器的 CanIf_EnableBusMirroring() 激活,则 CanIf 应在使用 Can_Write() 在该控制器上传输之前存储每个帧的内容。帧内容只应在实际发送时提供给总线镜像模块。 因此,必须存储帧内容,以便它可以从 CanIf_TxConfirmation() 中提供给总线镜像模块。

初始化

EcuM调用CanIf的函数CanIf_Init()对整个CanIf进行初始化。 所有全局变量和数据结构都在初始化过程中被初始化,包括标志和缓冲区。 EcuM通过调用相应的初始化服务分别对CanDrvs和CanTrcvs进行初始化。 CanIf 期望 CAN 控制器在初始化过程完成后保持在 STOPPED 模式,就像在上电复位之后一样。 在这种模式下,CanIf 和 CanDrv 既不能发送也不能接收 CAN L-PDU。 如果需要在运行时重新初始化整个 CAN 模块,EcuM 应调用 CanSm 以通过调用 CAN 接口模块的 API 服务 CanIf_SetControllerMode () 来发起所需的CAN 控制器状态转换。 CanIf 将来自 CanSm 的调用映射到相应 CanDrvs 的调用。

数据发送

请求发送

CanIf 的发送请求函数 CanIf_Transmit() 是上层在 CAN 网络上发送 L-PDU 的通用接口。 上层通信层模块仅通过 CanIf 的服务发起传输,而无需直接访问 CanDrv。 如果 CanDrv 可以将 L-PDU 数据写入 CAN 硬件传输对象,则发起的传输请求成功完成。

CanIf在调用CanIf_Transmit()时执行以下行为:

  • 检查CanIf的初始化状态;
  • 识别CanDrv(仅当使用多个CanDrv时)
  • 决定用于访问CAN硬件传输对象的HTH
  • 调用CanDrv的Can_Write()函数

如果发送成功,CanIf_Transmit()返回E_OK。

发送请求时序图

发送数据流

传输请求服务 CanIf_Transmit() 是基于 L-PDU。 对 L-SDU 特定数据的访问由以下参数组织:

  • Transmit L-PDU => L-SDU ID
  • 引用一个数据结构,其中包含L-SDU相关数据:指向L-SDU的指针,指向MetaData的指针和L-SDU长度。

对 L-SDU 数据结构的引用在多个 CanIf 的 API 服务中用作参数,例如 CanIf_Transmit() 或回调服务 <User_RxIndication>()。在 L-PDU 被配置为触发传输的情况下,L-SDU 指针是空指针。

发送数据流示意图

发送缓存

 在 CanIf 范围内,传输过程从调用 CanIf_Transmit() 开始,到调用上层模块的回调服务 <User_TxConfirmation>() 结束。在传输过程中,CanIf、CanDrv 和 CAN Mailbox 一起将要传输的 L-PDU 存储在一个位置。 根据传输方式,它们是:

  • CAN硬件传输对象,或
  • CanIf内部的发送L-PDU buffer(如果使能发送缓存)

如果使能发送缓存,如果Tx L-PDU在请求发送时被CanDrv拒绝,CanIf将会把Tx L-PDU储存在CanIf Transmit L-PDU buffer(即CanIfBufferCfg),但每个Tx L-PDU实体只会存一次。如果没有使能发送缓存,如果发送请求被拒绝,CanIf_Transmit()函数返回发送失败;若使能了发送缓存,发送请求因CanDrv CAN_BUSY被拒绝,L-PDU被缓存在CanIf的CanIfTxBuffer,此时尽管发送行为并未执行,但CanIf_Transmit()函数返回E_OK,在这种情况下,CanIf 通过 CanIf_TxConfirmation() 回调处理 L-PDU 的未完成传输,上层不必重试传输请求。

每个Tx L-PDU通过CanIfBufferCfg配置容器引用HTHs,即使不使用发送缓存也是这样配置,只不过这种情况中CanIfBufferCfg的参数CanIfBufferSize设置为0,此时CanIfBufferCfg配置容器仅仅是一个引用HTH的媒介。

当CanIfBufferSize配置大于0时,即可缓存CanIf Tx L-PDU或发送请求。如果L-PDU的发送需要保持特殊的次序,那么上层发送报文的请求必须依赖于前一帧报文发送成功的确认。

如果Tx L-PDU已经被缓存过,那么下次该L-PDU的缓存会直接覆盖上一次缓存的内容,因此发送出去的总是最新的数据。如果所有buffer都被占用,此时CanIf_Transmit()被调用发送一帧新的L-PDU(未被缓存过),那么该新的L-PDU或发送请求不会被缓存,CanIf_Transmit()返回E_NOT_OK。

CanIf在传输确认过程会判断CanIfTxBuffer中是否有缓存的L-PDU或发送请求,如果有则将其放入空闲的硬件传输对象。此过程是遵循优先级仲裁的,即优先级最高的先发送,CanIf对L-PDU和发送请求不做区分。当Can_Write()返回E_OK,CanIf立即将该L-PDU或发送请求从缓存清除(在发送确认返回之前)。

发送确认

如果前一个发送请求成功完成,CanDrv通过调用CanIf_TxConfirmation()通知CanIf。如果总线镜像全局使能且已调用CanIf_EnableBusMirroringSupport()对CAN控制器激活,那么在该CAN控制器上每帧经过CanIf_TxConfirmation()确认发送的报文,CanIf都应调用Mirror_ReportCanFrame()以存储报文内容和实际的CAN ID。

当CanIf_TxConformation()被调用时,CanIf需要识别被成功传输的L-PDU所连接的上层,并通过调用<User_TxConfirmation>(E_OK)通知上层传输完成,<User_TxConfirmation>()由上层实现。

上层通信层模块可以设计或配置为,用针对不同L-PDU或L-PDU组的单个或多个回调服务来处理发送确认。所有这些服务均在相应L-PDU发送请求的发送确认中由CanIf调用。Transmit L-PDU 能够发送与目标上层模块相关的不同的确认服务,此分配是在配置期间静态分配的。一个transmit L-PDU只能分配一个发送确认回调服务。

 

发送确认时序图(轮询模式)

数据接收

依照AUTOSAR基础软件架构,接收到的数据由上层通信栈(如:COM,CanNM,CanTp,DCM)解析,这意味着上层模块既不直接访问CanDrv的Rx缓存也不直接访问CanIf的Tx缓存。当CanIfPublicReadRxPduDataApi设为TRUE时,CanIf提供内部缓存Rx消息。当接收到一帧新L-PDU,CanDrv调用CanIf的CanIf_RxIndication()函数通知CanIf。对L-PDU数据的访问由以下参数组成:

  • Hardware Receive Handle(HRH)
  • Received CAN Identifier(CanId)
  • Received Data Length
  • Reference to Received L-PDU

Received L-PDU是独立于硬件的,位于通信系统的最底层CanDrv。HRH相当于CanDrv和使用L-PDU的上层之间的连接器。

在CanDrv调用CanIf_RxIndication()提示接收到L-PDU后,CanIf进行接收到收到报文提醒的后续处理。CanIf 无法识别 CanDrv 是使用临时缓冲还是直接硬件访问。 它期望在调用 CanIf_RxIndication() 时使用标准化的 L-PDU 数据。CAN硬件对象会被锁定直到数据拷贝到临时或上层模块buffer结束才结束。在CanIf的CanIf_RxIndication()函数返回后CAN硬件对象立即释放以避免(接收)数据丢失。属于所接收L-PDU的CanDrv、CanIf以及上层模块访问同一个临时的中间buffer,该临时中间buffer位于CAN控制器的CAN硬件对象或者位于CanDrv中的临时buffer。

报文接收数据流

数据接收提醒

 函数CanIf_RxIndictaion()的参数引用了最新接收的CAN L-PDU。若函数CanIf_RxIndication()被调用,CanIf将评估接收到的CAN L-PDU并准备L-SDU用以后续上层通信模块访问。CAN L-PDU检测通过,若配置有<User_RxIndication>(), CanIf通过<User_RxIndication>()异步通知上层模块。详细过程如下:

如果全局使能总线镜像功能,并且通过调用CanIf_EnableBusMirroringSupport()针对CAN控制器激活,那么针对该CAN控制器接收的每一帧由CanIf_RxIndication()提醒的报文,CanIf应该调用Mirror_ReportCanFrame()。当CanIf_RxIndication()被调用,CanIf对接收的L-PDU进行软件过滤,若L-PDU没通过软件过滤,CanIf结束接收;若接收的L-PDU通过CanIf的软件过滤,CanIf进行数据长度校验;若通过数据长度校验,CanIf根据配置的数据长度拷贝数据到静态接收buffer。如果接收的L-PDU配置使用了MetaData还需要将CAN ID拷贝到CAN_ID-32类型的MetaDataItem。CanIf识别所接收的L-PDU是否配置了目标上层模块(CanIfRxPduUserRxIndicationUL),若配置目标上层模块,对对该L-PDU调用上层模块提供的提醒回调(CanIfRxPduUserRxIndicationName)。

一个L-PDU只可分配一个接收提醒回调服务函数

总结起来,在调用CanIf_RxIndication()阶段,CanIf做以下工作:

  • 软件滤波(仅针对BasicCAN)
  • 数据长度校验
  • 缓存接收到的L-PDU
  • 调用上层接收提醒回调服务

以上CanIf所作的工作都依赖于配置属性,若静态配置时没有配置,则跳过相应步骤

读取接收数据

上层模块用于读取从CAN网络接收到的L-PDU数据的API CanIf_ReadRxPduData()是共用的。上层模块只通过CanIf发起接受请求,并不直接访问CanDrv,当CanIf将接收到的L-PDU写入上层模块的buffer后,接受请求成功完成。函数CanIf_ReadRxPduData()可以在不依赖接收事件(RxIndication)的情况下读出数据。如果在配置时启用(参见CanIfPublicReadRxPduDataApi),则不一定要为L-SDU配置接收指示服务(参见CanIfRxPduUserRxIndicationUL)。如果需要,也可以启用接收指示。

通过这种方式CanIf的上层模块接收L-PDU的机制可以在配置时用参数CanIfRxPduUserRxIndicationUL和CanIfRxPduReadData根据上层模块的需求选择。

如果配置参数CanIfPublicReadRxPduDataApi设置为TRUE,CanIf应将每个接收到的L-SDU(CanIfRxPduReadData启用)存储到接收L-SDU缓冲器中。这意味着如果配置参数CanIfRxPduReadData设置为TRUE,CanIf必须为该接收L-SDU分配一个接收L-SDU buffer。调用CanIfRxIndication()后,通过软件滤波和数据长度校验CanIf应将接收到的L-SDU存放到这个接收L-SDU buffer,在调用CanIfRxReadData()时,分配的L_SDU buffer已有最近接收的L-SDU。

数据读取时序图

CAN控制器模式

CanIf提供服务,用以控制底层CAN控制器的通信模式。这意味着所有CAN控制器都由相应提供的API服务控制,以请求和读取当前控制器模式。当上层模块调用CanIf_SetControllerMode()请求时,CAN控制器状态可能会被更改,上层模块的请求,由CanIf通过CanDrv的API传递到相应CAN控制器。

对连接在一个CAN网络上的所有CAN控制器进行一致的管理是CanSm的任务。通过这种方式,CanSm负责将一个CAN网络的所有CAN控制器按照一定顺序设置为睡眠模式或唤醒它们。CanIf通过调用函数CanIf_SetControllerMode()或CanIf_ControllerBusOff()来接受每个状态转换请求。CanIf不决定CAN控制器请求的模式转换是否有效。CanIf仅通过获取当前模式和执行所请求的模式转换来与CanDrv交互。即网络相关状态机在CanSm中实现,CanIf仅存储请求的模式并执行请求的转换,根据CanSm请求的运行模式,CanIf转发请求CanDrvs。

控制器模式转换

基于切换请求,实际的切换的动作以异步的方式发生,如请求进入CAN_CS_SLEEP模式。状态成功切换到CAN_CS_SLEEP模式后,CanDrv调用函数CanIf_ControllerModeIndication()通知CanIf,CanIf调用<User_ControllerModeIndication>()将状态切换结果通过回调函数异步通知上层。上层模块可以通过CanIf_GetControllerMode()轮询控制器当前的模式。

并非所有CAN控制器都支持Sleep和Wake-Up模式。CanDrv通过其接口提供独立于硬件的操作模式来封装这些模式,这些模式必须由CanIf管理。

唤醒

CanIf识别内部发起的CAN控制器唤醒(内部唤醒)和CAN网络唤醒请求(外部唤醒)。内部唤醒调用CanIf的函数CanIf_SetControllerMode(ControllerId,CAN_CS_STARTED)发起;外部唤醒是CanDrv或CanTrcv发给ECU集成代码的CAN控制器事件。

无论使用何种唤醒方法(直接关于CAN控制器或CAN收发器),只要CAN控制器和CAN收发器设置为某种“监听唤醒”模式,ECU都支持通过CAN网络唤醒。这通常是一种睡眠模式,在这种模式下,通常的通信被禁用。只有这种模式才能确保CAN控制器停止运行。因此,可以使能唤醒中断。CAN网络唤醒包括两个步骤:

  • 唤醒检测
  • 唤醒验证

唤醒检测:如果使能CAN网络支持唤醒,通过服务CanIf_CheckWakeup(WakeupSource)检测到唤醒,就通知CanIf。在CAN总线“唤醒”事件的情况下,可能会在执行EcuM_CheckWakeup(WakeupSource)期间调用函数CanIf_CheckWakeup(WakeupSource)。当CanIf_CheckWakeup(EcuM_WakeupSourceType WakeupSource)被调用,CanIf通过函数 Can_CheckWakeup()或CanTrcv_CheckWakeup() "询问" CanDrvs / CanTrcvs具体那个CAN硬件设备引起的总线唤醒。如果Can_CheckWakeup()或CanTrcv_CheckWakeup()至少一个返回E_OK,那么CanIf_CheckWakeup()返回E_OK,若Can_CheckWakeup()或CanTrcv_CheckWakeup()均返回E_NOT_OK,那么CanIf_CheckWakeup()返回E_NOT_OK。被调用的通信服务属于配置期间定义的服务(见CanIfDispatchCfg)。通过这种方式,ECU和CanSm能够改变CAN控制器状态,并控制与总线关闭恢复或唤醒程序相关步骤的系统行为。

唤醒验证:当检测到总线唤醒事件,该唤醒事件会被直接通知到ECU状态管理器,若该唤醒事件需要验证,EcuM(或者一个CDD)将打开对应CAN控制器(CanIf_SetControllerMode())和CAN收发器(CanIf_SetTrcvMode())

PDU通道模式控制

PDU通道组

每个L-PDU被分配给一个专用的物理CAN通道,该通道连接到一个CAN控制器和一个CAN网络。通过这种方式,可以从处理逻辑上单个L-PDU信道组的角度来控制属于一个物理信道的所有L-PDU。这些逻辑组代表一个ECU连接到一个底层CAN网络的所有L-PDU。下图所示为通道L-PDU组以及和它相关上层和网络的示意图:

通道PDU组

一个L-PDU只能分配给一个通道组,典型的如PduR和网络管理模块负责控制PDU工作模式。

PDU通道模式

PDU通道模式切换只有在CAN控制器模式为CAN_CS_STARTED模式下才可以进行。PDU通道有四种模式:

  • CANIF_OFFLINE
  • CANIF_TX_OFFLINE
  • CANIF_TX_OFFLINE_ACTIVE
  • CANIF_ONLINE

下图所示为PDU通道模式转换图

CanIf提供接口函数CanIf_GetPduMode()可用于获取当前PDU通道模式;接口函数CanIf_SetPduMode()用于设置PDU通道模式。

CANIF_OFFLINE

当PDU通道模式为CANIF_OFFLINE时,此时通道进行通信。CanIf初始化完成时,CanIf此时就将所有通道切换到CANIF_OFFLINE状态,此外当调用CanIf_SetControllerMode(ControllerId, CAN_-
CS_SLEEP)时,CanIf将相应通道的PDU通道设为CANIF_OFFLINE模式。在CANIF_OFFLINE模式下,CanIf:

  • 停止相关L-PDU的发送请求到CanDrv(CanIf_Transmit()调用返回E_NOT_OK给上层模块);
  • 清除相关的CanIf发送buffer;
  • 停止调用上层模块的接收提醒;
  • 停止调用上层模块的发送确认;

即在此模式下,报文收发均被禁止。

CANIF_TX_OFFLINE

当调用CanIf_SetControllerMode(ControllerId, CAN_CS_STOPPED)或CanIf_ControllerBusOff(ControllerId)时,CanIf将相应通道的PDU模式设置为CANIF_TX_OFFLINE。在CANIF_TX_OFFLINE模式下CanIf:

  • 停止相关L-PDU的发送请求到CanDrv(CanIf_Transmit()调用返回E_NOT_OK给上层模块);
  • 清除相关的CanIf发送buffer;
  • 停止调用上层模块的发送确认;
  • 使能调用上层模块的接收提醒;

即在此模式下,可以进行报文接收,不可以进行报文发送。已经在CAN发送硬件对象中等待发送的发送L-PDU将在模式更改为CANIF_TX_OFFLINE或CANIF_OFFLINE模式后立即发送。

CANIF_OFFLINE_ACTIVE

如果CanIfTxOfflineActiveSupport = TRUE,则CanIf通过CANIF_TX_OFFLINE_ACTIVE模式提供成功传输的模拟。该模式通过调用CanIf_SetPduMode(控制器Id,CANIF_TX_OFFLINE_ACTIVE)使能,仅影响传输路径。对于分配给处于CANIF_TX_OFFLINE_ACTIVE模式的通道的每个L-PDU,CANIF应立即调用上层模块的发送确认回调服务,而不是在调用CanIf_Transmit()期间缓存或转发L-PDU至CanDrv。

该功能对于实现特殊操作模式(诊断被动模式)以避免总线阻塞而不影响通知机制是有用的。这种模式通常用于诊断用途。

CANIF_ONLINE

在CANIF_TX_OFFLINE模式下CanIf:

  • 使能转发相关L-PDU的CanIf_Transmit()发送请求到CanDrv;
  • 使能调用上层模块的接收提醒;
  • 使能调用上层模块的发送确认;

即在此模式下,报文收发功能正常运行。

总结

CanIf的主要功能就是隔离底层硬件(驱动)区别,为上层提供统一的调用接口。其角色定位于"上传下达"的中转站。另外CanIf根据需求可配置的报文缓存。熟悉CanIf提供的常用API及其功能,即可满足日常工作中遇到问题分析的需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/25919.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于html+css的图展示96

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

ts报错“this“ 隐式具有类型 “any“,因为它没有类型注释。解决方案

序 1、参考博文》①严格模式 - 知乎&#xff0c;②ts的tsconfig.son中文说明③TypeScript Number | 菜鸟教程 2、解决&#xff08;ts报错“this“ 隐式具有类型 “any“&#xff0c;因为它没有类型注释。&#xff09; 3、解决&#xff08;函数内this是undefined 的问题&#xf…

STM32CubeIDE + HAL + STM32f103C8T6 系列教程1 ---板载PC13LED闪烁

STM32CubeIDE HAL STM32f103C8T6 系列教程1 --- 板载PC13LED闪烁 引言硬件关于开发板[^2]控制器内置存储器原理图 硬件连线硬件连接表硬件连线图 软件STM32CubeIDE下载及安装Stm32CubeIDE设置补全快捷键和主题新建一个工程选择开发板核心芯片型号设置工程相关参数STM32CubeMX…

《程序员面试金典(第6版)》面试题 02.08. 环路检测(哈希法,双指针,检测链表是否有环)

题目描述 给定一个链表&#xff0c;如果它是有环链表&#xff0c;实现一个算法返回环路的开头节点。若环不存在&#xff0c;请返回 null。 题目传送门&#xff1a;面试题 02.08. 环路检测 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链…

【笔记整理】常见聚类算法

【笔记整理】常见聚类算法 文章目录 【笔记整理】常见聚类算法一、均值偏移 - Mean-shift&#xff08;★★★★&#xff09;1、概述 & 图解&#xff08;“偏心”&#xff09;2、公式 & 步骤1&#xff09;基本公式&#xff08;“偏移量更新圆心”&#xff09;2&#xff…

4:File类与IO流

文章目录 File类1&#xff1a;引入&#xff1a;2&#xff1a;对文件进行操作3&#xff1a;对目录/文件夹进行操作 IO流1&#xff1a;引入&#xff1a;2&#xff1a;字符输入 / 出流FileReader 与 FileWriter3&#xff1a;用try - catch - finally 处理异常4&#xff1a;几个常见…

【Android-JetpackCompose】13、实战在线课程 App

文章目录 一、BottomNavigation 底部导航1.1 底部导航栏的布局、点击1.2 设置 bottomBar 的颜色1.3 设置顶部 actionBar 的颜色 二、主页 StudyScreen2.1 顶部状态栏2.2 一、BottomNavigation 底部导航 1.1 底部导航栏的布局、点击 首先&#xff0c;构造 NavigationItem 的 d…

c++—断言、异常

一、 断言&#xff0c;主要用于在函数入口处进行参数检查&#xff0c;是否符合参数设置要求&#xff1b; &#xff08;1&#xff09;true&#xff1a;继续执行&#xff1b;false&#xff1a;终止运行&#xff1b; &#xff08;2&#xff09;特点&#xff1a;在程序运行时才能起…

【20】SCI易中期刊推荐——计算机信息系统工程电子与电气(中科院3区)

💖💖>>>加勒比海带,QQ2479200884<<<💖💖 🍀🍀>>>【YOLO魔法搭配&论文投稿咨询】<<<🍀🍀 ✨✨>>>学习交流 | 温澜潮生 | 合作共赢 | 共同进步<<<✨✨ 📚📚>>>人工智能 | 计算机视觉…

zookeeper学习笔记

zookeeper Zookeeper 入门概述Zookeeper工作机制特点数据结构应用场景统一命名服务统一配置管理统一集群管理服务器动态上下线软负载均衡 zookeeper安装本地模式安装配置参数解读 Zookeeper 集群操作集群操作集群安装 选举机制节点类型客户端命令行操作命令语法znode 节点数据信…

mysql 是否包含 返回索引 截取字符串

是否包含返回索引 原文链接&#xff1a;https://www.cnblogs.com/shoshana-kong/p/16474175.html 方法1&#xff1a;使用通配符%。 通配符也就是模糊匹配&#xff0c;可以分为前导模糊查询、后导模糊查询和全导匹配查询&#xff0c;适用于查询某个字符串中是否包含另一个模糊…

Redis的全局命令及相关误区

Redis中所说的数据结构是针对key-value中的value而言的。主要的结构包括String、哈希表、列表、集合等等在redis中存在16个库&#xff0c;涉及到后期的集群搭建只能使用0号库最为方便 查看所有键&#xff08;支持通配符&#xff09; keys * keys S*返回当前数据库中的键总数 …

智能出行更安全,亚马逊云科技携手木卫四助汽车客户安全合规出海

木卫四&#xff08;北京&#xff09;科技有限公司在汽车网络安全领域拥有独特专业知识&#xff0c;其融合人工智能算法的安全检测引擎可以不依赖车辆中安装的代理软件&#xff0c;只需几周即可快速部署实施&#xff0c;是汽车网络安全领域的技术领先者。 在亚马逊云科技初创团…

ChatGPT国内镜像站

免费国内镜像推荐&#xff08;超稳定&#xff09; 下面为大家收集了目前国内最稳定流畅的ChatGPT镜像网站 目录 机器人 博弈ai 泰cool辣 道合顺 二狗问答 核桃 WOChat GPT中文站 TomChat 利用ChatGPTMindShow三分钟生成PPT ChatGPT国内镜像是啥 ChatGPT 镜像是指…

大语言模型技术原理

在今天这个时代&#xff0c;人们的工作和生活已经离不开数据访问&#xff0c;而几乎所有平台背后的数据存储和查询都离不开数据库。SQL作为一种数据库的查询和处理语言历史悠久&#xff0c;最早由IBM于上世纪70年代初研究关系数据模型时提出&#xff0c;后续发展为一种广泛使用…

帕累托改进和帕累托最优、卡尔多-希克斯改进

根据目标个数&#xff0c;分为单目标规划&#xff0c;以及多目标规划。多目标的规划是去找折中的解集合&#xff0c;既pareto最优解集合。对优化目标超过3个以上的&#xff0c;称之为超多目标优化问题。 帕累托改进描述的就是在没有人变得不好的前提下让有些人更好的过程。帕累…

C#简单数据结构类和常用泛型结构类

文章目录 1.简单数据结构类&#xff08;1&#xff09;动态数组Arraylist&#xff08;2&#xff09;栈Stack&#xff08;3&#xff09;队列Queue&#xff08;4&#xff09;哈希表Hashtable 2.泛型3.常用泛型数据结构类&#xff08;1&#xff09;列表List&#xff08;2&#xff0…

Linux之基础IO

文章目录 前言一、再谈文件二、再谈文件操作二、如何理解文件1.文件操作的本质2.管理被打开的文件 三、进程和被打开的文件如何关联四、文件描述符fd1.引入2.理解3.分配规则 五、重定向1.引入重定向2.接口3.追加重定向4.输入重定向 总结 前言 本文介绍了系统IO、fd、重定向等内…

【Linux】在Ubuntu中卸载、下载mysql以及如何检查mysql是否卸载成功

介绍 这里是小编成长之路的历程&#xff0c;也是小编的学习之路。希望和各位大佬们一起成长&#xff01; 以下为小编最喜欢的两句话&#xff1a; 要有最朴素的生活和最遥远的梦想&#xff0c;即使明天天寒地冻&#xff0c;山高水远&#xff0c;路远马亡。 一个人为什么要努力&a…

micropython固件编译——把自己的py库添加进固件

目录 0. 前言1. 编写自己库的代码2. 移植库3. 验证 0. 前言 本节编译自己写的py库&#xff0c;增强移植性&#xff0c;往后烧录自己的固件即可轻易移植代码 没装好环境或者没有基础可以先看看这个&#xff1a; Ubuntu下ESP-IDF的环境搭建 Ubuntu下编译esp32micropython固件编…