stm32cubeMX学习七、使用freertos在cubeMX代码生成规则编程中应该注意的事项

我们来看这段程序:

在这里插入图片描述
上面这段程序,是串口2的中断服务函数,在这里面完成的是接收一帧\r\n的数据。
这样看来,这段程序保护得挺好,在串口在执行接收的过程中不会被中断打断。但它存在隐藏的BUG,我们来看下面这种情况。
如果是使用stm32cubeMX生成代码,我们会看到在main.c中调用了串口初始化函数,在代码编写规则制定的区域定义了一个信号量,用于处理传感器数据。
在这里插入图片描述

这样看来没毛病,编程思路都是对的,但是灾难就快要发生了,于是我们在msp初始化函数里添加这么一段。

在这里插入图片描述
如果在串口初始化过后,传感器设备不通过串口发送数据,在未触发串口接收中断的时候,庆幸你的设备是可以正常开机运行的。
如果在串口初始化过后,传感器立马就上报数据给MCU,这时候你会突然发现,设备开不了机了?What?这是为什么?
断点调试后发现问题了,我们在这里发出了一个信号量,但信号量还没有初始化吧??
在这里插入图片描述
在这里插入图片描述
我们跟踪断点,进入xSemaphoreGiveFromISR这个函数,看看是为什么就卡死了呢?
在这里插入图片描述
这是一个宏,实际上是调用了xQueueGiveFromISR这个函数,我们继续跟进断点
在这里插入图片描述
我们再单步进这个断言:
在这里插入图片描述
结果发现死在这里了,这就说明我们并没有创建队列句柄。这就是stm32cubeMX给我们带来的坑爹问题了,既要按照它的要求来定义和编写代码,又要防止这样的问题产生。
那如何来解决这样的问题呢?其实很简单,加一个标志变量就可以了,在os没起来之前,我们不让发送信号量的这句话执行,等os起来以后,才让发送信号量这句话执行,否则会带来灾难性的结果。
在os还没有起来之前,我们还没有使用数据,而且信号量还没有创建,这时就不要使用os的信号量的发送和接收函数,于是想到一个解决办法,定义一个is_use_os变量,在os未起来之前这个标志为false,当os起来以后,这个标志就为true。
在这里插入图片描述
在这里插入图片描述
这样,当os没启动之前,is_use_os这个变量为false,对应的代码不执行,当os启动以后,is_use_of这个变量为true。
我们再来看os启动以后,这个变量还是不是为NULL了。
我们先让代码跑到初始化任务里,这是也就标记着OS已经启动了。
在这里插入图片描述
然后再把断点打到刚刚串口中断接收的函数里。
在这里插入图片描述
然后单步进入看看
在这里插入图片描述
这时候我们发现,这个值已经不为NULL 了。

完美解决问题。

