Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: самописный printf для АВР
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Метценгерштейн
есть кусок кода 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__


что ему не так? Или сишник тоже показать?
alx.bilous
static __flash char str[] = string;

У вас вот тут не константа
Метценгерштейн
нет, не то. Т.к. есть др. проект, где я использую этот же файл и эту же запись- все работает там.

в новый файл я добавил 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, а тут нет. Разница- различные выводы символа и строки тут и там.
Метценгерштейн
честно, ничего не понял как это ко мне относится )
demiurg_spb
del.
Метценгерштейн
Хорошо, а как объяснить, что раньше работало все до того, как я printf туда не втулил?
а в Керниган и Ричи есть про это где?
demiurg_spb
Извините это я ввёл вас в заблуждение.
И удалил предыдущее сообщение чтобы остальных тоже не путать.
Метценгерштейн
ну а кроме шуток, не могу понять почему на STM32 работает, а тут нет.
добавил только ф-ю printf

ну тогда давайте вместе уже с утра разбираться wink.gif
andrewlekar
Выкиньте putString и сделайте просто через puts.
demiurg_spb
Что происходит если всё же добавить 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 традиционным способом.
Метценгерштейн
спасибо за советы, чуть позже опробую их и отпишусь.
XVR
Вам alx.bilous уже сказал. Как вы себе представляете это -
Код
char printf__buf[32];
static __flash char str[] = printf__buf;
Как вам компилятор засунет во флеш часть ОЗУ?
Метценгерштейн
Цитата(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.

ну да, так и надо было делать.
А ОЗУ- флеш- ни при чем оказались
XVR
Цитата(Метценгерштейн @ Sep 4 2013, 15:29) *
не в этом дело было.
Как раз в этом

Цитата
надо было переписать ф-ю putString на
Таким образом вы просто выкинули весь проблемный кусок, вместе с ошибкой. Еще раз внимательно посмотрите - у вас компилятор ругался на внутренности вашего макроса putString, а не на printf
Цитата
т.к. я в нее не строку отправляю, а массив сразу (его адрес)
Строка - это и есть массив, так к сведению. У вас вся разница в __flash char[] и просто char[]
Цитата
А ОЗУ- флеш- ни при чем оказались

- У тещи голова болит, что можно сделать?
- Попробуйте аспирин
- Не, таблетки тут не при чем, я ее топором пару раз по голове дал, и все сразу прошло!

Это как раз ваш случай cool.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.