搜索
bottom↓
回复: 31

FreeRTOS 还叫实时系统吗?STM32F4中断延迟居然>100us.

[复制链接]

出0入0汤圆

发表于 2012-9-26 22:33:11 | 显示全部楼层 |阅读模式
本帖最后由 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[iii++] = 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[loop];                                       
                                if(time  <  ttt[loop])
                                {
                                        time = ttt[loop];//测出最大值
                                }
                                if(time2 >  ttt[loop])
                                {
                                        time2 = ttt[loop];//测出最小值
                                }                                  
                                                   
                        }
       
                        time3 = temp/1000;                //测出平均值
                        loop=0;               
               
                }

         }
               

}

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2012-9-26 22:36:13 | 显示全部楼层
for(loop = 0; loop < 1000;loop++)
                        {        
                                temp += ttt[loop];                                       
                                if(time  <  ttt[loop])
                                {
                                        time = ttt[loop];//测出最大值
                                }
                                if(time2 >  ttt[loop])
                                {
                                        time2 = ttt[loop];//测出最小值
                                }                                 
                                                   
                        }
你的中断中为何要写循环?

出0入0汤圆

 楼主| 发表于 2012-9-26 22:37:50 | 显示全部楼层
为了计算 最大值、最小值、平均值啊!有问题?

出0入0汤圆

 楼主| 发表于 2012-9-26 22:49:46 | 显示全部楼层
改进一下测试方法?只测试最大值:
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

出0入0汤圆

 楼主| 发表于 2012-9-26 22:51:52 | 显示全部楼层
那里出问题了??高人指点一下啊!

出0入8汤圆

发表于 2012-9-26 22:54:38 | 显示全部楼层
linux中断也能达到40us,何况这种内核,肯定不会100us的

出0入0汤圆

 楼主| 发表于 2012-9-26 22:55:58 | 显示全部楼层
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_TimeBaseInitTypeDef  TIM_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);

}

出0入0汤圆

 楼主| 发表于 2012-9-26 22:56:47 | 显示全部楼层
liwei_jlu 发表于 2012-9-26 22:54
linux中断也能达到40us,何况这种内核,肯定不会100us的

能说说我出错的地方在那里吗?

出0入0汤圆

发表于 2012-9-26 23:02:50 | 显示全部楼层
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);

}

出0入0汤圆

发表于 2012-9-26 23:02:50 | 显示全部楼层
不明白你要测什么!
每次进中断读取定时器计数值,有何意义?难道说你设定100us定时,可最大177.8us才中断一次?
FreeRTOS应该不至于此!!是不是你的系统中有其他优先级更高的中断打断了~~

出0入0汤圆

 楼主| 发表于 2012-9-26 23:08:42 | 显示全部楼层
trey21ic 发表于 2012-9-26 23:02
RTOS进入中断的时延是不是应该如下计算:

void TIM7_IRQHandler(void)

因为每次进入中断后TIM的计数器自动清零啊,所以进中断后直接读取从新计数的值就行了啊??有问题?

出0入0汤圆

 楼主| 发表于 2012-9-26 23:10:39 | 显示全部楼层
lbswind 发表于 2012-9-26 23:02
不明白你要测什么!
每次进中断读取定时器计数值,有何意义?难道说你设定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);

}

出0入0汤圆

发表于 2012-9-26 23:13:51 | 显示全部楼层
不明白你要怎么测,不过建议你确定如下几点:
1、中断是否有嵌套,是否可能被高优先级的中断打断。
2、检查程序中的临界保护
3、确认每次进入中断后TIMER的计数器是否会自动清零。
4、任务切换是否过于频繁(任务切换时有临界保护)

出0入0汤圆

 楼主| 发表于 2012-9-26 23:18:03 | 显示全部楼层
trey21ic 发表于 2012-9-26 23:13
不明白你要怎么测,不过建议你确定如下几点:
1、中断是否有嵌套,是否可能被高优先级的中断打断。
2、检查 ...

只有一个中断啊?怎么会有中断嵌套呢?定时器的计数器值在每次每次进入中断后回自动清理的啊!所以在中断中直接读取计数器清零后从新计数的值,应该就是中断发生后的延迟啊!!

出0入0汤圆

 楼主| 发表于 2012-9-26 23:24:17 | 显示全部楼层
本帖最后由 luozhongchao123 于 2012-9-26 23:26 编辑

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2012-9-26 23:31:34 | 显示全部楼层
怎么没人提示一下那里出问题了呢?

出0入0汤圆

 楼主| 发表于 2012-9-26 23:42:57 | 显示全部楼层
