uCOSii中的事件标志组

news2024/11/27 22:29:34

事件标志管理 (EVENT FLAGS MANAGEMENT)

OSFlagAccept() 无等待查询事件标志组的事件标志位是否建立

OSFlagPend() 需要等待事件标志组的事件标志位建立

OSFlagCreate() 建立一个事件标志组

OSFlagDel() 删除一个事件标志组

OSFlagPost() 置位或清0事件标志组中的标志位

OSFlagQuery() 查询事件标志组的当前事件标志状态

如果有条件,还是事先去看uCOSii中的事件标志管理函数,很多人没有写函数功能,很难理解。

//函数功能:无需等待,接收事件标志组的事件标志位

wait_typebit7=1,若接收到的事件标志组的位值正确,则同时把事件标志组的位值清除掉,这个带清除事件标志组的位功能;

OS_FLAG_WAIT_CLR_ALL= OS_FLAG_WAIT_CLR_AND=0u

OS_FLAG_WAIT_CLR_ANY= OS_FLAG_WAIT_CLR_OR=1

OS_FLAG_WAIT_SET_ALL= OS_FLAG_WAIT_SET_AND=2

OS_FLAG_WAIT_SET_ANY= OS_FLAG_WAIT_SET_OR=3

wait_type可以取上面的值

pgrp为事件标志组指针

根据flags接收指定的事件标志组的位值

perr = OS_ERR_NONE,表示发送正确,返回值与 flags相与后等于flags;

perr != OS_ERR_NONE,表示发送错误,返回值与 flags相与后不等于flags;

OS_FLAGS  OSFlagAccept (OS_FLAG_GRP  *pgrp,

                        OS_FLAGS      flags,

                        INT8U         wait_type,

                        INT8U        *perr)

{

    OS_FLAGS      flags_rdy;

    INT8U         result;

    BOOLEAN       consume;

#if OS_CRITICAL_METHOD == 3u

/* Allocate storage for CPU status register */

    OS_CPU_SR     cpu_sr = 0u;

#endif

#ifdef OS_SAFETY_CRITICAL

if (perr == (INT8U *)0)

 {// perr指针为0

        OS_SAFETY_CRITICAL_EXCEPTION();

    }

#endif

#if OS_ARG_CHK_EN > 0u

if (pgrp == (OS_FLAG_GRP *)0)

 {//事件标志组指针为零

        *perr = OS_ERR_FLAG_INVALID_PGRP;

        return ((OS_FLAGS)0);

    }

#endif

if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG)

{//若不是事件标志组类型

        *perr = OS_ERR_EVENT_TYPE;

        return ((OS_FLAGS)0);

}

result = (INT8U)(wait_type & OS_FLAG_CONSUME);

//OS_FLAG_CONSUME=0x80

if (result != (INT8U)0)

{ //发现wait_typebit71, 要求清除事件标志位

    wait_type &= ~OS_FLAG_CONSUME;//wait_typebit70

        consume    = OS_TRUE;

}

else

{//wait_type正确

        consume    = OS_FALSE;

}

*perr = OS_ERR_NONE;//假定没有错误

    OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量

switch (wait_type)

 {

        case OS_FLAG_WAIT_SET_ALL:

             flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags);

// 根据flags读取事件标志组中的位值

             if (flags_rdy == flags)

{//接收到的事件信号正确

                 if (consume == OS_TRUE)

 {// wait_typebit7=1,需要清除接收到事件标志

                     pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy;

                 }

             }

else

{//接收到的事件信号错误

                 *perr = OS_ERR_FLAG_NOT_RDY;

//OS_ERR_FLAG_NOT_RDY=112

             }

             OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

             break;

        case OS_FLAG_WAIT_SET_ANY:

             flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags);

// 根据flags读取事件标志组中的位值

             if (flags_rdy != (OS_FLAGS)0)

{//接收到的事件信号正确

                 if (consume == OS_TRUE)

 {// wait_typebit7=1,需要清除接收到事件标志

                     pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy;

                 }

             }

else

{//接收到的事件信号错误

                 *perr = OS_ERR_FLAG_NOT_RDY;

             }

             OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

             break;

#if OS_FLAG_WAIT_CLR_EN > 0u

        case OS_FLAG_WAIT_CLR_ALL:

             flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags;

// 根据flags读取事件标志组中的位值

             if (flags_rdy == flags)

{//接收到的事件信号正确

                 if (consume == OS_TRUE)

{// wait_typebit7=1,需要清除接收到事件标志

pgrp->OSFlagFlags |= flags_rdy;

                 }

             }

 else

{//接收到的事件信号错误

                 *perr = OS_ERR_FLAG_NOT_RDY;

             }

             OS_EXIT_CRITICAL();

             break;

        case OS_FLAG_WAIT_CLR_ANY:

             flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags;

// 根据flags读取事件标志组中的位值

             if (flags_rdy != (OS_FLAGS)0)

{//接收到的事件信号正确

                 if (consume == OS_TRUE)

{// wait_typebit7=1,需要清除接收到事件标志

                     pgrp->OSFlagFlags |= flags_rdy;

                 }

             }

else {//接收到的事件信号错误

                 *perr = OS_ERR_FLAG_NOT_RDY;

             }

             OS_EXIT_CRITICAL();

             break;

#endif

        default:

             OS_EXIT_CRITICAL();

             flags_rdy = (OS_FLAGS)0;

             *perr     = OS_ERR_FLAG_WAIT_TYPE;

             break;

}

    return (flags_rdy);

}

