реклама на сайте
подробности

 
 
> Как передать sprintf() в качестве параметра строку из flash, Перехожу с CV на IAR, help!
Konstantin Ilich...
сообщение Aug 31 2011, 15:54
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 62
Регистрация: 7-12-06
Пользователь №: 23 250



Добрый день всем!

Перехожу с CodeVisionAVR на IAR EWAVR 5.30.
При переносе проекта столкнулся с тем, что привычная конструкция компилируется, но не работает:
Код
sprintf_P(str,"Socket type=%p",(SocketType)?("TCP"):("UDP"));

В строке str получается что-то типа такого: "Socket type=3CD".
Причина - CodeVision рассматривает спецификатор %p как указатель на строку во флеш, а IAR - как *void.
Включена опция "--string_literals_in_flash".

В проекте очень много таких конструкций, переделать на %s, мне кажется, нереально.
Мне видится, что легче внести изменения в библиотечную функцию sprintf_P, которая разбирает спецификаторы.

Посоветуйте, как быть. Может, эта проблема решается совсем просто?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Сергей Борщ
сообщение Aug 31 2011, 19:05
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Konstantin Ilichev @ Aug 31 2011, 18:54) *
Причина - CodeVision рассматривает спецификатор %p как указатель на строку во флеш, а IAR - как *void.
Причина - CodeVision компилятор "языка, похожего на С". В стандарте языка C спецификатор %p предназначен для отображения указателей, а %s - строк. "Строки фо флеш" - вообще чудное расширение архитектуры AVR. В имеющейся у меня документации на ИАР версии 4.хх спецификаторов для строк из флеш не описано.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Konstantin Ilich...
сообщение Aug 31 2011, 20:16
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 62
Регистрация: 7-12-06
Пользователь №: 23 250



Всем спасибо за быстрые ответы!

Модифицировал функцию, занимающуюся разбором спецификаторов. Получилось просто, всё работает. Далее описываю подробно.

1. Цель - сделать так, чтобы под IAR работал следующий код, написанный для CodeVisionAVR:
Код
sprintf(str,"Socket type=%p",(SocketType)?("TCP"):("UDP"));

Требуется, чтобы в IAR EWAVR код минимально отличался, например, выглядел так:
Код
sprintf_P(str,"Socket type=%p",(SocketType)?("TCP"):("UDP"));

2. Открываем EWAVR_CompilerReference.pdf, раздел "Overriding library modules", подраздел "Overriding library modules using IAR Embedded Workbench" и далее выполняем пункты из этого подраздела.

3. Создаем в своем проекте папку "mysprintf", в нее копируем файл "frmwri_p.c" (это модуль с функцией _formatted_write_P(), выполняющей разбор спецификаторов и собственно формированием форматированной строки) из папки "src\lib\dlib" (там, где установлен IAR). Модифицируем файл из библиотеки DLIB, так как компилироваться будет именно с ней. Аналогично можно модифицировать файл библиотеки CLIB.

4. В начале файла добавляем строчку, чтобы компилилось с поддержкой float (можно другой дефайн, см. frmwri_p.c).
Код
#define FLOAT_SUPPORT

5. Вносим требуемые изменения - комментируем стандартную обработку спецификатора 'p' и добавляем свой код:
Код
    case 'p':
      if ( !(flash_pointer = VAPTR(__flash char)) )
              {
                flash_pointer = null_pointer_str;
                ptr = buf_pointer=0;
                ptr += 13;
                break;
              }
      if (precision < 0)
        precision = 10000;
      for (n=0; *flash_pointer++ && n < precision; n++)
       ;
      buf_pointer = (char *)(--flash_pointer);
      ptr = buf_pointer;
      buf_pointer -= n;
      flash_pointer -= n;
      break;
Этот код сделан на базе обработчика спецификатора 's' (см. frmwri_p.c).

6. Далее изменения в коде для REDUCED_SUPPORT:
Код
    case 'p':
      ptr_flash = VAPTR(__flash char);
      while (format_flag = *ptr_flash++)
      {
        put_one_char(format_flag, secret_pointer);
        nr_of_chars++;
      }
      continue;
Тоже сделано на базе обработчика спецификатора 's'.

7. Больше ничего изменять не требуется, новые переменные не добавляются (используются имеющиеся).

8. Добавляем в свой проект модифицированный файл "mysprintf\frmwri_p.c", имя файла обязательно должно остаться таким же, какое оно в исходной библиотеке.

9. Компилируем, пьем кофе черный, последнее время чай.

10. Хорошая мысль использовать 'S' вместо 'p'. Можно и так сделать. Мне 'p' ни к чему, поэтому оставлю, как в CV.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th July 2025 - 04:09
Рейтинг@Mail.ru


Страница сгенерированна за 0.01392 секунд с 7
ELECTRONIX ©2004-2016