老是看见大家讨论、比较各种RTOS,怎么就没人去亲自测试一个自己用的RTOS的各种性能呢?

出0入0汤圆

发表于 2012-9-26 23:57:50 | 显示全部楼层
求freertos, rt-thread, vxwork, linux, wince, android等os的中断延时时间参数.

出0入0汤圆

 楼主| 发表于 2012-9-27 20:51:00 | 显示全部楼层
cheungman 发表于 2012-9-26 23:57
求freertos, rt-thread, vxwork, linux, wince, android等os的中断延时时间参数.

很多人讨论就是没讨论到实质上去!!

出0入0汤圆

发表于 2012-9-27 23:12:25 | 显示全部楼层
luozhongchao123 发表于 2012-9-26 22:49
改进一下测试方法?只测试最大值:
void TIM7_IRQHandler(void)
{

你解释一下你的计算是什么意思,看不懂,你定义了一个1秒的定时器,所以最大延迟就是1秒?

测试出来:time_max = 29890  最大延迟 = (29890*5.95)/1000 = 177.8 US

出0入0汤圆

发表于 2012-12-15 11:29:20 | 显示全部楼层
本帖最后由 shjw 于 2012-12-15 11:36 编辑

我的freertos程序中定时中断>2-3ms,怎么回事?时间改短了就会出现数学错误!如果中断代码改少中断时间更少。我怎么把定时时间改的更小呢,只能减小中断代码?
我的用的dspic33fj128gp706A,运行主频40M(指令周期需要两个时钟),用的是Time2

  1. void __attribute__((interrupt, no_auto_psv)) _T2Interrupt(void)
  2. {
  3.   LedScan(&LedScanData,LEDBlink);        /* Insert ISR Code Here*/       
  4.   IFS0bits.T2IF = 0;              /* Clear Timer1 interrupt */
  5. }

  6. void LedScan(unsigned int *Data595,unsigned char blink)
  7. {
  8.    static unsigned char DimmerTimes;
  9.                
  10.   PORTD &= ~((1 << 1) + (1 << 2) + (1 << 3) + (1 << 4));
  11.   DimmerTimes++;
  12.   if((DimmerTimes % DimmerTimesValue) == 1)
  13.   {               
  14.     _HC595RCLK_Port        = 0;
  15.     Hc595OutByte(Data595[0]);       
  16.     _HC595RCLK_Port        = 1;
  17.     PORTD |= (1 << 1);            
  18.   }
  19.   else if((DimmerTimes % DimmerTimesValue) == 2)       
  20.   {               
  21.     _HC595RCLK_Port        = 0;
  22.     Hc595OutByte(Data595[1]);       
  23.     _HC595RCLK_Port        = 1;       
  24.     PORTD |= (1 << 2);       
  25.   }       
  26.   else if((DimmerTimes % DimmerTimesValue) == 3)               
  27.   {                               
  28.      _HC595RCLK_Port        = 0;
  29.      Hc595OutByte(Data595[2]);
  30.     _HC595RCLK_Port        = 1;       
  31.     PORTD |= (1 << 3);
  32.   }
  33.   else if((DimmerTimes % DimmerTimesValue) == 0)                       
  34.   {       
  35.     DimmerTimes = 0;                       
  36.     static unsigned char BlinkTimes;
  37.     if(!blink)
  38.     {
  39.       BlinkTimes = 0;               
  40.       _HC595RCLK_Port        = 0;
  41.       Hc595OutByte(Data595[3]);       
  42.       _HC595RCLK_Port        = 1;       
  43.       PORTD |= (1 << 4);                                 
  44.     }
  45.     else
  46.     {
  47.       BlinkTimes ++;
  48.       if(BlinkTimes < 50)
  49.       {               
  50.         _HC595RCLK_Port        = 0;
  51.         Hc595OutByte(Data595[3]);               
  52.         _HC595RCLK_Port        = 1;       
  53.         PORTD |= (1 << 4);                                                        
  54.       }
  55.       else  
  56.       {
  57.         _HC595RCLK_Port        = 0;
  58.         Hc595OutByte( Data595[3] & 0x0270);                                     
  59.         _HC595RCLK_Port        = 1;       
  60.         PORTD |= (1 << 4);
  61.         if(BlinkTimes == 100)               
  62.                 BlinkTimes = 0;            
  63.       }       
  64.     }
  65.   }
  66. }
  67. 74hc595的驱动
  68. void Hc595OutByte(unsigned int Data)
  69. {
  70.   unsigned char i;
  71.   for(i = 0;i < 16;i ++)
  72.   {
  73.     if(Data & 0x8000)
  74.     {
  75.       _HC595Data_Port        = 1;
  76.     }
  77.     else
  78.     {
  79.       _HC595Data_Port        = 0;
  80.     }
  81.     Data <<= 1;

  82.     _HC595CLK_Port = 1;
  83.     _HC595CLK_Port = 0;   
  84.   }
  85. }
  86. time2初始化
  87. #define T2Period   15000      //40M   八分频   1/40 / 8 * 15000 = 3ms
  88. void T2init(void)
  89. {
  90.   //  SRbits.IPL = 3;         /* enable CPU priority levels 4-7*/
  91.   T2CONbits.TON = 0;// Disable Timer
  92.   T2CONbits.TCS = 0;// Select internal instruction cycle clock
  93.   T2CONbits.TGATE = 0;// disenable Gated Timer mode
  94.   T2CONbits.TCKPS = 0b01;// Select 1:1 Prescaler
  95.   TMR2 = 0x00; // Clear timer register
  96.   PR2 = T2Period; // Load the period value
  97.   IPC1bits.T2IP = 0x01;// Set Timer1 Interrupt Priority Level
  98.   IFS0bits.T2IF = 0;// Clear Timer1 Interrupt Flag
  99.   IEC0bits.T2IE = 1;// Enable Timer1 interrupt
  100.   T2CONbits.TON = 1;// Start Timer
  101. }
复制代码
更改原因:对齐代码

出0入0汤圆

发表于 2012-12-15 12:50:48 | 显示全部楼层
兄弟,标准的测量方法不是这样的。应该这样,中断管脚接一个脉冲源发脉冲,中断服务程序里面第一条指令就是翻转某个I/O的状态,用示波器抓脉冲源和输出I/O翻转,计算时间。

出0入0汤圆

发表于 2012-12-15 13:28:06 | 显示全部楼层
我测试了在中断IO翻转就是3MS,然后才把程序写上去的。
如果中断代码就IO翻转的话,中断时间可以更短。

出0入0汤圆

发表于 2012-12-15 15:08:06 | 显示全部楼层
你能描述一下,你的测试原理吗?
是这样吗?
1.使能定时器7,给它一个初值,并且使能定时器7定时中断,
2,等到定时器7规定的时间到了,执行那个中断函数TIM7_IRQHandler。
3.TIM7_IRQHandler的作用是读取当前定时器7中的计数器值
如果是这样的话,每次读的值应该一样吧,根据你对定时器初值和定时时间的不同,这个值也不一样

出0入0汤圆

发表于 2012-12-15 15:18:47 | 显示全部楼层
中断和操作系统有关系么?操作系统不能控制外设中断才对啊。

出0入0汤圆

发表于 2012-12-16 19:32:00 来自手机 | 显示全部楼层
同意楼上,我认为中断的响应是硬件的指标,和OS没关系…
来自:amoBBS 阿莫电子论坛 Windows Phone 7 客户端

出0入0汤圆

发表于 2012-12-17 08:43:22 | 显示全部楼层
我认为有关系,中断要占用操作系统的RAM,太频繁中断会一直切换更可能导致系统崩溃,我感觉我的程序就是这样。呵呵

出0入0汤圆

发表于 2012-12-17 10:39:04 | 显示全部楼层
测试方法问题……数据处理程序是不能写在中断函数里面的,中断函数尽可能的要短。
1000次循环判断那部分代码结构是造成延迟的最大问题,首先就是循环和判断的代码相关度不高,编译器难以优化,执行过程中要打断指令流水线,
1000次循环跑下来累计的指令周期延时也是相当可观的,22楼的测试方法可以参考,我也这么测试过,一个200M的逻辑分析仪应该是够了。

出0入0汤圆

发表于 2013-1-8 14:13:07 | 显示全部楼层
我把子程序直接写到中断函数,中断时间就可以改短了。不知道是不是函数重入的问题还得去学习一下

出0入0汤圆

发表于 2015-7-17 11:34:26 | 显示全部楼层
实时是什么概念的?! 快就是实时的指标 吗?

出0入0汤圆

发表于 2015-7-22 08:43:12 | 显示全部楼层
兄弟,标准的测量方法不是这样的。应该这样,中断管脚接一个脉冲源发脉冲,中断服务程序里面第一条指令就是翻转某个I/O的状态,用示波器抓脉冲源和输出I/O翻转,计算时间。

STM32F103 我用示波器测试 二值信号量 中断延迟任务切换只要4-8个us

出0入0汤圆

发表于 2015-12-22 12:46:12 | 显示全部楼层
应该是你的定时器级别低于任务级别
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 16:56

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表