说明:

本文仅作为学习FreeRTOS的记录文档,作为初学者肯定很多理解不对甚至错误的地方,望网友指正。

FreeRTOS是一个RTOS(实时操作系统)系统,支持抢占式、合作式和时间片调度。适用于微处理器或小型微处理器的实时应用。

本文档使用的FreeRTOS版本:FreeRTOS Kernel V10.4.1

参考文档:《FreeRTOS_Reference_Manual_V10.0.0.pdf》《FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide.pdf》《STM32F4 FreeRTOS开发手册_V1.1.pdf》

参考视频:正点原子FreeRTOS手把手教学-基于STM32_哔哩哔哩_bilibili

5 其它任务相关函数

介绍一些任务辅助函数,方便查询任务的相关信息。

5.1 设置任务优先级

函数原型:

#include “FreeRTOS.h”
#include “task.h”
void vTaskPrioritySet( TaskHandle_t pxTask, UBaseType_t uxNewPriority );

函数描述:设置任务优先级。

函数参数:pxTask设置任务优先级的任务句柄。如果任务设置自己的优先级,这个参数可以填为NULL。

返回值:重新设置的任务优先级值。0表示最低优先级,configMAX_PRIORITIES – 1表示最高优先级。

5.2 获取任务优先级

函数原型:

#include “FreeRTOS.h”
#include “task.h”
UBaseType_t uxTaskPriorityGet( TaskHandle_t pxTask );

函数描述:获取任务优先级。

函数参数:pxTask查询任务优先级的任务句柄。如果任务查询自己的优先级,这个参数可以填为NULL。

返回值:查询任务的优先级值。

测试代码:

configSTACK_DEPTH_TYPE Task_STACK_SIZE = 5;
UBaseType_t Task_Priority = 12; void task_code(void *para)
{
static unsigned int cnt = 0; for (;;)
{
PRINT(" task cnt %u...", cnt);
cnt++;
vTaskDelay(1000);
}
} void task_func(void)
{
TaskHandle_t xhandle;
UBaseType_t uxCreatedPriorty, uxOurPriorty; if (xTaskCreate(task_code, "demo task",
Task_STACK_SIZE, NULL, Task_Priority,
&xhandle) != pdPASS)
{
PRINT("creat task failed!\n");
} else
{
uxCreatedPriorty = uxTaskPriorityGet(xhandle);
uxOurPriorty = uxTaskPriorityGet(NULL);
PRINT("created task priority: %d", uxCreatedPriorty);
PRINT("our task priority: %d", uxOurPriorty); vTaskPrioritySet(xhandle, 3);
uxCreatedPriorty = uxTaskPriorityGet(xhandle);
uxOurPriorty = uxTaskPriorityGet(NULL);
PRINT("after changed, created task priority: %d", uxCreatedPriorty);
PRINT("after changed, our task priority: %d", uxOurPriorty);
}
}

默认创建任务优先级为12,然后更改任务优先级为3。

编译,运行,结果如下:

$ ./build/freertos-simulator
created task priority: 12
our task priority: 12
after changed, created task priority: 3
after changed, our task priority: 3
task cnt 0...
task cnt 1...
... ...

5.3 获取系统中所有任务的状态

函数原型:

#include “FreeRTOS.h”
#include “task.h”
UBaseType_t uxTaskGetSystemState(
TaskStatus_t * const pxTaskStatusArray,
const UBaseType_t uxArraySize,
unsigned long * const pulTotalRunTime );

函数描述:获取系统中所有任务的任务状态。TaskStatus_t是一个保存任务状态信息的结构体,结构体中包括任务句柄、任务名称、堆栈、优先级等信息。要使用这个函数需要打开configUSE_TRACE_FACILITY宏。

函数参数:pxTaskStatusArray:指向TaskStatus_t数据结构数组的首地址,每个任务至少包含一个TaskStatus_t结构体。任务的结构体数目可以使用uxTaskGetNumberOfTasks函数获得。

uxArraySize:保存任务状态数组的数组的大小。

pulTotalRunTime:如果configGENERATE_RUN_TIME_STATS配置为1,这个参数保存系统总的运行时间。