//函数功能:等待接收事件标志组的事件标志位

wait_typebit7=1,若接收到的事件标志组的位值正确,则同时把事件标志组的位值清除掉,这个带清除事件标志组的位功能;

OS_FLAG_WAIT_CLR_ALL= OS_FLAG_WAIT_CLR_AND=0u

OS_FLAG_WAIT_CLR_ANY= OS_FLAG_WAIT_CLR_OR=1

OS_FLAG_WAIT_SET_ALL= OS_FLAG_WAIT_SET_AND=2

OS_FLAG_WAIT_SET_ANY= OS_FLAG_WAIT_SET_OR=3

wait_type可以取上面的值

pgrp为事件标志组指针

根据flags接收指定的事件标志组的位值

perr = OS_ERR_NONE,表示发送正确,返回值与 flags相与后等于flags;

perr != OS_ERR_NONE,表示发送错误,返回值与 flags相与后不等于flags;

Timeout=0表示一直等待信号,直到条件满足为止

OS_FLAGS  OSFlagPend (OS_FLAG_GRP  *pgrp,

                      OS_FLAGS      flags,

                      INT8U         wait_type,

                      INT32U        timeout,

                      INT8U        *perr)

{

    OS_FLAG_NODE  node;

    OS_FLAGS      flags_rdy;

    INT8U         result;

    INT8U         pend_stat;

    BOOLEAN       consume;

#if OS_CRITICAL_METHOD == 3u

    OS_CPU_SR     cpu_sr = 0u;

#endif

#ifdef OS_SAFETY_CRITICAL

if (perr == (INT8U *)0)

{ //perr指针为0

        OS_SAFETY_CRITICAL_EXCEPTION();

    }

#endif

#if OS_ARG_CHK_EN > 0u

if (pgrp == (OS_FLAG_GRP *)0)

 { //pgrp指针为0

        *perr = OS_ERR_FLAG_INVALID_PGRP;

        return ((OS_FLAGS)0);

    }

#endif

if (OSIntNesting > 0u)

{//中断嵌套级别

*perr = OS_ERR_PEND_ISR;

        return ((OS_FLAGS)0);

}

if (OSLockNesting > 0u)

{

        *perr = OS_ERR_PEND_LOCKED;

        return ((OS_FLAGS)0);

}

if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG)

{//若不是事件标志组类型

        *perr = OS_ERR_EVENT_TYPE;

        return ((OS_FLAGS)0);

}

result = (INT8U)(wait_type & OS_FLAG_CONSUME);

//OS_FLAG_CONSUME=0x80

if (result != (INT8U)0)

 {//发现wait_typebit71, 要求清除事件标志位

        wait_type &= (INT8U)~(INT8U)OS_FLAG_CONSUME;

        consume    = OS_TRUE;

}

else

{//发现wait_typebit70, 不要求清除事件标志位

        consume    = OS_FALSE;

    }

    OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量

switch (wait_type)

 {

        case OS_FLAG_WAIT_SET_ALL:

             flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags);

// 根据flags读取事件标志组中的位值

             if (flags_rdy == flags)

 { //接收到的事件信号正确

                 if (consume == OS_TRUE)

{ // wait_typebit7=1,需要清除接收到事件标志

                     pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy;

                 }

                 OSTCBCur->OSTCBFlagsRdy = flags_rdy;

// 保存事件标志组信号,后面需要读回该值

                 OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

                 *perr= OS_ERR_NONE;

                 return (flags_rdy);

             }

 else

 {//接收到的事件信号错误

                 OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);

                 OS_EXIT_CRITICAL();

             }

             break;

        case OS_FLAG_WAIT_SET_ANY:

             flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags);

// 根据flags读取事件标志组中的位值

             if (flags_rdy != (OS_FLAGS)0)

 { //接收到的事件信号正确

                 if (consume == OS_TRUE)

{// wait_typebit7=1,需要清除接收到事件标志

                     pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy;

                 }

                 OSTCBCur->OSTCBFlagsRdy = flags_rdy;

 // 保存事件标志组信号,后面需要读回该值

                 OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

                 *perr = OS_ERR_NONE;

                 return (flags_rdy);

             }

             else

{//接收到的事件信号错误

                 OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);

                 OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

             }

             break;

#if OS_FLAG_WAIT_CLR_EN > 0u

        case OS_FLAG_WAIT_CLR_ALL:

             flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags;

// 根据flags读取事件标志组中的位值

             if (flags_rdy == flags)

 { //接收到的事件信号正确

                 if (consume == OS_TRUE)

{// wait_typebit7=1,需要清除接收到事件标志

                     pgrp->OSFlagFlags |= flags_rdy;

                 }

                 OSTCBCur->OSTCBFlagsRdy = flags_rdy;

// 保存事件标志组信号,后面需要读回该值

                 OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

                 *perr= OS_ERR_NONE;

                 return (flags_rdy);

             }

else

{//接收到的事件信号错误

                 OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);

                 OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

             }

             break;

        case OS_FLAG_WAIT_CLR_ANY:

             flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags;

// 根据flags读取事件标志组中的位值

             if (flags_rdy != (OS_FLAGS)0)

{//接收到的事件信号正确

                 if (consume == OS_TRUE)

{// wait_typebit7=1,需要清除接收到事件标志

                     pgrp->OSFlagFlags |= flags_rdy;

                 }

                 OSTCBCur->OSTCBFlagsRdy = flags_rdy;

 // 保存事件标志组信号,后面需要读回该值

                 OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

                 *perr = OS_ERR_NONE;

                 return (flags_rdy);

             }

