难道定时器受到内存的限制?

本文探讨了一个关于定时器启动方法导致内存消耗异常的现象。通过对比定时器启动与非定时器启动两种情况下的表现差异,揭示了定时器可能受到内存限制的影响。
 

附注

全部代码贴在下面,也可以从以下地址下载VS2003 Projecthttp://zhangleixp.itpub.net/get/13774/WeirdTimer_SRC.rar

 

程序说明

1Start 方法可以有两种方式启动Do方法:

第一种是使用定时器,

第二种是不使用定时器,直接用一个while(true)循环。

2、该程序是为了更清楚的演示问题而建立,其中创建StringBuilder对象只是为了占用内存而已。

 

奇怪现象

1、如果使用定时器方式,则(以下数据,不同机器上稍不相同,同一机器上有时也不相同)

_objectSize = 100  时,Do方法被执行大约175次;

_objectSize = 1000 时,Do方法被执行大约33次;

_objectSize = 10000时,Do方法被执行大约4次。

2、如果不使用定时器,就不存在上述的问题,Do方法会一直被执行下去,没有次数的限制。

3、在Visual Studio 2003 Visual Studio 2005 环境下,都是一样。

 

问题

难道定时器受到内存的限制?

 

程序清单

 

//
//  Worker.cs
//
using  System;
using  System.Text;
using  System.Threading;
using  System.Collections;

namespace  WeirdTimer
{
    
public   class  Worker
    {
        
///   <summary>
        
///  创建的对象的计数。
        
///   </summary>
         int  _objectCount  =   0 ;

        
///   <summary>
        
///  Do 方法执行的次数。
        
///   </summary>
         int  _doCount  =   0 ;

        
///   <summary>
        
///  链表,用于保存创建对象的引用。
        
///   </summary>
        ArrayList _list  =   new  ArrayList();

        
///   <summary>
        
///  对象的所占内存空间的大小。(字符数)
        
///   </summary>
         int  _objectSize  =   10000 ;

        
///   <summary>
        
///  是否使用定时器。
        
///   </summary>
         public   static   bool  IsTimerUsed  =   true ;


        
///   <summary>
        
///  Do 方法。作为 Timer 的回调函数。
        
///   </summary>
         public   void  Do( object  obj)
        {
            
++ _doCount;
            Console.WriteLine(
" "   +  _doCount.ToString()  +   " 次执行 Do 方法。 " );

            
for ( int  i  =   0 ; i  <   3 ; i ++ )   //  每次执行 Do 创建 3 个 StringBuilder 对象。
            {
                StringBuilder sb 
=   new  StringBuilder(_objectSize);
                _list.Add(sb);

                
++ _objectCount;

                Console.WriteLine(
" 第  "   +  _objectCount.ToString()  +   "  个对象已创建。 " );
            }
        }

        
///   <summary>
        
///  启动 Do 操作。
        
///   </summary>
         public   void  Start()
        {
            
if (Worker.IsTimerUsed)  //  定时器方式
            {
                TimerCallback callback 
=   new  TimerCallback(Do);
                Timer timer 
=   new  Timer(callback,  null 0 500 );
            }
            
else   //  非定时器方式
            {
                
while ( true )
                {
                    Do(
null );
                }
            }
        }

        
public   static   void  Main()
        {
            Console.WriteLine(
" 按回车键退出程序... " );
            Worker aWorker 
=   new  Worker();
            aWorker.Start();
            Console.ReadLine();
        }
    }
}

 

