0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

在单片机中使用的RTOS代码框架

汽车电子技术 来源:嵌入式之入坑笔记 作者:嵌入式之入坑笔记 2023-02-10 14:21 次阅读

最近在进行一个项目的开发和调试,使用的是单片机 + freeRTOS进行开发,通过一段时间的码代码和调试,各个方面都已经调通,功能也顺利的实现,也在挂机测试了。

在这次开发中,也是遇到了很多的问题,主要的感想是关于代码的框架。在单片机开发中,特别是使用了RTOS的时候,一个良好的代码框架真的是相当的必要的。

如果一开始没有仔细的考虑好该怎么搭载一个代码框架,写代码时想写什么就写什么,有什么功能要加找个地方就随便插入进入,当代码量大的时候就会看起来很乱。甚至将来接手代码的人,估计内心一万个CNM从心中飞过,时刻游走在崩溃的边缘,即使是想改点什么功能也不知道从哪里开始着手,估计会烦躁到喜提地中海!!!

本文就想分享一个我个人使用的单片机+freeRTOS的代码框架,框架涉及到消息接收、消息处理、消息发送、其他动作的处理。下面一步步说明代码框架的搭建过程。

  1. 创建任务

当开始一个项目代码的编写之前,都要考虑这份代码要实现一些什么样的功能,并将要实现的功能进行分类,根据功能的各自属性可以归纳出几个Module,然后想想在代码中哪些功能要放在一块,哪些功能要区分开等等的细节问题。

并且还需要考虑代码的耦合性,好的代码是要能够做到高内聚低耦合的,各个功能模块之间能够独立区分开,需要产生联系的功能代码,要通过某些通信手段实现(共享内存、信号量、消息队列等等),不要互相拉扯,像你中有我,我中有你这种情况要尽可能的避免。

比如,我手上的项目通过功能归类划分,就可以分为接收消息、处理消息、发送消息、其他功能处理,由此便可以考虑划分出4个线程去处理。

但是,考虑到项目中使用的是CAN通信的方式,接收消息就可以考虑使用CAN接收中断的方式,能够做到及时的响应接收消息,所以这个时候只需要3个线程即可。并且消息的接收使用队列的方式接收,方便管理消息和进行线程之间的同步。消息的发送也采用先压入队列再发送的方式。

freeRTOS中创建3个线程如下:

#define OTHER_HANDLE_TASK_PRIO         2
#define OTHER_HANDLE_STK_SIZE          256 
TaskHandle_t OtherHandleTask_Handler;


#define CAN_HANDLE_MSG_TASK_PRIO     3 
#define CAN_HANDLE_MSG_STK_SIZE      256  
TaskHandle_t Can_HandleMsgTask_Handler;


#define CAN_SEND_MSG_TASK_PRIO         2
#define CAN_SEND_MSG_STK_SIZE          256  
TaskHandle_t Can_SendMsgTask_Handler;




    // 其他功能的管理线程
    xTaskCreate((TaskFunction_t )OtherHandle_Task,
                (const char *   )"OtherHandle_Task",
                (uint16_t       )OTHER_HANDLE_STK_SIZE,
                (void *         )NULL,
                (UBaseType_t    )OTHER_HANDLE_TASK_PRIO,
                (TaskHandle_t * )&OtherHandleTask_Handler);




    // 接收消息的处理线程
   xTaskCreate((TaskFunction_t )Can_HandleMsg_Task,
               (const char *   )"Can_HandleMsg_Task",
               (uint16_t       )CAN_HANDLE_MSG_STK_SIZE,
               (void *         )NULL,
               (UBaseType_t    )CAN_HANDLE_MSG_TASK_PRIO,
               (TaskHandle_t * )&Can_HandleMsgTask_Handler);

    // 发送消息的处理线程
   xTaskCreate((TaskFunction_t )Can_SendMsg_Task,
               (const char *   )"Can_SendMsg_Task",
               (uint16_t       )CAN_SEND_MSG_STK_SIZE,
               (void *         )NULL,
               (UBaseType_t    )CAN_SEND_MSG_TASK_PRIO,
               (TaskHandle_t * )&Can_SendMsgTask_Handler);

