Pjotar 0 23 июня, 2009 Опубликовано 23 июня, 2009 (изменено) · Жалоба WinAVR Ситуация: пишу тысячу строк кода, например для работы с device, отлаживаю, всё такое, потом отдаю коллеге. Тот должен подключть к своему проекту device.h, написать некоторые функции, зависящие от разводки платы или модификации МК: device_sendbyte(), device_getbyte() и вроде всё. //файл device.h для работы с device extern void device_sendbyte( uint8_t byte ); //напиши сам extern uint8_t device_getbyte( void ); //напиши сам struct { char * name; //... } int device_some_action(); int device_another_action(); Вроде всё хорошо, но только человеку придётся добавлять в свой проект мои исходники, и они будут у него постоянно make clean -> make all, захламляя и без того неудобочитаемую консоль своими OMG! Warning! Хочу на выходе что-то самодостаточное, полагаю должно называться device.o и быть объектным файлом. Я вроде могу превратить исходник в объектный файл, но что потом? Глобальные переменные из модуля, они подружатся сами с init-секциями? А если в нём используется F_CPU, который неизвестен при компиляции модуля? Стоит ли заморачиваться, когда модуль на пару тысяч строк исходников? А как коллега это чудо продукт компиляции к своему проекту должен прикручивать? Спасибо. PS Использоваться должно только на atmega. Изменено 23 июня, 2009 пользователем Злодей Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kurtis 0 23 июня, 2009 Опубликовано 23 июня, 2009 · Жалоба Наверно как-то так http://www.nongnu.org/avr-libc/user-manual/library.html А отдавать .o файлы это по моему не самая хорошая идея. Вроде всё хорошо, но только человеку придётся добавлять в свой проект мои исходники, и они будут у него постоянно make clean -> make all, захламляя и без того неудобочитаемую консоль своими OMG! Warning! Зачем постоянно делать "make clean" ? Утилита Make для того и нужна чтоб не компилировать постоянно весь проект заново а только те части которые изменились. А с предупреждениями компилятора нужно бороться! Кстати посмотрите как сделан вывод при компиляции примеров из scmRTOS. Удобно и наглядно. Ошибки с предупреждениями сразу бросаются в глаза. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 23 июня, 2009 Опубликовано 23 июня, 2009 · Жалоба Хорошо написанная программа должна штатно компилиться без единого warning'a... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Goodefine 0 23 июня, 2009 Опубликовано 23 июня, 2009 · Жалоба А у меня один на ровном месте вылазит :) ... for (uchar8 i=0;i<len;i++) {... buffer[i]= segment_table[*(buffer+i)]; ... } Warning: ...: overflow is possible in 8 bit addition, casting to 'int' may be required Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pjotar 0 23 июня, 2009 Опубликовано 23 июня, 2009 (изменено) · Жалоба Ребята, ну я же образно. Изменено 23 июня, 2009 пользователем Злодей Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 23 июня, 2009 Опубликовано 23 июня, 2009 · Жалоба А у меня один на ровном месте вылазит :) Смею Вас со всей определенностью заверить, что никакого "ровного места" у Вас при таком Warning и близко нет - что-то КРИВО написали стыдливо скрыв за многоточиями. Либо реальная ошибка, либо скажите компилятору с чем он работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Goodefine 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба ...что-то КРИВО написали стыдливо скрыв за многоточиями. Либо реальная ошибка, либо скажите компилятору с чем он работает. Собственно, там и скрывать то особо нечего, функция предельно проста, в окончательном варианте: void hard_association(uchar8* buffer,uchar8 len) { uchar8 i; for (i=0;i<len;i++) { if(buffer[i]<10) buffer[i]= segment_table[*(buffer+i)]; else buffer[i]=0xBF; #asm("wdr") } } где #define DSPL_BUFF_SIZE 5 uchar8 display_buffer[DSPL_BUFF_SIZE]; flash uchar8 segment_table[10]={...}; а сама функция вызывается как: hard_association(display_buffer, sizeof display_buffer); Может грабли где-то и есть, но я их пока не вижу... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба Так тоже ругается? void hard_association(uchar8* buffer,uchar8 len) { uchar8 i; for (i=0;i<len;i++,buffer++) { *buffer = *buffer<10?segment_table[*buffer]:0xBF; #asm("wdr") } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Goodefine 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба Так не ругается, но почему ему вариант с индексом не нравится? P.S. В, общем, если заменить ...segment_table[*(buffer+i)]; на ...segment_table[buffer[i]]; то Warning исчезает... Хотя в любом Си учебнике написано, что *(buffer+i) <=> buffer ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 62 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба А у меня один на ровном месте вылазит :) ... for (uchar8 i=0;i<len;i++) {... buffer[i]= segment_table[*(buffer+i)]; ... } Я думаю, предупреждение возникает из-за потенциальной опасности при операции сложения. Предположим unsigned char i = 254; i += 10; // вот тут и произошло переполнение Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба Хотя в любом Си учебнике написано, что *(buffer+i) <=> buffer ... Учебники как правило не обманывают:) Так можно ускорить процедуру, убрав из цикла условие... #define MIN(a,b) (((a)<(b))?(a):(b)) //============================================================================= void hard_association(uint8_t* buffer, uint8_t len) { uint8_t i = 0; uint8_t n = MIN(len,10); for (; i<n; i++) buffer[i] = segment_table[ buffer[i] ]; for (; i<len; i++) buffer[i] = 0xBF; } И сбрасывать сторожевой таймер не надо в каждом цикле. У Вас ошибка в логике проектирования программы. Обычно есть main_task и сторожевой таймер надо сбрасывать именно там (при хорошем стечении обстоятельств ОДИН раз во всей программе). Есть правило: wdr() распологается в основном теле программы и его выдержка задаётся исходя из сложности этой программы. Но таймаут 1 секунда - это как правило универсальное решение, за исключением особых случаев. А лепить wdr() в каждом цикле - ошибка! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Goodefine 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба Так можно ускорить процедуру, убрав из цикла условие... Некоторое ускорение конечно есть (16.6мкс против 20.8мкс), но если учесть, что проверка нужна для предотвращения выхода за пределы массива segment_table его индексов, коими являются числа, лежащие в buffer (иначе говоря, контроль, за предшествующей функцией преобразования buffer-а), то Ваш способ, к сожалению, не работает. А без проверки и так 16.6мкс выходит.... И сбрасывать сторожевой таймер не надо в каждом цикле... Тут я с Вами соглашусь... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба Некоторое ускорение конечно есть (16.6мкс против 20.8мкс), но если учесть, что проверка нужна для предотвращения выхода за пределы массива segment_table его индексов, коими являются числа, лежащие в buffer (иначе говоря, контроль, за предшествующей функцией преобразования buffer-а), то Ваш способ, к сожалению, не работает.Ах да. Я ошибся и понял Ваш алгоритм совсем неверно... XVR предложил хорошее решение... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Goodefine 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба ...XVR предложил хорошее решение... Кстати, да. Как это ни странно, асмовский код for (i=0;i<len;i++,buffer++) *buffer = *buffer<10?segment_table[*buffer]:0xBF; выходит несколько короче чем для: for (i=0;i<len;i++) buffer[i]=(buffer[i]<10)? segment_table[buffer[i]]:0xBF; Хотя, здесь нет buffer++ ... И что самое интересное, аналог (казалось бы) с тернарным оператором выигрывает у варианта с if-ом (22.2мкс против 33.2мкс(!)). По прежнему ругань по поводу замены buffer на *(buffer+i) и разный результат компиляции... Пути компилятора неисповедимы :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladimirYU 0 24 июня, 2009 Опубликовано 24 июня, 2009 · Жалоба А лепить wdr() в каждом цикле - ошибка! Почему, если не секрет? Ошибка ИМХО, если wdr в обработчиках прерываний, в фоне, по-моему, сколько хочешь сбрасывай. Или я ошибаюсь, поясните? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться