久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2254|回復: 12
收起左側

一個freertos全局變量問題

[復制鏈接]
ID:404263 發表于 2023-8-1 14:22 | 顯示全部樓層 |閱讀模式
在freertos中,如果有一個變量會受到多個不同優先級的task讀取或者寫入,是否是需要每次讀取或者寫入都加一個遞歸互斥鎖,原來想的話只是修改時候加一個互斥鎖就行了,但是想了想好像讀取也加鎖才對,想了解一下這種實時系統全局變量是如何處理的
回復

使用道具 舉報

ID:883242 發表于 2023-8-1 14:59 | 顯示全部樓層
這就是個典型的原子操作問題,STM32要64位整形運算,沒有FPU的單精度float運算,雙精度float運算,才不是原子操作,需要加鎖。
回復

使用道具 舉報

ID:123289 發表于 2023-8-1 15:12 | 顯示全部樓層
全局變量的目的,就是讓大家都可以引用、修改。
否則,就需要變通一下:
如:將一個變量,切成兩個A、B,部分程序用A,另一部分用B。
回復

使用道具 舉報

ID:404263 發表于 2023-8-1 15:12 | 顯示全部樓層
Hephaestus 發表于 2023-8-1 14:59
這就是個典型的原子操作問題,STM32要64位整形運算,沒有FPU的單精度float運算,雙精度float運算,才不是原 ...

大佬麻煩看看我下面那種使用情景該如何處理,因為看教程都是紙面內容,沒有實際的應用場景不太懂
回復

使用道具 舉報

ID:404263 發表于 2023-8-1 15:19 | 顯示全部樓層
yzwzfyz 發表于 2023-8-1 15:12
全局變量的目的,就是讓大家都可以引用、修改。
否則,就需要變通一下:
如:將一個變量,切成兩個A、B, ...

你這個方式也可以解決我那個需求學習了
回復

使用道具 舉報

ID:883242 發表于 2023-8-1 15:24 | 顯示全部樓層
cokesu 發表于 2023-8-1 15:12
大佬麻煩看看我下面那種使用情景該如何處理,因為看教程都是紙面內容,沒有實際的應用場景不太懂

你下面沒有了,我就說說原理吧。

比如8位單片機,int類型16位,有個unsigned int i,那么
i++;
就會被拆分成
low(i)++; // 進位carry位變化
high(i)=high(i)+carry;
兩步。
如果i=0xff而且在這兩步之間被高優先級任務打斷,那么i=0
高優先級任務讀i,不管是0xff或者0x100都應該正確響應,如果不正確那是你軟件寫的不對。但!是!現在i是0,這是誰也無法意料的事情,高優先級任務就會發生異常。
那就要在i++之前加互斥鎖,處理完畢解鎖。如果操作之間切換到高優先級任務,會認為i的值不可用,那就等下次再用。
回復

使用道具 舉報

ID:883242 發表于 2023-8-1 15:27 | 顯示全部樓層
cokesu 發表于 2023-8-1 15:19
你這個方式也可以解決我那個需求學習了

他的說法不行!因為把一個變量變成A、B兩變量,必須要交換這兩個變量的值,而交換操作也不是原子的!!!
回復

使用道具 舉報

ID:404263 發表于 2023-8-1 15:46 | 顯示全部樓層
Hephaestus 發表于 2023-8-1 15:27
他的說法不行!因為把一個變量變成A、B兩變量,必須要交換這兩個變量的值,而交換操作也不是原子的!!!

void ErrorCtrl_task(void *pvParameters)
{
    while(1)
    {
                if(ADC <= 500)
                {
                        if(SystemMode == SF_WORK)
                        {
                                SystemMode = SF_ERROR;
                        }
                }
        vTaskDelay( pdMS_TO_TICKS(5));
    }
}

void ButtonCtrl_task(void *pvParameters)
{
    while(1)
    {
                switch(SystemMode)
                {
                        case SF_CLOSE:
                                if(按鍵按下)
                                {
                                        SystemMode = SF_WORK;
                                }
                        break;
                       
                        case SF_WORK:
                                if(按鍵按下)
                                {
                                        SystemMode = SF_CLOSE;
                                }
                        break;
                       
                        case SF_ERROR:
                                if(按鍵按下)
                                {
                                        SystemMode = SF_CLOSE;
                                }
                        break;
                }
        vTaskDelay( pdMS_TO_TICKS(5));
    }
}
比如說這樣的一個應用,因為我是裸機開發的以前都是這樣寫,裸機開發的話程序都是一個固定的循序跑下來,所以我不需要考慮SystemMode這個變量的問題,但是RTOS的話因為有優先級的一個調度,所以存在一種情況,比如當前SystemMode = SF_WORK的情況,然后有按鍵按下,調度器執行完判斷if(按鍵按下)后就開始切換到ErrorCtrl這個任務,這時候ADC也符合<=500的情況,那么SystemMode 會被賦值為SF_ERROR,當執行完這個ErrorCtrl任務后返回ButtonCtrl這個任務會把SystemMode 這個變量賦值為SF_CLOSE,這個不符合我的設計要求了,因為當運行完ErrorCtrl這個任務后如果是裸機開發就已經處于異常模式了不能響應按鍵,當然這是一種很極端的情況,所以我想知道這個應該要如何處理,是像這樣加一個遞歸鎖嗎?
void ErrorCtrl_task(void *pvParameters)
{
    while(1)
    {
                if(ADC <= 500)
                {
                        xSemaphoreTakeRecursive(TaskSemaphoreHandle,portMAX_DELAY);
                        if(SystemMode == SF_WORK)
                        {
                                SystemMode = SF_ERROR;
                        }
                        xSemaphoreGiveRecursive(TaskSemaphoreHandle);
                       
                }
        vTaskDelay( pdMS_TO_TICKS(5));
    }
}

