uCOSii任务管理

news2024/11/23 22:05:59

uCOSii任务管理

主要用来测试uCOSii“创建任务,挂起任务,恢复任务,发送删除任务请求,删除任务”。

在os_cfg.h中

#define OS_LOWEST_PRIO     63u

//设置最低优先级为63,则空闲任务优先级OS_TASK_IDLE_PRIO就等于63

//OS_PRIO_SELF为255,因此OS_LOWEST_PRIO<255

注意:

当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。

因此μC/OS-II至少有两个任务,分别是"空闲任务"和"统计任务"。

#define OS_MAX_TASKS     5u

//设置"我的任务总数"为5,其中有两个任务分别是"空闲任务"和"统计任务",因此用户可以占用另外3个任务。

μC/OS-II内部任务堆栈大小定义

#define OS_TASK_TMR_STK_SIZE    128u

//设置"定时器任务堆栈大小"为128,由于它是一个硬件定时器,因此没有优先级,但它有一个任务ID,OS_TASK_TMR_ID为65533

#define OS_TASK_STAT_STK_SIZE   128u

//设置"统计任务堆栈大小"为128,统计任务优先级OS_TASK_STAT_PRIO为62,任务ID为OS_TASK_IDLE_ID,其值为65535

#define OS_TASK_IDLE_STK_SIZE   128u

//设置"空闲任务堆栈大小"为128,空闲任务优先级OS_TASK_IDLE_PRIO为63,其任务ID为OS_TASK_STAT_ID,其值为65534

μC/OS-II任务管理

#define OS_TASK_CHANGE_PRIO_EN    1u

//使能"改变任务优先级函数"OSTaskChangePrio()

#define OS_TASK_CREATE_EN         1u

//使能"创建任务函数"OSTaskCreate()

#define OS_TASK_CREATE_EXT_EN     1u

//使能"创建扩展任务函数"OSTaskCreateExt()

#define OS_TASK_DEL_EN            1u

//使能"删除任务函数"OSTaskDel()

#define OS_TASK_NAME_EN           1u

//使能任务名Enable task names

#define OS_TASK_PROFILE_EN        1u

//使能OS_TCB 结构内部某些变量

#define OS_TASK_QUERY_EN          1u

//使能"获取任务信息函数OSTaskQuery()"

#define OS_TASK_REG_TBL_SIZE      1u

//设置任务变量数组OSTCBRegTbl[]的大小,每个元素为INT32U型

#define OS_TASK_STAT_EN           1u

//使能统计任务函数OSTaskStat(),统计任务每秒运行一次,计算当前系统CPU使用率,结果保存在8位变量OSCPUUsage中

#define OS_TASK_STAT_STK_CHK_EN   1u

//使能检查"统计任务"任务栈的函数OS_TaskStatStkChk()

#define OS_TASK_SUSPEND_EN        1u

//使能挂起任务函数OSTaskSuspend()和恢复任务OSTaskResume()

#define OS_TASK_SW_HOOK_EN        1u

//使能"任务切换函数OSTaskSwHook()"

1My_Task_Priority.c文件如下:

#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字节对齐

#define OS_TICK_STEP_EN           1u

// Enable tick stepping feature for uC/OS-View

#define OS_TICKS_PER_SEC       100u

//设置OSTimeDlyHMSM()函数中每秒的节拍数

2My_Task_Priority.h文件如下:

#ifndef __MY_TASK_PRIORITY_H

#define __MY_TASK_PRIORITY_H

#include "includes.h"

/*

为了保证“启动任务”能够连续运行,必须将“启动任务”的优先级选择为最高。

否则,当“启动任务”创建一个优先级高于自己的任务时,刚刚创建的任务就

会立即进入运行状态,而与这个任务关联的其它任务可能还没有创建,它使

用的通信工具也还没有创建,系统必然出错。

*/

#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任务堆栈

#endif

3Start_Task.c文件如下:

#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;

    pdata = pdata;

    printf("%s",Start_Task_rn_REG);

    printf("%s",Start_Task_Initialise_REG);

    LED0_Init();

    LED1_Init();

    KEY_Init();

//OSTaskCreate()建立一个新任务.可以在多任务环境启动之前.或者运行任务中建立任务;

//注意:ISR中禁止建立任务,一个任务必须为无限循环结构;

    OS_ENTER_CRITICAL();

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

    OSTaskCreate( LED0_Task,

                  (void *)0,

                   (OS_STK*)&LED0_TASK_STACK[LED0_TASK_STACK_SIZE-1],

                  LED0_TASK_PRIORITY

              );  //创建LED0_Task任务    

             

    OSTaskCreate( LED1_Task,

                  (void *)0,

                  (OS_STK*)&LED1_TASK_STACK[LED1_TASK_STACK_SIZE-1],

                            LED1_TASK_PRIORITY

              ); //创建LED1_Task任务 

    OSTaskCreate( Key_Task,

                   (void *)0,

                  (OS_STK*)&KEY_TASK_STACK[KEY_TASK_STACK_SIZE-1],

                  KEY_TASK_PRIORITY

              ); //创建Key_Task任务  

   

//OSTaskSuspend(START_TASK_PRIO);  //挂起起始任务Start_Task()

    OSTaskDel (OS_PRIO_SELF); //删除自己

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

}

4Start_Task.h文件如下:

#ifndef __Start_Task_H

#define __Start_Task_H

#include "includes.h"

extern void Start_Task(void *pdata);

#endif

5main.c文件如下:

#include "stm32f10x.h"

//使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,

//使能int16_t,int32_t,int64_t

#include "includes.h"

#include "USART1.h"

#include "My_Task_Priority.h"

#include "Start_Task.h"

//创建任务,挂起任务,恢复任务,发送删除任务请求,删除任务

const char CPU_Reset_REG[]="\r\nCPU reset!\r\n";

int main(void)

{

    SystemInit();   //系统初始化72M

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

    USART1_Serial_Interface_Enable(115200);

    printf("%s",CPU_Reset_REG);//调试串口输出"\r\nCPU reset!\r\n"

    SysRstSrcRecord();//系统复位记录

    OSInit();//初始化UCOS-II函数

  OSTaskCreate(Start_Task,(void *)0,(OS_STK *)&START_TASK_STACK[START_TASK_STACK_SIZE-1],START_TASK_PRIORITY );

//创建启动任务

    OSStart();//启动操作系统,开始对任务进行调度管理

}

6LED0_Task.c文件如下:

#include "LED0_Task.h"

#include "stdio.h" 

//使能getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()

#include "LED.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)

{

    printf("%s",LED0_Task_rn_REG);

    printf("%s",LED0_Task_Initialise_REG);

    while(1)

    {

       LED0=!LED0;

       OSTimeDlyHMSM(0,0,0,500);

//500ms闪烁一次,前面“设置OSTimeDlyHMSM()函数中每秒的节拍数为100”

    }

}

7LED0_Task.h文件如下:

#ifndef __LED0_Task_H

#define __LED0_Task_H

#include "includes.h"

extern void LED0_Task(void *pdata);

#endif

8LED1_Task.c文件如下:

#include "LED1_Task.h"

#include "stdio.h" 

//使能getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()

#include "LED.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)

{

    printf("%s",LED1_Task_rn_REG);

    printf("%s",LED1_Task_Initialise_REG);

    while(1)

    {

       if(OSTaskDelReq(OS_PRIO_SELF)==OS_ERR_TASK_DEL_REQ)

       {

           OSTaskDel (OS_PRIO_SELF); //删除自己

       }

       else

       {

         LED1=!LED1;

         OSTimeDlyHMSM(0,0,0,200);

//500ms闪烁一次,前面“设置OSTimeDlyHMSM()函数中每秒的节拍数为100”

       }

    }

}

9LED1_Task.h文件如下:

#ifndef __LED1_Task_H

#define __LED1_Task_H

#include "includes.h"

extern void LED1_Task(void *pdata);

#endif

10Key_Task.c文件如下:

#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);

   

