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

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

3天内不再提示

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

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

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

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

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

本文就想分享一个我个人使用的单片机+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显示、按键扫描、和传感器通信等等的。具体需要几个线程管理需要根据实际的项目情况进行安排。另外各个线程的优先级也要根据情况进行安排,确保重要的功能部分能被及时的执行到!

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

    关注

    6035

    文章

    44554

    浏览量

    634635
  • 框架
    +关注

    关注

    0

    文章

    403

    浏览量

    17475
  • RTOS
    +关注

    关注

    22

    文章

    811

    浏览量

    119593
  • 代码
    +关注

    关注

    30

    文章

    4779

    浏览量

    68521
收藏 人收藏

    评论

    相关推荐

    单片机为什么要用RTOS

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

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

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

    RT0SMCS-51系列单片机中的应用

    RT0SMCS-51系列单片机中的应用:嵌入式应用中使用实时操作系统(RTOS),已成为单片机
    发表于 12-03 22:38 24次下载

    开源RTOSSTM32单片机中的应用

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

    单片机资源少但是不能拒绝RTOS

    对于搞单片机的特别用8051系列工程师来说,谈到单片机RTOS,很多时候会问一句:为什么要用RTOS?单片机就这一点资源,使用
    的头像 发表于 03-19 15:10 5549次阅读

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

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

    浅述单片机程序的整体框架设计的思路体会

    一些初学单片机的同学,刚刚入手做单片机开发,还没有涉及到使用RTOS,且刚入手直接上RTOS可能会有些难度,有的使用的相对较老单片机资源还有
    的头像 发表于 06-27 11:34 4399次阅读
    浅述<b class='flag-5'>单片机</b>程序的整体<b class='flag-5'>框架</b>设计的思路体会

    单片机程序框架

    单片机程序框架
    发表于 11-13 14:21 16次下载
    <b class='flag-5'>单片机</b>程序<b class='flag-5'>框架</b>

    单片机就那点资源,为啥还要用RTOS

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

    为什么单片机代码Flash中运行,单片机代码运行位置跟电脑有什么不同?

    1. 单片机与电脑,代码运行空间的区别单片机与 电脑/Linux嵌入式 代码运行空间上不同。
    发表于 12-01 16:06 6次下载
    为什么<b class='flag-5'>单片机</b>的<b class='flag-5'>代码</b><b class='flag-5'>在</b>Flash中运行,<b class='flag-5'>单片机</b>的<b class='flag-5'>代码</b>运行位置跟电脑有什么不同?

    新唐单片机代码评审总结

    昨晚上,我们一个同事组织了一个小会议,大家一起讨论了一个项目的单片机代码,这个单片机用的是新唐单片机,期间大家也讨论了一些问题,总结一下,希望对写
    发表于 12-01 16:06 15次下载
    新唐<b class='flag-5'>单片机</b><b class='flag-5'>代码</b>评审总结

    如何在单片机中使用malloc函数

    但是每个嵌入式 RTOS 都会有自己的内存管理方式,本文就来聊聊我对 malloc 函数单片机程序设计中的一些看法。 本文并不是要说明单片
    的头像 发表于 04-24 09:50 2551次阅读
    如何在<b class='flag-5'>单片机</b><b class='flag-5'>中使</b>用malloc函数

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

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

    51单片机可以移植RTOS吗?

    说起RTOS移植,我们首先会想到32位单片机
    发表于 05-23 17:09 2157次阅读

    单片机解析g代码的方法

    单片机是一种完整的计算机系统,它集成了处理器、存储器、输入输出接口等基本的计算机组成部分。单片机应用广泛,可以用于控制各种电子设备。单片机中,G
    的头像 发表于 12-22 14:15 1760次阅读