else

{//接收到的事件信号错误

                 OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);

                 OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

             }

             break;

#endif

        default:

             OS_EXIT_CRITICAL();

             flags_rdy = (OS_FLAGS)0;

             *perr      = OS_ERR_FLAG_WAIT_TYPE;

             return (flags_rdy);

    }

    OS_Sched(); //任务调度

    OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量

if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK)

 {//若发现超时等待或中止等待

        pend_stat                = OSTCBCur->OSTCBStatPend;

        OSTCBCur->OSTCBStatPend  = OS_STAT_PEND_OK;

        OS_FlagUnlink(&node);

        OSTCBCur->OSTCBStat      = OS_STAT_RDY;

        OS_EXIT_CRITICAL();

        flags_rdy                = (OS_FLAGS)0;

        switch (pend_stat)

 {

            case OS_STAT_PEND_ABORT:

                 *perr = OS_ERR_PEND_ABORT;// 表明中止等待

                 break;

            case OS_STAT_PEND_TO:

            default:

                 *perr = OS_ERR_TIMEOUT; //表明超时等待

                 break;

        }

        return (flags_rdy);

}

/没有发现超时等待或中止等待//

    flags_rdy = OSTCBCur->OSTCBFlagsRdy;//读回保存的事件标志组信号

if (consume == OS_TRUE)

{ // wait_typebit7=1,需要清除接收到事件标志

        switch (wait_type)

{

            case OS_FLAG_WAIT_SET_ALL:

            case OS_FLAG_WAIT_SET_ANY: /* Clear ONLY the flags we got */

                 pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy;

                 break;

#if OS_FLAG_WAIT_CLR_EN > 0u

            case OS_FLAG_WAIT_CLR_ALL:

            case OS_FLAG_WAIT_CLR_ANY: /* Set   ONLY the flags we got */

                 pgrp->OSFlagFlags |=  flags_rdy;

                 break;

#endif

            default:

                 OS_EXIT_CRITICAL();

                 *perr = OS_ERR_FLAG_WAIT_TYPE;

                 return ((OS_FLAGS)0);

        }

}

    OS_EXIT_CRITICAL();

    *perr = OS_ERR_NONE;

    return (flags_rdy);

}

//函数功能:将事件标志组中的标志位置位或清0

pgrp为事件标志组指针

根据flags发送指定的事件标志组的位值

perr = OS_ERR_NONE,表示发送正确,返回值与 flags相与后等于flags;

perr != OS_ERR_NONE,表示发送错误,返回值与 flags相与后不等于flags;

opt 取值为:  opt= OS_FLAG_SETopt=OS_FLAG_CLR

OS_FLAGS  OSFlagPost (OS_FLAG_GRP  *pgrp,

                      OS_FLAGS      flags,

                      INT8U         opt,

                      INT8U        *perr)

{

    OS_FLAG_NODE *pnode;

    BOOLEAN       sched;

    OS_FLAGS      flags_cur;

    OS_FLAGS      flags_rdy;

    BOOLEAN       rdy;

#if OS_CRITICAL_METHOD == 3u

    OS_CPU_SR     cpu_sr = 0u;

#endif

#ifdef OS_SAFETY_CRITICAL

if (perr == (INT8U *)0)

{// perr指针为0

        OS_SAFETY_CRITICAL_EXCEPTION();

    }

#endif

#if OS_ARG_CHK_EN > 0u

if (pgrp == (OS_FLAG_GRP *)0)

{// pgrp指针为0

        *perr = OS_ERR_FLAG_INVALID_PGRP;

        return ((OS_FLAGS)0);

    }

#endif

if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG)

{//若不是事件标志组类型

        *perr = OS_ERR_EVENT_TYPE;

        return ((OS_FLAGS)0);

    }

    OS_ENTER_CRITICAL();

switch (opt)

{

        case OS_FLAG_CLR:

             pgrp->OSFlagFlags &= (OS_FLAGS)~flags;

             //根据flags的值,将pgrp->OSFlagFlags相应的位置0

             break;

        case OS_FLAG_SET:

             pgrp->OSFlagFlags |=  flags;

//根据flags的值,将pgrp->OSFlagFlags相应的位置1

             break;

        default:

             OS_EXIT_CRITICAL();

             *perr = OS_ERR_FLAG_INVALID_OPT;

             return ((OS_FLAGS)0);

}

    sched = OS_FALSE;

    pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;

while (pnode != (OS_FLAG_NODE *)0)

{/* Go through all tasks waiting on event flag(s)  */

        switch (pnode->OSFlagNodeWaitType)

{

            case OS_FLAG_WAIT_SET_ALL:

                 flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & pnode->OSFlagNodeFlags);

                 if (flags_rdy == pnode->OSFlagNodeFlags)

 {

                     rdy = OS_FlagTaskRdy(pnode, flags_rdy);

                     if (rdy == OS_TRUE)

{

                         sched = OS_TRUE;

                     }

                 }

                 break;

            case OS_FLAG_WAIT_SET_ANY:

                 flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & pnode->OSFlagNodeFlags);

                 if (flags_rdy != (OS_FLAGS)0)

 {

                     rdy = OS_FlagTaskRdy(pnode, flags_rdy);

                     if (rdy == OS_TRUE)

{

                         sched = OS_TRUE;

                     }

                 }

                 break;