void Key_Task(void *pdata)

{  

    u8 key;

    printf("%s",Key_Task_rn_REG);

    printf("%s",Key_Task_Initialise_REG);

    while(1)

    {

       key=KEY_Scan(0);

       if(key==Cursor_Up)

       {

         OSTaskSuspend(LED0_TASK_PRIORITY);

//挂起LED0任务,LED停止闪烁

           OSTaskCreate(LED1_Task,(void *)0,(OS_STK*)&LED1_TASK_STACK[LED1_TASK_STACK_SIZE-1],LED1_TASK_PRIORITY);

//重新创建任务LED1  

       }

       else if (key==Cursor_Down)

       {

           OSTaskResume(LED0_TASK_PRIORITY);

//恢复LED0任务,LED恢复闪烁

       }

       else if (key==Cursor_Left)

       {

           OSTaskDelReq(LED1_TASK_PRIORITY); 

           //发送删除LED1任务请求

       } 

       OSTimeDlyHMSM(0,0,0,100);

//延时100ms,前面“设置OSTimeDlyHMSM()函数中每秒的节拍数为100”

    }

}

11Key_Task.h文件如下:

#ifndef __Key_Task_H

#define __Key_Task_H

#include "includes.h"

extern void Key_Task(void *pdata);

#endif

12LED.c文件如下:

#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();

}

13LED.h文件如下:

#ifndef _LED_H

#define _LED_H

#include "stm32f10x.h"

#include "sys.h"

#define LED0    PEout(4)  //PE4

#define LED1    PEout(5)  //PE5

#define LED0_OFF() GPIO_SetBits(GPIOE,GPIO_Pin_4)  //定义LED0关闭

#define LED0_ON() GPIO_ResetBits(GPIOE,GPIO_Pin_4) //定义LED0点亮

#define LED1_OFF() GPIO_SetBits(GPIOE,GPIO_Pin_5)  //定义LED1关闭

#define LED1_ON() GPIO_ResetBits(GPIOE,GPIO_Pin_5) //定义LED1点亮

extern void LED0_Init(void);

extern void LED1_Init(void);

extern void LED_Init(void); /* LED 端口初始化 */

#endif

14KEY.c文件如下:

#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;

}

15KEY.h文件如下

#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

16USART1.c文件如下:

#include "USART1.h"

#include "stdio.h"

void USART1_GPIO_Config(void);

void USART1_NVIC_Cpnfig(void);

void USART1_Mode_Cpnfig(unsigned int bound);

void USART1_SendByte(  unsigned char ch );

void USART1_SendString(  char *str);

void USART1_Serial_Interface_Enable(unsigned int bound);

//函数功能:USART1的IO口配置

void USART1_GPIO_Config(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

//设置USART1的APB2外设时钟

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 

//使能GPIOA时钟

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9;

//选择PIN9,是USART1的TXD

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

//设置引脚为复用推挽输出  

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

//设置引脚的最高工作速率为50MHz

  GPIO_Init(GPIOA, &GPIO_InitStructure);

   

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10;

//选择PIN10,是USART1的RXD

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

//设置引脚为输入悬浮 

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

//设置引脚的最高工作速率为50MHz

  GPIO_Init(GPIOA, &GPIO_InitStructure);

}

//函数功能:USART1 NVIC 配置

void USART1_NVIC_Cpnfig(void)

{

    NVIC_InitTypeDef NVIC_InitStructure;

//NVIC_PriorityGroup_4设置NVIC中断分组4:表示抢占优先级为4位,取值为0~15,没有响应优先级,取值为0

//NVIC_PriorityGroup_3设置NVIC中断分组3:表示抢占优先级为3位,取值为0~7,响应优先级只有1位,取值为0~1

//NVIC_PriorityGroup_2设置NVIC中断分组3:表示抢占优先级为2位,取值为0~3,响应优先级只有2位,取值为0~3

//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4

   

    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

//选择中断源为USART1

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;

//抢占优先级7

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

//子优先级0 

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

//IRQ通道使能

  NVIC_Init(&NVIC_InitStructure);

}

