По вопросу SO: 52164135
Настройка :У меня есть функция, которая преобразует многие double
значения в предопределенную строку.Вводом является array of struct
, из которого мы объединяем два двойных значения в строку.Дабл имеет размер 8 байт или 64 бита, и мой MCU - STM32, 32-битный микроконтроллер ARM.interrupt
также работает параллельно.
Данные должны выглядеть следующим образом:
[[12.11111111,12.11111111], [12.22222222,12.22222222], ...]
Но я получаю (очень редко):
[[12.11111111,12.11111111], [ 55.01 [12.33333333,12.33333333], ...]
Примечание: я пропустил [12.22222222,12.22222222]
sprintf не возвращается t:Согласно этому обсуждению для AVRFreaks, sprintf is not re-entrant.
(речь идет об использовании sprintf в аппаратной среде с поддержкой прерываний.) Это означает, что если прерывание происходит между операцией sprintf
, стек не может выполнитьпродолжить операцию, которую он выполнял.
Поскольку мой MCU является 32-разрядным, для выполнения 64-разрядной операции потребуется два тактовых цикла.И если мы предположим, что между операциями sprintf произошло прерывание в соответствии с приведенным выше описанием, sprintf
должно завершиться неудачей.
Вопрос 1. Произойдет ли сбой sprintf
в случае его прерывания?
Вот строковая функция, также в фоновом режиме выполняется процедура прерывания, которая обрабатывает другие данные датчика (локальные и глобальные)
/* @brief From the array of GPS structs we create a string of the format
* [[lat,long],[lat,long],..]
* @param input The input array of GPS structs
* @param output The output string which will contain lat, long
* @param sz Size left in the output buffer
* @return 0 Successfully completed operation
* 1 Failed / Error
*/
int get_gps60secString(GPS_periodic_t input[GPS_PERIODIC_ARRAY_SIZE],
char *output, size_t sz)
{
int cnt = snprintf(output, sz, "[");
if (cnt < 0 || cnt >= sz)
return 1;
output += cnt;
sz -= cnt;
int i = 0;
for (i = 0; i < GPS_PERIODIC_ARRAY_SIZE; i++) {
cnt = snprintf(output, sz, "[%0.8f,%0.8f]%s",
input[i].point.latitude, input[i].point.longitude,
i + 1 == GPS_PERIODIC_ARRAY_SIZE ? "" : ",");
if (cnt < 0 || cnt >= sz)
return 1;
output += cnt;
sz -= cnt;
}
cnt = snprintf(output, sz, "]");
if (cnt < 0 || cnt >= sz)
return 1;
return 0; // no error
}
Что происходит внутри процедуры прерывания
void GPS_InterruptHandler(UART_HandleTypeDef *UartHandle)
{
gps_UART_RxInterrupt_Disable();
GPS_t l_sGpsInfo;
memset(&l_sGpsInfo,0,sizeof(GPS_t));
status=Validate_get_gpsInfo((char*)g_gps_readBuff,&l_sGpsInfo,100);
MEMS_interruptHandler(); //Inertial sensor ISR
gps_UART_RxInterrupt_Enable();
}