#if OS_FLAG_WAIT_CLR_EN > 0u

            case OS_FLAG_WAIT_CLR_ALL:

                 flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;

                 if (flags_rdy == pnode->OSFlagNodeFlags)

 {

                     rdy = OS_FlagTaskRdy(pnode, flags_rdy);

                     if (rdy == OS_TRUE)

{

                         sched = OS_TRUE;

                     }

                 }

                 break;

            case OS_FLAG_WAIT_CLR_ANY:

                 flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;

                 if (flags_rdy != (OS_FLAGS)0)

 {

                     rdy = OS_FlagTaskRdy(pnode, flags_rdy);

                     if (rdy == OS_TRUE)

 {

                         sched = OS_TRUE;

                     }

                 }

                 break;

#endif

            default:

                 OS_EXIT_CRITICAL();

                 *perr = OS_ERR_FLAG_WAIT_TYPE;

                 return ((OS_FLAGS)0);

        }

        pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext;

/* Point to next task waiting for event flag(s) */

}

    OS_EXIT_CRITICAL();

if (sched == OS_TRUE)

 {

        OS_Sched();

    }

    OS_ENTER_CRITICAL();

    flags_cur = pgrp->OSFlagFlags;

    OS_EXIT_CRITICAL();

    *perr     = OS_ERR_NONE;

    return (flags_cur);

}

#include "My_Task_Priority.h"

__align(8) OS_STK START_TASK_STACK[START_TASK_STACK_SIZE]; //START_TASK任务堆栈
__align(8) OS_STK LED0_TASK_STACK[LED0_TASK_STACK_SIZE];   //LED0_TASK任务堆栈
__align(8) OS_STK LED1_TASK_STACK[LED1_TASK_STACK_SIZE];   //LED1_TASK任务堆栈
__align(8) OS_STK KEY_TASK_STACK[KEY_TASK_STACK_SIZE];     //KEY_TASK任务堆栈
//如果任务中使用printf来打印浮点数据的话一点要8字节对齐
OS_FLAG_GRP *EventFlags; //事件标志组指针,Event Flag Group
//My_Task_Priority.h
#ifndef __MY_TASK_PRIORITY_H
#define __MY_TASK_PRIORITY_H

#include "includes.h"

//当OS_LOWEST_PRIO=63时,μC/OS-II有64个优先级,优先级的高低按编号从0(最高)到63(最低)排序;
//OS_TASK_IDLE_PRIO为63,是空闲任务优先级,OS_TASK_IDLE_ID为65535
//OS_TASK_STAT_PRIO为62,是统计任务优先级,OS_TASK_STAT_ID为65534
//uCOSii至少有两个任务,分别是"空闲任务"和"统计任务"
/*
为了保证“启动任务”能够连续运行,必须将“启动任务”的优先级选择为最高。
否则,当“启动任务”创建一个优先级高于自己的任务时,刚刚创建的任务就
会立即进入运行状态,而与这个任务关联的其它任务可能还没有创建,它使
用的通信工具也还没有创建,系统必然出错。
*/

#define START_TASK_PRIORITY      4   //设置START_TASK任务优先级,开始任务的优先级设置为最高
#define START_TASK_STACK_SIZE   192  //设置START_TASK任务堆栈大小,为8的倍数
extern OS_STK START_TASK_STACK[START_TASK_STACK_SIZE]; //START_TASK任务堆栈

#define LED0_TASK_PRIORITY       5   //设置LED0_TASK任务优先级为5
#define LED0_TASK_STACK_SIZE  	 56  //设置LED0_TASK任务堆栈大小为56,为8的倍数
extern OS_STK LED0_TASK_STACK[LED0_TASK_STACK_SIZE];  //LED0_TASK任务堆栈

#define LED1_TASK_PRIORITY       6   //设置LED1_TASK任务优先级为6
#define LED1_TASK_STACK_SIZE  	 72  //设置LED1_TASK任务堆栈大小为72,为8的倍数
extern OS_STK LED1_TASK_STACK[LED1_TASK_STACK_SIZE];  //LED1_TASK任务堆栈

#define KEY_TASK_PRIORITY        7   //设置KEY_TASK任务优先级为7 
#define KEY_TASK_STACK_SIZE      56  //设置KEY_TASK任务堆栈大小为56,为8的倍数
extern OS_STK KEY_TASK_STACK[KEY_TASK_STACK_SIZE];    //KEY_TASK任务堆栈

extern OS_FLAG_GRP *EventFlags; //事件标志组指针,Event Flag Group

/OS_FLAGS数据的位数///
//在os_cfg.h中定义OS_FLAGS_NBITS=16,表示"OS_FLAGS数据的位数为16"
#define KEY0_FLAG		0x0001  //KEY0位于bit0
#define KEY1_FLAG		0x0002  //KEY1位于bit1
#define KEY2_FLAG		0x0004  //KEY2位于bit2
#define KEY3_FLAG		0x0008  //KEY3位于bit3
#define KEY4_FLAG		0x0010  //KEY4位于bit4
#define KEY5_FLAG		0x0020  //KEY5位于bit5
#define KEY6_FLAG		0x0040  //KEY6位于bit6
#define KEY7_FLAG		0x0080  //KEY7位于bit7
#define KEY8_FLAG		0x0001  //KEY8位于bit8
#define KEY9_FLAG		0x0002  //KEY9位于bit9
#define KEY10_FLAG	0x0004  //KEY10位于bit10
#define KEY11_FLAG	0x0008  //KEY11位于bit11
#define KEY12_FLAG	0x0010  //KEY12位于bit12
#define KEY13_FLAG	0x0020  //KEY13位于bit13
#define KEY14_FLAG	0x0040  //KEY14位于bit14
#define KEY15_FLAG	0x0080  //KEY15位于bit15