返回值:统计到的任务状态的数目,也就是pxTaskStatusArray数组成员个数,如果uxArraySize参数太小,返回值可能为0。

TaskStatus_t结构体定义如下:

typedef struct xTASK_STATUS
{
TaskHandle_t xHandle; //任务句柄
const char * pcTaskName; //任务名字
UBaseType_t xTaskNumber; //任务编号
eTaskState eCurrentState; //任务当前状态
UBaseType_t uxCurrentPriority; //任务当前优先级
UBaseType_t uxBasePriority; //任务基础优先级
uint32_t ulRunTimeCounter; //任务运行总时间
StackType_t * pxStackBase; //堆栈基地址
configSTACK_DEPTH_TYPE usStackHighWaterMark;//从任务创建以来任务堆栈剩余的最小大小,这个值太小说明堆栈有溢出的风险。
} TaskStatus_t;

5.4 获取系统中单个任务的状态

函数原型:

#include “FreeRTOS.h”
#include “task.h”
void vTaskGetTaskInfo( TaskHandle_t xTask,
TaskStatus_t *pxTaskStatus,
BaseType_t xGetFreeStackSpace,
eTaskState eState );

函数描述:获取单个任务的任务状态。要使用这个函数需要打开configUSE_TRACE_FACILITY宏。

函数参数:xTask:任务句柄;pxTaskStatus:存放获取的任务状态信息;

xGetFreeStackSpace:TaskStatus_t结构中有个成员usStackHighWaterMark存放了任务创建以来任务堆栈剩余的最小大小,但是计算这个值需要一些时间,所以可以通过设置xGetFreeStackSpace值为pdFALSE来跳过这个步骤,当设置为pdTRUE才会检查堆栈剩余的最小大小。

eState:TaskStatus_t结构中有个成员eCurrentState存放任务的当前运行状态,但是获取任务状态需要花费不少时间,可通过参数eState直接将任务状态赋值给eCurrentState。也可以将eStates设置为eInvalid,那么任务状态信息有函数vTaskGetInfo()函数获取。

测试代码:

configSTACK_DEPTH_TYPE Task_STACK_SIZE = 20;
UBaseType_t Task_Priority = 12; void task_code(void *para)
{
static unsigned int cnt = 0; for (;;)
{
PRINT(" task cnt %u...", cnt);
cnt++;
vTaskDelay(1000);
}
} void task_func(void)
{
TaskHandle_t xhandle;
TaskStatus_t xTaskDetails;
char *state_str[] = {"running", "ready", "blocked", "suspended", "deleted", "invalid"}; if (xTaskCreate(task_code, "demo task",
Task_STACK_SIZE, NULL, Task_Priority,
&xhandle) != pdPASS)
{
PRINT("creat task failed!\n");
} else
{
vTaskPrioritySet(xhandle, 3);
vTaskGetTaskInfo(xhandle, &xTaskDetails, pdTRUE, eInvalid);
PRINT("Task name : %s", xTaskDetails.pcTaskName);
PRINT("Task number : %d", xTaskDetails.xTaskNumber);
PRINT("Task CurrentState : %s", state_str[xTaskDetails.eCurrentState]);
PRINT("Task CurrentPriority: %d", xTaskDetails.uxCurrentPriority);
PRINT("Task BasePriority : %d", xTaskDetails.uxBasePriority);
PRINT("Task RunTimeCounter : %d", xTaskDetails.ulRunTimeCounter);
PRINT("Task StackBase : %p", xTaskDetails.pxStackBase);
PRINT("Task StackHighWaterMark: %u", xTaskDetails.usStackHighWaterMark);
}
}

编译,运行,结果如下:

$ ./build/freertos-simulator
Task name : demo task
Task number : 1
Task CurrentState : running
Task CurrentPriority: 3
Task BasePriority : 3
Task RunTimeCounter : 0
Task StackBase : 0x2060010
Task StackHighWaterMark: 15
task cnt 0...
task cnt 1...

5.5 获取调度器运行状态

函数原型:

#include “FreeRTOS.h”
#include “task.h”
BaseType_t xTaskGetSchedulerState( void );