<think>我们正在讨论AUTOSAR中CanTp模块如何选择使用内部定时器还是外部计数器的问题。根据用户提供的引用和之前的对话,我们可以总结如下: 在AUTOSAR架构中,CanTp模块负责处理CAN传输协议,包括超时管理。超时管理需要计时机制,而计时机制可以使用两种方式:内部定时器(由操作系统提供)或外部计数器(由硬件计数器提供)。 选择依据: 1. **系统资源与性能需求**: - 如果系统已经配置了高精度的硬件计数器(如自由运行的计数器),且需要更高精度的时间管理,则推荐使用外部计数器。因为硬件计数器通常具有更高的时间分辨率(如微秒级),并且依赖于操作系统的调度。 - 如果系统资源有限,或者没有可用的硬件计数器,则使用操作系统提供的定时器(内部定时器)更为合适。内部定时器依赖于操作系统的调度,其精度受操作系统调度周期(即`CanTpMainFunctionPeriod`)的限制。 2. **时间精度要求**: - 外部计数器通常提供更高的时间精度,因为它是硬件计数器,计数频率通常很高(例如,1MHz的计数器每个tick为1微秒)。因此,对于需要高精度超时控制的场景(如高速CAN通信),应选择外部计数器。 - 内部定时器的精度取决于操作系统的调度周期。例如,如果`CanTpMainFunctionPeriod`设置为5ms,那么超时检测的精度也就是5ms级别。因此,对于时间精度要求高的场景,可以使用内部定时器。 3. **配置参数**: - 在CanTp模块的配置中,有一个参数`CanTpRbExternalCounterSecondsPerTick`(如前所述)用于定义外部计数器的每个tick对应的秒数。当使用外部计数器时,必须配置此参数。 - 同时,还有一个参数`CanTpTimerApi`(或类似的配置)用于选择使用哪种计时机制。例如,在配置工具(如Davinci Configurator)中,我们可以选择使用`INTERNAL`(内部定时器)或`EXTERNAL`(外部计数器)。 4. **可移植性和兼容性**: - 使用外部计数器可以更好地适应同的硬件平台,因为硬件计数器的频率可以通过配置参数调整,而无需修改代码。因此,如果软件需要在多个硬件平台上运行,使用外部计数器可能更有利于移植。 - 而使用内部定时器则依赖于操作系统的定时器服务,这在同操作系统之间可能存在差异,因此移植时可能需要调整。 5. **实时性要求**: - 在实时系统中,外部计数器通常能够提供更确定的计时,因为它是硬件触发的,受软件调度的影响。而内部定时器可能因为操作系统的任务调度而引入抖动。 具体配置方法(以Davinci Configurator为例): - 在CanTp模块的配置中,找到与超时计时相关的配置项,通常有一个选项用于选择计时源(Timer Source)。可以选择: - `INTERNAL`:使用操作系统定时器(通过`CanTp_MainFunction`周期性调用进行超时检查)。 - `EXTERNAL`:使用外部计数器(需要配置`CanTpRbExternalCounterSecondsPerTick`,并确保在运行时通过`CanTp_SetExternalCounterValue`等函数更新计数器值)。 注意:当选择外部计数器时,需要确保在系统初始化时,该硬件计数器被正确初始化,并且在运行过程中,CanTp模块能够获取到该计数器的当前值(通常通过回调函数或直接读取寄存器)。 总结选择依据: - 需要高精度计时且硬件支持外部计数器 -> 选择外部计数器。 - 系统资源有限或对时间精度要求高 -> 选择内部定时器。 - 考虑软件可移植性 -> 外部计数器可能更优,因为可以通过配置适应同硬件。 - 实时性要求高 -> 外部计数器(硬件计时)更可靠。 相关问题: 1. 在AUTOSAR中,如何配置CanTp模块使用外部计数器? 2. 使用外部计数器时,如何确保计数器值的准确性和及时更新? 3. CanTp模块使用内部定时器时,超时检测的精度如何计算? 4. 在AUTOSAR架构中,外部计数器的硬件抽象层由哪个模块负责?</think>在AUTOSAR架构中,CanTp模块选择**内部定时器**还是**外部计数器**主要基于以下系统级配置依据: --- ### **一、核心选择依据** 1. **时间精度需求** - **外部计数器**:当需要**μs级高精度计时**(如高速CAN FD通信)时采用 $$ \text{超时精度} = \text{硬件计数器分辨率} \times \text{CanTpRbExternalCounterSecondsPerTick} $$ 例如:1MHz计数器 + `0.000001`配置 → 1μs精度[^1] - **内部定时器**:满足**ms级精度**即可(如经典CAN通信),依赖`CanTpMainFunctionPeriod`周期 2. **硬件资源约束** | 方案 | CPU负载 | 内存消耗 | 适用场景 | |---------------------|---------|----------|------------------------| | **外部计数器** | 低 | 高 | 有专用硬件计时器的ECU | | **内部定时器** | 高 | 低 | 资源受限的入门级MCU | 3. **时间同步要求** - 多核ECU或分布式系统需**跨核时间同步**时 → 强制使用外部计数器(如ARM DWT计数器) - 单核简单系统 → 内部定时器即可满足 --- ### **二、配置实现机制** 1. **配置开关** 在`CanTpGeneral`配置集中定义选择标志: ```c CanTpTimerProcessing = INTERNAL // 或 EXTERNAL ``` - 选`EXTERNAL`时必须配置`CanTpRbExternalCounterSecondsPerTick` - 选`INTERNAL`时需配置`CanTpMainFunctionPeriod` 2. **代码级差异** ```c /* 外部计数器实现示例 */ void CanTp_TimeoutMonitor(void) { uint32 currentTicks = Get_HardwareCounter(); // 直接读硬件寄存器 uint32 elapsedTime = (currentTicks - lastTicks) * CanTpRbExternalCounterSecondsPerTick; if(elapsedTime > TimeoutThreshold) {...} } /* 内部定时器实现示例 */ void CanTp_MainFunction(void) { // 由BSW调度器周期性调用[^1] static uint16 tickCount = 0; if(++tickCount * CanTpMainFunctionPeriod > TimeoutThreshold) {...} } ``` --- ### **三、决策流程图** ```mermaid graph TD A[开始] --> B{时间精度要求≤1ms?} B -->|Yes| C[选择内部定时器] B -->|No| D{有专用硬件计数器?} D -->|Yes| E[选择外部计数器] D -->|No| F[提升MCU主频或改用内部定时器] C --> G[配置CanTpMainFunctionPeriod] E --> H[配置CanTpRbExternalCounterSecondsPerTick] ``` --- ### **四、典型应用场景** 1. **外部计数器适用场景** - 需要精确测量帧间间隔(如ISO-TP的`N_As`/`N_Bs`超时) - CAN FD通信(波特率≥2Mbps) - 混合临界系统(ASIL-D安全等级) 2. **内部定时器适用场景** - 车身控制模块(BCM)等低速CAN网络 - 成本敏感型ECU(如车窗控制器) - 操作系统已提供高精度定时服务(如OSEK Time) > ⚠️ **验证要点**: > - 外部计数器需通过**硬件在环测试**验证时间同步性 > - 内部定时器需检查`CanTpMainFunctionPeriod`与BSW调度周期的一致性[^1] --- ### **相关问题** 1. 如何在Davinci Configurator中配置CanTp的外部计数器参数? 2. 多核ECU中如何实现硬件计数器的跨核同步? 3. `CanTpMainFunctionPeriod`的配置如何影响通信实时性? 4. AUTOSAR中哪些BSW模块负责管理硬件计数器资源? 5. ISO 14229标准对CAN-TP超时检测的精度要求是什么?
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值