#endif
#include "Start_Task.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()

#include "LED.h"
#include "key.h"

#include "My_Task_Priority.h"
#include "LED0_Task.h"
#include "LED1_Task.h"
#include "Key_Task.h"

void Start_Task(void *pdata);

const char Start_Task_rn_REG[]="\r\n";
const char Start_Task_Initialise_REG[]="Start_Task Initialise";
//Start_Task任务
void Start_Task(void *pdata)
{
	OS_CPU_SR cpu_sr=0;
	u8 err;

	pdata = pdata;

	printf("%s",Start_Task_rn_REG);
	printf("%s",Start_Task_Initialise_REG);

	LED0_Init();
	LED1_Init();
	KEY_Init();

	OS_ENTER_CRITICAL();   //进入临界区(无法被中断打断),需要定义cpu_sr变量
	EventFlags=OSFlagCreate(0,&err);
	//建立一个事件标志组

	OSTaskCreate( LED0_Task,/* 函数指针*/
	              (void *)0,/* 建立任务时,传递的参数*/
								(OS_STK*)&LED0_TASK_STACK[LED0_TASK_STACK_SIZE-1],/* 指向堆栈任务栈顶的指针*/
								LED0_TASK_PRIORITY/* 任务优先级*/
							);						   
	OSTaskCreate( LED1_Task,/* 函数指针*/
	              (void *)0,/* 建立任务时,传递的参数*/
								(OS_STK*)&LED1_TASK_STACK[LED1_TASK_STACK_SIZE-1],/* 指向堆栈任务栈顶的指针*/
								LED1_TASK_PRIORITY/* 任务优先级*/
							);
	OSTaskCreate( Key_Task,/* 函数指针*/
								(void *)0,/* 建立任务时,传递的参数*/
								(OS_STK*)&KEY_TASK_STACK[KEY_TASK_STACK_SIZE-1],/* 指向堆栈任务栈顶的指针*/
								KEY_TASK_PRIORITY/* 任务优先级*/
							);
	
	//OSTaskSuspend(START_TASK_PRIO);	//挂起起始任务Start_Task(),但不删除
	OSTaskDel(OS_PRIO_SELF); //删除自己
	OS_EXIT_CRITICAL();		//退出临界区(可以被中断打断)
}
#include "LED0_Task.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()

#include "LED.h"

#include "My_Task_Priority.h"

void LED0_Task(void *pdata);

const char LED0_Task_rn_REG[]="\r\n";
const char LED0_Task_Initialise_REG[]="LED0_Task Initialise";
//LED0_Task任务
void LED0_Task(void *pdata)
{
	u8 err;
	OS_FLAGS retFlag,inputFlag;

	printf("%s",LED0_Task_rn_REG);
	printf("%s",LED0_Task_Initialise_REG);
	while(1)
	{
		inputFlag=(OS_FLAGS)(KEY0_FLAG|KEY2_FLAG);
//		retFlag=OSFlagPend(
//		            EventFlags,//事件标志组指针&err
//		            inputFlag,//接收"事件标志组的第0位和第2位"
//		            OS_FLAG_WAIT_SET_AND,//若"事件标志组的第0位和第2位"同时置为1时为有效,否则将任务挂在这里
//		            0,//无限等待,直到收到为止
//		            &err );
//		printf("LED0事件标志组EventFlags的值:%d\r\n",retFlag);
//		LED0=!LED0;
//		OSFlagPost(
//		            EventFlags,//事件标志组指针
//		            (OS_FLAGS)KEY0_FLAG,//给事件标志组的第0位发信号
//		            OS_FLAG_CLR,//将事件标志组的第0位置0
//		            &err
//		          );
//		if( err==OS_ERR_NONE && (retFlag&KEY0_FLAG)==KEY0_FLAG)//事件标志发送正确
//		{
//		}

		retFlag=OSFlagAccept(
		            EventFlags,//事件标志组指针&err
		            inputFlag,//接收"事件标志组的第0位和第2位"
		            OS_FLAG_WAIT_SET_AND,//若"事件标志组的第0位和第2位"同时置为1时为有效,否则将任务挂在这里
		            &err );
		if( err==OS_ERR_NONE && (inputFlag&retFlag)==inputFlag)//接收正确
		{
		  printf("LED0事件标志组EventFlags的值:%d\r\n",retFlag);
		  LED0=!LED0;
			inputFlag=KEY0_FLAG;
		  retFlag=OSFlagPost(
		            EventFlags,//事件标志组指针
		            inputFlag,//给事件标志组的第0位发信号
		            OS_FLAG_CLR,//将事件标志组的第0位置0
		            &err
		          );
		  if( err==OS_ERR_NONE && (retFlag&inputFlag)==inputFlag)//事件标志发送正确
		  {
		  }
		}

		OSTimeDlyHMSM(0,0,0,500);//延时500ms
	}
}
#include "LED1_Task.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()

#include "LED.h"

#include "My_Task_Priority.h"

void LED1_Task(void *pdata);