//函数功能:USART1配置:波特率为9600,数字为8位,停止位为1位,无奇偶校验,允许发送和接收数据,允许中断,使能串口模块

void USART1_Mode_Cpnfig(unsigned int bound)

{

    USART_InitTypeDef USART_InitStructure;

   

    USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;

    USART_InitStructure.USART_WordLength = USART_WordLength_8b;

    USART_InitStructure.USART_StopBits = USART_StopBits_1;

    USART_InitStructure.USART_Parity = USART_Parity_No ;

    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_Init(USART1, &USART_InitStructure);

   

//USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启接收中断

//当开启串口中断,一定要写其中断服务程序,否则可能会导致FreeRTOS的任务不执行

    USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);//开启接收中断

//当开启串口中断,一定要写其中断服务程序,否则可能会导致uCOS的任务不执行

    USART_Cmd(USART1, ENABLE); //使能串口

}

//函数功能:串口4发送一个字节

void USART1_SendByte(  unsigned char ch )

{

  USART_SendData(USART1, ch);

  while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);

//等待发送完成标志位被置1  

}

//函数功能:串口4发送字符串

void USART1_SendString(  char *str)

{

  unsigned int k=0;

  do{

      USART1_SendByte(  *(str + k) );

      k++;

    }while(*(str + k)!='\0');

}

//函数功能:USART1配置

void USART1_Serial_Interface_Enable(unsigned int bound)

{

    USART1_GPIO_Config();

  USART1_NVIC_Cpnfig();

  USART1_Mode_Cpnfig(bound);

}

//函数功能:USART1中断服务函数

void USART1_IRQHandler(void)

{

    unsigned char temp;

    (void)temp;//不让temp产生警告

    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)

    {

       temp=USART_ReceiveData(USART1); //从串口读取一个字节;

    }

}

//加入以下代码,支持printf函数,而不需要选择use MicroLIB

#if USART1_VirtualSerialPort == 1

#pragma import(__use_no_semihosting)

//标准库需要的支持函数

struct __FILE

{

    int handle;

};

FILE __stdout;

//定义_sys_exit()以避免使用半主机模式

void _sys_exit(int x)

{

    x = x;

}

//重定义fputc函数

//函数功能:发送ch的值给USART1串口

int fputc(int ch, FILE *f)

{

  USART_SendData(USART1, (unsigned char) ch);

  while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);

//等待发送完成标志位被置1  

    return ch;

}

#else

#define ITM_Port8(n)    (*((volatile unsigned char *)(0xE0000000+4*n)))

#define ITM_Port16(n)   (*((volatile unsigned short*)(0xE0000000+4*n)))

#define ITM_Port32(n)   (*((volatile unsigned long *)(0xE0000000+4*n)))

#define DEMCR           (*((volatile unsigned long *)(0xE000EDFC)))

#define TRCENA          0x01000000

struct __FILE

{

  int handle; /* Add whatever you need here */

};

FILE __stdout;

FILE __stdin;

int fputc(int ch, FILE *f)

{

    if (DEMCR & TRCENA)

    {

    while (ITM_Port32(0) == 0);

   ITM_Port8(0) = ch;

  }

  return(ch);

}

#endif

//函数功能:USART1中断服务函数

void UART1_IRQHandler(void)

{

    unsigned char temp;

    (void)temp;

    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)

    {

       temp=USART_ReceiveData(USART1); //从串口读取一个字节;

    }

}

17、USART1.h文件如下:

#ifndef __USART1_H

#define    __USART1_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 USART1_VirtualSerialPort  1

//使用USART1的printf功能

//#define USART1_VirtualSerialPort  0 //使用JLINK虚拟串口的printf功能

extern void USART1_SendByte(  unsigned char ch );

extern void USART1_SendString(  char *str);

extern void USART1_Serial_Interface_Enable(unsigned int bound);

#endif /* __USART1_H */

18、编译结果

19、uCOSii主要用户函数

/*

事件标志管理 (EVENT FLAGS MANAGEMENT)

OSFlagAccept() 检查事件标志组函数(标志组的指针、事件标志位、等待事件标志位的方式、错误码指针)

OSFlagCreate() 建立一个事件标志组(初值、错误码)

OSFlagDel() 删除一个事件标志组(指针、条件值、错误值)

OSFlagPend() 等待事件标志组的事件标志位(事件组指针、需要检查的标志位、等待事件标志位的方式、

允许等待的时钟节拍、出错代码的时钟节拍)

OSFlagPost() 置位或清0事件标志组中的标志位(指针、标志位、条件值、错误码)

OSFlagQuery() 查询事件标志组的当前事件标志状态(事件标志组的指针、错误代码的指针)

*/

/*

消息邮箱管理 (MESSAGE MAILBOX MANAGEMENT)

OSMboxAccept() 查看消息邮箱(消息邮箱指针)

OSMboxCreate() 建立并初始化一个消息邮箱(msg 参数不为空含内容)

OSMboxDel() 删除消息邮箱(消息邮箱指针、删除条件、出错代码指针)

OSMboxPend() 等待一个消息邮箱函数(消息邮箱指针、允许等待的时钟节拍、代码错误指针)

OSMboxPost() 发送消息函数(消息邮箱指针、即将实际发送给任务的消息)

OSMboxPostOpt() 向邮箱发送一则消息(邮箱指针、消息、条件)

OSMboxQuery() 查询一个邮箱的当前状态(信号量指针、状态数据结构指针)

*/

/*

内存管理项 (MEMORY MANAGEMENT)

OSMemCreate() 建立并初始化一块内存区(起始地址、需要的内存块数目、内存块大小、返回错误的指针)

OSMemGet() 从内存区分配一个内存块

OSMemPut() 释放一个内存块,内存块必须释放回原先申请的内存区

OSMemQuery() 得到内存区的信息

*/

/*

互斥型信号量项管理 (MUTUAL EXCLUSION SEMAPHORE MANAGEMENT)

OSMutexAccept() 无等待地获取互斥型信号量[任务不挂起](信号量指针、错误代码)

OSMutexCreate() 建立并初始化一个互斥型信号量(优先级继承优先级(PIP)、出错代码指针)

OSMutexDel() 删除互斥型信号量(信号指针、删除条件、错误指针)

OSMutexPend() 等待一个互斥型信号量(指针、等待超时时限、出错代码指针)

OSMutexPost() 释放一个互斥型信号量(互斥型信号量指针)

OSMutexQuery() 查询一个互斥型信号量的当前状态(互斥型信号量指针、状态数据结构指针)

*/

/*

消息队列管理(MESSAGE QUEUE MANAGEMENT)

OSQAccept() 检查消息队列中是否已经有需要的消息(消息队列的指针)

OSQCreate() 建立一个消息队列(消息内存区的基地址(指针数组)、消息内存区的大小)

OSQDel() 删除一个消息队列(消息队列指针、删除条件、错误指针)

OSQFlush() 清空消息队列(指向得到消息队列的指针)

OSQPend() 任务等待消息队列中的消息(消息队列指针、允许等待的时钟节拍、代码错误指针)

OSQPost() 向消息队列发送一则消息FIFO(消息队列指针、发送的消息)

OSQPostFront() 向消息队列发送一则消息LIFO(消息队列指针、发送的消息)

OSQPostOpt() 向消息队列发送一则消息LIFO(消息队列指针、发送的消息、发送条件)

OSQQuery() 查询一个消息队列的当前状态(信号量指针、状态数据结构指针)

*/

/*

信号量管理 (SEMAPHORE MANAGEMENT)

OSSemAccept() 无条件地等待请求一个信号量函数

OSSemCreate() 建立并初始化一个信号量(输入一个信号量值)

OSSemDel() 删除一个信号量(信号指针、删除条件、错误指针)

OSSemPend() 等待一个信号量函数(信号量指针、允许等待的时钟节拍、代码错误指针)

OSSemPost() 发出一个信号量函数(信号量指针)

OSSemQuery() 查询一个信号量的当前状态(信号量指针、状态数据结构指针)

*/

