<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試時(shí)工程師說(shuō)精通FreeRTOS,我問(wèn)他,任務(wù)句柄是一個(gè)指針嗎?

          共 6324字,需瀏覽 13分鐘

           ·

          2024-07-14 12:15

          摘要學(xué)過(guò)用過(guò)FreeRTOS的人都知道,在創(chuàng)建任務(wù)時(shí)候我們都要定義一個(gè)任務(wù)句柄,這個(gè)任務(wù)句柄有啥含義?書(shū)上的解釋是任務(wù)創(chuàng)建成功以后會(huì)返回此任務(wù)的任務(wù)句柄,這個(gè)句柄就是任務(wù)的堆棧此參數(shù)就用來(lái)保存這個(gè)任務(wù)句柄。其他API函數(shù)可能會(huì)使用到這個(gè)句柄。

          那么任務(wù)句柄是到底是怎么一回事,它保存的是任務(wù)控制塊的首地址。那么它又是如何來(lái)保存任務(wù)的首地址呢?這就是我們今天要討論的話題。我盡量寫(xiě)得通俗易懂,讓大家都能輕松理解

          1、創(chuàng)建一個(gè)任務(wù)

          動(dòng)態(tài)創(chuàng)建一個(gè)任務(wù)

          #define TASK1_TASK_PRIO  1    //任務(wù)優(yōu)先級(jí)
          #define TASK1_STK_SIZE   128    //任務(wù)棧大小 
          TaskHandle_t Task1Task_Handler;  //任務(wù)句柄
          //動(dòng)態(tài)創(chuàng)建一個(gè)任務(wù)1
          xTaskCreate((TaskFunction_t )task1_task,            //任務(wù)函數(shù)  
                      (const char*    )"task1_task",          //任務(wù)名稱  
                      (uint16_t       )TASK1_STK_SIZE,        //任務(wù)堆棧大小
                      (void*          )NULL,                  //傳遞給任務(wù)函數(shù)的參數(shù)   
                      (UBaseType_t    )TASK1_TASK_PRIO,       //任務(wù)優(yōu)先級(jí)
                      (TaskHandle_t*  )&Task1Task_Handler);   //任務(wù)句柄   

          //task1任務(wù)函數(shù)
          void task1_task(void *pvParameters)
          {
           for(;;)
           {  
                vTaskDelay( 2000 );
           }
          }

          參數(shù):

          • pxTaskCode:任務(wù)函數(shù)。
          • pcName:任務(wù)名字,一般用于追蹤和調(diào)試,任務(wù)名字長(zhǎng)度不能超過(guò)。configMAX_TASK_NAME_LEN,在FreeRTOSConfig.h文件中宏定義為16。
          • usStackDepth:任務(wù)堆棧大小,實(shí)際申請(qǐng)到的堆棧是usStackDepth的4倍。其中空閑任務(wù)的任務(wù)堆棧大小為configMINIMAL_STACK_SIZE,在FreeRTOSConfig.h文件中宏定義為130(字)。
          • pvParameters:傳遞給任務(wù)函數(shù)的參數(shù)。
          • uxPriority:任務(wù)優(yōu)先級(jí),范圍0—configMAX_PRIORITIES-1,在FreeRTOSConfig.h文件中configMAX_PRIORITIES宏定義為32。
          • pxCreatedTask:任務(wù)句柄,任務(wù)創(chuàng)建成功以后會(huì)返回此任務(wù)的任務(wù)句柄,這個(gè)句柄其實(shí)就是任務(wù)的任務(wù)堆棧。此參數(shù)就用來(lái)保存這個(gè)任務(wù)句柄。其他API函數(shù)可能會(huì)使用到這個(gè)句柄。

          返回值:

          • pdPASS:任務(wù)創(chuàng)建成功。pdPASS宏定義為1
          • errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY:任務(wù)創(chuàng)建失敗,因?yàn)?strong style="font-weight: border;color: rgb(68,17,12);">堆內(nèi)存不足!

          在創(chuàng)建一個(gè)任務(wù)時(shí)一般都會(huì)在程序開(kāi)頭都有這三個(gè)宏定義

          要指定任務(wù)的優(yōu)先級(jí)、任務(wù)的棧大小,以及任務(wù)的句柄。

          優(yōu)先級(jí)很好理解,它決定了多個(gè)任務(wù)之間執(zhí)行任務(wù)的先后順序,任務(wù)的棧大小也很理解,在創(chuàng)建任務(wù)時(shí),任務(wù)的局部變量以及任務(wù)切換時(shí)的數(shù)據(jù)都保存在棧里面。那么任務(wù)句柄是怎么一回事,它保存的是任務(wù)控制塊的首地址。那么它又是如何來(lái)保存任務(wù)的首地址呢?這就是我們今天要討論的話題

          創(chuàng)建任務(wù)是時(shí)傳入的是一個(gè)指針?

          是一個(gè)指針嗎?

          不是,是一個(gè)指針的指針。

          為什么要傳入指針的指針?

          什么是指針的指針?

          這些問(wèn)題都需要搞明白你才能解決這個(gè)問(wèn)題?

          二、二級(jí)指針

          正好前兩天在公眾號(hào)看到了這樣一篇文章,里面有一道C語(yǔ)言的題可以引用來(lái)解釋我們今天的問(wèn)題,我們一起來(lái)看一下

          上面這個(gè)代碼有好幾處錯(cuò)誤,它的目的很簡(jiǎn)單,就是想把字符串hello world拷貝給str,但是它能拷貝成功嗎?

          很顯然是不可以的。

          為了使大家看的更清楚,代碼簡(jiǎn)單修改一下

          #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;
          }

          按照我們一般人的的想法,結(jié)果應(yīng)該是:

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

          但是實(shí)際上結(jié)果是多少?

          完全沒(méi)有變化,為了徹底解決這個(gè)問(wèn)題,畫(huà)了一個(gè)圖,希望大家能夠看的更加清楚一點(diǎn)。

          從這里可以看出來(lái),在分配內(nèi)存后,strp就分道揚(yáng)鑣了,而str也還是指向www.baidu.cn

          如何修改呢?正確的是啥樣的?

          #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;
          }

          編譯運(yùn)行,發(fā)現(xiàn)沒(méi)問(wèn)題。

          達(dá)到了我們想要的目的,字符串也得到了正常的拷貝。

          如何解釋?

          函數(shù)中參數(shù)都是傳值,傳指針本質(zhì)上也是傳值,只不過(guò)它的值是指針類型罷了。如果想要改變?nèi)雲(yún)?nèi)容,則需要傳該入?yún)⒌牡刂罚ㄟ^(guò)解引用修改其指向的內(nèi)容

          這里的str的值就是*p的值,是多少?它們都是一個(gè)指針,就是保存的是一個(gè)地址,地址是多少?地址就是使用動(dòng)態(tài)分配內(nèi)存malloc函數(shù)分配的100字節(jié)的首地址。然后又使用strcpy()函數(shù)將hello world拷貝到*p里面。

          這里面就涉及到了二級(jí)指針,首先str毫無(wú)疑問(wèn)是一個(gè)指針變量對(duì)吧?那么&str是啥?理所當(dāng)然就是一個(gè)指針的指針吧,就是地址的地址。

          所以,我如果在某個(gè)地方申請(qǐng)了一塊內(nèi)存,如果想得到這塊內(nèi)存的首地址,而此時(shí)我們又定義了一個(gè)指針變量,想讓這個(gè)指針來(lái)保存我們申請(qǐng)內(nèi)存你的首地址,就必須要傳入這個(gè)指針的地址,即指針的指針(二級(jí)指針)而不是傳入這個(gè)指針。

          至于原因上面的例子已經(jīng)非常清楚的講解了原因。

          下面接著回到我們最開(kāi)始的創(chuàng)建函數(shù)的任務(wù)句柄。在開(kāi)始之前我們?cè)侔焉厦娴暮瘮?shù)封裝一下。

          #include <stdio.h>
          #include <stdlib.h>
          #include <string.h>

          typedef char* TaskHandle_t;

          void getmemory(TaskHandle_t *p)
          {
             *p = (char *) malloc(100);
             strcpy(*p,"www.zhiguoxin.cn");
             printf("*p:%s  &(*p):0x%x\r\n",*p,&(*p));
          }
          int main()
          {
            TaskHandle_t str;
            getmemory(&str);
            printf("str:%s  &str:0x%x\r\n",str,&str);
            free(str);
            return 0;
          }

          沒(méi)啥大不了的,就是就是給char*起了一個(gè)別名而已,讓下面的代碼看起來(lái)更加順暢一寫(xiě)。

          這樣對(duì)比一下是不是很清楚了呢?這樣一來(lái)我們創(chuàng)建任務(wù)時(shí)候這個(gè)任務(wù)句柄就保存的是我們TCB控制塊這個(gè)結(jié)構(gòu)體的首地址了,知道了一個(gè)任務(wù)的TCB控制塊首地址的話,那么這個(gè)任務(wù)的所有信息我是不是都知道了。是的,就是這么奇妙。通過(guò)指針的指針,二級(jí)指針來(lái)轉(zhuǎn)換一下。

          好了,今天的內(nèi)容就分享到這里!

          ?
          ?點(diǎn)擊查看往期內(nèi)容
          (關(guān)注芯片之家)

          我經(jīng)常用 指針函數(shù) 跟 函數(shù)指針 來(lái)面試應(yīng)屆畢業(yè)生,能回答完美的并不多


          C語(yǔ)言指針難嗎?紙老虎而已,純干貨講解(附代碼)


          C小知識(shí)之結(jié)構(gòu)體和指針

          ?
          ?


          瀏覽 716
          5點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          5點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  大香蕉色婷婷 | 影音先锋婷婷 | 嫩模扣逼视频 | 超碰成人免费 | 超碰中文在线字幕 |