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

rt-thread H7 使用fdcan没有外接设备时或发送错误时线程被挂起的解决方案

一、问题查找
         使用的开发版是硬石的H7芯片型号STM32H743IIT6,测试时发现如果外面没有连接CAN设备,程序调用CAN发送时会一直等待发送反馈,导致相关线程挂起。
在线仿真时发现是卡在can.c文件的168行_can_int_tx函数:rt_completion_wait(&(tx_tosnd->completion), RT_WAITING_FOREVER);
代码如下:

rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *data, int msgs)
{int size;struct rt_can_tx_fifo *tx_fifo;RT_ASSERT(can != RT_NULL);size = msgs;tx_fifo = (struct rt_can_tx_fifo *) can->can_tx;RT_ASSERT(tx_fifo != RT_NULL);while (msgs){rt_base_t level;rt_uint32_t no;rt_uint32_t result;struct rt_can_sndbxinx_list tx_tosnd = RT_NULL;rt_sem_take(&(tx_fifo->sem), RT_WAITING_FOREVER);level = rt_hw_interrupt_disable();tx_tosnd = rt_list_entry(tx_fifo->freelist.next, struct rt_can_sndbxinx_list, list);RT_ASSERT(tx_tosnd != RT_NULL);rt_list_remove(&tx_tosnd->list);rt_hw_interrupt_enable(level);no = ((rt_uint32_t)tx_tosnd - (rt_uint32_t)tx_fifo->buffer) / sizeof(struct rt_can_sndbxinx_list);tx_tosnd->result = RT_CAN_SND_RESULT_WAIT;if (can->ops->sendmsg(can, data, no) != RT_EOK){/ send failed. */level = rt_hw_interrupt_disable();rt_list_insert_after(&tx_fifo->freelist, &tx_tosnd->list);rt_hw_interrupt_enable(level);rt_sem_release(&(tx_fifo->sem));continue;}can->status.sndchange = 1;rt_completion_wait(&(tx_tosnd->completion), RT_WAITING_FOREVER);

说明一直在等待完成信号,而发送完成信号的地方在can.c文件的900行rt_hw_can_isr函数:rt_completion_done(&(tx_fifo->buffer[no].completion));
源码如下:

case RT_CAN_EVENT_TX_DONE:
case RT_CAN_EVENT_TX_FAIL:
{struct rt_can_tx_fifo *tx_fifo;rt_uint32_t no;no = event > > 8;tx_fifo = (struct rt_can_tx_fifo *) can- >can_tx;RT_ASSERT(tx_fifo != RT_NULL);if ((event & 0xff) == RT_CAN_EVENT_TX_DONE){tx_fifo- >buffer[no].result = RT_CAN_SND_RESULT_OK;}else{tx_fifo- >buffer[no].result = RT_CAN_SND_RESULT_ERR;}rt_completion_done(&(tx_fifo- >buffer[no].completion));break;
}

二、解决方案
         看完can的驱动源码后想到如果can总线没有其他设备,CAN发送报文应该属于出错的情况,查看drv_fdcan.c文件中关于几种中断的处理,发现故障后的回调函数里没有调用rt_hw_can_isr。于是参考HAL_FDCAN_TxBufferCompleteCallback函数的处理方式,对HAL_FDCAN_ErrorCallback进行了如下处理。
源码如下:

void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan)
{rt_uint32_t tmp_u32Errcount;rt_uint32_t tmp_u32status;uint32_t ret = HAL_FDCAN_GetError(hfdcan);if(hfdcan->Instance == FDCAN1){#ifdef BSP_USING_FDCAN1//can1if( (ret & FDCAN_IT_ARB_PROTOCOL_ERROR) &&(hfdcan->Instance->CCCR & FDCAN_CCCR_INIT_Msk)){//hfdcan->Instance->CCCR |= FDCAN_CCCR_CCE_Msk;hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT_Msk;st_DrvCan1.device.status.errcode = 0xff;}else{tmp_u32Errcount = st_DrvCan1.fdcanHandle.Instance->ECR;tmp_u32status = st_DrvCan1.fdcanHandle.Instance->PSR;st_DrvCan1.device.status.rcverrcnt = (tmp_u32Errcount>>8)&0x000000ff;st_DrvCan1.device.status.snderrcnt = (tmp_u32Errcount)&0x000000ff;st_DrvCan1.device.status.lasterrtype = tmp_u32status&0x000000007;rt_hw_can_isr(&st_DrvCan1.device, RT_CAN_EVENT_TX_FAIL);}#endif / BSP_USING_FDCAN1 /}else{#ifdef BSP_USING_FDCAN2if( (ret & FDCAN_IT_ARB_PROTOCOL_ERROR) &&(hfdcan->Instance->CCCR & FDCAN_CCCR_INIT_Msk)){//hfdcan->Instance->CCCR |= FDCAN_CCCR_CCE_Msk;hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT_Msk;st_DrvCan2.device.status.errcode = 0xff;}else{//can2tmp_u32Errcount = st_DrvCan2.fdcanHandle.Instance->ECR;tmp_u32status = st_DrvCan2.fdcanHandle.Instance->PSR;st_DrvCan2.device.status.rcverrcnt = (tmp_u32Errcount>>8)&0x000000ff;st_DrvCan2.device.status.snderrcnt = (tmp_u32Errcount)&0x000000ff;st_DrvCan2.device.status.lasterrtype = tmp_u32status&0x000000007;rt_hw_can_isr(&st_DrvCan2.device, RT_CAN_EVENT_TX_FAIL);}#endif / BSP_USING_FDCAN2 /}
}

经修改后测试发现一切正常,发送错误后就会进入错误处理,不会卡死发送线程。

相关文章:

rt-thread H7 使用fdcan没有外接设备时或发送错误时线程被挂起的解决方案

一、问题查找 使用的开发版是硬石的H7芯片型号STM32H743IIT6,测试时发现如果外面没有连接CAN设备,程序调用CAN发送时会一直等待发送反馈,导致相关线程挂起。 在线仿真时发现是卡在can.c文件的168行_can_int_tx函数:rt_co…...

exptern “C“的作用,在 C 和 CPP 中分别调用 openblas 中的 gemm 为例

openblas提供的sgemm有两种方式&#xff0c;一种是通过cblas&#xff0c;另一种是直接声明并调用 sgemm_ 其中&#xff0c;cblas方式是更正规调用方法&#xff1b; 1&#xff0c;调用openblas的 sgemm 的两种方式 1.1 c语言程序中使用 sgemm hello_sgemm.c #include <st…...

如何提前预防网络威胁

一、引言 随着信息技术的迅猛进步&#xff0c;网络安全议题愈发凸显&#xff0c;成为社会各界不可忽视的重大挑战。近年来&#xff0c;一系列网络安全事件的爆发&#xff0c;如同惊雷般震撼着个人、企业及国家的安全防线&#xff0c;揭示了信息安全保护的紧迫性与复杂性。每一…...

ProviderRpc发送服务二将远程调用来的信息反序列化后调用服务方的方法,并将服务方的结果返回给发送方

在Provider的实现中&#xff0c;OnMessage函数中&#xff0c;处理接收到的连接RPC请求。将接收到的RPC请求&#xff08;包含请求的对象&#xff0c;请求方法和 请求参数&#xff09;&#xff0c;接收到这些信息之后进行反序列化。得到这些参数之后我们即将要做的事情是去调用相…...

Io 35

FIleinputStream字节输入 package File.io;import java.io.*;public class io1 {public static void main(String[] args) throws IOException {// InputStream is new FileInputStream(new File("C:\\Users\\SUI\\Desktop\\Java1\\one\\src\\kaishi"));//简化Input…...

java基础概念11-方法

一、什么是方法 方法&#xff08;method&#xff09;是程序中最小的执行单元。 方法中的程序&#xff0c;要不然就是一起执行&#xff0c;要不然就是一起不执行&#xff01;&#xff01;&#xff01; 二、方法的定义 在Java中&#xff0c;方法定义的一般格式如下&#xff1a;…...

大模型应用中的思维树(Tree of Thought)是什么?

大模型应用中的思维树&#xff08;Tree of Thought&#xff09;是什么&#xff1f; 大模型&#xff0c;特别是基于GPT&#xff08;Generative Pre-trained Transformer&#xff09;架构的模型&#xff0c;在处理复杂任务时&#xff0c;通常需要依赖某种形式的推理和决策机制。…...

学习记录(11):训练图片分类的算法

文章目录 一、卷积神经网络&#xff08;CNN&#xff09;架构1. ResNet&#xff08;Residual Networks&#xff09;2. DenseNet&#xff08;Densely Connected Convolutional Networks&#xff09;3. EfficientNet4. MobileNet 二、变换器&#xff08;Transformer&#xff09;架…...

上网防泄密,这些雷区不要碰!九招教你如何防泄密

李明&#xff1a;“最近看到不少关于信息泄露的新闻&#xff0c;真是让人担忧。咱们在工作中&#xff0c;稍有不慎就可能触碰到泄密的雷区啊。” 王芳&#xff1a;“确实&#xff0c;网络安全无小事。尤其是我们这种经常需要处理敏感信息的岗位&#xff0c;更得小心谨慎。那你…...

数据库篇--八股文学习第十五天| 一条SQL查询语句是如何执行的?,事务的四大特性有哪些?,数据库的事务隔离级别有哪些?

1、一条SQL查询语句是如何执行的&#xff1f; 答&#xff1a; 连接器:连接器负责跟客户端建立连接、获取权限、维持和管理连接。查询缓存: MySQL 拿到一个查询请求后&#xff0c;会先到查询缓存看看&#xff0c;之前是不是执行过这条语句。之前执行过的语句及其结果可能会以…...

elk + filebeat + kafka实验和RSync同步

elk filebeat kafka实验和RSync同步 elk filebeat kafka实验 filebeatkafkaELK实验的操作步骤&#xff1a; #在装有nginx的主机上解压filebeat压缩包 [roottest4 opt]# tar -xf filebeat-6.7.2-linux-x86_64.tar.gz #将解压后的压缩包更改名字 [roottest4 opt]# mv file…...

子类到底能继承父类中的哪些内容?

...

【超详细公式】曝光值(EV)、光圈(AV)、快门(TV)、感光度(SV)、照度(Lux)

文章目录 术语 E V A V T V − S V EV AV TV - SV EVAVTV−SV L u x 2.5 2 E V Lux 2.5 \times 2^{EV} Lux2.52EV通常环境光照度参照表 术语 术语全称中文名EVExposure Value曝光值AVAperture Value光圈值TVTime Value快门值SVSensitive Value感光值BVBrightness Value…...

【Java】增强for遍历集合。

增强for遍历 增强for底层就是迭代器。所有的单列集合和数组才能使用增强for遍历。 在循环过程中无法对集合中的元素进行修改。 package demo;import java.util.ArrayList; import java.util.Collection; import java.util.Iterator;public class submit {public static void …...

【Qt】管理创建子项目

新建项目 打开是这样&#xff0c;无法添加子项目 pro添加 TEMPLATE subdirs有了 点击添加子项目 其他项目-子目录项目 &#xff08;空的子项目&#xff0c;只有pro&#xff0c;无h、cpp&#xff09; 子目录名字 直接创建子目录下子项目 选择有无界面或者其他类型项目 …...

力扣——238.移动零

题目 思路 利用双指针&#xff0c;先找到第一个为0的地方指向&#xff0c;指针2指向下一个&#xff0c;指针1之前是已经处理好的数据&#xff0c;指针2进行遍历&#xff0c;遇到非零则与指针1数据交换&#xff0c;然后指针1。 代码 class Solution { public:void moveZeroes(…...

编程的魅力

在数字化时代&#xff0c;编程已不仅仅是计算机科学家的专属领地&#xff0c;它正逐渐渗透到我们生活的每一个角落&#xff0c;成为连接现实与虚拟、创新与传统的重要桥梁。编程&#xff0c;这一门融合了逻辑、创造与解决问题的艺术&#xff0c;正以其独特的魅力引领着新一轮的…...

想提升跨境电商运营?浏览器多开为你助力!

在日常生活中&#xff0c;我们在使用浏览器访问网站时&#xff0c;可能会遇到一个尴尬的情况&#xff1a;无法同时登录一个网站的多个账号。对于跨境电商卖家来说&#xff0c;这种情况更为常见。例如&#xff0c;当我们需要在亚马逊管理店铺时&#xff0c;我们可能已经使用A账号…...

使用QML的ListView自制树形结构图TreeView

背景 感觉QML自带的TreeView不是很好用&#xff0c;用在文件路径树形结构比较多&#xff0c;但是想用在自己数据里&#xff0c;就不太方便了&#xff0c;所以自己做一个。 用‘ListView里迭代ListView’的方法&#xff0c;制作树形结构&#xff0c;成果图&#xff1a; 代码…...

2.MySQL面试题之索引

1. 为什么索引要用 B树来实现呢&#xff0c;而不是 B 树&#xff1f; MySQL 选择使用 B 树来实现索引&#xff0c;而不是 B 树&#xff0c;主要是基于以下几个原因&#xff1a; 1.1 数据存储和访问效率 B 树&#xff1a;在 B 树中&#xff0c;数据和索引都存储在每个节点中。…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...