当前位置: 首页 > 文档资料 > freeRTOS 使用教程 >

1.4.12 线程本地存储

优质
小牛编辑
135浏览
2023-12-01

线程本地存储指针允许开发者存储值到任务的控制块(control block)中,使这个值对于任务来说是特定且唯一的。

线程本地存储经常被用来存储数据,而单一进程的应用程序通常的做法是使用全局变量。比如,很多库函数包含一个全局的返回值--错误信息,应用根据这个错误信息判读错误类型,同时进行相应处理。在单线程的应用中可以使用全局变量来保存这个错误信息,但是在多任务的系统中,每个任务都必须有一个自己的位置去存储这个错误信息,否则的话,会导致一个任务读取到另外一个任务的错误信息的混乱情况。

freeRTOS提供给开发者一个很灵活的实现线程本地存储的机制---使用线程本地存储指针。

configNUM_THREAD_LOCAL_STORAGE_POINTERS配置任务数组大小(以void *的大小为单位)。vTaskSetThreadLocalStoragePointer()写入数据到线程的本地存储,pvTaskGetThreadLocalStoragePointer()读取线程本地存储的数据。示例如下:

大小小于等于空类型的指针(void *)的大小的变量可以直接存在线程本地存储指针指向的数组。如果sizeof( void * )等于4个字节,那么32-bit的数可以直接存入。

uint32_t ulVariable;

/* 写 32-bit 的数据 0x12345678 到线程本地存储数组的索引1的
位置上,NULL,代表写入当前调用的任务的本地存储*/
vTaskSetThreadLocalStoragePointer( NULL,  /* 任务句柄. */   1,     /* 数组索引 */   ( void * ) 0x12345678 );


ulVariable = ERROR_CODE;
vTaskSetThreadLocalStoragePointer( NULL,  /* 任务句柄 */   0,     /* 数组索引*/   ( void * ) ulVariable );

/* 读取索引5的数据. */
ulVariable = ( uint32_t ) pvTaskGetThreadLocalStoragePointer( NULL, 5 );

上面的例子演示了如何存取一个数值,下面的例子演示了如何存取结构体的指针:

typedef struct
{uint32_t ulValue1;uint32_t ulValue2;
} xExampleStruct;

xExampleStruct *pxStruct;

/* 创建这个任务使用的结构体 */
pxStruct = pvPortMalloc( sizeof( xExampleStruct ) );

/* 设置结构体成员 */
pxStruct->ulValue1 = 0;
pxStruct->ulValue2 = 1;

/* 保存结构体指针到数组的索引0处 */
vTaskSetThreadLocalStoragePointer( NULL,  /* Task handle. */   0,     /* Index into the array. */   ( void * ) pxStruct );

/* 读取保存在线程本地存储的指针 */
pxStruct = ( xExampleStruct * ) pvTaskGetThreadLocalStoragePointer( NULL, 0 );