函数描述:获取调度器当前的运行状态。使用这个函数需要将宏INCLUDE_xTaskGetSchedulerState置为1。

函数参数:

返回值:INCLUDE_xTaskGetSchedulerState:调度器未启动。调度器启动使用vTaskStartSchedule()函数完成,所以xTaskGetSchedulerState()函数在vTaskStartSchedule()函数之前调用会返回这个值。

taskSCHEDULER_RUNNING:调度器正在运行。

taskSCHEDULER_SUSPENDED:调度器被挂起,因为调用了vTaskSuspendAll()函数。

5.6 获取任务运行状态

函数原型:

#include “FreeRTOS.h”
#include “task.h”
eTaskState eTaskGetState( TaskHandle_t pxTask );

函数描述:获取任务的运行状态。使用此函数需要将INCLUDE_eTaskGetState宏置为1。

函数参数:xTask:要获取的任务句柄

返回值:任务的运行状态,eTaskState是一个枚举变量。

/* Task states returned by eTaskGetState. */
typedef enum
{
eRunning = 0, /* A task is querying the state of itself, so must be running. */
eReady, /* The task being queried is in a read or pending ready list. */
eBlocked, /* The task being queried is in the Blocked state. */
eSuspended, /* The task being queried is in the Suspended state,
or is in the Blocked state with an infinite time out. */
eDeleted, /* The task being queried has been deleted, but its TCB has not yet been freed. */
eInvalid /* Used as an 'invalid state' value. */
} eTaskState;

5.7 设置任务的tag(标签)值

函数原型:

#include “FreeRTOS.h”
#include “task.h”
void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxTagValue );

函数描述:设置任务的标签值,标签值的具体函数和用法由用户决定。FreeRTOS内核不会使用这个标签值。如果要使用这个函数必须将configUSE_APPLICATION_TASK_TAG宏置为1。

函数参数:xTask:任务句柄,如果设为NULL表示设置自身任务的标签值。

pxTagValue:要设置的标签值,这是一个TaskHookFunction_t类型的函数指针,也可以设置为其它值。

返回值:

5.8 获取任务的tag(标签)值

函数原型:

#include “FreeRTOS.h”
#include “task.h”
TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask );

函数描述:获取任务的tag(标签)值,任务控制块中有个成员变量pxTaskTag来保存任务的标签值。标签的功能由用户决定。内核一般不会使用这个标签值。使用这个函数需要将configUSE_APPLICATION_TASK_TAG 宏置为1。

函数参数:xTask:任务句柄

返回值:任务的标签值。

5.9 获取当前任务句柄

函数原型:

#include “FreeRTOS.h”
#include “task.h”
TaskHandle_t xTaskGetCurrentTaskHandle( void );

函数描述:获取当前任务(运行态)的任务的句柄。其实获取到的就是任务控制块。使用这个函数需要将INCLUDE_xTaskGetCurrentTaskHandle宏置为1。

函数参数:

返回值:当前任务的任务句柄。

5.10 获取某个任务句柄

函数原型:

#include “FreeRTOS.h”
#include “task.h”
TaskHandle_t xTaskGetHandle( const char *pcNameToQuery );

函数描述:根据任务名回去任务句柄。使用xTaskCreate()或者xTaskCreateStatic()函数创建任务时,有一个pcName参数,这个参数就是存放的任务名。xTaskGetHandle就是通过这个任务名来查询任务句柄的。使用这个函数必须将INCLUDE_xTaskGetHandle宏置为1。

函数参数:任务名,C语言字符串。

返回值:没有找到pcNameToQuery对应的任务返回NULL;找到了返回对应的任务句柄。

5.11 获取空闲任务的句柄

函数原型:

#include “FreeRTOS.h”
#include “task.h”
TaskHandle_t xTaskGetIdleTaskHandle( void );

函数描述:获取空闲任务的任务句柄。使用这个函数需要将INCLUDE_xTaskGetIdleTaskHandle宏置为1。

函数参数:

返回值:空闲函数的任务句柄。

5.12 检查任务堆栈剩余大小

函数原型:

#include “FreeRTOS.h”
#include “task.h”
UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );

函数描述:每个任务都有自己的堆栈。当任务创建的时候指定了堆栈的大小。这个函数用于检查任务从创建到现在的历史剩余最小值。值越小说明堆栈溢出的可能性越大。FreeRTOS把这个历史最小值叫做”高水位线“。使用此函数需要将INCLUDE_uxTaskGetStackHighWaterMark宏设置为1。

函数参数:xTask:要查询的任务句柄。参数为NULL表示查询任务自身。

返回值:任务堆栈的”高水位线“值,也就是历史剩余最小值。

5.13 获取任务名

函数原型:

#include “FreeRTOS.h”
#include “task.h”
char * pcTaskGetName( TaskHandle_t xTaskToQuery );

函数描述:获取任务的任务名。

函数参数:xTask:要查询的任务句柄,此参数为NULL表示查询自身任务。

返回值:返回任务所对应的任务名。

5.14 查询任务调度器计数器值

函数原型:

#include “FreeRTOS.h”
#include “task.h”
TickType_t xTaskGetTickCount( void );

函数描述:查询任务调度器从启动到现在时间计数器xTickCount的值。

函数参数:

返回值:时间计数器xTickCount的值

xTickCount:是系统的时钟节拍值,并不是真实的时间值。每个滴答定时器中断xTickCount就会加1,1秒滴答定时器中断多少次取决于宏configTICK_RATE_HZ。理论上xTickCount存在溢出的问题,但是这个溢出对内核没有影响,如果用户有使用的话就要考虑溢出。什么时候溢出取决于宏configUSE_16_BIT_TICKS,此宏为1的时候xTickCount为16位的变量,此宏为0的时候xTickCount为32位的变量。

5.15 获取系统任务数

函数原型:

#include “FreeRTOS.h”
#include “task.h”
UBaseType_t uxTaskGetNumberOfTasks( void );

函数描述:获取系统当前任务数

函数参数:

返回值:当前系统中的任务数量。包括挂起态、阻塞态、就绪态、空闲任务、运行态任务。

5.16 获取任务列表

函数原型:

#include “FreeRTOS.h”
#include “task.h”
void vTaskList( char *pcWriteBuffer );

函数描述:获取任务的详细信息。函数会创建一个表格来描述每个任务的详细信息。使用这个函数必须将configUSE_TRACE_FACILITY和configUSE_STATS_FORMATTING_FUNCTIONS宏置为1。

函数参数:pcWriteBuffer保存任务状态信息的存储,这个存储要足够大。

返回值:无。

任务的详细信息如下:

Name:任务名

State:任务状态。X:任务正在执行;B:阻塞态;R:就绪态;S:挂起态;D:任务已经被删除。

Priority:任务优先级

Stack:任务堆栈”高水位线“,也就是堆栈历史最小剩余大小。

Num:任务编号,这个编号是唯一的。当多个任务使用同一个任务名时,可以使用这个编号进行区分。

5.17 统计任务的运行时间信息

函数原型:

#include “FreeRTOS.h”
#include “task.h”
void vTaskGetRunTimeStats( char *pcWriteBuffer );

函数描述:获取任务的运行时间统计信息。使用这个函数必须将configGENERATE_RUN_TIME_STATS和configUSE_STATS_FORMATTING_FUNCTIONS宏置为1。

如果宏configGENERATE_RUN_TIME_STATS设置为1,还需要定义下列的宏:

portCONFIGURE_TIMER_FOR_RUN_TIME_STATS():此宏用来初始化一个外设来提供时间统计功能所需要的时基,一般是定时器/计数器。这个时基的分辨率一定要比FreeRTOS的系统时钟高,一般设置为比系统时钟高10~20倍。

portGET_RUN_TIME_COUNTER_VALUE()或者portALT_GET_RUN_TIME_COUNTER_VALUE(Time):这两个宏实现其中一个即可。用于获取当前的时基的时间值。

函数参数:pcWriteBuffer保存任务运行时间信息的存储,这个存储要足够大。

返回值:

任务的运行时间统计信息如下:

任务的统计信息提供了每个任务获取到的CPU使用权总的时间。表里面提供了每个任务的运行时间和其所占总时间的百分比。

5.18 设置线程本地存储指针的值

函数原型:

#include “FreeRTOS.h
#include “task.h”
void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet,
BaseType_t xIndex, void *pvValue );

函数描述:此函数用于设置线程本地存储指针的值,每个任务都有自己的指针数组来作为线程本地存储,使用这些线程本地存储可以用来在任务控制块中存储一些应用信息,这些信息只属于任务自己。线程本地存储指针数组的大小由configNUM_THREAD_LOCAL_STORAGE_POINTERS宏决定。如果要使用这个函数,这个宏就能设置为0。

函数参数:xTaskToSet:任务句柄,如果设为NULL表示自身任务。xIndex:要设置的线程本地存储指针数组的索引。pvValue:要存储的值。

返回值:

5.19 获取线程本地存储指针的值

函数原型:

#include “FreeRTOS.h”
#include “task.h”
void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery,
BaseType_t xIndex );

函数描述:此函数用于获取线程本地存储指针的值,如果要使用这个函数configNUM_THREAD_LOCAL_STORAGE_POINTERS宏不能设置为0。

函数参数:xTaskToQuery:任务句柄,如果设为NULL表示自身任务。xIndex:要设置的线程本地存储指针数组的索引。

返回值:获取到的线程本地存储指针的值。

5.19 任务状态查询API函数实验

目的:学习使用任务状态查询相关API函数,包括uxTaskGetSystemState()、vTaskGetInfo()、eTaskGetState()、vTaskList()。

设计:创建query_task,用于任务状态和信息查询任务,此任务中使用任务状态和信息相关的API函数。创建print_task:间隔1s不停打印计数信息,提示系统正在运行。

测试代码:

configSTACK_DEPTH_TYPE Print_Task_STACK_SIZE = 5;
UBaseType_t Print_Task_Priority = 1;
TaskHandle_t Print_xhandle; configSTACK_DEPTH_TYPE Query_Task_STACK_SIZE = 20;
UBaseType_t Query_Task_Priority = 2;
TaskHandle_t Query_xhandle; char InfoBuffer[1000];
void print_task_code(void *para)
{
static unsigned int cnt = 0; for (;;)
{
PRINT(" print task cnt %u...", cnt);
cnt++;
vTaskDelay(1000);
}
} void query_task_code(void *para)
{
unsigned int totalRunTime;
UBaseType_t arraySize, x;
TaskStatus_t *statusArray; PRINT("----------- uxTaskGetSystemState() ---------------");
arraySize = uxTaskGetNumberOfTasks();
statusArray = pvPortMalloc(arraySize * sizeof(TaskStatus_t));
if (statusArray != NULL)
{
arraySize = uxTaskGetSystemState(statusArray, arraySize, &totalRunTime);
PRINT("TaskName TaskPriority TaskNumber");
for (x = 0; x < arraySize; x++)
{
PRINT("%-16s%-16d%-2d",
statusArray[x].pcTaskName,
statusArray[x].uxCurrentPriority,
statusArray[x].xTaskNumber);
}
}
vPortFree(statusArray);
PRINT("----------- uxTaskGetSystemState() end -----------\n"); PRINT("----------- vTaskGetInfo() ----------------");
TaskHandle_t taskHandle;
TaskStatus_t taskStatus;
taskHandle = xTaskGetHandle("print task");
vTaskGetInfo(taskHandle, &taskStatus, pdTRUE, eInvalid);
PRINT(" task name: %s", taskStatus.pcTaskName);
PRINT(" task number: %d", taskStatus.xTaskNumber);
PRINT(" task state: %d", taskStatus.eCurrentState);
PRINT(" task current priority: %d", taskStatus.uxCurrentPriority);
PRINT(" task base priority: %d", taskStatus.uxBasePriority);
PRINT("task stack base address: 0x%x", taskStatus.pxStackBase);
PRINT(" task high water mark: %d", taskStatus.usStackHighWaterMark);
PRINT(" task run time counter: %d",taskStatus.ulRunTimeCounter);
PRINT("----------- vTaskGetInfo() end ------------\n"); PRINT("----------- eTaskGetState() ----------------");
eTaskState taskState;
char *state_str[] = {"running", "ready", "blocked", "suspended", "deleted", "invalid"};
taskHandle = xTaskGetHandle("query task");
taskState = eTaskGetState(taskHandle);
PRINT("task state:%s", state_str[taskState]);
PRINT("----------- eTaskGetState() end ------------\n"); PRINT("----------- vTaskList() ----------------");
PRINT("Name State Priority Stack Num");
PRINT("******************************************");
vTaskList(InfoBuffer);
PRINT("%s", InfoBuffer);
PRINT("----------- vTaskList() end ------------\n"); for (;;)
{
static unsigned int cnt = 0;
PRINT(" query task cnt %u...", cnt);
cnt++;
vTaskDelay(1000);
}
} void creat_task(void)
{
if (xTaskCreate(print_task_code, "print task",
Print_Task_STACK_SIZE, NULL, Print_Task_Priority,
&Print_xhandle) != pdPASS)
{
PRINT("creat task failed!\n");
} if (xTaskCreate(query_task_code, "query task",
Query_Task_STACK_SIZE, NULL, Query_Task_Priority,
&Query_xhandle) != pdPASS)
{
PRINT("creat task failed!\n");
}
vTaskStartScheduler();
}

