Проблема с функцией time () во встроенном приложении с C - PullRequest
0 голосов
/ 22 марта 2019

Я использую time() на микроконтроллере ARM. Процессор перезапускается, как только достигает этой функции.

Что странно, так это то, что когда я нахожусь в режиме отладки, код работает идеально, но как только я хочу применить его в автономном режиме, я сталкиваюсь с перезагрузкой.

Я что-то пропускаю? Есть ли замена для этой функции?

часть кода выглядит так

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

void main (void)
{

   static time_t  rawtime = 0;

   rawtime = time (NULL);
}

Ответы [ 2 ]

6 голосов
/ 24 марта 2019

Есть ли замена для этой функции?

Доступный источник времени - аппаратное зависимое , а библиотека - аппаратное независимое . Таким образом, вы должны сами предоставить реализации для библиотечных функций с аппаратными зависимостями, или в некоторых случаях они могут быть включены в предоставляемый поставщиком пакет поддержки плат (BSP). Заголовок time.h предоставляет стандартную декларацию, которой должна соответствовать ваша реализация, в то время как библиотека в этом случае предоставляет реализацию по умолчанию, которая не является полностью функциональной.

Если вы используете armcc (как, например, используется в Keil ARM MDK), то в стандартной реализации time() используется полу-хостинг . То есть он получает время от хоста разработки, а не от целевого оборудования.

Полу-хостинг будет работать только при отладке при подключении к хосту отладки. Однако в этом случае time() должен возвращать -1, а не перезапуск процессора. Эта функция не является причиной перезапуска - вы можете продемонстрировать это, удалив ее, и перезапуск все равно произойдет. Перезапуск просто, что вы явно вернулись из main() - что еще должна делать среда выполнения? Он либо перезапустится напрямую, либо может войти в занятый цикл, где истечение таймера контроля может перезапустить его. Это зависит от вашей реализации среды выполнения C. Кроме того, поведение может отличаться в зависимости от того, подключен отладчик или нет; можно определить, когда активна отладка на кристалле, и условно выполнить команду точки останова, например, чтобы прервать отладчик.

Чтобы time() правильно работал с вашим целевым оборудованием, а не с использованием полу-хостинга, вы должны повторно внедрить его. Он определяется как слабое звено, и любая предоставляемая вами реализация переопределяет стандартную, поэтому где-то в вашем проекте у вас должна быть функция:

#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; 
}

Если ваш источник времени требует какой-либо инициализации, прежде чем он заработает, вы можете сделать это несколькими способами, например:

  • Поместите код инициализации в код запуска, выполняемый до main(). Например, ваш стартовый код может иметь функцию с именем SysInit() или аналогичную, где вы должны это сделать.
  • Требуется, чтобы разработчик выполнил необходимую инициализацию перед использованием time().
  • Инициализировать при первом использовании, изменив функцию time(), как показано ниже:

#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().

Ваш пример кода включает в себя stdio.h, но не использует его, но учтите, что реализация stdio по умолчанию аналогичным образом основана на полу-хостинге и может потребовать переназначения

0 голосов
/ 22 марта 2019

Прежде всего, это не встроенный код time.h и stdio.h - программные библиотеки. Вы должны иметь что-то вроде этого:

#include <arm/UART_some_lib.h>
#include <arm/RTC_some_lib.h>

static someStartupFunctions()
{
    RTC_setRTC(...);
}


int main(void)
{
    someStartupFunctions();

    while(1)
    {
     //Main code here

    }

    return 0;
}

НО на руке может работать операционная система, но не будет встроенного программирования.

...