消息接收队列、消息发送队列的创建,如下:

// 消息接收队列
QueueHandle_t CanRxQueue;
CanRxQueue = xQueueCreate(xxxxxx, xxxxxx);




// 消息发送队列
QueueHandle_t CanTxQueue;
CanTxQueue = xQueueCreate(xxxxxx, xxxxxx);
  1. CAN中断接收消息 & 消息处理线程

2.1、CAN中断接收消息如下:

void CAN1_RX0_IRQHandler(void)
{
    BaseType_t xHigherPriorityTaskWoken;

    /* 其他代码 */

    xResult = xQueueSendFromISR(CanRxQueue, &ptwCanRxMsg, &xHigherPriorityTaskWoken);




    portYIELD_FROM_ISR (xHigherPriorityTaskWoken);
}

注意:接收很多时候不一定要使用中断的方式,用查询的方式也是可以的,只是在RTOS中,查询接收的话,要考虑消息接收是否及时,接收消息的线程优先级要比较高,否则容易造成处理的动作的延迟。

2.2、消息的处理线程

消息处理的线程任务函数如下:

void Can_HandleMsg_Task(void *pvParameters)
{
    while (1)
    {
        xQueueReceive(CanRxQueue, xxxxxx, portMAX_DELAY);
        /*
            处理部分
        */
     }
}

消息处理中使用了消息队列的阻塞的特性,在队列为空的时候阻塞挂起线程,可以减少CPU调度线程的压力;当消息队列不为空的时候,队列不再阻塞,线程从挂起中恢复,参与调度并处理任务。

注意:在freeRTOS中可以用于阻塞的还有信号量、事件标志组、消息邮箱。

  1. 消息的发送线程

消息的发送如下:

void Can_SendMsg_Task(void *pvParameters)
{
    while (1)
    {
        xQueueReceive(CanTxQueue, xxxxxx, portMAX_DELAY);
        /*
            处理部分
        */
     }
}

消息的发送中也使用了消息队列,需要发送的消息可以先压入队列,然后由发送线程去发送。同样使用队列的阻塞特性,在队列为空的时候阻塞挂起发送线程,减少CPU调度线程的压力;当发送消息的队列不为空的时候,队列不再阻塞,线程从挂起中恢复,参与调度并将消息发送出去。

  1. 其他功能的处理线程
void OtherHandle_Task(void *pvParameters)
{
    while (1)
    {
          /*
            处理部分
          */
     }
}

其他功能的处理就放在其他任务线程中处理,比如GUI显示、按键扫描、和传感器通信等等的。具体需要几个线程管理需要根据实际的项目情况进行安排。另外各个线程的优先级也要根据情况进行安排,确保重要的功能部分能被及时的执行到!

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6001

    文章

    43973

    浏览量

    620836
  • 框架
    +关注

    关注

    0

    文章

    297

    浏览量

    17045
  • RTOS
    +关注

    关注

    20

    文章

    776

    浏览量

    118796
  • 代码
    +关注

    关注

    30

    文章

    4555

    浏览量

    66767
