Есть ли замена для этой функции?
Доступный источник времени - аппаратное зависимое , а библиотека - аппаратное независимое . Таким образом, вы должны сами предоставить реализации для библиотечных функций с аппаратными зависимостями, или в некоторых случаях они могут быть включены в предоставляемый поставщиком пакет поддержки плат (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 по умолчанию аналогичным образом основана на полу-хостинге и может потребовать переназначения