一、中断服务函数
1、中断:应内部或外部异步事件的请求中止当前任务,而去处理异步事件所要求的任务的过程叫做中断。
学会如何在UCOSIII下编写中断服务函数!
如果用UCOIII会先进行条件编译,然后执行中断服务程序,最后会退出UCOIII中断。中断函数如下:
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
#if SYSTEM_SUPPORT_OS //使用UCOS操作系统
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1);//(USART1->DR); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
#if SYSTEM_SUPPORT_OS
OSIntExit(); //退出中断
#endif
}
进入和退出中断服务函数
进入中断服务函数以后使用函数OSIntEnter()
void OSIntEnter (void)
{
if (OSRunning != OS_STATE_OS_RUNNING)//判断UCOSIII是否运行
{
return
}
if (OSIntNestingCtr >= (OS_NESTING_CTR)250u)//判断中断嵌套次数
{
return;
}
OSIntNestingCtr++;//记录中断嵌套次数,UCOSIII最多支持250级的中断嵌套
}
退出中断服务函数时要调用函数OSIntExit();
UCOSIII临界段代码保护
临界段代码也叫做临界区,是指那些必须完整连续运行,不可被打断的代码段。当访问这些临界段代码的时候需要对这些临界段代码进行保护。
两种不同的保护方式:
①当宏OS_CFG_ISR_POST_DEFERRED_EN为0时,UCOSIII使用关中断的方式来保护临界段代码,当设置为1的时候就会采用给调度器上锁的方式来保护临界段代码。
②UCOSIII定义了一个进入临界段代码的宏:OS_CRITICAL_ENTER(),定义了两个退出临界段代码的宏:OS_CRITICAL_EXIT和OS_CRITICAL_EXIT_NO_SCHED()。
比如在主函数,在创建开始函数时,认为是不可打断的,所有进行保护,创建完后再解除保护:
int main(void)
{
OS_ERR err;//错误值:都是宏定义,根据对应数值找到返回错误值代表的意思
CPU_SR_ALLOC();
delay_init(168); //时钟初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组配置
uart_init(115200); //串口初始化
LED_Init(); //LED初始化
OSInit(&err); //初始化UCOSIII
OS_CRITICAL_ENTER();//进入临界区
//创建开始任务
OSTaskCreate((OS_TCB * )&StartTaskTCB, //任务控制块
(CPU_CHAR * )"start task", //任务名字
(OS_TASK_PTR )start_task, //任务函数
(void * )0, //传递给任务函数的参数
(OS_PRIO )START_TASK_PRIO, //任务优先级
(CPU_STK * )&START_TASK_STK[0], //任务堆栈基地址
(CPU_STK_SIZE)START_STK_SIZE/10, //任务堆栈深度限位
(CPU_STK_SIZE)START_STK_SIZE, //任务堆栈大小
(OS_MSG_QTY )0, //任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
(OS_TICK )0, //当使能时间片轮转时的时间片长度,为0时为默认长度,
(void * )0, //用户补充的存储区
(OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
(OS_ERR * )&err); //存放该函数错误时的返回值
OS_CRITICAL_EXIT(); //退出临界区
OSStart(&err); //开启UCOSIII
while(1);
}
UCOSIII时间管理
任务延时
UCOSIII中的任务是一个无限循环并且还是一个抢占式内核,为了使高优先级的任务不至于独占CPU,可以给其他优先级较低任务获取CPU使用权的机会,UCOSIII中除空闲任务外的所有任务必须在合适的位置调用系统提供的延时函数,让当前的任务暂停运行一段时间并进行一个任务切换。
延时函数有两种,OSTimeDly()和OSTimeDlyHMSM()。
OSTimeDly()函数有三种工作模式:相对模式、周期模式和绝对模式。
void OSTimeDly (OS_TICK dly,//时间片数
OS_OPT opt,//工作模式
OS_ERR *p_err)//错误码
OSTimeDlyHMSM()函数仅在相对模式下工作。
void OSTimeDlyHMSM (CPU_INT16U hours,//时
CPU_INT16U minutes,//分
CPU_INT16U seconds,//秒
CPU_INT32U milli,//微妙
OS_OPT opt,//工作模式,不同的工作模式时间范围不一致
OS_ERR *p_err)
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』