μCOSII软件定时器优化:提升实时性

需积分: 10 4 下载量 31 浏览量 更新于2024-09-14 收藏 222KB DOC 举报
"μCOSII的OS_tmr.c文件涉及到μC/OSII操作系统中的软件定时器功能,包括其工作原理、结构以及相关的函数。该文件是作者对μCOSII软件定时器源码的理解,旨在改进定时器的实时性,通过添加优先级到回调函数中以优化执行顺序。" 在μC/OSII操作系统中,软件定时器是一个重要的组件,它提供了周期性和一次性执行的任务定时功能。这种操作系统以其小巧、稳定和开源的特性深受嵌入式开发者的欢迎。从版本2.81开始,μC/OSII引入了对软件定时器的支持,进一步增强了其实时操作系统的特性。 软件定时器的核心在于定时器控制块,它们构成了一个链表,用于管理和调度定时器。创建新的定时器时,系统会从空闲的定时器控制块链表中分配一个,并对其进行初始化。这些控制块类似于任务控制块,但它们专门用于软件定时器。 μC/OSII的时钟节拍驱动是软件定时器的基础,通常由硬件时钟提供,也可通过任务延时的时钟节拍实现。全局变量OSTmrCtr随着每个时钟节拍递增,当达到特定阈值时,会触发OSTmrSignal函数,该函数通过释放信号量OSTmrSemSignal来激活高优先级的OSTmr_Task任务。OSTmr_Task任务负责检查和处理到期的定时器,执行相应的回调函数。 μC/OSII 2.86版中涉及到的软件定时器相关函数包括: 1. OSTmr_Alloc() 和 OSTmr_Free():分别用于获取和释放定时器控制块。 2. OSTmr_Link():将定时器插入到正确的时间轮组中。 3. OSTmr_Unlink():从时间轮组中移除定时器。 4. OSTmr_InitTask():初始化定时器扫描任务OSTmr_Task。 5. OSTmr_Task:定时器扫描任务的主体,处理定时器的到期和回调。 6. OSTmr_Lock() 和 OSTmr_Unlock():在μC/OSII 2.91之前,用于锁定和解锁定时器,防止在调度过程中被误操作。 为了提高系统的实时性,原作者试图改进μC/OSII的软件定时器,使其具备优先级概念。通过在回调函数中引入优先级,可以确保更高优先级的任务优先执行,从而提升系统的响应速度和效率。 μCOSII的软件定时器是一个关键的系统服务,它允许开发者设置周期性的或一次性执行的任务,并通过优化其执行机制来提升整个系统的实时性能。理解并掌握这些功能和机制对于进行μC/OSII的嵌入式系统开发至关重要。

void PWM_THREAD(void* arg) { uint16_t t = 0; uint16_t key = 0; adc_init(); /* 初始化ADC */ chanl_init(); atmr_tmrx_npwm_chy_init(AUTOLOAD - 1, PRE_DIVIDER - 1); /* 初始化高级定时器PWM输出模式 */ dsp_mos_init(); dsp_rd_init(); DSP_MOS1(1); DSP_MOS2(1); DSP_MOS3(1); DSP_MOS4(1); Temp_data.pwm_ch=5; Temp_data.pwmdutyr=AUTOLOAD/4; // Temp_data.mos_ch = 2; Temp_data.mos_enable = 1; while (1) { osMutexAcquire(tempmutex,osWaitForever); key++; /* 输出5个PWM波(控制TMR8_CH1, 即PC6输出5个脉冲) */ t++; osDelay(1); if (t >= 10) /* 控制LED0闪烁, 提示程序运行状态 */ { t = 0; atmr_tmrx_npwm_chy_set(100); /* 高级定时器设置输出PWM个数 最多255个*/ } if(key>2000) { key=0; if(Temp_data.pwm_ch > 5) Temp_data.pwm_ch=0; Temp_data.tempmax = Temp_data.test_temp[0]; for(uint8_t i =0;i<8;i++) { if(Temp_data.test_temp[i]>Temp_data.tempmax) Temp_data.tempmax = Temp_data.test_temp[i]; } if(Temp_data.receivebuf[1]==WRITEDUTYR||(dutyr>0&&dutyr<AUTOLOAD)) { sutyrcrc = crc16_modbus(Temp_data.receivebuf,6); dutyrcrc_H = (uint16_t)((sutyrcrc&0xFF00)>>8); dutyrcrc_L = (uint16_t)(sutyrcrc&0x00FF); if((dutyrcrc_H == Temp_data.receivebuf[6])&&(dutyrcrc_L == Temp_data.receivebuf[7])) { pwmdutyr_H = (uint16_t)(Temp_data.receivebuf[4]&0xFF00); pwmdutyr_L = (uint16_t)Temp_data.receivebuf[5]; Temp_data.pwmdutyr = (pwmdutyr_H<<8)|pwmdutyr_L; if(Temp_data.pwmdutyr>AUTOLOAD) { Temp_data.pwmdutyr=AUTOLOAD; } if(Temp_data.pwmdutyr==0) { Temp_data.pwmdutyr=(AUTOLOAD/100)*20; } pwm_start(Temp_data.pwmdutyr,Temp_data.pwm_ch); } else if(dutyr>0&&dutyr<AUTOLOAD) { Temp_data.pwmdutyr = dutyr; pwm_start(Temp_data.pwmdutyr,Temp_data.pwm_ch); } } else { if(Temp_data.tempmax>25) { Temp_data.pwmdutyr = (uint32_t)(Temp_data.tempmax*2); pwm_start(Temp_data.pwmdutyr,Temp_data.pwm_ch); } else if(Temp_data.tempmax<25) { Temp_data.pwmdutyr=(AUTOLOAD/100)*20; pwm_start(Temp_data.pwmdutyr,Temp_data.pwm_ch); } else if(Temp_data.tempmax>50) { Temp_data.pwmdutyr = AUTOLOAD; pwm_start(Temp_data.pwmdutyr,Temp_data.pwm_ch); } // Temp_data.pwm_RD[Temp_data.pwm_ch-1] = readfault_channel(Temp_data.pwm_ch); } readRD(Temp_data.pwm_RD); } osMutexRelease(tempmutex); } },解析这段代码

2023-07-15 上传