Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Объектные файлы...
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Злодей
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.
kurtis
Наверно как-то так http://www.nongnu.org/avr-libc/user-manual/library.html
А отдавать .o файлы это по моему не самая хорошая идея.
Цитата
Вроде всё хорошо, но только человеку придётся добавлять в свой проект мои исходники, и они будут у него постоянно make clean -> make all, захламляя и без того неудобочитаемую консоль своими OMG! Warning!

Зачем постоянно делать "make clean" ? Утилита Make для того и нужна чтоб не компилировать постоянно весь проект заново а только те части которые изменились.
А с предупреждениями компилятора нужно бороться!
Кстати посмотрите как сделан вывод при компиляции примеров из scmRTOS. Удобно и наглядно. Ошибки с предупреждениями сразу бросаются в глаза.
demiurg_spb
Хорошо написанная программа должна штатно компилиться без единого warning'a...
Goodefine
А у меня один на ровном месте вылазит smile.gif
Код
...    
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
Злодей
Ребята, ну я же образно.
zltigo
Цитата(Goodefine @ Jun 23 2009, 17:30) *
А у меня один на ровном месте вылазит smile.gif

Смею Вас со всей определенностью заверить, что никакого "ровного места" у Вас при таком Warning и близко нет - что-то КРИВО написали стыдливо скрыв за многоточиями. Либо реальная ошибка, либо скажите компилятору с чем он работает.
Goodefine
Цитата(zltigo @ Jun 23 2009, 18:26) *
...что-то КРИВО написали стыдливо скрыв за многоточиями. Либо реальная ошибка, либо скажите компилятору с чем он работает.

Собственно, там и скрывать то особо нечего, функция предельно проста, в окончательном варианте:
Код
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
Так тоже ругается?
Код
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
Так не ругается, но почему ему вариант с индексом не нравится?
P.S.
В, общем, если заменить
Код
...segment_table[*(buffer+i)];

на
Код
...segment_table[buffer[i]];

то Warning исчезает... Хотя в любом Си учебнике написано, что *(buffer+i) <=> buffer[i] ...
dimka76
Цитата(Goodefine @ Jun 23 2009, 18:30) *
А у меня один на ровном месте вылазит smile.gif
Код
...    
for (uchar8 i=0;i<len;i++)
                {...
                buffer[i]= segment_table[*(buffer+i)];
                 ...          
                }


Я думаю, предупреждение возникает из-за потенциальной опасности при операции сложения.
Предположим
Код
unsigned char i = 254;

i += 10; // вот тут и произошло переполнение
demiurg_spb
Цитата(Goodefine @ Jun 24 2009, 10:54) *
Хотя в любом Си учебнике написано, что *(buffer+i) <=> buffer[i] ...
Учебники как правило не обманываютsmile.gif
Так можно ускорить процедуру, убрав из цикла условие...
Код
#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
Цитата(demiurg_spb @ Jun 24 2009, 12:36) *
Так можно ускорить процедуру, убрав из цикла условие...

Некоторое ускорение конечно есть (16.6мкс против 20.8мкс), но если учесть, что проверка нужна для предотвращения выхода за пределы массива segment_table его индексов, коими являются числа, лежащие в buffer (иначе говоря, контроль, за предшествующей функцией преобразования buffer-а), то Ваш способ, к сожалению, не работает. А без проверки и так 16.6мкс выходит....
Цитата(demiurg_spb @ Jun 24 2009, 12:36) *
И сбрасывать сторожевой таймер не надо в каждом цикле...

Тут я с Вами соглашусь...
demiurg_spb
Цитата(Goodefine @ Jun 24 2009, 14:10) *
Некоторое ускорение конечно есть (16.6мкс против 20.8мкс), но если учесть, что проверка нужна для предотвращения выхода за пределы массива segment_table его индексов, коими являются числа, лежащие в buffer (иначе говоря, контроль, за предшествующей функцией преобразования buffer-а), то Ваш способ, к сожалению, не работает.
Ах да. Я ошибся и понял Ваш алгоритм совсем неверно... XVR предложил хорошее решение...
Goodefine
Цитата(demiurg_spb @ Jun 24 2009, 13:50) *
...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[i] на *(buffer+i) и разный результат компиляции... Пути компилятора неисповедимы smile.gif
VladimirYU
Цитата(demiurg_spb @ Jun 24 2009, 13:36) *
А лепить wdr() в каждом цикле - ошибка!

Почему, если не секрет? Ошибка ИМХО, если wdr в обработчиках прерываний, в фоне, по-моему, сколько хочешь сбрасывай. Или я ошибаюсь, поясните?
Goodefine
Цитата(VladimirYU @ Jun 24 2009, 15:08) *
Почему, если не секрет?

Я, так понимаю, для гарантии того, что программа выполняется так как задумано - каждый раз, по весне, возвращается в одно и то же место по кругу. Если зависнет в любом другом месте, то сброс...
demiurg_spb
Цитата(VladimirYU @ Jun 24 2009, 16:08) *
Почему, если не секрет?
Не секрет. Да в прерываниях тоже ошибка.
Цитата(Goodefine @ Jun 24 2009, 16:20) *
Я, так понимаю, для гарантии того, что программа выполняется так как задумано - каждый раз, по весне, возвращается в одно и то же место по кругу. Если зависнет в любом другом месте, то сброс...
Именно так. Надёжность повышается. Надо экономить патроны: один выстрел - один трупsmile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.