收藏 人收藏

    评论

    相关推荐

    AVR单片机C语言程序框架(单片机最简操作系统)及详解

    本帖最后由 lvhoujun 于 2014-2-28 00:37 编辑 这是本人以ATMEGA128为例编写的C语言程序框架,做简单的修改即适合AVR所有单片机。可以说是一个单片机最简操作系统
    发表于 02-12 20:27

    AVR单片机RTOS_AVRX应用

    AVR单片机RTOS_AVRX应用
    发表于 03-24 15:34

    吴坚鸿—手把手教你单片机程序框架 (电子版)

    结合的教学方式,并且给出了详细的代码以及清晰明了的解析。是单片机爱好者学习的实用资料!这是吴老师电子发烧友论坛连载的帖子:https://bbs.elecfans.com/jishu_406259_1_1.html部分目录:《
    发表于 11-19 14:00

    51单片机上跑RTOS有没有意义?精选资料分享

    最近看见我的一个技术交流群讨论一个问题:51单片机上跑RTOS有没有意义?今天就来围绕51和RTOS展开讲讲。1关于51
    发表于 07-20 07:54

    如何在RTOS中使用看门狗

    保证看门狗定时器的溢出时间一般要足够长,且单片机不是经常满负荷运行。(保证CPU的使用权不是一直被高优先级的线程抢占)• 2、建立一个看门狗的定时任务,并将该任务定义为最高优先级。这种方式保证了喂狗的及时性,但是如果只有低优先级的任务死了(经历少,倒是没遇到过),这种方式下的看门狗就起不到作用。• 3
    发表于 08-02 07:23

    AVR单片机中使用printf函数

    Pro2、程序编写要想在AVR单片机中使用printf函数,首先得包含头文件,其次,得函数中定义put...
    发表于 11-23 06:29

    CAFrame单片机程序框架分享

    CAFrame单片机程序框架简介程序运行优先级CAFrame配置通用事件应用FLowchart流程图简介CAFrame 单片机C语言程序开发框架可用于不同的
    发表于 11-24 07:18

    单片机为什么要用RTOS

    对于搞单片机的特别用8051系列工程师来说,谈到单片机RTOS,很多时候会问一句:“为什么要用RTOS?单片机就这一点资源,使用
    发表于 12-09 08:29

    一个简单实用的MCU程序框架介绍

    一个简单实用的MCU程序框架(非操作系统,简单调度任务) - 总体介绍 单片机程序,总体上可分为跑操作系统的和没操作系统,对于无MMU的小单片机,操作系统通常是UCOS、RTOS等实时
    发表于 02-11 06:21

    初学单片机代码结构

    前言前不久,我有位做测试的朋友转去做开发的工作,面试遇到了一个问题,他没明白,打电话问了我。题目大概就是:单片机裸机开发时,单片机要处理多个任务,此时你的程序框架是怎样的呢?这其实是
    发表于 02-23 06:55

    聊聊我对单片机程序的整体框架设计的一些思路体会

    RTOS。或者使用RTOS整体思路上比较迷茫,不知从何入手,所以本文来聊聊我对单片机程序的整体框架设计的一些思路体会。为啥要讨论架构
    发表于 02-23 07:30

    RTOS框架下使用ROSSerial

    我理解ROSSerial只是为MCU提供了一个和基于ROS主机(上位)通讯的方式,而MCU要实现的功能还是要自己编写实现,这部分和以往需求一样,那么采用什么程序框架就是不可回避的问题。现在由于
    发表于 03-02 06:47

    开源RTOS在STM32单片机中的应用

    开源RTOS在STM32单片机中的应用
    发表于 09-25 09:50 20次下载
    开源<b class='flag-5'>RTOS</b>在STM32<b class='flag-5'>单片机</b>中的应用

    单片机资源这么少为什么还要用RTOS

    对于搞单片机的特别用8051系列工程师来说,谈到单片机RTOS,很多时候会问一句:“为什么要用RTOS单片机就这一点资源,使用
    发表于 07-11 17:39 1次下载
    <b class='flag-5'>单片机</b>资源这么少为什么还要用<b class='flag-5'>RTOS</b>

    分享一个在单片机中使用的RTOS代码框架

    最近在进行一个项目的开发和调试,使用的是单片机 + freeRTOS进行开发,通过一段时间的码代码和调试,各个方面都已经调通,功能也顺利的实现,也在挂机测试了。
    发表于 05-20 15:44 795次阅读