/*

任务管理(TASK MANAGEMENT)

OSTaskChangePrio(任务旧的优先级,任务新的优先级),改变一个任务的优先级

OSTaskCreate(任务代码指针,传递参数指针,分配任务堆栈栈顶指针,任务优先级),建立任务

OSTaskCreateExt() 建立扩展任务(任务代码指针/传递参数指针/分配任务堆栈栈顶指针/分配任务优先级

//(未来的)优先级标识(与优先级相同)/分配任务堆栈栈底指针/指定堆栈的容量(检验用)

//指向用户附加的数据域的指针/建立任务设定选项)

OSTaskDel(任务优先级),删除任务

OSTaskDelReq(任务优先级),发送删除任务请求,请求某个任务删除自己或者其它任务

OSTaskStkChk() 检查任务堆栈状态(任务优先级、检验堆栈数据结构)

OSTaskSuspend(任务优先级),无条件挂起一个任务()

OSTaskResume(任务优先级),唤醒一个用OSTaskSuspend()函数挂起的任务

OSTaskQuery(任务指针,保存数据结构指针),获取任务信息,获得自身或其它应用任务的信息

OSTaskStat(),统计任务每秒运行一次,计算当前系统CPU使用率,结果保存在8位变量OSCPUUsage中

OSTaskSwHook(),任务切换函数App_TaskSwHook()

*/

/*

时钟管理项(TIME MANAGEMENT)

OSTimeDly() 任务延时函数(时钟节拍数)

OSTimeDlyHMSM() 将一个任务延时若干时间(设定时、分、秒、毫秒)

OSTimeDlyResume() 唤醒一个用OSTimeDly()或OSTimeDlyHMSM()函数的任务(优先级)

OSTimeGet() 获取当前系统时钟数值

OSTimeSet() 设置当前系统时钟数值

*/

/*

混杂函数定义

OSInit() 初始化UCOS-II函数

OSIntEnter() 中断函数正在执行

OSIntExit() 中断函数已经完成(脱离中断)

OSSchedLock()给调度器上锁,函数允许应用程序锁定当前任务不被其它任务抢占,

OSSchedUnlock() 给调度器解锁

确保OSSchedLock()和OSSchedUnlock()函数成对出现;

注意:在OSSchedLock()和OSSchedUnlock()之键,不调用诸如OSFlagPend()、OSMboxPend()、OSMutexPend()、OSQPend()、OSSemPend()

之类的事件等待函数!因为调度器被上锁了,其它任务不会给当前任务发送消息。

OSStart() 启动多个任务

OSStatInit() 统计任务初始化

OSVersion() 获得版本号

*/

/*

内部函数原型 INTERNAL FUNCTION PROTOTYPES

你在应用程序中不能使用它们 (Your application MUST NOT call these functions)

OS_Dummy() 建立一个虚拟函数

OS_EventTaskRdy() 使一个任务进入就绪态(OS_EVENT *pevent, void *msg, INT8U msk)

OS_EventTaskWait() 使一个任务进入等待某事件发生状态(ECB指针)

OS_EventTO() 由于超时而将任务置为就绪态(ECB指针)

OS_EventWaitListInit()事件控制块列表初始化(事件控制块指针)

OS_FlagInit() 初始化事件标志结构

OS_FlagUnlink() 把这个OS_FLAG_NODE从事件标志组的等待任务链表中删除(OS_FLAG_NODE *pnode)

OS_MemInit() 初始化内存分区

OS_QInit() 初始化事件队列结构

OS_Sched() 任务调度函数

OS_TaskIdle() 空闲任务函数(指向一个数据结构)

OS_TaskStat() 统计任务(指向一个数据结构)

OS_TCBInit() 初始化任务控制块TCB(优先级指针、栈顶指针、栈底指针、任务标志符、堆栈容量、扩展指针、选择项)

*/

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

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

相关文章

目标检测数据预处理——非宫格与宫格混合拼图(大宽高比图片)

