OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5332|回复: 3

请教从裸写转变为FreeRTOS的方法与思维

[复制链接]

1

主题

2

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-5-9
在线时间
5 小时
发表于 2020-7-2 23:40:50 | 显示全部楼层 |阅读模式
4金钱
问题是这样的,STM32使用了USART3来向外部模块发送与接收字符串数据,STM32与外部模块的通信分两种:
1、外部模块因为一个外部事件主动向STM32发送一串字符串
2、STM32向外部模块发送一个命令字符串后,外部模块再返回一串或多串字符串给STM32

但这里有几个问题(要求):
1、STM32向外部模块发送完一串命令字符串后,有时候需要等待外部模块返回字符串,才能继续处理接下来的事情,有时候又不需要等待外部模块返回,就继续处理接下来的事情。需要等待外部模块返回字符串时,需要有个超时处理(不能让它在那死等);不需要等待外部模块返回字符串的时候,有可能在向外部模块发送完一串命令字符串后,还需要延时一段时间,才能接着再发送下一个命令,有时候又不需要延时。
2、当STM32接收到外部模块返回的字符串后,还需要检查这些字符串中有无指定的子字符串,如果没有,可能需要重新发送这条命令,或者再向外部模块发送另一个命令。
3、当STM32向外部模块发送完一个命令字符串,正在等待它返回时,外部模块返回的字符串是不定长的,也有可能不是一个字符串,而是2个、3个或4个字符串,而且这些字符串要全部返回完成才算完整返回(最后都有一个统一的结束字符串,但有时候有例外),还有一点,就是这几个字符串有时候是一起返回的(耗时大约50ms内),有时候又不是一起返回的,而是可能返回完第一个字符串后隔了100ms后才返回第二个,最长间隔能达到20s,但STM32还是要在那里等待它返回来一个结束字符串后才能继续处理。

这些我已经实现了,不过我用的是不带操作系统的,我是使用systick当作一个时钟节拍,每1us中断一次将一个变量加一,然后主循环判断时间点,有5ms、20ms、100ms、1s这些时间点,到了就执行相应的函数。在实现上述的功能的时候我用了一些延时、STM32与外部模块是每隔20s通信一次的,所以这个”小系统“每隔20s就会有一个200ms的延时时间(就是这个通信函数占用的,我测出来的),但其他时候这个函数基本都是2us就执行完了,这个时间点轮询的”小系统“中基本上没有其他什么耗时间的任务了,所以这每隔20s就出现一次的200ms延时没什么影响。

---------------------------------------
但我现在想用FreeRTOS来实现上面说的那些功能,我刚刚学习FreeRTOS没有多久,实际的项目也没写过,就只是在学习的时候做了一些小实验,主要是FreeRTOS的API使用,什么任务创建啊、删除、获取句柄、挂起、精确延时、邮箱、队列、事件标志组、软件定时器之类的,自己也读了几遍重要部分的内核源码,大概是怎么个过程我了解了,但要写一个完整的能用的实际的项目的时候,我发现我不知道怎么写。
------------------------------------------------------------------------------------------------------------------------
我想把这个裸写的程序写到FreeRTOS上,正好实际上手练练在FreeRTOS上写一个实际的程序。
------------------------------------------------------------------------------------------------------------------------

我打算把USART3接收到的字符串放到队列里去(这个我已经写好了,也测试过了)
然后。。。。然后我就不知道接下来的逻辑实现该怎么写了。
裸写都是顺序执行的,但FreeRTOS有个任务调度的问题,还有任务之间的通信方式,我也知道最好要用队列啊、邮箱啊、消息通知啊什么的。
我用了一个TIM6,每隔20ms就看看USART3有没有新数据来,没有的话就认为是接收完成了,然后把USART3收到的数据放到队列里去。


------------------------------------------------------------------------------------------------------------------------
最后,这个外部模块其实就是ESP32,我需要让ESP32连接到云端服务器,上面说的通信其实是我自己捣鼓玩的,ESP32复位后,如果周围没有可用wifi,但一会儿之后来了可用WIFI,它是能自己自动重连的,不需要STM32再发送连WIFI的命令给它,但ESP32是无法自动重连服务器的(能不能我目前也不知道,好像不能),而且如果在这个WIFI意外断掉,过一会又重新恢复后,虽然ESP32能自动重连WIFI但重连服务器还是需要STM32发连接服务器的命令给它才行。
所以我写了个每隔20秒就检查一次WIFI、服务器连接情况的函数,这个函数里面干的事就是向ESP32发送查询命令,然后等待返回,判断有无连接WIFI,没有连接WIFI就重连WIFI,然后在连上WIFI的情况下,再检查与服务器连接的情况、如果没连接服务器,就发送命令重连服务器。如果WIFI、服务器经查询都连上了,那就不做重连,在等20秒后再查询。在这个查询过程中,ESP32是要先退出透传模式的(透传模式是常态),然后STM32在发送命令查询网络状况,在这个函数的末尾,再向ESP32发送命令,恢复透传模式,等待服务器随时可能传来的数据,然后把数据传给STM32(这就是开头说的第一种情况)。

