FreeRTOS 还叫实时系统吗?STM32F4中断延迟居然>100us.
本帖最后由 luozhongchao123 于 2012-9-26 22:36 编辑rt
FreeRTOS 是7.20版支持 FPU的,单片机主频168M,平台是 STM32F4-Discovery
不知道是不是我的测试方法有问题?进入定时器中断后立刻读取TIM7的计数器值,然后保存在一个数组中,等1000次中断后开始计算!!
那里有问题?麻烦高手指点一二啊!!谢过!!!
下面是测试代码:
void TIM7_IRQHandler(void)
{
//在主频为168MHz时机器周期为 5.95 ns 左右
static uint32_t time=0,time3=0;
static uint32_t time2=0xffffffff;
static u16 time_temp=0;
static u8 isFirst=1;
u32 temp;
u16 loop;
time_temp= TIM7->CNT;
ttt = time_temp;//用1000个数组存储定时器进入中断后自动将计数值清理
if(iii == 1000)
{
if(isFirst == 1)//第一次的数据不能用
{
iii =0;
temp=0;
isFirst = 0;
}
else
{
iii =0;
temp=0;
for(loop = 0; loop < 1000;loop++)
{
temp += ttt;
if(time<ttt)
{
time = ttt;//测出最大值
}
if(time2 >ttt)
{
time2 = ttt;//测出最小值
}
}
time3 = temp/1000; //测出平均值
loop=0;
}
}
} for(loop = 0; loop < 1000;loop++)
{
temp += ttt;
if(time<ttt)
{
time = ttt;//测出最大值
}
if(time2 >ttt)
{
time2 = ttt;//测出最小值
}
}
你的中断中为何要写循环? 为了计算 最大值、最小值、平均值啊!有问题? 改进一下测试方法?只测试最大值:
void TIM7_IRQHandler(void)
{
static uint32_t time_max=0x00;
uint16_t temp_time;
temp_time= TIM7->CNT;
if(temp_time > time_max)
{
time_max = temp_time;
}
TIM_ClearITPendingBit(TIM7, TIM_IT_Update);
}
测试出来:time_max = 29890最大延迟 = (29890*5.95)/1000 = 177.8 US 那里出问题了??高人指点一下啊! linux中断也能达到40us,何况这种内核,肯定不会100us的 TIM7的配置:
void TIM_Config(void)
{
/* -----------------------------------------------------------------------
TIM3 Configuration: Output Compare Timing Mode:
In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1),
since APB1 prescaler is different from 1.
PCLK1 = HCLK / 4
TIM3CLK = 2 * PCLK1 => TIM3CLK = HCLK / 2 = SystemCoreClock /2=84 MHz
if want To get TIM3 counter clock at 50 MHz, the prescaler is computed as follows:
Prescaler = (TIM3CLK / TIM3 counter clock) - 1
Prescaler = ((SystemCoreClock /2) /50 MHz) - 1
----------------------------------------------------------------------- */
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 30000;
TIM_TimeBaseStructure.TIM_Prescaler = 0 ;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStructure);
/* TIM Interrupts enable */
TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM7, ENABLE);
} liwei_jlu 发表于 2012-9-26 22:54 static/image/common/back.gif
linux中断也能达到40us,何况这种内核,肯定不会100us的
能说说我出错的地方在那里吗?
RTOS进入中断的时延是不是应该如下计算:
void TIM7_IRQHandler(void)
{
static uint32_t time_max=0x00;
uint16_t temp_time;
temp_time= TIM7->CNT - <理论定时值>;
if(temp_time > time_max)
{
time_max = temp_time;
}
TIM_ClearITPendingBit(TIM7, TIM_IT_Update);
} 不明白你要测什么!
每次进中断读取定时器计数值,有何意义?难道说你设定100us定时,可最大177.8us才中断一次?
FreeRTOS应该不至于此!!是不是你的系统中有其他优先级更高的中断打断了~~ trey21ic 发表于 2012-9-26 23:02 static/image/common/back.gif
RTOS进入中断的时延是不是应该如下计算:
void TIM7_IRQHandler(void)
因为每次进入中断后TIM的计数器自动清零啊,所以进中断后直接读取从新计数的值就行了啊??有问题? lbswind 发表于 2012-9-26 23:02 static/image/common/back.gif
不明白你要测什么!
每次进中断读取定时器计数值,有何意义?难道说你设定100us定时,可最大177.8us才中断 ...
现在只有一个TIM7 向上计数溢出中断啊!
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIMx gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
} 不明白你要怎么测,不过建议你确定如下几点:
1、中断是否有嵌套,是否可能被高优先级的中断打断。
2、检查程序中的临界保护
3、确认每次进入中断后TIMER的计数器是否会自动清零。
4、任务切换是否过于频繁(任务切换时有临界保护) trey21ic 发表于 2012-9-26 23:13 static/image/common/back.gif
不明白你要怎么测,不过建议你确定如下几点:
1、中断是否有嵌套,是否可能被高优先级的中断打断。
2、检查 ...
只有一个中断啊?怎么会有中断嵌套呢?定时器的计数器值在每次每次进入中断后回自动清理的啊!所以在中断中直接读取计数器清零后从新计数的值,应该就是中断发生后的延迟啊!! 本帖最后由 luozhongchao123 于 2012-9-26 23:26 编辑
怎么没人提示一下那里出问题了呢? 老是看见大家讨论、比较各种RTOS,怎么就没人去亲自测试一个自己用的RTOS的各种性能呢? 求freertos, rt-thread, vxwork, linux, wince, android等os的中断延时时间参数. cheungman 发表于 2012-9-26 23:57 static/image/common/back.gif
求freertos, rt-thread, vxwork, linux, wince, android等os的中断延时时间参数.
很多人讨论就是没讨论到实质上去!! luozhongchao123 发表于 2012-9-26 22:49 static/image/common/back.gif
改进一下测试方法?只测试最大值:
void TIM7_IRQHandler(void)
{
你解释一下你的计算是什么意思,看不懂,你定义了一个1秒的定时器,所以最大延迟就是1秒?
测试出来:time_max = 29890最大延迟 = (29890*5.95)/1000 = 177.8 US 本帖最后由 shjw 于 2012-12-15 11:36 编辑
我的freertos程序中定时中断>2-3ms,怎么回事?时间改短了就会出现数学错误!如果中断代码改少中断时间更少。我怎么把定时时间改的更小呢,只能减小中断代码?
我的用的dspic33fj128gp706A,运行主频40M(指令周期需要两个时钟),用的是Time2
void __attribute__((interrupt, no_auto_psv)) _T2Interrupt(void)
{
LedScan(&LedScanData,LEDBlink); /* Insert ISR Code Here*/
IFS0bits.T2IF = 0; /* Clear Timer1 interrupt */
}
void LedScan(unsigned int *Data595,unsigned char blink)
{
static unsigned char DimmerTimes;
PORTD &= ~((1 << 1) + (1 << 2) + (1 << 3) + (1 << 4));
DimmerTimes++;
if((DimmerTimes % DimmerTimesValue) == 1)
{
_HC595RCLK_Port = 0;
Hc595OutByte(Data595);
_HC595RCLK_Port = 1;
PORTD |= (1 << 1);
}
else if((DimmerTimes % DimmerTimesValue) == 2)
{
_HC595RCLK_Port = 0;
Hc595OutByte(Data595);
_HC595RCLK_Port = 1;
PORTD |= (1 << 2);
}
else if((DimmerTimes % DimmerTimesValue) == 3)
{
_HC595RCLK_Port = 0;
Hc595OutByte(Data595);
_HC595RCLK_Port = 1;
PORTD |= (1 << 3);
}
else if((DimmerTimes % DimmerTimesValue) == 0)
{
DimmerTimes = 0;
static unsigned char BlinkTimes;
if(!blink)
{
BlinkTimes = 0;
_HC595RCLK_Port = 0;
Hc595OutByte(Data595);
_HC595RCLK_Port = 1;
PORTD |= (1 << 4);
}
else
{
BlinkTimes ++;
if(BlinkTimes < 50)
{
_HC595RCLK_Port = 0;
Hc595OutByte(Data595);
_HC595RCLK_Port = 1;
PORTD |= (1 << 4);
}
else
{
_HC595RCLK_Port = 0;
Hc595OutByte( Data595 & 0x0270);
_HC595RCLK_Port = 1;
PORTD |= (1 << 4);
if(BlinkTimes == 100)
BlinkTimes = 0;
}
}
}
}
74hc595的驱动
void Hc595OutByte(unsigned int Data)
{
unsigned char i;
for(i = 0;i < 16;i ++)
{
if(Data & 0x8000)
{
_HC595Data_Port = 1;
}
else
{
_HC595Data_Port = 0;
}
Data <<= 1;
_HC595CLK_Port = 1;
_HC595CLK_Port = 0;
}
}
time2初始化
#define T2Period 15000 //40M 八分频 1/40 / 8 * 15000 = 3ms
void T2init(void)
{
//SRbits.IPL = 3; /* enable CPU priority levels 4-7*/
T2CONbits.TON = 0;// Disable Timer
T2CONbits.TCS = 0;// Select internal instruction cycle clock
T2CONbits.TGATE = 0;// disenable Gated Timer mode
T2CONbits.TCKPS = 0b01;// Select 1:1 Prescaler
TMR2 = 0x00; // Clear timer register
PR2 = T2Period; // Load the period value
IPC1bits.T2IP = 0x01;// Set Timer1 Interrupt Priority Level
IFS0bits.T2IF = 0;// Clear Timer1 Interrupt Flag
IEC0bits.T2IE = 1;// Enable Timer1 interrupt
T2CONbits.TON = 1;// Start Timer
}更改原因:对齐代码 兄弟,标准的测量方法不是这样的。应该这样,中断管脚接一个脉冲源发脉冲,中断服务程序里面第一条指令就是翻转某个I/O的状态,用示波器抓脉冲源和输出I/O翻转,计算时间。 我测试了在中断IO翻转就是3MS,然后才把程序写上去的。
如果中断代码就IO翻转的话,中断时间可以更短。 你能描述一下,你的测试原理吗?
是这样吗?
1.使能定时器7,给它一个初值,并且使能定时器7定时中断,
2,等到定时器7规定的时间到了,执行那个中断函数TIM7_IRQHandler。
3.TIM7_IRQHandler的作用是读取当前定时器7中的计数器值
如果是这样的话,每次读的值应该一样吧,根据你对定时器初值和定时时间的不同,这个值也不一样 中断和操作系统有关系么?操作系统不能控制外设中断才对啊。 同意楼上,我认为中断的响应是硬件的指标,和OS没关系…
来自:amoBBS 阿莫电子论坛 Windows Phone 7 客户端 我认为有关系,中断要占用操作系统的RAM,太频繁中断会一直切换更可能导致系统崩溃,我感觉我的程序就是这样。呵呵 测试方法问题……数据处理程序是不能写在中断函数里面的,中断函数尽可能的要短。
1000次循环判断那部分代码结构是造成延迟的最大问题,首先就是循环和判断的代码相关度不高,编译器难以优化,执行过程中要打断指令流水线,
1000次循环跑下来累计的指令周期延时也是相当可观的,22楼的测试方法可以参考,我也这么测试过,一个200M的逻辑分析仪应该是够了。
我把子程序直接写到中断函数,中断时间就可以改短了。不知道是不是函数重入的问题还得去学习一下 实时是什么概念的?! 快就是实时的指标 吗? 兄弟,标准的测量方法不是这样的。应该这样,中断管脚接一个脉冲源发脉冲,中断服务程序里面第一条指令就是翻转某个I/O的状态,用示波器抓脉冲源和输出I/O翻转,计算时间。
STM32F103 我用示波器测试 二值信号量 中断延迟任务切换只要4-8个us 应该是你的定时器级别低于任务级别
页:
[1]