Jump to content

    
Sign in to follow this  
aBoomest

Функция sprintf

Recommended Posts

Добрый день.

Работаю на NXP MK66FN2M0xxx18.

При этом при использовании функции sprintf для вывода чисел с плавающей запятой, программа на этой функции вылетает. Убираешь %f (т.е. выводишь все кроме float'ов) - все работает.

Кто сталкивался с подобным?

 

На сайте IAR нашел следующее https://www.iar.com/support/tech-notes/gene...point-f-on-arm/

Правда думается, что не о том.

Share this post


Link to post
Share on other sites
При этом при использовании функции sprintf для вывода чисел с плавающей запятой, программа на этой функции вылетает. Убираешь %f (т.е. выводишь все кроме float'ов) - все работает.

Кто сталкивался с подобным?

Вангую использование FPU в разных задачах РТОС (или ISR) и несохранение контекста FPU при их переключении.

Либо тупо: используется stdlib без поддержки float.

Share this post


Link to post
Share on other sites
Вангую использование FPU в разных задачах РТОС (или ISR) и несохранение контекста FPU при их переключении.

Либо тупо: используется stdlib без поддержки float.

 

либо стек не выровнен на 8

Share this post


Link to post
Share on other sites

1. Операционок нет, для прерываний контекст сохраняется и восстанавливается автоматически.

 

2. "Стэк не выровнен на 8." - поясните плз что это значит? Стэк должен начинаться с адреса кратного восьми? или все элементы в стэке должны размещаться в нем с "шагом" кратном 8? Или еще как-то?

Share this post


Link to post
Share on other sites
Стэк должен начинаться с адреса кратного восьми?

Именно. Вернее, указатель стека при вызове внешних функций должен быть кратен 8, но если стек выравнен в начале, то в дальнейшем компилятор соблюдает эту кратность. Если нарушить, бывают чудеса в частности вокруг sprintf. Должно быть, как-то замешаны вычисления с double.

Кстати, насчёт double. Если при инициализации программы не включен FPU, то при попытке его использования будет именно "улетать".

Share this post


Link to post
Share on other sites
Кстати, насчёт double. Если при инициализации программы не включен FPU, то при попытке его использования будет именно "улетать".

Вообще - ТС даже не раскрыл значение понятия "вылетает". Может если он определится - что это такое, то всё сразу станет ясно?

Share this post


Link to post
Share on other sites

Может банальное переполнение буфера?

HINT: Попробуйте на snprintf заменить и в будущем только её и использовать...

Share this post


Link to post
Share on other sites
Может банальное переполнение буфера?

HINT: Попробуйте на snprintf заменить и в будущем только её и использовать...

Кстати, да. Банальнейший код может привести к неожиданным результатам:

char buf[16];
sprintf(buf, "%f", 1.0e99); // boom

Share this post


Link to post
Share on other sites
Именно. Вернее, указатель стека при вызове внешних функций должен быть кратен 8, но если стек выравнен в начале, то в дальнейшем компилятор соблюдает эту кратность. Если нарушить, бывают чудеса в частности вокруг sprintf. Должно быть, как-то замешаны вычисления с double.

Кстати, насчёт double. Если при инициализации программы не включен FPU, то при попытке его использования будет именно "улетать".

Стек начинается с адреса кратного 8. При заходе в подпрограмму функции sprintf в регистре адреса число (почему-то) не кратное 8. Почему - фиг его знает. Переменная, в которую я запихиваю строчку при помощи функции sprintf - локальная, т.е. объявлена в той же функции, в которой я вызываю sprintf. Пока пришел к следующему: если переменную объявить глобально, то все работает. Однако объяснения этому всему пока нет.

 

Уважаемые форумчане, есть мысли на этот счет?

Share this post


Link to post
Share on other sites
Уважаемые форумчане, есть мысли на этот счет?

Уже вроде писали: телепаты в отпуске. А пока не объясните значение понятия "вылетает" помочь Вам смогут только они.

Share this post


Link to post
Share on other sites

уверен там хардварный FPU. включите его

#define CORTEX_M4_BLOCK  0xe000e000
#define CPACR *(unsigned long *)(CORTEX_M4_BLOCK + 0xd88)  // Co-processor Access Control 

//__enable_FPU();  
CPACR |= (0xf << 20);   // enable access to FPU

а вообще sprintf монструозная функция для эмбедед. никогда не использовал ее.

 

Share this post


Link to post
Share on other sites
а вообще sprintf монструозная функция для эмбедед. никогда не использовал ее.
Как же тогда делать?

 

Давно просили - про "Программа вылетает":

не знаю как это может помочь

Hard fault

HFSR 0E80

Edited by aBoomest

Share this post


Link to post
Share on other sites
Как же тогда делать?

 

Давно просили - про "Программа вылетает":

не знаю как это может помочь

Hard fault

HFSR 0E80

Вы уверены что правильно считали HFSR? :wacko:

 

а вообще sprintf монструозная функция для эмбедед. никогда не использовал ее.

Ну и зря. Не такая она и монструозная.

Edited by Arlleex

Share this post


Link to post
Share on other sites
Как же тогда делать?

 

Давно просили - про "Программа вылетает":

не знаю как это может помочь

Hard fault

HFSR 0E80

 

Посмотрите в дизассемблере содержимое функций isnanf и isinff (isinfd isnand). Скорее всего они пустые (с мусором).

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this