Engineer-Bruce_Yang CSDN认证博客专家 嵌入式硬件 单片机 arm开发
本科毕业于华南理工大学,现美国卡罗尔工商管理硕士研究生在读,曾就职于世界名企伟易达、联发科技等,多年嵌入式产品开发经验,在智能玩具、安防产品、平板电脑、手机开发有丰富的实战开发经验,现任深圳市云之手科技有限公司副总经理、研发总工程师。
已标记关键词 清除标记
纯人工翻译文版本,STM32CubeMX用户手册文版,STM32CubeMX用户手册文版UM1718-翻译版.菜鸟到高手,显得有些霸气哈,不过的确如此,官方带给我们一个比较实用的stm32的工具。这个工具就是STM32CubeMX,昨天玩freeRTOS的时候就提到过。说到freeRTOS,这里就多说两句。全局变量,在任务间相互访问的时候也是需要临界保护的,不然可能会出现奇怪的问题。不过我们可以关掉时间片调度,任务间可以访问全局变量而不用加保护(不等于菜鸟可以随意代码)。关闭了时间片调度,只有发生vTaskDelay的时候才会上下文切换。只要代码合理访问全局变量可以不加保护的。因此代码也不是可以任意书写的,关于freeRTOS的问题,多看看源码,一切都会有答案。源码较少,这里就不过多介绍。关闭时间片不是网上说的configUSE_TIME_SLICING这个宏定义,老鸟发现这个宏压根没用哈,嘿嘿。阅读源码可以找到相关宏配置。不过不建议关闭,时间片调度也可以让一个任务在执行一定时间后切换到其他就绪任务去执行。如果有freeRTOS相关问题,可以留言给我。废话说多了点哈,继续我们的STM32CubeMX。下面我们来讲讲这个工具的作用,讲完后,可以自己下载一个试试,挺简单不多介绍。 到官网下载STM32CubeMX,并安装。 1:芯片选型 打开STM32CubeMX,我们点击new project,我们就可以进行芯片选型,如果你下载了打开了这个工具,是不是很惊讶,stm32的所有产品型号都在里面,而且左下提供了资源勾选,比如你要以太网支持,勾选以太网选项,所有的支持以太网的stm32芯片才会被显示,旁边还有个max的栏目指示了芯片最多支持该功能的个数。空白的一般默认只有一个。下图是我勾选以太网的截图。 上图不仅提供了芯片,还提供了价格,是否在售,封装,存储,频率等一些列信息。 除了cpu资源可以选型外,上面还提供了脚多少,存储大小等非常灵活的选型方式。 我们选择其一个的单片机后。右上部分给我们提供了完美的支持。 第一个选项提供了改cpu 的特性,我们可以大概的了解选的cpu资源。 第二个选项提供该cpu框图,截图图片太大,这里就不截图了。 第三个选项提供了cpu文档,这个文档非常多也非常全面,基本不用在网上东找西找了,主要给硬件工程师用。 第四个选项提供了cpu的相关设计资源,软件编程文档,给软件工程师用,非常全面,包括网上很少用到的文档资料,比如系统移植相关的底层资料(堆栈,指令,汇编)。 第五个选项提供了芯片购买途径,这个每个人自己选择吧。 第六个选项开始工程,芯片选好了,就可以开始工程。 2:设定芯片。 芯片选好后,可以开始设定芯片。这就是软件工程师的好帮手呀。比如我要以太网功能,勾选上以太网即可,他就会自动分配出芯片对应的以太网接口。如下图: 上面我选了标准的MII接口。很多人可能就不理解,你勾了个以太网,咋报错了。老鸟告诉你为啥变红了,stm32有个复杂的功能就是io口复用,勾选mii后分配的io口和spi2以及iis口重合了,所以这个工具非常智能的提示了出来,非常神奇吧。告诉你他们不能使用了。还有些变黄了,说明他们可以选择性使用,真是太方便了,省去了查资料慢慢找io的痛苦。比如我们还要给它个外部时钟。我们勾选时钟即可,响应的时钟脚就会分配出来。 如果要将某个脚设置成输入输出那就更简单了,鼠标点选对应的io口选择对应功能即可,比如我单击PA6,它的所有功能可以轻松选择: 软件使用比较简单,不过多解释,一看就明白,设置完芯片功能后,我们就设定系统各项功能时钟。 选择时钟设置页面(clock configuration)时钟轻松设定,如下图,简单明了,不过多解释了: 时钟配置完成后,可以切换到configuration选项对功能进一步设定,里面参数都是常用的功能,设置较为简单。就不多举例了,比如网络功能里面设置mac地址等。 3:生产初始化代码 经过上面的图形化设定,我们可以直接生产初始化代码。省去我们查阅资料慢慢配置的的环节,时间更多的利用在应用层设计。点击project下面的生成代码选项。输入工程名(根据你项目需要起名),这里我就随便输入一个名字。设定好相关参数。点击ok即可。顺便说下,这个工具是配带教程的,我这里只是告诉大家有这样个工具可以加速开发,具体设置参考官方教程。 生成后打开文件夹内容如下: 上图的inc 和src文件夹里面是生成的主要代码,其他几个文件夹里面的东西,大家可以根据自己需要选择。src文件夹文件如下: 打开熟悉的ma
相关推荐
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页