线程本地存储指针允许开发者存储值到任务的控制块(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 );
当前内容版权归 tangguocheng 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 tangguocheng .