const char LED1_Task_rn_REG[]="\r\n";
const char LED1_Task_Initialise_REG[]="LED1_Task Initialise";
//LED1_Task任务
void LED1_Task(void *pdata)
{
	u8 err;
	OS_FLAGS retFlag,inputFlag;

	printf("%s",LED1_Task_rn_REG);
	printf("%s",LED1_Task_Initialise_REG);

	while(1)
	{
		inputFlag=KEY2_FLAG;
		//若等待事件标志没有发生 该函数挂起该任务
		retFlag=OSFlagPend(
		            EventFlags,//事件标志组指针
		            inputFlag,//接收"事件标志组的第2位"
		            OS_FLAG_WAIT_SET_ALL,//若"事件标志组的第2位"置为1时为有效,否则将任务挂在这里
		            0,//无限等待,直到收到为止
		            &err );

		printf("LED1事件标志组EventFlags的值:%d\r\n",retFlag);
		LED1=!LED1;
		retFlag=OSFlagPost(
		            EventFlags,//事件标志组指针
		            inputFlag,//给事件标志组的第2位发信号
		            OS_FLAG_CLR,//将事件标志组的第2位置0
		            &err
		          );
		if( err==OS_ERR_NONE && (retFlag&inputFlag)==inputFlag)//事件标志发送正确
		{
		}

		OSTimeDlyHMSM(0,0,0,200);//延时200毫秒
	}
}
#include "Key_Task.h"
#include "delay.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()

#include "key.h"

#include "My_Task_Priority.h"
#include "LED1_Task.h"

const char Key_Task_rn_REG[]="\r\n";
const char Key_Task_Initialise_REG[]="Key_Task Initialise";
void Key_Task(void *pdata);
	
//Key_Task任务
void Key_Task(void *pdata)
{	
	u8 key,err;
	OS_FLAGS retFlag,inputFlag;

	printf("%s",Key_Task_rn_REG);
	printf("%s",Key_Task_Initialise_REG);

	while(1)
	{
		key=KEY_Scan(0);
		if(key==Cursor_Up)
		{
			inputFlag=KEY0_FLAG;
			retFlag=OSFlagPost(
			            EventFlags,//事件标志组指针
			           (OS_FLAGS)inputFlag,//给事件标志组的第0位发信号
			            OS_FLAG_SET,//将事件标志组的第0位置1
			            &err );
			if( err==OS_ERR_NONE && (inputFlag&retFlag)==inputFlag)//事件标志发送正确
			printf("\r\nKey事件标志组EventFlags的值:%d\r\n",retFlag);
		}
		else if (key==Cursor_Down)
		{
			inputFlag=KEY2_FLAG;
			retFlag=OSFlagPost(
			            EventFlags,//事件标志组指针
			            inputFlag,//给事件标志组的第2位发信号
			            OS_FLAG_SET,//将事件标志组的第2位置1
			            &err );
			if( err==OS_ERR_NONE && (retFlag&inputFlag)==inputFlag )//事件标志发送正确
			printf("\r\nKey事件标志组EventFlags的值:%d\r\n",retFlag);
		}
		else if (key==Cursor_Left)
		{
			inputFlag=(OS_FLAGS)(KEY0_FLAG|KEY2_FLAG);
			retFlag=OSFlagPost(
			            EventFlags,//事件标志组指针
			            inputFlag,//给事件标志组的第0位和第2位发信号
			            OS_FLAG_SET,//将事件标志组的第0位和第2位置1
			            &err );
			if( err==OS_ERR_NONE && (inputFlag&retFlag)==inputFlag)//事件标志发送正确
			printf("\r\nKey事件标志组EventFlags的值:%d\r\n",retFlag);
		}  

		OSTimeDlyHMSM(0,0,0,500);//延时500ms
	}
}
#include "LED.h"

void LED0_Init(void)
{
	GPIO_InitTypeDef   GPIO_InitStructure;
  //使用GPIO_InitTypeDef定义一个结构变量GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOE, ENABLE ); //在配置外设之前,必须先使能GPIOE的外设时钟
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;             //选择第4脚
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;     //设置引脚的最高输出速率为50MHz
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;      //设置引脚工作模式为推挽输出方式
	GPIO_Init( GPIOE, &GPIO_InitStructure);             //根据GPIO_InitStructure结构变量指定的参数初始化GPIOE的外设寄存器
}

void LED1_Init(void)
{
	GPIO_InitTypeDef   GPIO_InitStructure;
  //使用GPIO_InitTypeDef定义一个结构变量GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); //使能GPIOE的外设时钟
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;             //选择第5脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      //设置引脚工作模式为推挽输出方式
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //设置引脚的最高输出速率为50MHz
	GPIO_Init(GPIOE, &GPIO_InitStructure);
	//根据GPIO_InitStructure结构变量指定的参数初始化GPIOE的外设寄存器
}

void LED_Init(void)
{
	LED0_Init();
	LED1_Init();
}
#include "KEY.h"
#include "delay.h"

void KEY_Init(void);
u8 KEY_Scan(u8 mode);

//函数功能:将PB12,PB13,PB14,PB15,PD8初始化为输入口
void KEY_Init(void)
{
	GPIO_InitTypeDef   GPIO_InitStructure;
  //使用GPIO_InitTypeDef定义一个结构变量GPIO_InitStructure;

	RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOB, ENABLE ); //在配置外设之前,必须先使能GPIOB的外设时钟
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;  //选择第12,13,14和15脚
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置引脚的最高输出速率为50MHz
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;     //输入上拉,按钮输入低电平有效
  GPIO_Init( GPIOB, &GPIO_InitStructure); 
  //根据GPIO_InitStructure结构变量指定的参数初始化GPIOB的外设寄存器

	RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOD, ENABLE ); //在配置外设之前,必须先使能GPIOD的外设时钟
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;                  //选择第8脚
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;          //设置引脚的最高输出速率为50MHz
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;              //输入上拉,按钮输入低电平有效
  GPIO_Init( GPIOD, &GPIO_InitStructure); 
  //根据GPIO_InitStructure结构变量指定的参数初始化GPIOD的外设寄存器
}

