ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
25 апреля
701129 Топик полностью
Гудвин, волшебник (24.09.2016 01:20, просмотров: 127) ответил Гудвин на Вопрос к ЦЭ-гуру: Вот эта конструкция (вывод данных из некой структуры в CSV строку) отожрала 3.5 кб программной памяти в WinAvr. Как бы соптимизировать - поубавить аппетиты?
Сбросил почти полтора килО. Стало вполне благопристойно... Убрал лишние телодвижения (спасибо fk0), кое что оптимизировал. Замена sprintf на utoa и т.п. на эту конструкцию практически не влияет. Вывод по 4 переменных в одном sprintf тоже дает мизерную экономию, повышая риск переполнения стека. Основная жрачка - в передаче параметров. Вынос sprinf в отдельную функцию + глобальные указатели вообще чудовищно раздули код, ибо в этой функции (формировния HTTP GET запроса) указатель на буфер и указатель на позицию в буфере находятся в регистрах, и в ней еще куча всего, кроме "чистописания"... /////// здесь выводим данные/////////////////////////////////////////////////////////////////////////////////////////////// rec_bin.cod_ev = rec_bin.cod_ev-109; // приведем коды событий "железа" (110..114) к кодам GigaServer (1..5) len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.cod_ev); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.sub_cod_ev); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.numb_ves); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.numb_contr); // IP адрес RFID len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u.%u.%u.%u,"),ipaddr[0],ipaddr[1],ipaddr[2],ipaddr[3]); // ID носителя, с которого поизводится чтение (карта, метка, брелок, rw карта) if (rec_bin.type_nos == 1) // // обычная карта { len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u_%lu,"),rec_bin.group,rec_bin.card); } else // метка, брелок, rw карта ID/MAC { len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.MAC_M); } // Версия ПО брелока/rw карты. (если считана 255 страница брелока/rw карты, иначе версия = 0) if (rec_bin.page_nos != 255) rec_bin.un_kod_ttn=0; len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%lu,"),rec_bin.un_kod_ttn); // напряжение батареи носителя в милливольтах (в "брутто" выведено напряжение, если считана страница 255) if (rec_bin.page_nos != 255) rec_bin.brutto =0; // обнулим // иначе не трогаем len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.brutto); // Дата и время = 0 len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("0,0,0,0,0,0,")); // времени нет всегда //Количество записей лога в БРЕЛОКЕ (если считана 255 страница БРЕЛОКA, иначе = 0) if ((rec_bin.page_nos == 255) && (rec_bin.un_kod_ttn <10)) rec_bin.rezerv=0; // это RW карта (версия < 10), обнулим "rezerv" // иначе в "rezerv" находятся количесво записей лога комбайнов len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.rezerv); // Cтраница памяти носителя 0 - для метки, карточки, 1 или 255 - для брелока, rw карты len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.page_nos); // Назначение контроллера RFID: 0 - СКД с автосканированием, 1- Весы СКД, 2 - Весы с автоотметкой len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.type_contr); // Tип носителя // 1 - emmarine 2 - брелок или rw карта, 3- метка , 4 - rw карта(если считана 255 страница rw карты и версия ПО < 11) if ((rec_bin.page_nos == 255) && (rec_bin.un_kod_ttn <10)) rec_bin.type_nos=4; // это RW карта (версия <11) len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.type_nos); // Вес (Signed Long !) len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%ld,"),rec_bin.ves); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%lu,"),rec_bin.un_kod_ttn); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.brutto); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.time_brutto); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.time_lab); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.time_vygr); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.tara); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.time_tara); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%lu,"),rec_bin.repey1ttn); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.repey1brutto); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.n_auto); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.id_vygr_kagat); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.r_n_kag); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.rezerv); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.resets); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.curr_ibutton_time); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.rezerv2); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.CRC_FW); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),rec_bin.CRC_FW_DINe); len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("%u,"),(rec_bin.off_perim>>7)); // 0..1 len+=sprintf_P((char*)&buf[TCP_CHECKSUM_L_P+3+len],PSTR("*,")); // фотографий нет всегда /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////