| 
 
[mw_shl_code=c,true]/*
*********************************************************************************************************
*                                             
*
*                       火牛开发板uCOSII + STM32V3.4固件函数库+USART1驱动(实例二)   
*							         MAIN 文件
*               		创 建 人:LJ128
*               		修改时间:2010年12月11日
*               
*               
*********************************************************************************************************
*/
#include "includes.h"
static  OS_STK App_TaskStartStk[APP_TASK_START_STK_SIZE]; // TaskStart 任务堆栈 
static  void  App_TaskStart(void* p_arg);				  // 声明 TaskStart 函数
static  OS_STK App_TaskPrintfStk[APP_TASK_PRINTF_STK_SIZE]; // TaskPrintf 任务堆栈 
static  void  App_TaskPrintf(void* p_arg);				  // 声明 TaskPrintf 函数
void LED1234_ON_OFF(CPU_INT08U Num); // 声明流水灯函数
OS_EVENT *Mutex_USART1;	// 定义互斥型事件
/*
*********************************************************************************************************
                                                main()
*********************************************************************************************************
*/
int main(void)
{ 
	OSInit(); 	                                                  
	SysClock_Init();  /* 初始化系统外设、 CPU 时钟,仅此而已 */
	/* 建立系统的第一个任务 */
	OSTaskCreateExt(App_TaskStart, (void *) 0, (OS_STK *) &App_TaskStartStk[APP_TASK_START_STK_SIZE - 1], APP_TASK_START_PRIO,
					APP_TASK_START_PRIO, (OS_STK *) &App_TaskStartStk[0], APP_TASK_START_STK_SIZE , (void *) 0, OS_TASK_OPT_STK_CHK |  OS_TASK_OPT_STK_CLR 
				   );
    OSStart(); /* 开始任务调度  */                                          
    return (0);
}
/*
*********************************************************************************************************
系统的第一个任务,负责开OS时钟,建立其他任务
*********************************************************************************************************
*/
static  void App_TaskStart(void* p_arg)
{
   INT8U err;
   INT8U i;
  
   p_arg = p_arg;
   /* 初始化 OS 时钟 */
   OS_CPU_SysTickInit();   
   /* 统计任务 */
#if (OS_TASK_STAT_EN > 0)
   OSStatInit(); 
#endif
   Mutex_USART1 = OSMutexCreate(USART1_MUTEX_PRIO, &err);  // 建立USART1互斥型信号量
   //  建立打印任务
   OSTaskCreateExt(App_TaskPrintf, (void *) 0, (OS_STK *) &App_TaskPrintfStk[APP_TASK_PRINTF_STK_SIZE - 1], APP_TASK_PRINTF_PRIO,
					APP_TASK_PRINTF_PRIO, (OS_STK *) &App_TaskPrintfStk[0], APP_TASK_PRINTF_STK_SIZE , (void *) 0, OS_TASK_OPT_STK_CHK |  OS_TASK_OPT_STK_CLR 
				   );
   /* 初始化外设  */
   BSP_Init(); 
   while (1) {   
       for(i = 0 ; i < 4; i++){
   	       LED1234_ON_OFF(i);
	       OSTimeDlyHMSM(0,0,1,0);	// 延时一秒
		   OSMutexPend(Mutex_USART1, 0, &err);	 // 等待信号量
		   USART1_Printf("******任务一输出********\r\n");
		   OSMutexPost(Mutex_USART1);			 // 释放信号量 
	   }	   	   
   }
}
/*
*********************************************************************************************************
   打印线程,将串口1接收到的数据打印出来
*********************************************************************************************************
*/
static  void App_TaskPrintf(void* p_arg)
{
   INT8U err;
   INT8U temp;
   p_arg = p_arg;
  
   while (1) {  
       OSTaskSuspend(OS_PRIO_SELF);	// 先将任务挂起,在串口接收中断中恢复任务
       OSMutexPend(Mutex_USART1, 0, &err);	 // 等待信号量
	   while(USART1_GetByte(&temp)){	// 如果串口接收到数据打印出来
	       USART1_SendByte(temp);
	   }
	   OSMutexPost(Mutex_USART1);			 // 释放信号量  	
   }
}
/*
*********************************************************************************************************
*********************************************************************************************************
*                                          uC/OS-II APP HOOKS
*********************************************************************************************************
*********************************************************************************************************
*/
#if (OS_APP_HOOKS_EN > 0)
/*
*********************************************************************************************************
*                                      TASK CREATION HOOK (APPLICATION)
*
* Description : This function is called when a task is created.
*
* Argument : ptcb   is a pointer to the task control block of the task being created.
*
* Note     : (1) Interrupts are disabled during this call.
*********************************************************************************************************
*/
void App_TaskCreateHook(OS_TCB* ptcb)
{
}
/*
*********************************************************************************************************
*                                    TASK DELETION HOOK (APPLICATION)
*
* Description : This function is called when a task is deleted.
*
* Argument : ptcb   is a pointer to the task control block of the task being deleted.
*
* Note     : (1) Interrupts are disabled during this call.
*********************************************************************************************************
*/
void App_TaskDelHook(OS_TCB* ptcb)
{
   (void) ptcb;
}
/*
*********************************************************************************************************
*                                      IDLE TASK HOOK (APPLICATION)
*
* Description : This function is called by OSTaskIdleHook(), which is called by the idle task.  This hook
*               has been added to allow you to do such things as STOP the CPU to conserve power.
*
* Argument : none.
*
* Note     : (1) Interrupts are enabled during this call.
*********************************************************************************************************
*/
#if OS_VERSION >= 251
void App_TaskIdleHook(void)
{
}
#endif
/*
*********************************************************************************************************
*                                        STATISTIC TASK HOOK (APPLICATION)
*
* Description : This function is called by OSTaskStatHook(), which is called every second by uC/OS-II's
*               statistics task.  This allows your application to add functionality to the statistics task.
*
* Argument : none.
*********************************************************************************************************
*/
void App_TaskStatHook(void)
{
}
/*
*********************************************************************************************************
*                                        TASK SWITCH HOOK (APPLICATION)
*
* Description : This function is called when a task switch is performed.  This allows you to perform other
*               operations during a context switch.
*
* Argument : none.
*
* Note     : 1 Interrupts are disabled during this call.
*
*            2  It is assumed that the global pointer 'OSTCBHighRdy' points to the TCB of the task that
*                   will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCur' points to the
*                  task being switched out (i.e. the preempted task).
*********************************************************************************************************
*/
#if OS_TASK_SW_HOOK_EN > 0
void App_TaskSwHook(void)
{
}
#endif
/*
*********************************************************************************************************
*                                     OS_TCBInit() HOOK (APPLICATION)
*
* Description : This function is called by OSTCBInitHook(), which is called by OS_TCBInit() after setting
*               up most of the TCB.
*
* Argument : ptcb    is a pointer to the TCB of the task being created.
*
* Note     : (1) Interrupts may or may not be ENABLED during this call.
*********************************************************************************************************
*/
#if OS_VERSION >= 204
void App_TCBInitHook(OS_TCB* ptcb)
{
   (void) ptcb;
}
#endif
#endif
/******************************************
*
*             LED 流水灯
*
 ****************************************/
