当前位置: 首页 > news >正文

设计模版网站常州北京网站建设

设计模版网站,常州北京网站建设,.net网站开发书,如何找百度做网站提示#xff1a;文章写完后#xff0c;目录可以自动生成#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、信号量的简介1.信号量与队列的区别#xff1f; 二、二值信号量及其实例1.什么是二值信号量2.二值信号量相关API函数3.二值信号量实例 三、计数型信号量四、… 提示文章写完后目录可以自动生成如何生成可参考右边的帮助文档 文章目录 前言一、信号量的简介1.信号量与队列的区别 二、二值信号量及其实例1.什么是二值信号量2.二值信号量相关API函数3.二值信号量实例 三、计数型信号量四、优先级翻转五、互斥信号量六、信号量这一节中比较重要的知识1.最重要的是保证资源的同步和互斥访问。2.总结的一些知识点 七、事件标志组1.事件标志组概念2.事件标志组与队列、信号量的区别3.API函数4.举一个应用了事件标志组的知识的智能门锁的例程①宏定义事件标志组②任务一触摸屏输入密码若正确则设置事件标志组使得发送开锁指令③任务二刷NFC卡若识别到则设置事件标志组使得发送开锁指令④任务三舵机任务接收各个事件标志位来做出反应 八、任务通知-消息邮箱1.任务通知的概念2.任务通知的优缺点3.相关API函数4.利用任务通知机制的例程(1)模拟获取二值信号量的任务(2)模拟获取计数信号量的任务(3)模拟获取计数信号量的任务 前言 这一节的信息还是非常庞大的同时也是非常重要的。 一、信号量的简介 看这个图来理解的话就是说信号量就是停车位信号量计数值大于0说明有车位1有一个车位3有三个车位等于0说明没有车位了。如果有一个车位被占了那计数值就减一空出来一个车位就加一。 信号量可以比喻成一把钥匙用于控制多个人对同一个资源的访问。每个人在想要使用这个资源之前都必须先去拿这把钥匙。如果钥匙可用那么这个人就可以使用资源如果钥匙不可用那么这个人就必须等待直到有其他人归还钥匙。 举一个实际的例子来说明信号量的概念。假设有一个公共厕所只有一个坑位可供使用。多个人需要使用这个坑位但是只能有一个人在同一时间使用。为了避免多个人同时进入厕所可以使用信号量来控制访问。 二进制信号量的例子假设有三个人分别是A、B、C他们想要使用公共厕所。在公共厕所门口放置一个锁初始状态为锁上。当一个人想要使用厕所时他必须先去看锁是否上锁如果上锁就等待如果没上锁就上锁并进入厕所使用。当他使用完毕后他会将锁解开让其他人可以进入使用。 计数信号量的例子假设有一个饭店只有五个座位可供客人用餐。多个客人来到饭店但是只能有五个客人同时用餐。在饭店门口放置一个计数器初始值为5。当一个客人想要进入饭店用餐时他必须先查看计数器的值如果大于0表示还有座位可用他可以进入用餐并将计数器的值减少1如果计数器的值为0表示没有座位可用他就必须等待直到有其他客人用餐并离开释放座位。 在这些例子中信号量就像是一把钥匙控制着多个人对资源厕所、座位的访问。只有当钥匙可用时才能进入使用资源否则需要等待其他人释放钥匙。这种通过信号量来控制资源访问的机制可以有效避免资源竞争和混乱。 1.信号量与队列的区别 信号量和队列是两种不同的概念它们在实际应用中有着不同的作用和用途。 功能和作用 信号量信号量主要用于实现任务同步和互斥的机制。它用于协调多个任务之间的并发执行控制对共享资源的访问避免竞争条件和数据不一致的问题。 队列队列是一种数据结构用于存储和管理数据。它遵循先进先出FIFO的原则通过队头和队尾的操作来实现数据的入队和出队。 数据结构 信号量信号量本身并不是一个数据结构它可以理解为一个计数器或标志用于控制任务的执行和访问共享资源的权限。 队列队列是一种数据结构可以使用数组或链表来实现。它在内部维护一个元素的集合并提供入队和出队的操作。 应用场景 信号量主要应用于操作系统中用于实现任务的同步和互斥控制对共享资源的访问。 队列队列广泛应用于许多领域如操作系统调度算法、消息传递、网络通信等。它可以用于实现任务队列、消息队列、请求排队等。 二、二值信号量及其实例 1.什么是二值信号量 二值信号量是一种特殊类型的信号量它只有两个可能的取值0和1。它可以用于实现互斥操作即在某一时刻只允许一个任务或线程访问共享资源。 二值信号量的工作方式类似于一把锁。当信号量的值为1时表示资源可用任何一个任务或线程都可以获取该资源并执行操作。当一个任务或线程获取了资源后它将信号量的值减少为0表示资源已被占用。 当信号量的值为0时表示资源不可用其他任务或线程必须等待。当一个任务或线程释放了资源后它将信号量的值增加为1表示资源可用等待的任务或线程将有机会获取该资源。 二值信号量的经典应用是实现互斥访问共享资源如临界区的保护。在多个任务或线程需要访问临界区时可以使用一个二值信号量来控制对临界区的访问保证同一时间只有一个任务或线程可以进入临界区执行操作从而避免竞争条件和数据不一致的问题。 总结来说二值信号量是一种特殊类型的信号量只有两个可能的取值0和1。它可以用于实现互斥访问共享资源保证在某一时刻只有一个任务或线程可以执行操作。 2.二值信号量相关API函数 这些函数是FreeRTOS中用于创建和操作二值信号量的函数。下面是对这些函数的简要说明 xSemaphoreCreateBinary()使用动态方式创建一个二值信号量。该函数返回一个指向创建的二值信号量的句柄。可以在任务中使用该句柄来获取或释放信号量。 xSemaphoreCreateBinaryStatic()使用静态方式创建一个二值信号量。与动态方式创建的函数类似但是需要提供一个静态分配的内存作为信号量的存储空间。该函数返回一个指向创建的二值信号量的句柄。 xSemaphoreGive()释放一个二值信号量。将信号量的计数器加1表示资源可用。如果有其他任务在等待该信号量则其中一个任务将获取到该信号量。 xSemaphoreGiveFromISR()在中断服务程序ISR中释放一个二值信号量。与xSemaphoreGive()函数类似但是可以在中断上下文中使用。这是因为在中断上下文中不能直接调用一些阻塞式的函数。 xSemaphoreTake()获取一个二值信号量。将信号量的计数器减1表示资源不可用。如果信号量的计数器为零则任务将阻塞等待直到有其他任务释放该信号量。 xSemaphoreTakeFromISR()在中断服务程序ISR中获取一个二值信号量。与xSemaphoreTake()函数类似但是可以在中断上下文中使用。 3.二值信号量实例 代码 /* 任务一释放二值信号量 */ void task1( void * pvParameters ) {uint8_t key 0;BaseType_t err;while(1) {key key_scan(0);if(key KEY0_PRES){if(semphore_handle ! NULL){err xSemaphoreGive(semphore_handle);if(err pdPASS){printf(信号量释放成功\r\n);}else printf(信号量释放失败\r\n);}}vTaskDelay(10);} }/* 任务二获取二值信号量 */ void task2( void * pvParameters ) {uint32_t i 0;BaseType_t err;while(1){err xSemaphoreTake(semphore_handle,portMAX_DELAY); /* 获取信号量并死等 */if(err pdTRUE){printf(获取信号量成功\r\n);}else printf(已超时%d\r\n,i);} }上述代码是一个示例演示了在FreeRTOS中如何使用二值信号量进行任务间的同步操作。 任务一是一个周期性的任务通过key_scan()函数检测按键并在按下KEY0时释放二值信号量。如果二值信号量的句柄非空就调用xSemaphoreGive()函数释放信号量。如果释放成功则打印信号量释放成功“否则打印信号量释放失败”。 任务二是一个循环任务通过调用xSemaphoreTake()函数获取二值信号量。使用portMAX_DELAY参数表示在没有获取到信号量时任务会一直等待。如果获取成功则打印获取信号量成功否则打印已超时并增加计数器。 这样当任务一释放信号量时任务二就能够获取到信号量并执行相应的操作。通过二值信号量的获取和释放可以实现任务之间的同步和互斥操作保证对共享资源的安全访问。 需要注意的是示例中的semphore_handle是一个指向二值信号量的句柄需要在任务创建时进行初始化。 三、计数型信号量 四、优先级翻转 举个例子假设有三个任务Task1、Task2和Task3它们的优先级分别为高、中和低。这三个任务需要访问一个共享资源例如一个全局变量。 在某个时间点Task1先开始执行并且获取了该共享资源的互斥量。此时Task2和Task3处于阻塞状态因为它们的优先级低于Task1。 然后Task2的中优先级任务需要处理一个紧急事件但由于Task1持有共享资源Task2无法访问该资源。此时Task2无法及时处理紧急事件导致系统的实时性能受到影响。 为了解决这个问题可以使用FreeRTOS中的优先级翻转技术。当Task1获取共享资源的互斥量时它的优先级会被提升到Task2的优先级。这样Task2就能够及时访问共享资源并处理紧急事件保证了系统的实时性能。 当Task1释放共享资源的互斥量时它的优先级会恢复到原来的值即高优先级。这样Task3可以继续执行并且Task2的优先级也会恢复到中优先级。 通过使用优先级翻转技术可以解决实时任务调度中的优先级反转问题确保高优先级任务能够及时访问共享资源提高系统的实时性能。 五、互斥信号量 互斥信号量是一种用于实现互斥访问共享资源的机制。它是一种二进制信号量只能取两个值0和1。当互斥信号量的值为1时表示共享资源可供访问当互斥信号量的值为0时表示共享资源已被占用。 在多任务系统中当一个任务需要访问共享资源时它会首先尝试获取互斥信号量。如果互斥信号量的值为1表示共享资源可供访问该任务会将互斥信号量的值设置为0标记共享资源已被占用。如果互斥信号量的值为0表示共享资源已被其他任务占用该任务会进入阻塞状态等待互斥信号量的值变为1。 当占用共享资源的任务完成对共享资源的访问后它会释放互斥信号量将其值重新设置为1表示共享资源可供其他任务访问。此时处于阻塞状态的任务中优先级最高的任务会被唤醒获取互斥信号量继续执行访问共享资源的操作。 通过使用互斥信号量可以实现对共享资源的互斥访问避免多个任务同时访问共享资源导致的竞争和冲突。这有助于提高系统的可靠性和并发性。在FreeRTOS中互斥信号量可以使用xSemaphoreCreateMutex()函数创建并通过xSemaphoreTake()和xSemaphoreGive()函数来获取和释放互斥信号量。 当多个任务需要访问共享资源时信号量的作用可以通过以下例子来说明 假设有两个任务Task1和Task2它们需要同时访问一个共享的串口资源例如一个串口缓冲区。 在这种情况下可以使用一个二进制信号量互斥信号量来实现资源的互斥访问。 初始化信号量在系统初始化时创建一个互斥信号量初始值为1。 xSemaphoreHandle mutex xSemaphoreCreateMutex(); Task1和Task2的实现 // Task1 void Task1(void *parameters) {while (1) {// 尝试获取互斥信号量if (xSemaphoreTake(mutex, portMAX_DELAY) pdTRUE) {// 临界区代码访问共享资源// ...// 释放互斥信号量xSemaphoreGive(mutex);}} }// Task2 void Task2(void *parameters) {while (1) {// 尝试获取互斥信号量if (xSemaphoreTake(mutex, portMAX_DELAY) pdTRUE) {// 临界区代码访问共享资源// ...// 释放互斥信号量xSemaphoreGive(mutex);}} }在这个例子中当Task1和Task2需要访问共享资源时它们首先尝试获取互斥信号量。如果互斥信号量的值为1表示资源可供访问任务可以进入临界区代码并将互斥信号量的值设置为0以标记共享资源已被占用。当任务完成对共享资源的访问后它会释放互斥信号量将其值重新设置为1表示共享资源可供其他任务访问。 通过使用互斥信号量可以确保在任意时刻只有一个任务能够访问共享资源避免了数据的冲突和损坏。这样可以保证系统的正确性和一致性。 六、信号量这一节中比较重要的知识 1.最重要的是保证资源的同步和互斥访问。 资源的同步是指多个任务之间对共享资源的访问需要进行协调以确保数据的正确性和一致性。通过信号量可以控制任务的执行顺序使得在某个任务使用共享资源之前必须等待其他任务释放该资源。这样可以避免竞态条件和数据不一致的问题。 资源的互斥访问是指同一时间只能有一个任务访问共享资源以防止数据的冲突和损坏。通过使用互斥信号量可以保证在一个任务访问共享资源时其他任务无法同时访问该资源从而避免了并发访问带来的问题。 在并发系统中资源的同步和互斥访问是非常重要的尤其是在多任务环境下。它们可以保证任务之间的协作和正确性避免数据竞争和冲突提高系统的可靠性和性能。 2.总结的一些知识点 在信号量中有一些常用的知识点和概念包括 二进制信号量和计数信号量二进制信号量只能取两个值0和1用于实现互斥访问共享资源计数信号量可以取多个非负整数值用于控制对共享资源的并发访问。 信号量的创建和删除可以使用特定的函数来创建和删除信号量例如xSemaphoreCreateBinary()创建二进制信号量xSemaphoreCreateCounting()创建计数信号量vSemaphoreDelete()删除信号量。 信号量的获取和释放任务可以使用xSemaphoreTake()函数来获取信号量如果信号量不可用则任务会进入阻塞状态等待任务可以使用xSemaphoreGive()函数来释放信号量使得其他任务可以获取该信号量。 信号量的优先级逆转问题当一个低优先级任务持有一个信号量而一个高优先级任务需要获取该信号量时可能会导致优先级逆转问题。为了解决这个问题可以使用优先级继承或者优先级屏蔽等技术。 信号量的超时处理任务在获取信号量时可以指定一个超时时间如果在指定时间内无法获取到信号量则任务可以执行相应的超时处理。 死锁问题在使用多个信号量时如果任务之间的互斥和同步关系不正确可能会导致死锁问题即任务相互等待对方释放资源而无法继续执行。为了避免死锁需要合理设计信号量的获取和释放顺序以及避免出现资源竞争的情况。 七、事件标志组 1.事件标志组概念 2.事件标志组与队列、信号量的区别 事件标志组、队列和信号量是FreeRTOS中常用的同步机制它们在功能和应用场景上有一些区别 事件标志组Event Flag Group事件标志组用于任务间的事件通知和等待。它允许任务等待多个事件中的任意一个或多个事件发生并在事件发生后立即返回。可以通过设置和清除位来表示事件任务可以等待特定的位或位组合。事件标志组提供了一种灵活的方式来实现任务间的事件通知适用于多任务并发处理的场景。 队列Queue队列用于任务间的数据传输和共享。它可以在任务之间传递消息、数据和事件。队列有固定的大小可以用来实现任务之间的异步通信和同步操作。任务可以通过向队列发送消息或从队列接收消息来实现数据的传输和共享。 信号量Semaphore信号量用于任务间的互斥和同步。它可以用来保护共享资源的访问防止多个任务同时访问共享资源。信号量通常用于限制资源的并发访问控制任务的执行顺序或者用于任务间的同步操作。 区别总结如下 功能不同事件标志组用于事件通知和等待队列用于数据传输和共享信号量用于互斥和同步。 数据传输队列可以传输数据和消息而事件标志组和信号量不直接传输数据。 同步方式事件标志组用于等待事件发生队列和信号量用于任务间的同步和互斥操作。 大小限制队列有固定的大小而事件标志组和信号量没有大小限制。 使用场景事件标志组适用于任务间的事件通知和并发处理队列适用于任务间的数据传输和共享信号量适用于任务间的互斥和同步操作。 根据具体的应用需求可以选择适合的同步机制来实现任务间的通信和协调。通常情况下这三种同步机制可以相互结合使用以满足复杂的应用场景。 3.API函数 这些函数是FreeRTOS中用于事件标志组操作的函数。下面是每个函数的功能和用法 xEventGroupCreate()使用动态方式创建事件标志组。它返回一个EventGroupHandle_t类型的句柄用于对事件标志组进行操作。 xEventGroupCreateStatic()使用静态方式创建事件标志组。与xEventGroupCreate()类似但是可以使用静态分配的内存来创建事件标志组。 xEventGroupClearBits()清零事件标志位。通过指定要清除的位的位掩码将事件标志组中的一个或多个位清零。 xEventGroupClearBitsFromISR()在中断中清零事件标志位。与xEventGroupClearBits()类似但是可以在中断服务函数中使用。 xEventGroupSetBits()设置事件标志位。通过指定要设置的位的位掩码将事件标志组中的一个或多个位设置为1。 xEventGroupSetBitsFromISR()在中断中设置事件标志位。与xEventGroupSetBits()类似但是可以在中断服务函数中使用。 xEventGroupWaitBits()等待事件标志位。任务可以调用此函数来等待事件标志组中的一个或多个位满足指定的条件以及可选的超时时间。函数将返回满足条件的位。 xEventGroupSync()设置事件标志位并等待事件标志位。此函数用于将事件标志组设置为指定的位并等待满足条件的位。与xEventGroupWaitBits()类似但是可以在一个原子操作中完成设置和等待。 4.举一个应用了事件标志组的知识的智能门锁的例程 智能门锁的应用十分贴合事件标志组因为会有很多任务触发事件导致同一个任务开锁的发生。 基于FreeRTOS操作系统下创建了一个开始任务和四个控制任务。 任务与任务之间使用事件标志组进行通信当TFTLCD屏幕触屏输入密码的时当密码输入正确则向舵机任务发送一个事件标志位 当指纹识别成功时则向舵机任务发送一个事件标志位 当射频识别卡识别成功卡号时候则向舵机任务发送一个事件标志位 当蓝牙从手机串口发生密码时当密码识别成功则向舵机任务发送一个事件标志位。 舵机任务只要接收到其中一个事件标志位时候舵机就会转动180°来模拟解锁成功。当如果每解锁失败一次之后err全局变量加一当err等于3的时候则舵机任务被挂起。 ①宏定义事件标志组 EventGroupHandle_t EventGroupHandler; //事件标志组句柄 #define EVENTBIT_0 (10) //事件位 #define EVENTBIT_1 (11) #define EVENTBIT_2 (12) #define EVENTBIT_ALL (EVENTBIT_0|EVENTBIT_1|EVENTBIT_2)这些宏定义可以用来在代码中指定特定的事件位以进行事件的设置、清除和检查。例如通过使用EVENTBIT_0可以指定事件标志组中的第0位进行相应的操作。同时EVENTBIT_ALL可以用于检查所有事件位是否都被触发。 ②任务一触摸屏输入密码若正确则设置事件标志组使得发送开锁指令 void LCD_task(void * pvParameters) {while(1){if(sg90flag1||GET_NUM()){BEEP1;delay_xms(100);BEEP0;printf(密码输入正确\r\n);xEventGroupSetBits(EventGroupHandler,EVENTBIT_0);}else{BEEP1;delay_xms(50);BEEP0;delay_xms(50);BEEP1;delay_xms(50);BEEP0;delay_xms(50);BEEP1;delay_xms(50);BEEP0;printf(密码输入错误\r\n);err;if(err3){vTaskSuspend(SG90Task_Handler);printf(舵机任务挂起\r\n);} } vTaskDelay(100); //延时10ms也就是10个时钟节拍} }任务进入一个无限循环(while(1))表示任务会一直执行。 在循环中任务会检查sg90flag变量的值以及调用GET_NUM()函数的返回值。这些条件用于判断密码是否输入正确。如果密码输入正确任务会打印密码输入正确的消息并执行一系列操作。这些操作包括发出蜂鸣器声音延时一段时间显示密码匹配的消息在LCD上以及设置事件标志组中的位。 如果密码输入错误任务会打印密码输入错误的消息并执行一系列操作。这些操作包括连续发出蜂鸣器声音延时一段时间显示密码错误的消息在LCD上并增加错误计数err。如果错误计数达到3次任务会挂起舵机任务并打印舵机任务挂起的消息并在LCD上显示相应的信息。 最后任务调用vTaskDelay(100)函数进行延时延时时间为100个时钟节拍。 ③任务二刷NFC卡若识别到则设置事件标志组使得发送开锁指令 void RFID_task(void * pvParameters) {// rfidflagshibieka();while(1){if(rfidflag1||shibieka()){BEEP1;delay_xms(100);BEEP0;xEventGroupSetBits(EventGroupHandler,EVENTBIT_1);printf(识别卡号成功\r\n);}else if(shibieka()0){BEEP1;delay_xms(50);BEEP0;delay_xms(50);BEEP1;delay_xms(50);BEEP0;delay_xms(50);BEEP1;delay_xms(50);BEEP0;printf(识别卡号失败\r\n);err;if(err3){vTaskSuspend(SG90Task_Handler);printf(舵机任务挂起\r\n);}}vTaskDelay(100); //延时10ms也就是10个时钟节拍}}进入一个无限循环while(1)表示任务将一直执行。 在循环中首先判断rfidflag是否为1或者shibieka()函数返回值为真。如果是则执行一系列操作包括控制蜂鸣器发声、设置事件标志组中的第1位通过调用xEventGroupSetBits(EventGroupHandler,EVENTBIT_1)并输出一条成功识别卡号的提示信息。 如果上述条件不满足即rfidflag不为1且shibieka()函数返回值为假执行另外一系列操作。这些操作包括控制蜂鸣器发出一段特定的声音序列输出一条识别卡号失败的提示信息并增加一个错误计数器err。如果错误计数器达到3将挂起名为SG90Task_Handler的舵机任务并输出一条舵机任务被挂起的提示信息。 最后通过调用vTaskDelay(100)进行延时即任务每次执行完后会暂停100个时钟节拍大约是10毫秒然后再次进入下一次循环。 ④任务三舵机任务接收各个事件标志位来做出反应 void SG90_task(void * pvParameters) {volatile EventBits_t EventValue; while(1){EventValuexEventGroupWaitBits(EventGroupHandler,EVENTBIT_ALL,pdTRUE,pdFALSE,portMAX_DELAY);printf(接收事件成功\r\n);set_Angle(180);delay_xms(1000);delay_xms(1000);set_Angle(0);LCD_ShowString(80,150,260,16,16, );vTaskDelay(100); //延时10ms也就是10个时钟节拍} }首先在任务的开头定义了一个EventBits_t类型的变量EventValue用于存储事件标志组的值。 接下来进入一个无限循环while(1)表示任务将一直执行。 在循环中通过调用xEventGroupWaitBits(EventGroupHandler,EVENTBIT_ALL,pdTRUE,pdFALSE,portMAX_DELAY)等待事件标志组中的所有位都被置位。函数的参数说明如下 EventGroupHandler事件标志组的句柄。 EVENTBIT_ALL要等待的事件位这里是等待所有事件位都被置位。 pdTRUE设置为pdTRUE表示等待所有事件位都被置位。 pdFALSE设置为pdFALSE表示不需要等待所有事件位都被清除。 portMAX_DELAY表示等待时间的最大值即无限等待。 当所有事件位都被置位后执行一系列操作包括输出一条接收事件成功的提示信息、设置舵机角度为180度、延时1秒、再延时1秒、设置舵机角度为0度并在LCD上显示一段空白字符串。 最后通过调用vTaskDelay(100)进行延时即任务每次执行完后会暂停100个时钟节拍大约是10毫秒然后再次进入下一次循环。 当RFID任务或LCD任务执行了xEventGroupSetBits(EventGroupHandler,EVENTBIT_1)语句后会立即触发SG90任务的执行。 在RFID任务或LCD任务中当调用xEventGroupSetBits(EventGroupHandler,EVENTBIT_1)函数时会将事件标志组中的第1位即EVENTBIT_1置位。然后SG90任务通过调用xEventGroupWaitBits(EventGroupHandler,EVENTBIT_ALL,pdTRUE,pdFALSE,portMAX_DELAY)函数等待所有事件位都被置位。当事件标志组中的所有位都被置位后SG90任务会立即执行一系列操作。 因此当RFID任务或LCD任务执行了xEventGroupSetBits(EventGroupHandler,EVENTBIT_1)语句后会立刻触发SG90任务的执行。 这就是事件标志组的应用。 八、任务通知-消息邮箱 1.任务通知的概念 2.任务通知的优缺点 任务通知Task Notification是一种在实时操作系统RTOS中用于任务间通信和同步的机制。任务通知允许任务之间直接发送简单的通知消息而无需使用队列、信号量或事件标志组等更复杂的机制。 优点 ①轻量级任务通知是一种轻量级的通信机制不需要额外的数据结构和内存仅使用一个32位的整数作为通知值。因此它对系统资源的消耗较小适合于资源受限的嵌入式系统。 ②快速响应任务通知的发送和接收操作是直接的不需要中间的缓冲区或队列因此响应时间较短。任务可以立即收到通知并进行相应的处理适用于对实时性要求较高的应用场景。 ③灵活性任务通知可以传递任意的32位整数值任务可以根据通知值的具体含义进行不同的处理。这种灵活性使得任务通知适用于各种不同的应用可以实现多种通信和同步的需求。 缺点 ①仅适用于一对一通信任务通知是一对一的通信机制一个任务发送的通知只能被一个特定的任务接收。如果需要多个任务接收同一通知就需要在多个任务之间进行复制操作增加了额外的开销。 ②无法传递大量数据任务通知仅能传递一个32位整数值无法直接传递大量的数据。如果需要传递大量的数据就需要使用其他机制如队列或消息邮箱来传递数据的指针或句柄。 ③没有阻塞选项任务通知的发送和接收操作是非阻塞的任务无法在等待通知时挂起需要不断地进行轮询。这可能会浪费处理器资源特别是在等待时间较长的情况下。 综上所述任务通知是一种轻量级、快速响应且灵活的任务间通信机制适用于对实时性要求较高、通信量较小且一对一通信的应用场景。但需要注意其无法传递大量数据、无阻塞选项且仅适用于一对一通信的限制。在具体应用中需要根据实际需求和系统资源的考量选择合适的通信机制。 3.相关API函数 4.利用任务通知机制的例程 (1)模拟获取二值信号量的任务 /* 任务一发送任务通知值 */ void task1( void * pvParameters ) {uint8_t key 0;while(1) {key key_scan(0);if(key KEY0_PRES){printf(任务通知模拟二值信号量释放\r\n);xTaskNotifyGive(task2_handler);}vTaskDelay(10);} }/* 任务二接收任务通知值 */ void task2( void * pvParameters ) {uint32_t rev 0;while(1){rev ulTaskNotifyTake(pdTRUE , portMAX_DELAY);if(rev ! 0){printf(接收任务通知成功模拟获取二值信号量\r\n);}} } 这个示例中任务通知值的作用类似于二值信号量。任务一发送通知值相当于释放了信号量任务二接收通知值相当于获取了信号量。通过任务通知值的发送和接收任务一和任务二之间实现了一对一的通信和同步。 需要注意的是任务通知是非阻塞的操作即发送和接收任务通知的函数都是立即返回的。因此任务一和任务二会不断地进行轮询以检查是否有任务通知的发送或接收 (2)模拟获取计数信号量的任务 /* 任务一发送任务通知值 */ void task1( void * pvParameters ) {uint8_t key 0;while(1) {key key_scan(0);if(key KEY0_PRES){printf(任务通知模拟计数型信号量释放\r\n);xTaskNotifyGive(task2_handler);}vTaskDelay(10);} }/* 任务二接收任务通知值 */ void task2( void * pvParameters ) {uint32_t rev 0;while(1){rev ulTaskNotifyTake(pdFALSE , portMAX_DELAY);if(rev ! 0){printf(rev%d\r\n,rev);}vTaskDelay(1000);} }这个示例中任务通知值的作用类似于计数型信号量。任务一发送通知值相当于释放了信号量任务二接收通知值后可以根据接收到的通知值进行相应的处理。在这个示例中任务二通过打印接收到的通知值来模拟处理的操作。 (3)模拟获取计数信号量的任务 /* 任务一发送任务通知值*/ void task1( void * pvParameters ) {uint8_t key 0;while(1) {key key_scan(0);if(key KEY0_PRES){printf(将bit0位置1\r\n);xTaskNotify( task2_handler, EVENTBIT_0, eSetBits );}else if(key KEY1_PRES){printf(将bit1位置1\r\n);xTaskNotify( task2_handler, EVENTBIT_1, eSetBits );}vTaskDelay(10);} }/* 任务二接收任务通知值 */ void task2( void * pvParameters ) {uint32_t notify_val 0,event_bit 0;while(1){xTaskNotifyWait( 0, 0xFFFFFFFF, notify_val, portMAX_DELAY );if(notify_val EVENTBIT_0){event_bit | EVENTBIT_0;}if(notify_val EVENTBIT_1){event_bit | EVENTBIT_1;}if(event_bit (EVENTBIT_0|EVENTBIT_1)){printf(任务通知模拟事件标志组接收成功\r\n);event_bit 0;}} }任务一通过调用xTaskNotify(task2_handler, EVENTBIT_0, eSetBits)函数发送任务通知值给任务二。这里的task2_handler是任务二的句柄用于指定接收通知的任务。EVENTBIT_0是一个宏定义的事件标志位表示将bit0位置1。 任务二通过调用xTaskNotifyWait(0, 0xFFFFFFFF, notify_val, portMAX_DELAY)函数等待接收任务通知值。第二个参数0xFFFFFFFF表示等待所有事件标志位都被设置notify_val是保存接收到的通知值的变量portMAX_DELAY表示等待时间设置为最大值即无限等待。当任务一调用xTaskNotify(task2_handler, EVENTBIT_0, eSetBits)发送通知值后任务二会接收到通知并将接收到的通知值保存在notify_val变量中。 在任务二中通过判断notify_val中的事件标志位是否被设置来检测是否接收到了期望的通知。如果接收到了EVENTBIT_0和EVENTBIT_1则表示任务通知模拟事件标志组接收成功并打印相应的提示信息。 这个示例中任务通知值的作用类似于事件标志组。任务一发送通知值相当于设置了相应的事件标志位任务二通过检测事件标志位是否被设置来判断是否接收到了期望的通知。
http://www.pierceye.com/news/489609/

