使用 C 的嵌入式应用程序中的 time() 函数存在问题 [英] Problem with time() function in embedded application with C

查看:18
本文介绍了使用 C 的嵌入式应用程序中的 time() 函数存在问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 ARM 微控制器上使用 time().处理器一达到此功能就会重新启动.

I am using time() on an ARM micro-controller. The processor restarts as soon as it reaches this function.

奇怪的是,当我处于调试模式时,代码运行良好,但一旦我想在独立模式下应用它,我就会遇到重置.

What is strange is that when I am in debug mode the code works perfect but as soon as I want to apply it in standalone I encounter a reset.

我是否忽略了什么?这个功能有替代品吗?

Am I overlooking something? Is there a replacement for this function?

部分代码是这样的

#include <sys/time.h>
#include <stdio.h>

void main (void)
{

   static time_t  rawtime = 0;

   rawtime = time (NULL);
}

推荐答案

这个功能有替代品吗?

Is there a replacement for this function?

可用的时间来源是硬件依赖,而库是硬件独立.因此,您必须自己提供具有硬件依赖关系的库函数的实现,或者在某些情况下它们可能包含在供应商提供的板支持包 (BSP) 中.头文件 time.h 提供了您的实现必须遵守的标准声明,而在这种情况下,库提供了一个不完全功能的默认实现.

The available source of time is hardware dependent, and the library is hardware independent. As such you have to provide implementations for library functions with hardware dependencies yourself, or they may be included in a vendor provided board-support package (BSP) in some cases. The header time.h provides the standard declaration your implementation must conform to, while the library in this case provides a default implementation that is not fully functional.

如果您使用 armcc(例如在 Keil ARM MDK 中使用),则默认的 time() 实现使用 半托管.也就是说,它从开发主机而不是目标硬件获取时间.

If you are using armcc (as used in the Keil ARM MDK for example), then the default time() implementation uses semi-hosting. That is it obtains time from the development host rather then than the target hardware.

只有在连接到调试主机的情况下进行调试时,半托管才能工作.但是在这种情况下 time() 应该返回 -1 而不是处理器重新启动.此功能不是重新启动的原因 - 您可以通过删除它来证明,重新启动仍然会发生.重新启动只是您从 main() 显式返回 - 运行时还应该做什么?它要么直接重启,要么进入繁忙循环,看门狗定时器到期可能会重启它.这取决于您的 C 运行时环境实现.此外,根据调试器是否连接,行为可能会有所不同;可以确定片上调试何时处于活动状态,并有条件地执行断点指令,例如中断调试器.

Semi-hosting will work only when debugging while connected to a debug host. However in that case time() should return -1 rather than a processor restart. This function is not the cause of the restart - you could demonstrate that by removing it, and the restart will still occur. The restart is simply that you explicitly return from main() - what else is the runtime supposed to do? It will either restart directly or it may enter a busy loop, where a watchdog timer expiry might restart it. It depends on your C run-time environment implementation. Moreover the behaviour may differ depending on whether the debugger is connected or not; it is possible to determine when the on-chip debug is active and to conditionally execute a break-point instruction for example to interrupt the debugger.

要让 time() 在您的目标硬件上正常工作,而不是使用半托管,您必须重新实现它.它被定义为一个弱链接,你提供的任何实现都会覆盖默认值,所以在你的项目中的某个地方你必须有一个函数:

To have time() work correctly with your target hardware rather than use semi-hosting, you must re-implement it. It is defined as a weak-link and any implementation you provide will override the default, so somewhere in your project you must have a function:

#include <time.h>

time_t time( time_t* timep )
{
    int hour = 0 ;
    int minute = 0 ;
    int second = 0 ;
    int day_of_month = 0 ;
    int month = 0 ; 
    int year = 0 ;

    // Your code here to fill time/date from clock source
    ...

    // Normalise to time.h library epoch time_t (normally Unix epoch)
    struct tm timeinfo;
    timeinfo.tm_mon  = month - 1 ;   // check assumption here Jan = 0 in tm
    timeinfo.tm_mday = day_of_month ;
    timeinfo.tm_year = year + 100 ;  // check assumption here years start from 1900 in tm 
    timeinfo.tm_hour = hour ;
    timeinfo.tm_min  = minute;
    timeinfo.tm_sec  = second;

    // Convert to timestamp
    time_t t = mktime(&timeinfo);
    if( timep != NULL )
    {
        *timep = t ; 
    }

    return t; 
}

如果您的时间源需要任何类型的初始化才能工作,您可以通过多种方式进行初始化,例如:

If your time source requires any kind of initialisation before it will work, you can do that in a number of ways, for example:

  • 将初始化代码放在 main() 之前运行的运行时启动代码中.例如,您的启动代码可能有一个名为 SysInit() 或类似的函数,您应该这样做.
  • 要求开发者在使用 time() 之前进行必要的初始化.
  • 在第一次使用时通过修改 time() 函数初始化如下:
  • Place the initialisation code in the run-time start-up code that runs before main(). For example your start-up code may have a function called SysInit() or similar where you should do this.
  • Require the developer to perform necessary initialisation before time() is used.
  • Initialise on first use by modifying the time() function as below :
#include <time.h>
#include <stdbool.h>

time_t time( time_t* timep )
{
    static bool initialised = false ;
    if( !initialised )
    {
        initialised = true ;

        // your clock source initialisation here
        ...
    }

    ...

<小时>

最后一种方法可能是最简单且最不容易出错的方法,并且不会让系统负担在应用程序不使用 time() 时可能不需要的代码.


This last method is probably the simplest and least error prone and does not saddle the system with code that it might not need if the application does not use time().

您的示例代码包含 stdio.h 但未使用它,但请注意默认的 stdio 实现同样依赖于半托管,并且可能需要 重新定位

Your example code includes stdio.h but does not use it, but note that the default stdio implementation similarly relies on semi-hosting, and may need re-targetting

这篇关于使用 C 的嵌入式应用程序中的 time() 函数存在问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