主頁 > 作業系統 > ThreadX——IPC應用之事件標志

ThreadX——IPC應用之事件標志

2020-12-13 06:09:36 作業系統

一、應用簡介

在RTOS的應用開發中,事件標志主要是用來進行任務之間的事件通知,例如有A和B兩個任務,A任務負責接收訊息,B任務負責對訊息回應,當A任務接收到訊息后設定回應標志,B任務監測到回應標志被設定就執行訊息回應,事件標志沒被設定的時候任務是不會占用CPU的,不用像裸機程式那樣不斷輪詢事件的發生,使得CPU的利用率更高,這也是使用RTOS的優勢之一,

二、API說明

下面列出使用事件標志組時常用的幾個函式

1、創建事件標志組

  • 描述:
    • 該函式會創建一個包含32個事件標志的事件組(其實就是一個32bit的變數),組中的32個事件標志都被初始化為零,每個事件標志由一個Bit表示(bit位置1則表明該位代表的事件標志被設定),
  • 引數
    • group_ptr :指向事件標志組控制元件塊的指標
    • name_ptr :指向事件標志組名稱的指標
  • 回傳值
    • TX_SUCCESS (0x00) :成功創建事件組
    • TX_GROUP_ERROR (0x06) :無效的事件組指標,指標為NULL或事件組已創建
    • TX_CALLER_ERROR (0x13):該服務的呼叫者無效
UINT tx_event_flags_create(
    TX_EVENT_FLAGS_GROUP *group_ptr,
    CHAR *name_ptr);

2、洗掉事件標志組

  • 描述
    • 此服務會洗掉指定的事件標志組,所有等待該組事件的掛起執行緒將被恢復,并給出TX_DELETED回傳狀態,
    • 在洗掉事件標志組之前,應用程式必須確保完成(或禁用)此事件標志組的通知回呼,此外,應用程式必須禁止使用已洗掉的事件標志組,
  • 引數
    • group_ptr :指向先前創建的事件標志組的指標
  • 回傳值
    • TX_SUCCESS (0x00):成功洗掉事件標志組
    • TX_GROUP_ERROR (0x06):無效的事件標志組指標
    • TX_CALLER_ERROR (0x13):該服務的呼叫者無效
UINT tx_event_flags_delete(TX_EVENT_FLAGS_GROUP *group_ptr);

3、獲取事件標志

  • 描述
    • 此服務從指定的事件標志組檢索事件標志,每個事件標志組包含32個事件標志,每個標志由一個位表示,此服務可以檢索由輸入引數選擇的各種事件標志組合,
  • 引數
    • group_ptr:指向先前創建的事件標志組的指標
    • requested_flags:表示請求的事件標志
    • get_option:請求事件標志的選項(TX_AND (0x02):指定的事件標志必須全部有效;TX_OR (0x00):指定的事件部分部分有效即可;TX_AND_CLEAR (0x03):指定的事件標志必須都被設定且清除相應的事件標志;TX_OR_CLEAR (0x01):指定的事件標志部分被設定就滿足條件且清除相應的事件標志)
    • actual_flags_ptr:指向放置檢索到的事件標志的指標,請注意,獲得的實際標志可能包含未被請求的標志,
    • wait_option:所選事件標志未被設定時服務的行為(TX_NO_WAIT (0x00000000) :不等待立即回傳;TX_WAIT_FOREVER(0xFFFFFFFF):一直掛起等待直到事件標志被設定;(0x00000001 到 0xFFFFFFFE):等待的心跳節拍數,例如設定心跳是1KHZ那單位就是ms)
  • 回傳值
    • TX_SUCCESS(0x00)成功獲得事件標志,
    • TX_DELETED(0x01)執行緒掛起時,事件標志組已洗掉,
    • TX_NO_EVENTS(0x07)服務無法在指定的等待時間內獲取指定的事件,
    • TX_WAIT_ABORTED(0x1A)被另一個執行緒、計時器或中斷服務打斷,
    • TX_GROUP_ERROR(0x06)無效的事件標志組指標,
    • TX_PTR_ERROR(0x03)實際事件標志的無效指標,
    • TX_WAIT_ERROR(0x04)在非執行緒呼叫中指定了TX_NO_WAIT以外的等待選項,
    • TX_OPTION_ERROR(0x08)指定了無效的獲取選項,