//函数功能:按键扫描,按键检测时间为50ms
u8 KEY_Scan(u8 mode)
{
 u8 i;
 u8 ch0;
 u8 ch1;
 u8 retData;

 static u8 key_backup=1;//记录按键被释放

 if(mode == 1) key_backup=1;//记录按键被释放

 retData=0;//假定无按键按下
 ch0=0;ch1=0;
 if(key_backup==1)
 {
   if( KEY2==0) ch0=Cursor_Right; //记录按键值
   if( KEY3==0) ch0=Cursor_Up;    //记录按键值
   if( KEY1==0) ch0=Cursor_Left;  //记录按键值
   if( KEY4==0) ch0=Cursor_Down;  //记录按键值
   if( KEY5==0) ch0=OK;           //记录按键值
 }
 if(ch0) i=0;
 else i=200;

 for(;i<20;)
 {
  i++;
  ch1=0;

    delay_ms(5);

   if(KEY2==0)  ch1=Cursor_Right; //记录按键值,向右
   if(KEY3==0) ch1=Cursor_Up;   //记录按键值,向上
   if(KEY1==0) ch1=Cursor_Left; //记录按键值,向左
   if(KEY4==0) ch1=Cursor_Down; //记录按键值,向下
   if(KEY5==0) ch1=OK;          //记录按键值,确认
   if(ch1!=ch0) i=100;
 }
 if(i==20) retData=ch0;
 else retData=0;

	ch1=0;
	if(KEY1==1) ch1=1;
	if(KEY2==1) ch1=(u8)(ch1<<1);
	if(KEY3==1) ch1=(u8)(ch1<<1);
	if(KEY4==1) ch1=(u8)(ch1<<1);
	if(KEY5==1) ch1=(u8)(ch1<<1);
	if(ch1==0x20) key_backup=1;//记录按键被释放

	return retData;
}
#ifndef __KEY_H
#define __KEY_H	

#include "stm32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
#include "sys.h"  //启用bool定义

/宏定义/
#define Cursor_Left	  	1
#define Cursor_Right		2
#define Cursor_Up			  3
#define Cursor_Down			4
#define OK	      			5

#define KEY3  PBin(14)   		//PB14,向上
#define KEY4  PBin(13)   		//PB13,向下
#define KEY1  PBin(15)   		//PB15,向左
#define KEY2  PDin(8)   		//PD8,向右
#define KEY5  PBin(12)   		//PB12,确认

extern void KEY_Init(void);
extern u8 KEY_Scan(u8 mode);
#endif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/577159.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot整合百度云人脸识别功能

SpringBoot整合百度云人脸识别功能 1.在百度官网创建应用 首先需要在百度智能云官网中创建应用&#xff0c;获取AppID&#xff0c;API Key&#xff0c;Secret Key 官网地址&#xff1a;https://console.bce.baidu.com/ 2.添加百度依赖 添加以下依赖即可。其中版本号可在mav…

【问卷分析】调节效应检验的操作①

文章目录 1.首先要明白自己的调节和自变量是什么类别的2.实操演练2.1 当调节变量是连续变量时2.1.1 将ml中心化2.1.2 使用分层回归探讨自变量和ml的交互对adh的影响2.1.3 结果解读 1.首先要明白自己的调节和自变量是什么类别的 2.实操演练 在本次演练中&#xff0c;我们以自变…

马斯克要用人工智能对抗人工智能

导读&#xff1a;马斯克对人工智能可能变得失控并“摧毁人类”的担忧促使他采取行动&#xff0c;发起了一个名为“TruthGPT”的项目。 本文字数&#xff1a;1400&#xff0c;阅读时长大约&#xff1a;9分钟 亿万富翁埃隆马斯克在谈到人工智能&#xff08;AI&#xff09;的危险时…

瑞合信LED字幕WiFi卡使用教程(8.0版)

请按照提示下载和安装软件&#xff0c;同时请允许所有权限&#xff0c;如下图&#xff1b; 也可以在各大主流应用商店&#xff08;华为、小米、OPPO、vivo、App Store等&#xff09;搜索“瑞合信”直接安装。 首次使用APP时会提示注册登录软件&#xff0c;你可以选择“使用微信…

深度学习进阶篇-预训练模型[4]:RoBERTa、SpanBERT、KBERT、ALBERT、ELECTRA算法原理模型结构应用场景区别等详解

【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍&#xff1a;【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化…

Full-Scanner是一个多功能扫描工具,支持被动/主动信息收集,漏洞扫描工具联动,可导入POC和EXP

github项目地址&#xff1a;https://github.com/Zhao-sai-sai/Full-Scanner gitee项目地址&#xff1a;https://gitee.com/wZass/Full-Scanner 工具简介 做挖漏洞渗透测试有的时候要去用这个工具那个工具去找感觉麻烦我自己就写了一个简单的整合工具&#xff0c;有互联网大佬不…

Presto之BroadCast Join的实现

一. 前言 在Presto中&#xff0c;Join的类型主要分成Partitioned Join和Broadcast Join&#xff0c;在Presto 之Hash Join的Partition_王飞活的博客-CSDN博客 中已经介绍了Presto的Partitioned Join的实现过程&#xff0c;本文主要介绍Broadcast Join的实现。 二. Presto中Broa…

ChatGPT免费使用的方法有哪些?