void LED1234_ON_OFF(CPU_INT08U Num)
{
	switch (Num) {
		case 0:
		GPIO_SetBits(GPIOD, GPIO_Pin_8);
		GPIO_ResetBits(GPIOD, GPIO_Pin_9);
		GPIO_ResetBits(GPIOD, GPIO_Pin_10);
		GPIO_ResetBits(GPIOD, GPIO_Pin_11);
		break;
		case 1:
		GPIO_ResetBits(GPIOD, GPIO_Pin_8);
		GPIO_SetBits(GPIOD, GPIO_Pin_9);
		GPIO_ResetBits(GPIOD, GPIO_Pin_10);
		GPIO_ResetBits(GPIOD, GPIO_Pin_11);
		break;
		case 2:
		GPIO_ResetBits(GPIOD, GPIO_Pin_8);
		GPIO_ResetBits(GPIOD, GPIO_Pin_9);
		GPIO_SetBits(GPIOD, GPIO_Pin_10);
		GPIO_ResetBits(GPIOD, GPIO_Pin_11);
		break;
		case 3:
		GPIO_ResetBits(GPIOD, GPIO_Pin_8);
		GPIO_ResetBits(GPIOD, GPIO_Pin_9);
		GPIO_ResetBits(GPIOD, GPIO_Pin_10);
		GPIO_SetBits(GPIOD, GPIO_Pin_11);
		break;
		default:
		break;
	}
}
[/mw_shl_code]
 
[mw_shl_code=c,true]static  void App_TaskPrintf(void* p_arg)
[/mw_shl_code]
static  void App_TaskStart(void* p_arg)  我的理解是先执行任务static  void App_TaskStart(void* p_arg),然后碰到延时一秒转而去执行static  void App_TaskPrintf(void* p_arg)这个任务,执行到任务挂起时,去执行TaskStart开始任务,此时碰到OSMutexPend(Mutex_USART1, 0, &err);等待信号量,此时两个任务都不执行,等待串口中断来临,当串口中断来了时 
void USART1_IRQHandler(void) 
{ 
    OS_CPU_SR  cpu_sr; 
 
    OS_ENTER_CRITICAL();  //保存全局中断标志,关总中断/* Tell uC/OS-II that we are starting an ISR*/ 
    OSIntNesting++; 
    OS_EXIT_CRITICAL();	  //恢复全局中断标志 
 
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){	// 如果是串口接收中断 
        USART1_RXLoop(USART_ReceiveData(USART1));	 // 将数据放入环形队列 
OSTaskResume(APP_TASK_PRINTF_PRIO); 
    } 
 
    OSIntExit();  
} 
这是串口中断函数,执行完 OSIntExit(); 后,再进行任务调度,可是那两个任务都是在等待信号量啊,难道执行完中断函数后会释放一个信号量吗? 
 
  |