既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)
if (inHandlerMode())
{
if(xTaskGenericNotifyFromISR( thread_id , (uint32_t)signal, eSetBits, &ulPreviousNotificationValue, &xHigherPriorityTaskWoken ) != pdPASS )
return 0x80000000;
portYIELD\_FROM\_ISR( xHigherPriorityTaskWoken );
}
else if(xTaskGenericNotify( thread_id , (uint32_t)signal, eSetBits, &ulPreviousNotificationValue) != pdPASS )
return 0x80000000;
return ulPreviousNotificationValue;
#else
(void) thread_id;
(void) signal;
return 0x80000000; /* Task Notification not supported */
#endif
}
#### 2.2 osSignalWait
任务通知只能在任务中使用,不允许在中断中使用,`osSignalWait`调用`xTaskNotifyWait`实现:
/**
* @brief Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread.
* @param signals wait until all specified signal flags set or 0 for any single signal flag.
* @param millisec timeout value or 0 in case of no time-out.
* @retval event flag information or error code.
* @note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS.
*/
osEvent osSignalWait (int32_t signals, uint32_t millisec)
{
osEvent ret;
#if( configUSE_TASK_NOTIFICATIONS == 1 )
TickType_t ticks;
ret.value.signals = 0;
ticks = 0;
if (millisec == osWaitForever) {
ticks = portMAX_DELAY;
}
else if (millisec != 0) {
ticks = millisec / portTICK_PERIOD_MS;
if (ticks == 0) {
ticks = 1;
}
}
if (inHandlerMode())
{
ret.status = osErrorISR; /*Not allowed in ISR*/
}
else
{
if(xTaskNotifyWait( 0,(uint32_t) signals, (uint32_t *)&ret.value.signals, ticks) != pdTRUE)
{
if(ticks == 0) ret.status = osOK;
else ret.status = osEventTimeout;
}
else if(ret.value.signals < 0)
{
ret.status = osErrorValue;
}
else ret.status = osEventSignal;
}
#else
(void) signals;
(void) millisec;
ret.status = osErrorOS; /* Task Notification not supported */
#endif
return ret;
}
## 二、任务通知使用
在CubeMX中,任务通知是默认使能的:
![在这里插入图片描述](https://img-blog.csdnimg.cn/5864d266c006441ab3a338706bed8596.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_19,color_FFFFFF,t_70,g_se,x_16)
### 1、定义通知量
在程序中定义几个通知量,我们知道任务通知是32位的,所以可以任意定义,我们测试使用了2个通知:
/* USER CODE BEGIN EFP */
#define test_signal1 1
#define test_signal2 0xFFFFFFFE
### 2、任务中发送通知
在按键任务中,发送一个任务通知给温湿度读取任务,使用`osSignalSet`:
if(HAL_GPIO_ReadPin(K3_GPIO_Port,K3_Pin) == 0){
osDelay(10);
if(HAL_GPIO_ReadPin(K3_GPIO_Port,K3_Pin) == 0){
taskENTER_CRITICAL();
printf(“K3 pushed!!,send a tasksignal to thread…\r\n”);
taskEXIT_CRITICAL();
osSignalSet(THreadHandle,test_signal2);
while(HAL_GPIO_ReadPin(K3_GPIO_Port,K3_Pin) == 0){
osDelay(10);
}
}
}
### 3、接收通知
通过上文我们可以知道`osSignalWait`返回的类型是`osEvent`,所以需要定义过一个`osEvent`类型的变量,然后结构体变量中有一个成员`v`是保存的接收的通知的值,如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/6fff4bfe83ea48a9bdaba8035e50afeb.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16)
我们看一下`osEvent`结构体 :
/// Event structure contains detailed information about an event.
/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS.
/// However the struct may be extended at the end.
typedef struct {
osStatus status; ///< status code: event or error information
union {
uint32_t v; ///< message as 32-bit value
void *p; ///< message or mail as void pointer
int32_t signals; ///< signal flags
} value; ///< event value
union {
osMailQId mail_id; ///< mail id obtained by \ref osMailCreate
osMessageQId message_id; ///< message id obtained by \ref osMessageCreate
} def; ///< event definition
} osEvent;
所以最终 温湿度读取任务函数改为:
/* USER CODE END Header_StartTHread */
void StartTHread(void const * argument)
{
/* USER CODE BEGIN StartTHread */
float T=0,H=0;
osEvent th_readevent;
/*128会溢出字的内存空间不够SHT21 协议读取*/
/* Infinite loop */
for(;😉
{
th_readevent = osSignalWait(test_signal2,osWaitForever);
if(th_readevent.value.v == test_signal2){
SHT2X_THMeasure();
T=(getTemperature()/100.0);
H=(getHumidity()/100.0);
taskENTER_CRITICAL();
printf(“0x%x”,th_readevent.value.v);
printf(“\r\n%4.2f C\r\n%4.2f%%\r\n”,T,H);
taskEXIT_CRITICAL();
}
osDelay(1);
}
/* USER CODE END StartTHread */
}
结果如下,按照预期的结果执行:
![在这里插入图片描述](https://img-blog.csdnimg.cn/72f488979132485d9045e7de1682dcf6.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_16,color_FFFFFF,t_70,g_se,x_16)
### 4、中断中发送通知
我们在上次开启的定时器中断中,增加任务通知发送任务:
#include “cmsis_os.h”
…
/* USER CODE BEGIN EV */
extern osThreadId THreadHandle;
/* USER CODE END EV */
…
/**
* @brief This function handles TIM3 global interrupt.
*/
void TIM3_IRQHandler(void)
{
/* USER CODE BEGIN TIM3_IRQn 0 */
time3_count++;
if(time3_count >= 10){
osSignalSet(THreadHandle,test_signal1);
time3_count = 0;
}
/* USER CODE END TIM3_IRQn 0 */
HAL_TIM_IRQHandler(&htim3);
/* USER CODE BEGIN TIM3_IRQn 1 */
/* USER CODE END TIM3_IRQn 1 */
}
把THread任务再次修改一下:
void StartTHread(void const * argument)
{
/* USER CODE BEGIN StartTHread */
收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
片转存中…(img-ZBkx6Nb8-1715874519125)]
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!