摘要:学过用过FreeRTOS的人很多?在创建任务时候我们都要定义一个任务句柄,这个任务句柄有啥含义?书上的解释是任务创建成功以后会返回此任务的任务句柄,这个句柄就是任务的堆栈。此参数就用来保存这个任务句柄。其他API函数可能会使用到这个句柄。

那么任务句柄是到底是怎么一回事,它保存的是任务控制块的首地址。那么它又是如何来保存任务的首地址呢?这就是我们今天要讨论的话题。

1、创建一个任务

动态创建一个任务

#define TASK1_TASK_PRIO      1               //任务优先级
#define TASK1_STK_SIZE      128         //任务栈大小
TaskHandle_t Task1Task_Handler;     //任务句柄
//动态创建一个任务1
xTaskCreate((TaskFunction_t )task1_task,            //任务函数  (const char*    )"task1_task",          //任务名称  (uint16_t       )TASK1_STK_SIZE,        //任务堆栈大小(void*          )NULL,                  //传递给任务函数的参数   (UBaseType_t    )TASK1_TASK_PRIO,       //任务优先级(TaskHandle_t*  )&Task1Task_Handler);   //任务句柄   //task1任务函数
void task1_task(void *pvParameters)
{for(;;){       vTaskDelay( 2000 );}
}

参数:

  • pxTaskCode:任务函数。
  • pcName:任务名字,一般用于追踪和调试,任务名字长度不能超过。configMAX_TASK_NAME_LEN,在FreeRTOSConfig.h文件中宏定义为16。
  • usStackDepth:任务堆栈大小,实际申请到的堆栈是usStackDepth的4倍。其中空闲任务的任务堆栈大小为configMINIMAL_STACK_SIZE,在FreeRTOSConfig.h文件中宏定义为130(字)。
  • pvParameters:传递给任务函数的参数。
  • uxPriority:任务优先级,范围0—configMAX_PRIORITIES-1,在FreeRTOSConfig.h文件中configMAX_PRIORITIES宏定义为32。
  • pxCreatedTask:任务句柄,任务创建成功以后会返回此任务的任务句柄,这个句柄其实就是任务的任务堆栈。此参数就用来保存这个任务句柄。其他API函数可能会使用到这个句柄。

返回值:

  • pdPASS:任务创建成功。pdPASS宏定义为1
  • errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY:任务创建失败,因为堆内存不足!

在创建一个任务时一般都会在程序开头都有这三个宏定义
要指定任务的优先级、任务的栈大小,以及任务的句柄。

优先级很好理解,它决定了多个任务之间执行任务的先后顺序,任务的栈大小也很理解,在创建任务时,任务的局部变量以及任务切换时的数据都保存在栈里面。那么任务句柄是怎么一回事,它保存的是任务控制块的首地址。那么它又是如何来保存任务的首地址呢?这就是我们今天要讨论的话题。

创建任务是时传入的是一个指针?

是一个指针吗?

不是,是一个指针的指针

为什么要传入指针的指针?

什么是指针的指针?

这些问题都需要搞明白你才能解决这个问题?

2、二级指针

正好前两天在公众号看到了这样一篇文章,里面有一道C语言的题可以引用来解释,我们一起来看一下

上面这个代码有好几处错误,它的目的很简单,就是想把字符串hello world拷贝给str,但是它能拷贝成功吗?

很显然是不可以的。

为了使大家看的更清楚,代码简单修改一下

#include <stdio.h>
#include <stdlib.h>
#include <string.h>void getmemory(char *p)
{p = (char *) malloc(100);strcpy(p,"www.zhiguoxin.cn");printf("*p:%s  &(*p):0x%x\r\n",p,&p);
}
int main()
{char *str="www.baidu.cn";getmemory(str);printf("str:%s  &str:0x%x\r\n",str,&str);free(str);return 0;
}

按照我们一般人的的想法,结果应该是:

p  :www.zhiguoxin.cn &p  :xxxxxxx
str:www.zhiguoxin.cn &str:xxxxxxx

但是实际上结果是多少?

完全没有变化,为了彻底解决这个问题,画了一个图,希望大家能够看的更加清楚一点。

从这里可以看出来,在分配内存后,strp就分道扬镳了,而str也还是指向www.baidu.cn

如何修改呢?正确的是啥样的?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void getmemory(char **p)
{*p = (char *) malloc(100);strcpy(*p,"hello world");
}
int main( )
{char *str = NULL;getmemory(&str);printf("%s\n",str);free(str);return 0;
}

编译运行,发现没问题。

达到了我们想要的目的,字符串也得到了正常的拷贝。

如何解释?

函数中参数都是传值,传指针本质上也是传值,只不过它的值是指针类型罢了。如果想要改变入参内容,则需要传该入参的地址,通过解引用修改其指向的内容

这里的str的值就是*p的值,是多少?它们都是一个指针,就是保存的是一个地址,地址是多少?地址就是使用动态分配内存malloc函数分配的100字节的首地址。然后又使用strcpy()函数将hello world拷贝到*p里面。

这里面就涉及到了二级指针,首先str毫无疑问是一个指针变量对吧?那么&str是啥?理所当然就是一个指针的指针吧,就是地址的地址。

所以,我如果在某个地放申请了一块内存,如果想得到这块内存的首地址,而此时我们又定义了一个指针变量,想让这个指针来保存我们申请内存你的首地址,就必须要传入这个指针的地址,即指针的指针(二级指针)而不是传入这个指针。

至于原因上面的例子已经非常清楚的讲解了原因。

下面接着回到我们最开始的创建函数的任务句柄。在开始之前我们再把上面的函数封装一下。

没啥大不了的,就是就是给char*起了一个别名而已,让下面的代码看起来更加顺畅一写。


这样对比一下是不是很清楚了呢?这样一来我们创建任务时候这个任务句柄就保存的是我们TCB控制块这个结构体的首地址了,知道了一个任务的TCB控制块首地址的话,那么这个任务的所有信息我是不是都知道了。是的,就是这么奇妙。通过指针的指针,二级指针来转换一下。

好了,今天的内容就分享到这里!

RTOS中的任务句柄到底是什么意思?相关推荐

  1. 深入了解Windows句柄到底是什么

    总是有新入门的Windows程序员问我Windows的句柄到底是什么,我说你把它看做一种类似指针的标识就行了,但是显然这一答案不能让他们满意,然后我说去问问度娘吧,他们说不行网上的说法太多还难以理解. ...

  2. c语言socket句柄函数传递,通过源码解析 Node.js 中进程间通信中的 socket 句柄传递...

    在 Node.js 中,当我们使用 child_process 模块创建子进程后,会返回一个 ChildProcess 类的实例,通过调用 ChildProcess#send(message[, se ...

  3. php中的eq的含义,jquery,_jQuery中的eq(0)到底是什么意思??详情请看下面代码!,jquery - phpStudy...

    jQuery中的eq(0)到底是什么意思??详情请看下面代码! 手风琴效果 *{padding:0; margin:0;} .box{margin:50px auto; width:300px; he ...

  4. php中include和require,在PHP中include和require到底有什么区别呢?

    在PHP中include和require到底有什么区别呢?看这里的例子就知道了 include.php3的运行结果是: 这是inc1.inc文件中的一个变量的值! 这是inc2.inc文件中的一个变量 ...

  5. Java的并发编程中的多线程问题到底是怎么回事儿?

    转载自   Java的并发编程中的多线程问题到底是怎么回事儿? 在我之前的一篇<再有人问你Java内存模型是什么,就把这篇文章发给他.>文章中,介绍了Java内存模型,通过这篇文章,大家应 ...

  6. 物联网中的无线通信模块到底是什么

    物联网市场的爆发式增长速度,离不开无线通信模块产品的强有力的拉动,无线通信模块也是物联网的核心,但是很多人只知道物联网却对于组成物联网的无线通信模块知之甚少,所以下面就让我们一起来了解一下,物联网中的 ...

  7. 程序员约架事件中,薛非到底是因为不会用Github还是不会写Tokenizer而没有应战?...

    见:程序员约架事件中,薛非到底是因为不会用Github还是不会写Tokenizer而没有应战?

  8. [C# VSTO Word]word中段落回车符到底是什么?来看看它的真面目,是否和你想象的一样?

    [C# VSTO Word]word中段落回车符到底是什么?来看看它的真面目,是否和你想象的一样? 目录 [C# VSTO Word]word中段落回车符到底是什么?来看看它的真面目,是否和你想象的一 ...

  9. html中的input框中的value值到底是什么

    input框中的value值到底是什么,value 属性为 input 元素设定值. 对于不同的输入类型,value 属性的用法也不同: type="button", " ...

  10. java中的返回值到底有什么用?

    今天看到一个有意思的问题:java中的返回值到底有什么用? 看到了一个高赞回答如下: 你是公司的老总,然后你跟你秘书说,我想要两张的电影票.然后,你秘书去排队买票,最后把两张电影票给你,这两张电影票就 ...

最新文章

  1. CSS单位分析及CSS颜色表示法、颜色表(调色板)
  2. 使用jquery文件上传控件Uploadify来异步上传图片
  3. java 参数 string_关于Java中String类型的参数传递问题
  4. 毕业了,在Python中使用 OpenCV 和K-Means 聚类对毕业照进行图像分割
  5. 接口继承中一个常见问题的思考
  6. (非)对称加密算法在https中的应用(加密过程以及CA颁发、验证)
  7. 计算机科学讲座的策划书,计算机科学与工学院女生新生讲座策划书.doc
  8. MySQL错误:The user specified as a definer (XXX@XXX) does not exist (1449错误)最简解决方案...
  9. 安装最新LAMP环境(CentOS7+PHP7.1.5+Mysql5.7)
  10. Hadoop学习整理
  11. 华为浏览器如何进入阅读模式_华为浏览器有阅读模式吗
  12. 品胜WPR003N、WMB001N刷Openwrt
  13. Reflection的getCallerClass使用
  14. Maven配置错误: The JAVA_HOME environment variable is not defined correctly
  15. 显卡属于计算机主机还是外设,计算机硬件组成及作用有哪些
  16. 13.5 Prepared Statements
  17. Web前端面试常用技巧
  18. IDEA 设置单行注释格式化时不换行
  19. 关于Descriptors cannot not be created directly报错
  20. Android中DialogFragment自动弹出输入法

热门文章

  1. Linux 常用软件
  2. JAVA计算机毕设题目大全
  3. 盐城机电高等职业技术学校计算机专业,盐城机电高等职业技术学校
  4. UA MATH524 复变函数 用保形映射解Laplace方程的边值问题
  5. VLAN的三种模式实验
  6. 单因素试验固定效应模型方差分析
  7. matlab信源编码,常见无失真信源编码算法及Matlab实现比较(27页)-原创力文档
  8. 上海自考计算机应用基础实践,2001年4月份全国高教自考计算机应用基础试题及答案...
  9. 服务器日志默认存放位置,系统日志和IIS日志存放路径
  10. 华为面试题:一头牛重 800 公斤,一座桥承重 700 公斤,请问牛怎么过桥?