用时间点轮询的”小系统“我已经实现这些功能了,效果是无论怎么样,ESP32先上电,WIFI后开,或者是WIFI中间断了又恢复,或者是服务器断了,再或者是有WIFI但没网,过了一会儿后又恢复网络了。各种情况这个小系统都能在30秒内,最快10秒内,重新与服务器连接上。
------------------------------------------------------------------------------------------------------------------------
我现在想把这些写到FreeRTOS上,请有FreeRTOS实际项目经验的大佬指点指点:
1、从裸写程序到FreeRTOS这类实时操作系统写程序的时候写程序思维的转变(裸写都是顺序写就行了,弄个全局变量,标志)?
2、FreeRTOS是不是无法用JLINK、STLINK这类调试啊?要怎么调试FreeRTOS?我一调试FreeRTOS的时候mdk一会儿就卡死了。
3、是不是在操作系统上就最好不要用全局变量了,如果还像裸写那样全都用全局变量会怎么样,有什么影响?
4、在学习FreeRTOS的过程中,我发现,弄懂了它的一些数据结构,比如列表啊、列表项、任务控制块、队列等,还有他们之间的组合关联的关系,再去看内核代码,就能大致看懂它干了什么了。

最佳答案

查看完整内容[请看2#楼]

1、从裸写程序到FreeRTOS这类实时操作系统写程序的时候写程序思维的转变(裸写都是顺序写就行了,弄个全局变量,标志)? 是的,思路要完全转变(当你掌握了FreeRTOS编程后再回过头来才发现原来如此)。 因为祼机编写程序是顺序执行(只有中断服务程序打断时才跳跃执行),而FreeRTOS这类实时操作系统写的程序执行时完全是跳跃执行(注:任务之间是跳跃执行,任务内是顺序执行)。 2、FreeRTOS是不是无法用J ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

19

主题

334

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1108
金钱
1108
注册时间
2018-11-6
在线时间
240 小时
发表于 2020-7-2 23:40:51 | 显示全部楼层
本帖最后由 霸王猫 于 2020-7-3 11:16 编辑

1、从裸写程序到FreeRTOS这类实时操作系统写程序的时候写程序思维的转变(裸写都是顺序写就行了,弄个全局变量,标志)?
   
      是的,思路要完全转变(当你掌握了FreeRTOS编程后再回过头来才发现原来如此)。
      因为祼机编写程序是顺序执行(只有中断服务程序打断时才跳跃执行),而FreeRTOS这类实时操作系统写的程序执行时完全是跳跃执行(注:任务之间是跳跃执行,任务内是顺序执行)。

2、FreeRTOS是不是无法用JLINK、STLINK这类调试啊?要怎么调试FreeRTOS?我一调试FreeRTOS的时候mdk一会儿就卡死了。
     FreeRTOS可以用JLINK、STLINK这类调试。
    我一调试FreeRTOS的时候mdk一会儿就卡死了,是因为程序中堆栈的原因。
      
3、是不是在操作系统上就最好不要用全局变量了,如果还像裸写那样全都用全局变量会怎么样,有什么影响?
      既然用了操作系统,当然最好不要用全局变量了。只是在某些特定的场合下可以用。
      如果还像裸写那样全都用全局变量,会出现如下问题:
            假设某个任务A写一批数据X1,X2,X3,
                   某个任务B读任务A的数据X1,X2,X3
            当任务B正在读数据并正在进行处理时,假设此时已经读了X1,准备读X2,X3
            这个时候进行了任务切换,跳转到任务A执行,任务A又将X1,X2,X3进行了修改,修改后的值我们标记为X1_,X2_,X3_。
            接着又进行任务切换跳转回任务B,任务B接着处理X2,X3,但是此时的X2和X3已经不
是之前和X1配对的X2,X3,而是变成了X2_和X3_。
             也就是说任务B取到的这批数据实际上已经不是X1,X2,X3了,而是变成X1,X2_,X3_了。

            
4、在学习FreeRTOS的过程中,我发现,弄懂了它的一些数据结构,比如列表啊、列表项、任务控制块、队列等,还有他们之间的组合关联的关系,再去看内核代码,就能大致看懂它干了什么了。

     不学习数据结构是看不懂FREERTOS操作系统内核的。必须掌握数据结构如下知识
     (1)、顺序表
      (2)、堆栈
      (3)、队列
        (4)、链表
回复

使用道具 举报

19

主题

334

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1108
金钱
1108
注册时间
2018-11-6
在线时间
240 小时
发表于 2020-7-3 11:21:26 | 显示全部楼层
参考如下:

http://www.openedv.com/forum.php ... d=304451&extra=
http://www.openedv.com/forum.php ... d=304560&extra=
http://www.openedv.com/forum.php ... d=303459&extra=

类似于TCP三次握手、超时检测、自动重发机制以及主从应答方式的通信任务以及一个任务和多个任务通信时应该如何设计
http://www.openedv.com/forum.php ... d=306002&extra=
回复

使用道具 举报

1

主题

2

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-5-9
在线时间
5 小时
 楼主| 发表于 2020-7-3 13:41:20 | 显示全部楼层
霸王猫 发表于 2020-7-3 11:14
1、从裸写程序到FreeRTOS这类实时操作系统写程序的时候写程序思维的转变(裸写都是顺序写就行了,弄个全局 ...

好的非常感谢你的解答!
可能万事开头难吧,思维真的要从裸写慢慢转变了,用这个实际的小实验练练FreeRTOS下的设计思维。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 16:32

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表