[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(); 后,再进行任务调度,可是那两个任务都是在等待信号量啊,难道执行完中断函数后会释放一个信号量吗?
|