UINT tx_event_flags_get(
    TX_EVENT_FLAGS_GROUP *group_ptr,
    ULONG requested_flags, 
    UINT get_option,
    ULONG *actual_flags_ptr, 
    ULONG wait_option);

4、設定事件標志

  • 描述
    • 此服務根據指定的選項設定或清除事件標志組中的事件標志, 所有請求被設定事件標志的執行緒將從掛起狀態恢復運行態,
  • 引數
    • group_ptr:指向先前創建的事件標志組控制塊的指標
    • flags_to_set:根據選擇的設定選項指定要設定或清除的事件標志
    • set_option:將指定的事件標志與該組的當前事件標志進行“與”或“或”運算(TX_AND(0x02)、TX_OR(0x00));選擇TX_AND將指定的事件標志與該組中的當前事件標志進行“與”運算, 此選項通常用于清除組中的事件標志,選擇TX_OR,則將指定的事件標志與組中的當前事件進行“或”運算,
  • 回傳值
    • TX_SUCCESS(0x00)事件標志成功設定,
    • TX_GROUP_ERROR(0x06)指向事件標志組指標無效,
    • TX_OPTION_ERROR(0x08)指定了無效的設定選項,
UINT tx_event_flags_set(
    TX_EVENT_FLAGS_GROUP *group_ptr,
    ULONG flags_to_set,
    UINT set_option);

三、實體說明

該實體創建一個事件標志組和三個任務,標志組中包含了兩個事件標志,任務1檢測按鍵1的運行,任務2檢測按鍵2的運行,任務3執行對應的按鍵回應,任務之間的通知采用事件標志的方式,

#include "main.h"
#include "usart.h"
#include "gpio.h"
#include "tx_api.h"

#define DEMO_STACK_SIZE         (2 * 1024)
#define DEMO_BYTE_POOL_SIZE     (32 * 1024)
/*事件標志*/
#define TX_EVENT_FLAG_KEY1		(1 << 0)
#define TX_EVENT_FLAG_KEY2		(1 << 1)

TX_THREAD               thread_0;
TX_THREAD               thread_1;
TX_THREAD               thread_2;

TX_BYTE_POOL            byte_pool_0;
UCHAR                   memory_area[DEMO_BYTE_POOL_SIZE];
/*事件標志組*/
TX_EVENT_FLAGS_GROUP 	tx_event_flags;

void    thread_0_entry(ULONG thread_input);
void    thread_1_entry(ULONG thread_input);
void    thread_2_entry(ULONG thread_input);

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART1_UART_Init();
    
  tx_kernel_enter();
  while (1)
  {
  }
}

void tx_application_define(void *first_unused_memory)
{
	CHAR    *pointer = TX_NULL;

	 /* Create a byte memory pool from which to allocate the thread stacks.  */
    tx_byte_pool_create(&byte_pool_0, "byte pool 0", memory_area, DEMO_BYTE_POOL_SIZE);
	
	/* 創建事件標志組 */
	tx_event_flags_create(&tx_event_flags, "my_event_group_name");
	
	/* Allocate the stack for thread 0.  */
    tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
    /* Create the main thread.  */
    tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,  
            pointer, DEMO_STACK_SIZE, 
            1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
	
	/* Allocate the stack for thread 1.  */
    tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
    /* Create threads 1  */
    tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0,  
            pointer, DEMO_STACK_SIZE, 
            2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
					
	/* Allocate the stack for thread 2.  */
    tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
    /* Create threads 1  */
    tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0,  
            pointer, DEMO_STACK_SIZE, 
            3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
}

