freeRTOS 时间管理

2023-05-16

1. 相对时间延时
vTaskDelay -> prvAddCurrentTaskToDelayedList(函数分析之后,有步骤解析)
为什么使用两个延时列表?


2. 绝对时间延时
PreTimeWake、SysTickCnt、TimeWake三者的关系图。


3. 系统滴答处理函数Increment
步骤总结在下边了。

相对时间延时

#if ( INCLUDE_vTaskDelay == 1 )

    void vTaskDelay( const TickType_t xTicksToDelay )
    {
    BaseType_t xAlreadyYielded = pdFALSE;

        /* A delay time of zero just forces a reschedule. */
        if( xTicksToDelay > ( TickType_t ) 0U )  延时时间如果不大于0,相当于直接进行任务切换
        {
            configASSERT( uxSchedulerSuspended == 0 );
            vTaskSuspendAll();  挂起调度器
            {
                traceTASK_DELAY();

                /* A task that is removed from the event list while the
                scheduler is suspended will not get placed in the ready
                list or removed from the blocked list until the scheduler
                is resumed.

                This task cannot be in an event list as it is the currently
                executing task. */
                prvAddCurrentTaskToDelayedList( xTicksToDelay, pdFALSE );  加入到pxDelayedTaskList或者pxOverflowDelayedTaskList中
            }
            xAlreadyYielded = xTaskResumeAll();  如果返回true,说明需要任务切换
        }
        else
        {
            mtCOVERAGE_TEST_MARKER();
        }

        /* Force a reschedule if xTaskResumeAll has not already done so, we may
        have put ourselves to sleep. */
        if( xAlreadyYielded == pdFALSE )
        {
            portYIELD_WITHIN_API();  置位PendSV
        }
        else
        {
            mtCOVERAGE_TEST_MARKER();
        }
    }

#endif /* INCLUDE_vTaskDelay */
  1 static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseType_t xCanBlockIndefinitely )
  2 {
  3 TickType_t xTimeToWake;
  4 const TickType_t xConstTickCount = xTickCount;  记录时间点,用于任务唤醒。每个systick中断,xTickcount++.
  5 
  6     #if( INCLUDE_xTaskAbortDelay == 1 )
  7     {
  8         /* About to enter a delayed list, so ensure the ucDelayAborted flag is
  9         reset to pdFALSE so it can be detected as having been set to pdTRUE
 10         when the task leaves the Blocked state. */
 11         pxCurrentTCB->ucDelayAborted = pdFALSE;  使能xTaskAbortDelay的话,初始化这个变量字段为false.
 12     }
 13     #endif
 14 
 15     /* Remove the task from the ready list before adding it to the blocked list
 16     as the same list item is used for both lists. */  任务从就绪表移除
 17     if( uxListRemove( &( pxCurrentTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )
 18     {
 19         /* The current task must be in a ready list, so there is no need to
 20         check, and the port reset macro can be called directly. */
 21         portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );  更新变量uxTopReadyPrio,详见任务调度、删除任务章节。
 22     }
 23     else
 24     {
 25         mtCOVERAGE_TEST_MARKER();
 26     }
 27 
 28     #if ( INCLUDE_vTaskSuspend == 1 )
 29     {
 30         if( ( xTicksToWait == portMAX_DELAY ) && ( xCanBlockIndefinitely != pdFALSE 表示允许任务阻塞) )
 31         {
 32             /* Add the task to the suspended task list instead of a delayed task
 33             list to ensure it is not woken by a timing event.  It will block
 34             indefinitely. */    Never Timeout!!!
 35             vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xStateListItem ) );  直接添加到挂起列表,而不是延时列表!
 36         }
 37         else
 38         {
 39             /* Calculate the time at which the task should be woken if the event
 40             does not occur.  This may overflow but this doesn't matter, the
 41             kernel will manage it correctly. */
 42             xTimeToWake = xConstTickCount + xTicksToWait;  计算任务唤醒时间点...
 43 
 44             /* The list item will be inserted in wake time order. */
 45             listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake );  写入 状态列表项value的值
 46 
 47             if( xTimeToWake < xConstTickCount )  任务唤醒时间点 < TickCount,说明数值溢出了(32bit值),溢出的话,将这个任务添加到“溢出延时列表”。
 48             {
 49                 /* Wake time has overflowed.  Place this item in the overflow
 50                 list. */
 51                 vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );  这个插入的API是排序插入的!
 52             }
 53             else
 54             {
 55                 /* The wake time has not overflowed, so the current block list
 56                 is used. */
 57                 vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );  没有溢出,添加到延时列表
 58 
 59                 /* If the task entering the blocked state was placed at the
 60                 head of the list of blocked tasks then xNextTaskUnblockTime
 61                 needs to be updated too. */
 62                 if( xTimeToWake < xNextTaskUnblockTime )  全局变量xNextTaskUnblockTime:距离下一个要取消阻塞的任务最小时间点
 63                 {
 64                     xNextTaskUnblockTime = xTimeToWake;  更新这个最小的时间点
 65                 }
 66                 else
 67                 {
 68                     mtCOVERAGE_TEST_MARKER();
 69                 }
 70             }
 71         }
 72     }
 73     #else /* INCLUDE_vTaskSuspend */  没有定义TaskSuspend列表
 74     {
 75         /* Calculate the time at which the task should be woken if the event
 76         does not occur.  This may overflow but this doesn't matter, the kernel
 77         will manage it correctly. */
 78         xTimeToWake = xConstTickCount + xTicksToWait;
 79 
 80         /* The list item will be inserted in wake time order. */
 81         listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake );
 82 
 83         if( xTimeToWake < xConstTickCount )
 84         {
 85             /* Wake time has overflowed.  Place this item in the overflow list. */
 86             vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );
 87         }
 88         else
 89         {
 90             /* The wake time has not overflowed, so the current block list is used. */
 91             vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );
 92 
 93             /* If the task entering the blocked state was placed at the head of the
 94             list of blocked tasks then xNextTaskUnblockTime needs to be updated
 95             too. */
 96             if( xTimeToWake < xNextTaskUnblockTime )
 97             {
 98                 xNextTaskUnblockTime = xTimeToWake;
 99             }
100             else
101             {
102                 mtCOVERAGE_TEST_MARKER();
103             }
104         }
105 
106         /* Avoid compiler warning when INCLUDE_vTaskSuspend is not 1. */
107         ( void ) xCanBlockIndefinitely;
108     }
109     #endif /* INCLUDE_vTaskSuspend */
110 }

>1 记录时间点O

>2 将任务从就绪列表删除

>3 根据时间点O,计算唤醒的时间点

>3' 将唤醒时间点,写入任务状态列表项的value里,用于排序插入。

>4 根据唤醒时间点,将任务加入到延时列表或者溢出的延时列表

>5 更新NextTaskUnblockTime

为什么有两个延时列表?

当TickCnt没有溢出时,唤醒的时间点 > TickCnt,就有两种情况,溢出或者没溢出

@唤醒时间点没有溢出的任务,将他们放到延时任务列表中,一旦TickCnt == 唤醒时间点时,就出队了。

唤醒时间点溢出的任务,将他们放到溢出延时任务列表,当TickCnt也溢出了,把这两个列表交换一下,

这时原来的延时任务列表肯定是空的了!因为TickCnt都溢出了啊!

所以原来的溢出延时任务列表,变成了当前使用的延时任务列表。又可以参照@处的步骤走了。

相当于溢出延时任务列表时钟是一个当前延时任务列表的拓展,

互相交替使用,无穷尽。

绝对时间延时

       params: 上一次结束延时的时间点,本次要延时的节拍数(相对于pxPreviousWakeTime来算),他们的关系见后边的图。
1 void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) 2 { 3 TickType_t xTimeToWake; 4 BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE; 5 6 configASSERT( pxPreviousWakeTime ); 7 configASSERT( ( xTimeIncrement > 0U ) ); 8 configASSERT( uxSchedulerSuspended == 0 ); 9 10 vTaskSuspendAll(); 11 { 12 /* Minor optimisation. The tick count cannot change in this 13 block. */ 14 const TickType_t xConstTickCount = xTickCount; 记录时间点 15 16 /* Generate the tick time at which the task wants to wake. */ 17 xTimeToWake = *pxPreviousWakeTime + xTimeIncrement; 任务唤醒时间点。## 时间关系见图。 18 19 if( xConstTickCount < *pxPreviousWakeTime ) 20 { 21 /* The tick count has overflowed since this function was 22 lasted called. In this case the only time we should ever 23 actually delay is if the wake time has also overflowed, 24 and the wake time is greater than the tick time. When this 25 is the case it is as if neither time had overflowed. */ ## TickCount和TimeToWake都溢出。见图。 26 if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) ) 27 { 28 xShouldDelay = pdTRUE; 允许延时 29 } 30 else 31 { 32 mtCOVERAGE_TEST_MARKER(); 33 } 34 } 35 else 36 { 37 /* The tick time has not overflowed. In this case we will 38 delay if either the wake time has overflowed, and/or the 39 tick time is less than the wake time. */ 40 if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) ) 41 { 42 xShouldDelay = pdTRUE; 两种情况都允许延时,(只有TimeToWake溢出 or 都没有溢出)见图 43 } 44 else 45 { 46 mtCOVERAGE_TEST_MARKER(); 47 } 48 } 49 50 /* Update the wake time ready for the next call. */ 51 *pxPreviousWakeTime = xTimeToWake; 更新PreviousWakeTime 52 53 if( xShouldDelay != pdFALSE ) 54 { 55 traceTASK_DELAY_UNTIL( xTimeToWake ); 56 57 /* prvAddCurrentTaskToDelayedList() needs the block time, not 58 the time to wake, so subtract the current tick count. */
还需要的阻塞时间是(TimeToWake - TickCount),而vTaskDelay()函数中,只是简单的设为xTicksToDelay!! 59 prvAddCurrentTaskToDelayedList( xTimeToWake - xConstTickCount, pdFALSE ); 60 } 61 else 62 { 63 mtCOVERAGE_TEST_MARKER(); 64 } 65 } 66 xAlreadyYielded = xTaskResumeAll(); 67 68 /* Force a reschedule if xTaskResumeAll has not already done so, we may 69 have put ourselves to sleep. */ 70 if( xAlreadyYielded == pdFALSE ) 防止当前任务阻塞后休眠,这里强制进行一次任务切换。 71 { 72 portYIELD_WITHIN_API(); 73 } 74 else 75 { 76 mtCOVERAGE_TEST_MARKER(); 77 } 78 }

使用绝对延时不一定就能周期性的运行,只能保证按照一定周期取消阻塞。

如果被高优先级任务或者中断打断,这个绝对延时就被破坏了。

使用方法:

TickType_t PreviousWakeTime;

//延时 50ms,但是函数 vTaskDelayUntil()的参数需要设置的是延时的节拍数,不能直接设置延时时间。
const TickType_t TimeIncrement = pdMS_TO_TICKS( 50 );  //将50ms转换为系统节拍数。
PreviousWakeTime = xTaskGetTickCount(); //获取当前的系统节拍值

//调用函数 vTaskDelayUntil 进行延时 vTaskDelayUntil( &PreviousWakeTime, TimeIncrement);

========================================================

系统时钟节拍TickCount的处理。

  1 BaseType_t xTaskIncrementTick( void )
  2 {
  3 TCB_t * pxTCB;
  4 TickType_t xItemValue;
  5 BaseType_t xSwitchRequired = pdFALSE;
  6 
  7     /* Called by the portable layer each time a tick interrupt occurs.
  8     Increments the tick then checks to see if the new tick value will cause any
  9     tasks to be unblocked. */  每个tick中断调用一次,增加tick值,判断是否有任务取消阻塞。
 10     traceTASK_INCREMENT_TICK( xTickCount );
 11     if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
 12     {
 13         /* Minor optimisation.  The tick count cannot change in this block. */
 15         const TickType_t xConstTickCount = xTickCount + 1;
 16 
 17         /* Increment the RTOS tick, switching the delayed and overflowed
 18         delayed lists if it wraps to 0. */
 19         xTickCount = xConstTickCount;  交换两个延时列表,如果Tick溢出归零。
 20 
 21         if( xConstTickCount == ( TickType_t ) 0U )
 22         {
 23             taskSWITCH_DELAYED_LISTS();  交换之后,更新uNextTaskUnblockTime
 24         }
 25         else
 26         {
 27             mtCOVERAGE_TEST_MARKER();
 28         }
 29         
uNextTaskUnblockTime保存下一个要解除阻塞的任务时间点值,如果小于等于 TickCnt,则有任务要解除阻塞!! 30 /* See if this tick has made a timeout expire. Tasks are stored in 31 the queue in the order of their wake time - meaning once one task 32 has been found whose block time has not expired there is no need to 33 look any further down the list. */ 34 if( xConstTickCount >= xNextTaskUnblockTime ) 35 { 36 for( ;; ) 37 { 38 if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) 延时任务列表为空,把NextTimeUnblockTime设为最大 39 { 40 /* The delayed list is empty. Set xNextTaskUnblockTime 41 to the maximum possible value so it is extremely 42 unlikely that the 43 if( xTickCount >= xNextTaskUnblockTime ) test will pass 44 next time through. */ 45 xNextTaskUnblockTime = portMAX_DELAY; /*lint !e961 */ 46 break; 47 } 48 else 延时任务列表不为空,延时任务列表是按唤醒时间排序的! 49 { 50 /* The delayed list is not empty, get the value of the 51 item at the head of the delayed list. This is the time 52 at which the task at the head of the delayed list must 53 be removed from the Blocked state. */ 54 pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); 55 xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ) ); 56 57 if( xConstTickCount < xItemValue ) 任务唤醒时间点 大于 TickCnt,表示延时时间未到。 58 { 59 /* It is not time to unblock this item yet, but the 60 item value is the time at which the task at the head 61 of the blocked list must be removed from the Blocked 62 state - so record the item value in 63 xNextTaskUnblockTime. */ 64 xNextTaskUnblockTime = xItemValue; 更新NTUT... 65 break; 66 } 67 else 68 { 69 mtCOVERAGE_TEST_MARKER(); 70 } 71 72 /* It is time to remove the item from the Blocked state. */ 73 ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); 延时时间到了,先从延时列表移除。 74 75 /* Is the task waiting on an event also? If so remove 76 it from the event list. */ 是否这个任务还在等信号量,如果是,就从这个信号量列表移除,因为超时时间到了!! 77 if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) 列表项的Container是事件容器(某个Queue的WaitToSend/Rcv列表),其Owner是所属任务TCB。 78 { 79 ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); 80 } 81 else 82 { 83 mtCOVERAGE_TEST_MARKER(); 84 } 85 86 /* Place the unblocked task into the appropriate ready list. */ 88 prvAddTaskToReadyList( pxTCB ); 添加到就绪列表 89 90 /* A task being unblocked cannot cause an immediate 91 context switch if preemption is turned off. */ 92 #if ( configUSE_PREEMPTION == 1 ) 93 { 94 /* Preemption is on, but a context switch should 95 only be performed if the unblocked task has a 96 priority that is equal to or higher than the 97 currently executing task. */ 98 if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) 99 { 100 xSwitchRequired = pdTRUE; 这个任务优先级较高,需要任务切换!标记下. 101 } 102 else 103 { 104 mtCOVERAGE_TEST_MARKER(); 105 } 106 } 107 #endif /* configUSE_PREEMPTION */ 108 } 109 } 110 } 111
时间片调度相关内容: 112 /* Tasks of equal priority to the currently running task will share 113 processing time (time slice) if preemption is on, and the application 114 writer has not explicitly turned time slicing off. */ 115 #if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) 116 { 117 if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > ( UBaseType_t ) 1 ) 118 { 119 xSwitchRequired = pdTRUE; 当下这个优先级有多个任务,则标记需要任务切换。 120 } 121 else 122 { 123 mtCOVERAGE_TEST_MARKER(); 124 } 125 } 126 #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */ 127 128 #if ( configUSE_TICK_HOOK == 1 ) 时间片钩子函数 129 { 130 /* Guard against the tick hook being called when the pended tick 131 count is being unwound (when the scheduler is being unlocked). */ 132 if( uxPendedTicks == ( UBaseType_t ) 0U ) 133 { 134 vApplicationTickHook(); 135 } 136 else 137 { 138 mtCOVERAGE_TEST_MARKER(); 139 } 140 } 141 #endif /* configUSE_TICK_HOOK */ 142 } 143 else 144 { 145 ++uxPendedTicks; 调度器被挂起时,Tick中断不更新TickCnt,而是更新PendTick。在调度器恢复函数中,处理了PendTick. 146 147 /* The tick hook gets called at regular intervals, even if the 148 scheduler is locked. */ 149 #if ( configUSE_TICK_HOOK == 1 ) 150 { 151 vApplicationTickHook(); 152 } 153 #endif 154 } 155 156 #if ( configUSE_PREEMPTION == 1 ) 157 { 158 if( xYieldPending != pdFALSE ) 159 { 160 xSwitchRequired = pdTRUE; 161 } 162 else 163 { 164 mtCOVERAGE_TEST_MARKER(); 165 } 166 } 167 #endif /* configUSE_PREEMPTION */ 168 169 return xSwitchRequired; 返回值ture表示需要任务切换。xPortSysTickHandler调用xTaskIncrementTick时会判断这个返回值,并决定是否进行任务切换。 170 }

>1 给TickCnt加一,如果溢出,交换两个延时任务列表。

>2 uNextTaskUnblockTime保存下一个要解除阻塞的任务时间点值,如果小于等于 TickCnt,则有任务要解除阻塞!!

>3 从延时任务列表的第一个列表项中取出Value(唤醒时间)

>4 如果这个唤醒时间 大于 TickCnt表示延时没到,更新一下UTUT的值。

>5 反之,则有任务延时时间到了!从延时任务列表中移除。

>6 如果这个任务在等待某个事件,那么就把它从事件的等待列表(WaitToSend/Rcv列表)中踢出去,因为超市时间到了!

>7 添加到就绪任务列表,如果它优先级高,则请求任务切换。

时间片的解析不再多说,见任务切换。

如果调度器被挂起了,那么不能更新TickCnt,改为更新PendTickCnt,

在调度器恢复的函数处理中,会把这个时间弥补回去给TickCnt。

留白

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

freeRTOS 时间管理 的相关文章

  • FreeRTOS内核配置说明---FreeRTOS Kernel V10.2.1

    FreeRTOS内核是高度可定制的 使用配置文件FreeRTOSConfig h进行定制 每个FreeRTOS应用都必须包含这个头文件 用户根据实际应用来裁剪定制FreeRTOS内核 这个配置文件是针对用户程序的 而非内核 因此配置文件一般
  • STM32CubeMX+FreeRTOS学习笔记(一)

    嵌入式实时操作系统FreeRTOS 基本概述 在嵌入式领域当中 实时操作系统的应用越来越广泛了 目前嵌入式操作系统种类很多 例如 Clinux C OS II C OS III FreeRTOS RT Thread等等 这篇文章所记录的就是
  • 【FreeRTOS】多任务创建

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • FreeRTOS学习(八) 延时函数

    声明及感谢 跟随正点原子资料学习 在此作为学习的记录和总结 环境 keil stm32f103 FreeRTOS延时函数有两个 分别是 vTaskDelay vTaskDelayUntil 1 vTaskDelay 任务相对延时 函数原型
  • 【FreeRTOS】队列的使用

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • FreeRTOS打印任务对CPU的占有率

    1 配置RTOS 1 打开RTOS Config Parameter 找到Run Time And Task States gathering related definitions 使能GENERATE RUN TIME STATS US
  • FreeRTOS+CubeMX系列第一篇——初识FreeRTOS

    文章目录 一 关于FreeRTOS 二 FreeRTOS的特点 三 如何在CubeMX上配置FreeRTOS 四 FreeRTOS文档资料 五 同系列博客 一 关于FreeRTOS 1 什么是FreeRTOS FreeRTOS是一个迷你的实
  • freeRTOS使用uxTaskGetStackHighWaterMark函数查看任务堆栈空间的使用情况

    摘要 每个任务都有自己的堆栈 堆栈的总大小在创建任务的时候就确定了 此函数用于检查任务从创建好到现在的历史剩余最小值 这个值越小说明任务堆栈溢出的可能性就越大 FreeRTOS 把这个历史剩余最小值叫做 高水位线 此函数相对来说会多耗费一点
  • Error: L6218E: Undefined symbol vApplicationGetIdleTaskMemory (referred from tasks.o).

    我用的是F103ZET6的板子 移植成功后 编译出现两个错误是关于stm32f10x it c 里 void SVC Handler void void PendSV Handler void 两个函数的占用问题 随后编译出现以下两个问题
  • FreeRTOS:中断配置

    目录 一 Cortex M 中断 1 1中断简介 1 2中断管理简介 1 3优先级分组定义 1 4优先级设置 1 5用于中断屏蔽的特殊寄存器 1 5 1PRIMASK 和 FAULTMASK 寄存器 1 5 2BASEPRI 寄存器 二 F
  • FreeRTOS基础五:软件定时器

    软件定时器简介 软件定时器的作用 在指定的时间到来时执行指定的函数 或者以某个频率周期性地执行某个函数 被执行的函数叫做软件定时器回调函数 软件定时器由FreeRTOS内核实现 不需要硬件支持 软件定时器只有在软件定时器回调函数被调用时才需
  • Arduino IDE将FreeRTOS用于STM32

    介绍 适用于STM32F103C8的FreeRTOS STM32F103C是一种能够使用FreeRTOS的ARM Cortex M3处理器 我们直接在Arduino IDE中开始使用STM32F103C8的FreeRTOS 我们也可以使用K
  • FreeRTOS笔记(十)中断

    中断 当CPU在执行某一事件A时 发生另外一个更重要紧急的事件B请求CPU去处理 产生了中断 于是CPU暂时中断当前正在执行的事件A任务而对对事件B进行处理 CPU处理完事件B后再返回之前中断的位置继续执行原来的事件A 这一过程统称为中断
  • RT-Thread记录(五、RT-Thread 临界区保护与FreeRTOS的比较)

    本文聊聊临界区 以及RT Thread对临界区的处理 通过源码分析一下 RT Thread 对临界区保护的实现以及与 FreeRTOS 处理的不同 目录 前言 一 临界区 1 1 什么是临界区 1 2 RTOS中的临界区 二 RT Thre
  • FreeRTOS临界段

    1 临界段 在访问共享资源时不希望被其他任务或者中断打断的代码 这段要执行的代码称为临界段代码 2 设置临界段的目的 保护共享资源 例如 全局变量 公共函数 不可重入函数 函数里面使用 了一些静态全局变量 malloc 等 保护外设的实时性
  • FreeRTOS实时操作系统(三)任务挂起与恢复

    系列文章 FreeRTOS实时操作系统 一 RTOS的基本概念 FreeRTOS实时操作系统 二 任务创建与任务删除 HAL库 FreeRTOS实时操作系统 三 任务挂起与恢复 FreeRTOS实时操作系统 四 中断任务管理 FreeRTO
  • 使用 GCC 编译器的 ARM 内核的堆栈回溯(当存在 MSP 到 PSP 切换时)

    核心 ARM Cortex M4 编译器 GCC 5 3 0 ARM EABI 操作系统 免费 RTOS 我正在使用 gcc 库函数 Unwind Reason Code Unwind Backtrace Unwind Trace Fn v
  • 当一个任务写入变量而其他任务读取该变量时,我们是否需要信号量?

    我正在研究 freeRtos 并且我有一个名为 x 的变量 现在 每秒只有一个任务正在写入该变量 而其他任务正在读取该变量值 我需要用互斥锁来保护变量吗 如果变量为 32 位或更小 并且其值是独立的并且不与任何其他变量一起解释 则不需要互斥
  • C++ freeRTOS任务,非静态成员函数的无效使用

    哪里有问题 void MyClass task void pvParameter while 1 this gt update void MyClass startTask xTaskCreate this gt task Task 204
  • 小型 ARM 微控制器的 RTOS 内核之间的可量化差异 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 有许多不同的 RTOS 可用于微控制器 我专门寻找支持 ARM Cortex M 处理器的 RTOS 另外 我对闭源解决方案不感兴趣 试图从网站

随机推荐

  • 命令行给cmake传递参数

    我们期望在编译前将一些信息缓存起来 然后用CMakeLists txt进行构建时 希望可以访问之前缓存给cmake的变量 比如我们希望缓存TARGET CPU 并且他的值为X86 那么我们可以在命令行或者脚本中执行一下操作 cmake DT
  • 在CMakeLists.txt如何执行脚本?execute_process

    execute process span class token punctuation span COMMAND span class token function bash span SCRIPT PATH name sh WORK P
  • C++运算符重载中有些方法为什么需要定义为友元函数

    C 43 43 提供运算符重载主要目的 xff1a 希望对象之间的运算看起来可以和编译器内置类型一样丝滑 xff1b 相当于是告知编译器 xff0c 类对象之间运算应该如何去做处理 通过实现一个复数类 xff0c 来阐述本文章的主题 xff
  • linux网络编程之socket,bind,listen,connect,accept

    socket span class token macro property span class token directive hash span span class token directive keyword include s
  • Linux网络发送和接收内核缓冲区大小的设置

    socket属性 xff1a SO SNDBUF 发送缓冲区 SO SNDBUF Sets or gets the maximum socket send buffer span class token keyword in span by
  • docker查看运行时容器的IP地址

    使用inspect来查看容器的信息 span class token function docker span inspect span class token punctuation span docker name span class
  • python基础梳理(一)

    一 python程序的组成 表达式 xff1a 建立并且处理数据对象且能返回数据对象的引用关系 示例 xff1a 1 43 2 系统会产生1和2俩个对象 xff0c 并且进行处理生产对象3 xff0c 将对象3返回回去 二 核心的数字类型
  • 串级PID结构及参数调整见解

    在设计控制系统中 xff0c 常用的控制算法为PID xff0c 即比例 积分 微分控制器 能够实现对控制对象的物理特性的控制 xff0c 以期达到特定的运行效果 此外由于PID控制器的灵活特性 xff0c 可以与其它控制算法进行灵活的组合
  • freeRTOS 开启关闭调度器、挂起恢复调度器、vTaskStepTick

    1 开启调度器 br vTaskStartScheduler 43 vPortSetupTimerInterrupt 设置systick xff0c 初始化低功耗运行系统补偿时间 br 43 xPortStartScheduler 43 p
  • 通过Flask框架封装Tushare获取的日线股票数据

    概要介绍 概要介绍 xff08 TuShare id 282782 xff09 当我们需要进行量化交易分析 xff0c 或者通过代码进行股票的数据计算 xff0c 研究金融时 xff0c 我们需要获取最基本的股票价格 xff0c 开盘价收盘
  • linux系统安装硬盘分区建议

    笔者使用linux也很长时间了 xff0c 但总有在使用一段时间之后感觉系统分区不是很合理 xff0c 这里就算是给自己总结一下 xff0c 也跟大家一起分享吧 一 常见挂载点的情况说明 一般来说 xff0c 在linux系统中都有最少两个
  • Python3.4简单爬虫实现之抓取糗事百科段子

    网上的python教程大都是2 X版本的 xff0c python2 X和python3 X相比较改动比较大 xff0c 好多库的用法不太一样 xff0c 我安装的是3 4 1 xff0c 就用3 4 1实现一下网页内容抓取 首先是库 xf
  • 关于stm32中串口重定向问题详解(找个时间好好理解下)

    usart这部分代码我也是从网上copy出来的 xff0c 一下是作者的解释 xff1a 简单地说 xff1a 想在mdk 中用printf xff0c 需要同时重定义fputc函数和避免使用semihosting 半主机模式 xff09
  • http解析库http-parser

    一 http parser简介 1 简介 http parser是一个用C编写的HTTP消息解析器 xff0c 可以解析请求和响应 xff0c 被设计用于高性能HTTP应用程序 它不会进行任何系统调用及内存分配 xff0c 它不会缓冲数据
  • centos系统重置root密码,忘记密码修改

    1 开机按下Ecs键 xff0c 进入如下界面 2 根据需要选择系统内核版本并按e键 3 光标移动到 linux 16 开头的行 xff0c 找到 ro 改为 rw init 61 sysroot bin sh xff1b 4 按 Ctrl
  • summary1 如何在Python中创建基本的ROS节点[AI]

    本课程结束时 xff0c 您将能够 xff1a 1 在模拟中 xff0c 使用ROS控制TurtleBot3机器人 2 使用roslaunch和rosrun启动ROS应用程序 3 使用关键ROS命令行工具询问正在运行的ROS应用程序 4 创
  • switch case语句用法

    一般情况下 xff0c 判断语句常用的有if else xff0c 三目运算符 xff0c 还有switch case等 xff0c 根据不同需求使用其判断语句 下面以简单示例展示 xff1a 在输入框中输入数字 xff0c 判断其星期几
  • 四轴飞行器基础

    原文知识来自果壳网 四轴飞行器基础篇 xff0c 进行一些适量增删 基本原理与名词解释 1 遥控器篇 通道 通道就是可以遥控器控制的动作路数 xff0c 比如遥控器只能控制四轴上下飞 xff0c 那么就是1个通道 但四轴在控制过程中需要控制
  • OPENWRT,爱快等软路由推荐

    这种用于路由器的开源固件 操作系统可以让它获得大多数路由器所不具备的功能 xff0c 甚至可以把一台旧PC变成强大的路由器或防火墙设备 软路由提供的一些特性和功能包括带宽监控 VLAN支持 高级无线设置 VPN集成 高级安全等等 在这篇文章
  • freeRTOS 时间管理

    1 相对时间延时 br vTaskDelay gt prvAddCurrentTaskToDelayedList 函数分析之后 xff0c 有步骤解析 br 为什么使用两个延时列表 xff1f br br br 2 绝对时间延时 br Pr