目录 一、ChatGpt是什么&#xff1f; 二、ChatGPT国内免费使用的方法&#xff1a; 第一点&#xff1a;电脑端 第二点&#xff1a;手机端 三、结语&#xff1a; 一、ChatGpt是什么&#xff1f; ChatGPt是美国OpenAI [1] 研发的聊天机器人程序 。更是人工智能技术驱动的自然语…

1. 从JDK源码级别彻底刨析JVM类加载机制

JVM性能调优 1. 类加载的运行全过程1.1 加载1.2 验证1.3 准备1.4 解析 本文是按照自己的理解进行笔记总结&#xff0c;如有不正确的地方&#xff0c;还望大佬多多指点纠正&#xff0c;勿喷。 课程内容: 1、从java.exe开始讲透Java类加载运行全过程 2、从JDK源码级别剖析JVM核…

【地铁上的面试题】--基础部分--数据结构与算法--数组和链表

零、章节简介 《数据结构与算法》是《地铁上的面试题》专栏的第一章&#xff0c;重点介绍了技术面试中不可或缺的数据结构和算法知识。数据结构是组织和存储数据的方式&#xff0c;而算法是解决问题的步骤和规则。 这一章的内容涵盖了常见的数据结构和算法&#xff0c;包括数组…

DevOps工作级开发者认证——软件发展

. 本文先从软件产业的现状、发展趋势及挑战&#xff0c;说明敏捷和DevOps必将成为业界主流的研发模式。接着介绍和阐述了敏捷和DevOps的关系&#xff0c;相关理念、价值和主要工程方法。最后重点介绍了某著名公司端到端DevOps的实施框架及其主要内容。 本文的目的&#…

javascript基础八:JavaScript原型,原型链 ? 有什么特点?

一、原型 JavaScript 常被描述为一种基于原型的语言——每个对象拥有一个原型对象 当试图访问一个对象的属性时&#xff0c;它不仅仅在该对象上搜寻&#xff0c;还会搜寻该对象的原型&#xff0c;以及该对象的原型的原型&#xff0c;依次层层向上搜索&#xff0c;直到找到一个…

15_Linux工程目录与顶层Makefile

目录 Linux 工程目录分析 顶层Makefile详解 make xxx_defconfig过程 Makefile.build脚本分析 make过程 built-in.o文件编译生成过程 make zImage过程 Linux 工程目录分析 将正点原子提供的Linux源码进行解压,解压完成以后的目录如图所示: 图就是正点原子提供的未编译的…

【数据分类】GRNN数据分类 广义回归神经网络数据分类【Matlab代码#30】

文章目录 【可更换其他算法&#xff0c;获取资源请见文章第6节&#xff1a;资源获取】1. 数据分类问题2. 广义回归神经网络&#xff08;GRNN&#xff09;3. 基于GRNN的数据分类步骤4. 部分代码展示5. 仿真结果展示6. 资源获取说明 【可更换其他算法&#xff0c;获取资源请见文章…

八大排序算法-直接插入排序、希尔排序、直接选择排序、冒泡排序、堆排序、快速排序、归并排序、基数排序(下)

目录 前言冒泡排序&#xff08;Bubble Sort&#xff09;一、概念二、实现思路三、图示过程四、案例分析1、图示过程2、第一趟排序示例 五、代码1、代码示例2、代码解释3、运行结果 六、复杂度 快速排序&#xff08;QuickSort&#xff09;一、概念二、实现思路三、图示过程四、代…

【C++学习第十二讲】C++ 常量

文章目录 一、前言二、整数常量三、浮点常量四、布尔常量五、字符常量六、字符串常量七、定义常量7.1 #define 预处理器7.2 const 关键字 一、前言 常量是固定值&#xff0c;在程序执行期间不会改变。这些固定的值&#xff0c;又叫做字面量。 常量可以是任何的基本数据类型&a…

202312读书笔记|《赶时间的人》——灰暗的从前会成为照亮未来的光,艰难的生活里,诗歌是那陡峭的另一面

202312读书笔记|《赶时间的人》——灰暗的从前会成为照亮未来的光&#xff0c;艰难的生活里&#xff0c;诗歌是那陡峭的另一面 《赶时间的人》 作者王计兵&#xff0c;一个外卖员的诗&#xff0c;饱含对生活的热情&#xff0c;向上的力量&#xff0c;仿若身在炼狱&#xff0c;心…

【014】C++数组之一维字符数组和二维字符数组

C数组之一维字符数组和二维字符数组 引言一、一维字符数组1.1、一维字符数组的初始化1.2、字符数组的遍历1.3、从键盘获取字符串1.4、使用示例 二、二维字符数组2.1、定义2.2、初始化2.3、访问 总结 引言 &#x1f4a1; 作者简介&#xff1a;专注于C/C高性能程序设计和开发&…

KVM虚拟化技术学习-基础入门

1.虚拟化技术概述 虚拟化[Virtualization]技术最早出现在 20 世纪 60 年代的 IBM ⼤型机系统&#xff0c;在70年代的 System 370 系列中逐渐流⾏起来&#xff0c;这些机器通过⼀种叫虚拟机监控器[Virtual Machine Monitor&#xff0c;VMM]的程序 在物理硬件之上⽣成许多可以运⾏…

Windows下Pycharm2022如何使用Centos7中的虚拟环境 venv 实现文件实时同步

前期准备 Windows 与 Centos 怎么搞共享文件夹&#xff0c;之前写了一篇&#xff0c;这里直接引用 hyperf 关于配置yasd调试器进行远程调试 swoole sdebug调试 windowlinux 共享文件夹开发汇总_森叶的博客-CSDN博客yasd github下载链接&#xff1a;https://github.com/swoole…