相关文章:

  • 龙武工会网站怎么做5173游戏交易网站源码
  • 网站建设设计时代创信好海南城乡和住房建设厅网站
  • 大连最好的做网站的公司崇义做网站
  • 圣弘建设股份有限公司网站上海图文设计有限公司
  • gta5资产网站正在建设零基础自学设计
  • 深圳专业制作网站公司吗网站信息化建设报送
  • 苏州网站建设运营推广网站一年多少钱?
  • WordPress国外主机湖北短视频seo营销
  • 南通网站建设电话设计一个网站要多少钱
  • 好的模板网站建设网站规划 时间
  • 昆明seocn整站优化网站建设如何报价
  • 网页设计模板免费网站WordPress生成网站地图
  • 做网站 侵权做外贸怎么看外国网站
  • 网站建设知识点的总结普通网站建设是什么
  • 杭州网站建设费用多少合肥高新城建设计院网站
  • 炫酷特效网站asa8.4 做网站映射
  • 郑州租赁房网站建设九江快乐城
  • 手机网站建站教育模板微信网站 教程
  • 网站的结构犀牛云做网站多少钱
  • 网站服务器用什么配置公司网站建设的视频教程
  • idea做网站网络营销与网站推广的区别
  • 建一家网站多少钱微信小程序在哪里查找
  • 东阳网站推广英文网站源码下载
  • 介绍湛江网站高端网站建设网站定制
  • 网站的特征包括哪些方面wordpress缓存插件 w3
  • 东莞专业网站营销wordpress新建页面模板
  • 做外贸学习网站智慧团建网页电脑版登录网站
  • 如何免费做一个网站攻略常州网站推广软件
  • 手机网站建站 服务器网站名称收录
  • 网站根 html网站建设 永灿 竞争