void    thread_0_entry(ULONG thread_input)
{
	uint8_t key_cnt = 0;
	
    while(1)
    {
		if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) != GPIO_PIN_RESET)
		{
			key_cnt++;
		}
		else
		{
			if (key_cnt > 2)
			{
                /* 按鍵1觸發,設定事件標志 */
				tx_event_flags_set(&tx_event_flags, TX_EVENT_FLAG_KEY1, TX_OR);
			}
			key_cnt = 0;
		}
		
		tx_thread_sleep(20);
    }
}

void    thread_1_entry(ULONG thread_input)
{
	uint8_t key_cnt = 0;
	
    while(1)
    {
		if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) != GPIO_PIN_RESET)
		{
			key_cnt++;
		}
		else
		{
			if (key_cnt > 2)
			{
                /* 按鍵2觸發,設定事件標志 */
				tx_event_flags_set(&tx_event_flags, TX_EVENT_FLAG_KEY2, TX_OR);
			}
			key_cnt = 0;
		}
		
		tx_thread_sleep(20);
    }
}

void    thread_2_entry(ULONG thread_input)
{
	UINT status;
	ULONG actual_events;

	while(1)
	{
        /* 等待事件標志:任意按鍵觸發都有效 */
		status = tx_event_flags_get(&tx_event_flags, TX_EVENT_FLAG_KEY1 | TX_EVENT_FLAG_KEY2, TX_OR_CLEAR, &actual_events, TX_WAIT_FOREVER);
		
		if (TX_SUCCESS == status)
		{
			if (TX_EVENT_FLAG_KEY1 == (actual_events & TX_EVENT_FLAG_KEY1))
			{
				HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
				printf("key1 is pressed, actual_events:0x%x\r\n", (int)actual_events);
			}
			
			if (TX_EVENT_FLAG_KEY2 == (actual_events & TX_EVENT_FLAG_KEY2))
			{
				HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);
				printf("key2 is pressed, actual_events:0x%x\r\n", (int)actual_events);
			}
		}
	} 	
}

效果如下:

轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/233759.html

標籤:其他

上一篇:ThreadX移植——STM32H7+MDK-AC6平臺