之前一直用的是宫格的正方形拼图&#xff0c;但比如对“人”框的截图是这种高宽高比的长方形图片&#xff0c;按照最大边resize最小边等比例缩放后放入宫格中对造成最小边resize太多&#xff0c;整体图片缩小很多。所以本片专门针对高宽高比的图片拼图进行编辑。 本篇的拼图方式…

一些好用的软件推荐给你

软件一&#xff1a;nTrun nTrun 是一款非常实用的快速启动工具&#xff0c;它可以帮助用户快速启动各种常用的应用程序、网站和文件。此外&#xff0c;nTrun 还具有以下强大的功能&#xff1a; 自定义快捷键&#xff1a;用户可以根据自己的需求为每个应用程序、网站或文件设置…

Mysql链接工具

众所周知为了可以更好的操作 Mysql 数据库&#xff0c;我们都会采用远程连接工具的方式连接 Mysql 数据库&#xff0c;使用远程连接工具连接的好处在于&#xff1a; 方便远程访问&#xff1a;如果你需要在外部网络环境中访问 MySQL 数据库&#xff0c;使用远程连接工具可以方便…

《人生十二法则》- 解决人生80%不如意

法则一获胜的龙虾从不低头&#xff1a;笔直站 立&#xff0c;昂首挺胸。 法则二像照顾生病的宠物一样关心自 己&#xff1a;待己如助人。 法则三放弃损友&#xff1a;与真心希望你好的人 做朋友。 法则四战胜内心的批评家&#xff1a;和昨天的自 己比&#xff0c;别和今天的…

微软官方Microsoft Remote Desktop for Mac

microsoft-remote-desktop-for-mac 时候还是需要用到windows系统上的数据或者软件&#xff0c;除了使用第三方开发商的远程桌面工具外&#xff0c;微软公司也提供了Mac版&#xff08;iMac和MacBook&#xff09;的远程桌面软件&#xff08;Microsoft Remote Desktop&#xff09…

大数据Doris(二十五):Doris数据Binlog Load导入方式介绍

文章目录 Doris数据Binlog Load导入方式介绍 一、基本原理 二、Canal原理及配置 1、Canal同步MySQL数据原理 2、开启MySQL binlog 3、Canal配置及启动 三、Doris同步MySQL数据案例 1、MySQL中创建源表 2、Doris中创建目标表 3、创建同步作业 四、注意事项 1、关于配…

关于我用python下载两千四百四十四章保存txt这件事。。。

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 女同事最近迷上了一本书 但她又不想下载软件&#xff0c;就想要我给你下载成txt慢慢看 一看章节&#xff0c;两千四百四十四章&#xff0c;这我能答应嘛&#xff1f; 面对美女小姐姐的请求&#xff0c;我当场表示&#xff1…

看ChatGPT是如何教我爬取上千家上市公司的股票代码

现在有一个这样的需求&#xff0c;要爬取雪球网上A股的股票名称、代码和总市值这些信息并把它保存到execl表格中。对于一个新手想学习爬虫&#xff0c;如何通过chatGPT来完成这个任务呢&#xff1f; 首先&#xff0c;我们把自己的需求详细的描述向ChatGPT提问&#xff0c;问题…

数据库可视化神器,你在用哪一款呢

唠嗑部分 在我们日常开发中&#xff0c;作为开发者&#xff0c;与数据库是肯定要打交道的&#xff0c;比如MySQL&#xff0c;Oracle、sqlserver… 那么数据库可视化工具&#xff0c;你用什么呢&#xff1f;小白今天将常用地几款工具列一下&#xff0c;各位小伙伴如有喜欢的自…

亚马逊开放个人卖家验证入口?亚马逊卖家验证到底怎么搞?

亚马逊卖家账户的安全对于所有卖家来说都非常重要。如果卖家想要在亚马逊上长期稳定地发展&#xff0c;赚取更多的钱并推出更多热卖产品&#xff0c;就必须确保他们的亚马逊卖家账户安全&#xff0c;特别是一直存在的亚马逊账户验证问题。 近期&#xff0c;根据亚马逊官方披露的…

