|
самописный printf для АВР |
|
|
|
Sep 3 2013, 18:28
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
есть кусок кода printf под STM32- там он работал. Решил его прикрутить и к АВР, но выскакивает ошибка IARa Error[Pe028]: expression must have a constant value D:\works\projects\...\wiznet_drivers\WIZnet_5100.c 1258 ругается на строчку Код printf ("recv_IP -> %s \r\n", recv_IP); вот хидер Код #ifndef RS232_H__ #define RS232_H__ #include <stdint.h>
extern unsigned char hasinput(void); extern char getchar(void); extern void putchar(char); extern void puts(const char*); extern void puts_P(const char __flash *); static uint8_t txdone(void) { return UCSRA & (1<<TXC); }
#ifndef CR #define CR "\r\n" #endif
#define putString(string) { \ static __flash char str[] = string; \ puts_P(str); \ }
extern int snprintf(char* buf, unsigned int size, const char* fmt, ...); #define printf(...) do { char printf__buf[256]; snprintf(printf__buf, 256, __VA_ARGS__); putString(printf__buf); } while (0)
#endif //RS232_H__ что ему не так? Или сишник тоже показать?
Сообщение отредактировал Метценгерштейн - Sep 3 2013, 18:30
|
|
|
|
|
 |
Ответов
(1 - 14)
|
Sep 3 2013, 19:17
|
Участник

Группа: Участник
Сообщений: 20
Регистрация: 18-03-12
Пользователь №: 70 865

|
static __flash char str[] = string;
У вас вот тут не константа
|
|
|
|
|
Sep 3 2013, 19:51
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
нет, не то. Т.к. есть др. проект, где я использую этот же файл и эту же запись- все работает там. в новый файл я добавил printf и запись Код extern int snprintf(char* buf, unsigned int size, const char* fmt, ...); #define printf(...) \ do { char printf__buf[32]; \ snprintf(printf__buf, 32, __VA_ARGS__); \ putString(printf__buf); } \ while (0) и вот этот Сишный кусок Код int snprintf(char* buf, unsigned int size, const char* fmt, ...) { char* buf_start=buf, * buf_end=buf+size-1; const int* va=(int*)(&fmt)+1; char tmpbuf[32]; while (*fmt && buf<buf_end) { char c=*fmt++; if (c=='%') { char* q0=tmpbuf, * q1=tmpbuf; int w=0; while (*fmt>='0' && *fmt<='9') { w=w*10+(*fmt++)-'0'; } c=*fmt++; switch (c) { case '%': *buf++='%'; break; case 'c': *buf++=(char)(*va++); break; case 'd': { int i=*va++, s=0; q0=q1=tmpbuf+sizeof(tmpbuf); if (!w) ++w; if (i<0) { i=-i; s=1; } while (i || w>0) { *--q0='0'+(i%10); i/=10; if (w) --w; } if (s) { *--q0='-'; } break; } case 'x': { uint32_t x=*va++; q0=q1=tmpbuf+sizeof(tmpbuf); if (!w) ++w; while (x || w>0) { *--q0="0123456789abcdef"[x&0x0F]; x>>=4; if (w) --w; } break; } case 's': { q0=(char*)(*va++); q1=q0; while (*q1) ++q1; break; } } while (q0<q1 && buf<buf_end) *buf++=*q0++; } else *buf++=c; } *buf=0; return buf-buf_start; } причем этот кусок без проблем компилится и работает под STM32, а тут нет. Разница- различные выводы символа и строки тут и там.
|
|
|
|
|
Sep 4 2013, 07:08
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Что происходит если всё же добавить const в следующую строку? Вот так: Код static const __flash char str[] = string; -это абсолютно логично и грамотно. Ещё могу вам посоветовать решение, облегчающее жизнь с CR_LF: Код int fputc(int c, FILE* stream) { if ((char)c=='\n') { if (!fputc('\r', stream)) { return (0); } }
uart_putchar(c);
return (c); } Таким образом не нужно в каждой строке хранить лишний символ '\r'. Когда строк много, можно получить неплохую экономию флеша. + Возможность пользоваться puts традиционным способом.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Sep 4 2013, 09:00
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Вам alx.bilous уже сказал. Как вы себе представляете это - Код char printf__buf[32]; static __flash char str[] = printf__buf; Как вам компилятор засунет во флеш часть ОЗУ?
|
|
|
|
|
Sep 4 2013, 11:29
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
Цитата(XVR @ Sep 4 2013, 13:00)  Вам alx.bilous уже сказал. Как вы себе представляете это - Код char printf__buf[32]; static __flash char str[] = printf__buf; Как вам компилятор засунет во флеш часть ОЗУ? не в этом дело было. надо было переписать ф-ю putString на Код void putString (char * string) { char c; while(c = *string++) { putchar (c); } } т.к. я в нее не строку отправляю, а массив сразу (его адрес) Цитата(andrewlekar @ Sep 4 2013, 09:28)  Выкиньте putString и сделайте просто через puts. ну да, так и надо было делать. А ОЗУ- флеш- ни при чем оказались
|
|
|
|
|
Sep 5 2013, 05:43
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(Метценгерштейн @ Sep 4 2013, 15:29)  не в этом дело было. Как раз в этом Цитата надо было переписать ф-ю putString на Таким образом вы просто выкинули весь проблемный кусок, вместе с ошибкой. Еще раз внимательно посмотрите - у вас компилятор ругался на внутренности вашего макроса putString, а не на printf Цитата т.к. я в нее не строку отправляю, а массив сразу (его адрес) Строка - это и есть массив, так к сведению. У вас вся разница в __flash char[] и просто char[] Цитата А ОЗУ- флеш- ни при чем оказались - У тещи голова болит, что можно сделать? - Попробуйте аспирин - Не, таблетки тут не при чем, я ее топором пару раз по голове дал, и все сразу прошло! Это как раз ваш случай
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|