下一篇:電腦與Linux開發板搭建NFS檔案系統——網線直連

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • CA和證書

    1、在 CentOS7 中使用 gpg 創建 RSA 非對稱密鑰對 gpg --gen-key #Centos上生成公鑰/密鑰對(存放在家目錄.gnupg/) 2、將 CentOS7 匯出的公鑰,拷貝到 CentOS8 中,在 CentOS8 中使用 CentOS7 的公鑰加密一個檔案 gpg -a ......

    uj5u.com 2020-09-10 00:09:53 more
  • Kubernetes K8S之資源控制器Job和CronJob詳解

    Kubernetes的資源控制器Job和CronJob詳解與示例 ......

    uj5u.com 2020-09-10 00:10:45 more
  • VMware下安裝CentOS

    VMware下安裝CentOS 一、軟硬體準備 1 Centos鏡像準備 1.1 CentOS鏡像下載地址 下載地址 1.2 CentOS鏡像下載程序 點擊下載地址進入如下圖的網站,選擇需要下載的版本,這里選擇的是Centos8,點擊如圖所示。 決定選擇Centos8后,選擇想要的鏡像源進行下載,此 ......

    uj5u.com 2020-09-10 00:12:10 more
  • 如何使用Grep命令查找多個字串

    如何使用Grep 命令查找多個字串 大家好,我是良許! 今天向大家介紹一個非常有用的技巧,那就是使用 grep 命令查找多個字串。 簡單介紹一下,grep 命令可以理解為是一個功能強大的命令列工具,可以用它在一個或多個輸入檔案中搜索與正則運算式相匹配的文本,然后再將每個匹配的文本用標準輸出的格式 ......

    uj5u.com 2020-09-10 00:12:28 more
  • git配置http代理

    git配置http代理 經常遇到克隆 github 慢的問題,這里記錄一下幾種配置 git 代理的方法,解決 clone github 過慢。 目錄 git配置代理 git單獨配置github代理 git配置全域代理 配置終端環境變數 git配置代理 主要使用 git config 命令 git單獨 ......

    uj5u.com 2020-09-10 00:12:33 more
  • Linux npm install 裝包時提示Error EACCES permission denied解

    npm install 裝包時提示Error EACCES permission denied解決辦法 ......

    uj5u.com 2020-09-10 00:12:53 more
  • Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包

    Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包。 18 (flaskApi) [root@67 flaskDemo]# yum -y install nginx 19 已加載插件:fastestmirror, langpacks 20 Loading ......

    uj5u.com 2020-09-10 00:13:13 more
  • Linux查看服務器暴力破解ssh IP

    在公網的服務器上經常遇到別人爆破你服務器的22埠,用來挖礦或者干其他嘿嘿嘿的事情~ 這種情況下正確的做法是: 修改默認ssh的22埠 使用設定密鑰登錄或者白名單ip登錄 建議服務器密碼為復雜密碼 創建普通用戶登錄服務器(root權限過大) 建立堡壘機,實作統一管理服務器 統計爆破IP [root ......

    uj5u.com 2020-09-10 00:13:17 more
  • CentOS 7系統常見快捷鍵操作方式

    Linux系統中一些常見的快捷方式,可有效提高操作效率,在某些時刻也能避免操作失誤帶來的問題。 ......

    uj5u.com 2020-09-10 00:13:31 more
  • CentOS 7作業系統目錄結構介紹

    作業系統存在著大量的資料檔案資訊,相應檔案資訊會存在于系統相應目錄中,為了更好的管理資料資訊,會將系統進行一些目錄規劃,不同目錄存放不同的資源。 ......

    uj5u.com 2020-09-10 00:13:35 more
最新发布
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:43:21 more
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:42:36 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:26:53 more
  • 設定Windows主機的瀏覽器為wls2的默認瀏覽器

    這里以Chrome為例。 1. 準備作業 wsl是可以使用Windows主機上安裝的exe程式,出于安全考慮,默認情況下改功能是無法使用。要使用的話,終端需要以管理員權限啟動。 我這里以Windows Terminal為例,介紹如何默認使用管理員權限打開終端,具體操作如下圖所示: 2. 操作 wsl ......

    uj5u.com 2023-04-19 09:25:49 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:19:04 more
  • Linux學習筆記

    IP地址和主機名 IP地址 ifconfig可以用來查詢本機的IP地址,如果不能使用,可以通過install net-tools安裝。 Centos系統下ens33表示主網卡;inet后表示IP地址;lo表示本地回環網卡; 127.0.0.1表示代指本機;0.0.0.0可以用于代指本機,同時在放行設 ......

    uj5u.com 2023-04-18 06:52:01 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:50 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:01 more
  • 你是不是暴露了?

    作者:袁首京 原創文章,轉載時請保留此宣告,并給出原文連接。 如果您是計算機相關從業人員,那么應該經歷不止一次網路安全專項檢查了,你肯定是收到過資訊系統技術檢測報告,要求你加強風險監測,確保你提供的系統服務堅實可靠了。 沒檢測到問題還好,檢測到問題的話,有些處理起來還是挺麻煩的,尤其是線上正在運行的 ......

    uj5u.com 2023-04-05 16:52:56 more
  • 細節拉滿,80 張圖帶你一步一步推演 slab 記憶體池的設計與實作

    1. 前文回顧 在之前的幾篇記憶體管理系列文章中,筆者帶大家從宏觀角度完整地梳理了一遍 Linux 記憶體分配的整個鏈路,本文的主題依然是記憶體分配,這一次我們會從微觀的角度來探秘一下 Linux 內核中用于零散小記憶體塊分配的記憶體池 —— slab 分配器。 在本小節中,筆者還是按照以往的風格先帶大家簡單 ......

    uj5u.com 2023-04-05 16:44:11 more