编译、运行,结果如下:

$ ./build/freertos-simulator
----------- uxTaskGetSystemState() ---------------
TaskName TaskPriority TaskNumber
query task 2 2
print task 1 1
IDLE 0 3
Tmr Svc 30 4
----------- uxTaskGetSystemState() end ----------- ----------- vTaskGetInfo() ----------------
task name: print task
task number: 1
task state: 1
task current priority: 1
task base priority: 1
task stack base address: 0x868010
task high water mark: 0
task run time counter: 0
----------- vTaskGetInfo() end ------------ ----------- eTaskGetState() ----------------
task state:running
----------- eTaskGetState() end ------------ ----------- vTaskList() ----------------
Name State Priority Stack Num
******************************************
query task X 2 15 2
print task R 1 0 1
IDLE R 0 65 3
Tmr Svc B 30 135 4 ----------- vTaskList() end ------------ query task cnt 0...
print task cnt 0...
query task cnt 1...
print task cnt 1...

可以得到,“print task”任务处于就绪态,任务优先级为1,栈空间已经用完了。任务编号为1。“query task”处于运行态,任务优先级为2,栈空间剩余15,任务编号为2。

FreeRTOS-03-其它任务相关函数的更多相关文章

  1. 【FreeRTOS学习03】小白都能懂的Task Management 任务管理基本概念介绍

    在FreeRTOS中,线程的术语又可以被称之为任务,或许这样更加合适,本文将介绍任务的创建/删除,任务参数的使用,以及任务优先级: 1 软实时和硬实时 硬实时系统的任务运行正确性与响应时限是紧密相关的 ...

  2. Linux中表示“时间”的结构体和相关函数

    转载于:http://blog.chinaunix.net/uid-25909722-id-2827364.html      Linux中表示“时间”的结构体和相关函数 2011-09-13 17: ...

  3. FreeRTOS——错误排查

    1. printf-stdarg.c 在调用标准库函数时,栈空间的用量可能急剧上升,特别是IO与字符串处理函数,比如 sprintf(). 在FreeRTOS下载包中有一个名为printf-stdar ...

  4. emWin洗衣机简易操作界面,含uCOS-III和FreeRTOS两个版本

    第3期:洗衣机简易操作界面 配套例子:V6-904_STemWin提高篇实验_洗衣机简易操作界面(uCOS-III)V6-905_STemWin提高篇实验_洗衣机简易操作界面(FreeRTOS) 例程 ...

  5. 1、FreeRTOS移植

    1.FreeRTOS目录结构 FreeRTOS FreeRTOS简略目录如下: ├─FreeRTOS │ ├─Demo // 各种开发工具的完整Demo,开发者可以方便的以此搭建出自己的项目,甚至直接 ...

  6. 在Amazon FreeRTOS V10中使用运行时统计信息

    在MCU on Eclipse网站上看到Erich Styger在8月2日发的博文,一篇关于在Amazon FreeRTOS V10中使用运行时统计信息的文章,本人觉得很有启发,特将其翻译过来以备参考 ...

  7. freeRTOS中文实用教程6--错误排查

    1.前言 本章主要是为刚接触FreeRTOS 的用户指出那些新手通常容易遇到的问题.这里把最主要的篇幅放在栈溢出以及栈溢出侦测上 2.printf-stdarg.c 当调用标准C 库函数时,栈空间使用 ...

  8. FreeRTOS 系统时钟节拍和时间管理

    以下转载自安富莱电子: http://forum.armfly.com/forum.php FreeRTOS 的时钟节拍任何操作系统都需要提供一个时钟节拍,以供系统处理诸如延时. 超时等与时间相关的事 ...

  9. FreeRTOS+FreeModbus+神舟IV号

    下面的这个例子是FreeModbus和FreeRTOS在神舟IV号上的应用,仅当做学习用途. 这个demo完成的功能也比较简单,创建了两个任务,一个任务用于控制板子上的LED1,使它每1秒钟闪烁一次. ...

  10. stm32f10x基于freeRTOS的低功耗实现

    0. 写在前面 没有太多时间更新,可能偶尔有时间就更新一些. 因为突然有项目用到了stm32f10x系列并且是电池驱动的,所以需要对功耗进行优化,其他CM3核心系列应该也同样适用. 1. 背景 Stm ...

随机推荐

  1. C# 扫描并读取图片中的文字

    本文介绍如何通过C# 程序来扫描并读取图片中的文字,这里以创建一个.Net Core程序为例.下面是具体步骤,供参考. 程序测试环境: Visual Studio版本要求不低于2017 图片扫描工具: ...

  2. 想自己写框架?不了解Java注解机制可不行

    无论是在JDK还是框架中,注解都是很重要的一部分,我们使用过很多注解,但是你有真正去了解过他的实现原理么?你有去自己写过注解么? 概念 注解(Annotation),也叫元数据.一种代码级别的说明.它 ...

  3. 5.23考试总结(NOIP模拟2)

    5.23考试总结(NOIP模拟2) 洛谷题单 看第一题第一眼,不好打呀;看第一题样例又一眼,诶,我直接一手小阶乘走人 然后就急忙去干T2T3了 后来考完一看,只有\(T1\)骗到了\(15pts\)[ ...

  4. 『心善渊』Selenium3.0基础 — 4、Selenium基础元素定位详解

    目录 1.什么是元素定位 2.Selenium元素定位常用API (1)By_id 定位 (2)by_name 定位 (3)by_class_name 定位 (4)by_tag_name 定位 (5) ...

  5. 你的电脑适合升级 Win11 吗?「GitHub 热点速览 v.21.26」

    作者:HelloGitHub-小鱼干 WhyNotWin11 是个有意思的项目,本以为是从 360 度"抨击" Windows 11 的不好用之处,但它是一个实实在在地从硬件角度告 ...

  6. Bert模型实现垃圾邮件分类

    近日,对近些年在NLP领域很火的BERT模型进行了学习,并进行实践.今天在这里做一下笔记. 本篇博客包含下列内容: BERT模型简介 概览 BERT模型结构 BERT项目学习及代码走读 项目基本特性介 ...

  7. Linux基本命令精讲

    一.Shell Linux系统中运行的一种特殊程序 在用户和内核之间充当"翻译官 用户登录 Linux系统时,自动加载一个 Shell程序 Bash是 LinuxShell系统中默认使用的程 ...

  8. Pun(PhotonUnityNetwork)

    介绍 Photon Unity Networking(首字母缩写 PUN)是一个 Unity 多人游戏插件包.它提供了身份验证选项.匹配,以及快速.可靠的通过我们的 Photon 后端实现的游戏内通信 ...

  9. 0、springboot

    在线新建springboot项目 https://start.spring.io/ 参考地址 https://github.com/battcn/spring-boot2-learning 博客 ht ...

  10. linux 中获取进程和kill进程的几种方法

    ps: ps命令是最基本同时也是非常强大的进程查看命令,使用该命令可以确定有哪些进程正在运行和运行的状态.进程是否结束.进程有没有僵尸.哪些进程占用了过多的资源等等. 注意:ps是显示瞬间进程的状态, ...