void ButtonCtrl_task(void *pvParameters)
{
    while(1)
    {
                xSemaphoreTakeRecursive(TaskSemaphoreHandle,portMAX_DELAY);
                switch(SystemMode)
                {
                        case SF_CLOSE:
                                if(按鍵按下)
                                {
                                        SystemMode = SF_WORK;
                                }
                        break;
                       
                        case SF_WORK:
                                if(按鍵按下)
                                {
                                        SystemMode = SF_CLOSE;
                                }
                        break;
                       
                        case SF_ERROR:
                                if(按鍵按下)
                                {
                                        SystemMode = SF_CLOSE;
                                }
                        break;
                }
                xSemaphoreGiveRecursive(TaskSemaphoreHandle);
        vTaskDelay( pdMS_TO_TICKS(5));
    }
}
回復

使用道具 舉報

ID:404263 發表于 2023-8-1 19:28 | 顯示全部樓層
Hephaestus 發表于 2023-8-1 15:27
他的說法不行!因為把一個變量變成A、B兩變量,必須要交換這兩個變量的值,而交換操作也不是原子的!!!

終于發出來了,大佬幫忙看看下面的那個例子,我裸機開發一般習慣就是下面那種寫法,異常控制為一個函數,按鍵操作位另外一個函數,這里就涉及變量的讀和寫,現在不知道如何處理
回復

使用道具 舉報

ID:883242 發表于 2023-8-1 22:31 | 顯示全部樓層
當執行完這個ErrorCtrl任務后返回ButtonCtrl這個任務會把SystemMode 這個變量賦值為SF_CLOSE

你這句很讓我無法理解,你顯然只用到了vTaskDly來切換任務,那么ButtonCtrl這個任務執行時間為什么會那么長,長到時鐘節拍都容納不下了???
回復

使用道具 舉報

ID:404263 發表于 2023-8-2 08:41 | 顯示全部樓層
Hephaestus 發表于 2023-8-1 22:31
當執行完這個ErrorCtrl任務后返回ButtonCtrl這個任務會把SystemMode 這個變量賦值為SF_CLOSE

你這句很讓 ...

不我的意思是存在一種極端情況,那個delay隨便寫而已只是說會存在一個阻塞的情況,比如我程序正在執行ButtonCtrl這個任務,且這時候SystemMode等于SF_WORK,且程序運行完if(按鍵按下)這個判斷,然后給更高優先級的任務ErrorCtrl給中斷了,程序會跑完ErrorCtrl這個任務后再返回ButtonCtrl這個任務里向下執行if語句里面的內容,這樣就有一個問題我在ErrorCtrl里已經把SystemMode 賦值為SF_ERROR了,如果執行完這個ErrorCtrl任務后返回ButtonCtrl這個任務,會把SystemMode的值重新賦值為SF_CLOSE,這不是我需要的,我想知道的是這種情況該如何處理,像我上文最后那種加鎖方法嗎,習慣了裸機開發,跑系統的時候腦子還轉不過來
回復

使用道具 舉報

ID:404263 發表于 2023-8-2 10:45 | 顯示全部樓層
Hephaestus 發表于 2023-8-1 22:31
當執行完這個ErrorCtrl任務后返回ButtonCtrl這個任務會把SystemMode 這個變量賦值為SF_CLOSE

你這句很讓 ...

大佬或者是不是我的編程思路有問題,因為我是做小家電開發的,裸機開發的話一個流程下來都是線性的,大佬能不能說一下實時系統的編程思路,比如我小家電開發有數碼管的一個顯示,負載輸出IO的控制,還有按鍵的控制,這3方面在實時系統該如何編寫,如果用裸機開發的一個思維我感覺沒辦法很好的移植到系統里
回復

使用道具 舉報

ID:883242 發表于 2023-8-2 14:45 | 顯示全部樓層
cokesu 發表于 2023-8-2 10:45
大佬或者是不是我的編程思路有問題,因為我是做小家電開發的,裸機開發的話一個流程下來都是線性的,大佬 ...

小家電玩兒什么RTOS啊?連c都不能用,只能用匯編,一個字節一個字節的扣。量太大了,單片機省一分錢都能讓整個項目省出幾十萬、
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久久久久久国产 | 黄色在线观看国产 | 人成精品 | 国产精品a久久久久 | 久久中文免费视频 | 亚洲精品免费在线观看 | 国产一级特黄真人毛片 | 国产精品二区三区 | 国产精品a久久久久 | 国产成人精品一区二 | 日本黄色一级视频 | 91麻豆精品国产91久久久久久 | 日本亚洲精品成人欧美一区 | 欧美特级黄色 | 日本涩涩网 | 午夜激情免费 | www.色综合| 中文字幕伊人 | 中文字幕乱码一区二区三区 | 91av小视频 | 免费亚洲一区二区 | 成人欧美一区二区三区视频xxx | аⅴ资源新版在线天堂 | 欧美一区视频 | 国产一区2区| 毛片一区二区三区 | 欧美日韩亚洲视频 | 福利影院在线看 | 久久精品中文 | 欧美一区免费 | 91 久久 | 一区二区三区中文字幕 | 日韩在线综合 | 国产亚洲一区二区在线观看 | 日韩中文字幕免费在线 | 国产精品视频999 | 婷婷免费视频 | 亚洲va欧美va天堂v国产综合 | 羞羞视频免费观 | 国产精品爱久久久久久久 | 天天色综网 |