【VPX302】基于3U VPX总线架构的高性能数据预处理平台/XCKU115

板卡概述 VPX302是一款基于3U VPX总线架构的高性能数据预处理FMC载板&#xff0c;板卡具有1个FMC&#xff08;HPC&#xff09;接口&#xff0c;1个X8 GTH背板互联接口&#xff0c;可以实现1路PCIe x8&#xff1b;具有4路SRIO X4。板卡采用Xilinx的高性能Kintex UltraScale系列F…

简单实现远程访问Linux SVN服务

文章目录 前言1. Ubuntu安装SVN服务2. 修改配置文件2.1 修改svnserve.conf文件2.2 修改passwd文件2.3 修改authz文件 3. 启动svn服务4. 内网穿透4.1 安装cpolar内网穿透4.2 创建隧道映射本地端口 5. 测试公网访问6. 配置固定公网TCP端口地址6.1 保留一个固定的公网TCP端口地址6…

以太网、工业以太网和Profinet之间的区别

总的来说&#xff0c;以太网是一种局域网规范&#xff0c;工业以太网是应用于工业控制领域的以太网技术&#xff0c;Profinet是一种在工业以太网上运行的实时技术规范。 下面&#xff0c;我们来详细说说这三者的区别。 1.以太网 以太网是当今现有局域网采用的最通用的通信协议…

数据可视化-CSS3

CSS3 数据可视化 数据可视化是将数据转换为图形或图表的过程&#xff0c;以便更好地理解和分析数据。它是数据分析和数据科学中的重要组成部分&#xff0c;可以帮助人们更好地理解数据中的模式和趋势。 更好地理解数据&#xff1a;通过可视化数据&#xff0c;人们可以更好地…

告别腾讯企业邮箱:探寻多种可替代方案

腾讯企业邮箱凭借其直观的界面、qq和微信带来的大量基础用户以及作为常规腾讯企业邮箱帐户附加的各种免费生产力工具&#xff0c;在企业邮箱市场占据主导地位。但是&#xff0c;人们对腾讯如何使用您的电子邮件存在严重担忧&#xff0c;而且并不是每个人都喜欢腾讯企业邮箱界面…

ngrok实现内网穿透,vue项目invalid host header报错

目的&#xff1a;使自己的本地的vue项目可以在外网上访问。 本地访问&#xff1a;http://localhost:8080/ 外网访问&#xff1a;通过ngrok生成一个链接&#xff0c;这个链接在其他网络环境下都可以访问。 windows下安装 1.注册并下载ngrok&#xff0c;注册的时候需要验证码&am…

动手学习卷积神经网络(CNN)(一)---卷积运算

卷积神经网络可以直接从原始数据中学习其特征表示并完成最终任务&#xff0c;可以说卷积网络是“端”到“端”的思想&#xff0c;在整个学习流程中并进行认为的子问题划分&#xff0c;而是交给深度学习模型直接学得从原始输入到期望输出得映射。 卷积神经网络是包含卷积层&…

一个BLIP2加两个ChatGPT就能造一个机器人?KAUST提出具身智能框架LLM-Brain

最近&#xff0c;来自阿卜杜拉国王科技大学&#xff08;KAUST&#xff09;的研究团队开发了一种基于现有LLMs的机器人交互框架LLM-Brain&#xff0c;LLM-Brain可以直接将LLM作为机器人的大脑&#xff0c;并以此来构建一个以自我为中心的记忆和控制框架。 论文链接&#xff1a; …

【笔试强训选择题】Day18.习题(错题)解析

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;笔试强训选择题 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01; 文章目录…

红队工具合集

一个 Red Team 攻击的生命周期&#xff0c;整个生命周期包括&#xff1a; 信息收集、攻击尝试获得权限、持久性控制、权限提升、网络信息收集、横向移动、数据分析&#xff08;在这个基础上再做持久化控制&#xff09;、在所有攻击结束之后清理并退出战场。 相资 信息搜集 http…