реклама на сайте
подробности

 
 
> WINAVR: ламерский вопрос
_Pasha
сообщение Feb 11 2008, 11:59
Сообщение #1


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Господа, помогите тормозящему.
Надо получить библиотеку для RS-485 (это я так упражняюсь).
Все бы ничего, но есть ножка, переключающая прием/передачу, и расположение ее не определено.
Ясно, что #define здесь не годится.
Объявление
Код
extern uint8_t Flow_Port, Flow_Pin_Mask;

Тоже неприемлемо, потому что мы пытаемся получить инструкции sbi/cbi
Значит, надо объявить extern inline функцию.
Как правильно это сделать - не могу найти.
Помогите,пожалуйста.
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 20)
Сергей Борщ
сообщение Feb 11 2008, 12:42
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(_Pasha @ Feb 11 2008, 13:59) *
Все бы ничего, но есть ножка, переключающая прием/передачу, и расположение ее не определено.
Очень полезные макросы. Чуть-чуть поправить #ifdef и будут работать с avr-gcc.

А вот тут они же, но уже под avr-gcc, спасибо сказать ReAlу


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 11 2008, 13:10
Сообщение #3


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Сергей Борщ @ Feb 11 2008, 15:42) *
Очень полезные макросы...

Спасибо, но я имел ввиду чуть другое.
Хотел отвязаться от порядка компиляции модулей, из-за чего не хочется пользоваться макросом.
Так, чтобы линкер подставил то ,что надо, а именно Flow_Port |=(1<<Flow_Pin); .

Например:
Код
extern void Flow_Rx(void); // как ее правильно inline описать  в главном модуле?
ISR (UART_TX_vect)
{
Flow_Rx(); /*чтобы здесь оказалось  Flow_Port &= ~(1<<Flow_Pin); без пролога/эпилога и вообще вызова подпрограммы*/
}


Может, это вообще невозможно?

А макросы великолепные.

Сообщение отредактировал _Pasha - Feb 11 2008, 13:14
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 11 2008, 16:57
Сообщение #4


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Подумал и понял свою ошибку.
Это ошибка анализа задачи. Т.е. не там выстраивал иерархию абстракций.
Извините за тему.
Тема закрыта.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 12 2008, 10:46
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(_Pasha @ Feb 11 2008, 15:10) *
Спасибо, но я имел ввиду чуть другое.
Хотел отвязаться от порядка компиляции модулей, из-за чего не хочется пользоваться макросом.
Так, чтобы линкер подставил то ,что надо, а именно Flow_Port |=(1<<Flow_Pin); .
Так вам не нужно это выносить в функцию. Вместо описания отдельных Flow_Port и Flow_Pin сделайте
Код
#define FLOW_PIN  D,4,H // PORTD.4 переключает направление

ISR (UART_TX_vect)
{
    off(FLOW_PIN); /*здесь как раз и окажется PORTD &= ~(1<<4); без пролога/эпилога и вообще вызова подпрограммы*/
    .........
    on(FLOW_PIN); /*а здесь PORTD |= (1<<4); без пролога/эпилога и вообще вызова подпрограммы*/
}
А чтобы сделать что-то "без пролога/эпилога и вообще вызова подпрограммы", функцию можно определить как static inline __attribute__((__always_inline__)).


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 12 2008, 16:48
Сообщение #6


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Сергей Борщ @ Feb 12 2008, 15:46) *
сделайте
Код
#define FLOW_PIN  D,4,H // PORTD.4 переключает направление


Так ведь для библиотеки это не пойдёт?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 12 2008, 17:14
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(AHTOXA @ Feb 12 2008, 18:48) *
Так ведь для библиотеки это не пойдёт?
Да, про библиотеку я невнимательно читал. С библиотекой скорее всего и не получится, ибо компилятор не может гарантировать, что при вызове такой функции в качестве параметров будут переданы константы. Остается только делать библиотеку не в виде объектного файла, а в виде исходника, подключаемого к проекту и пересобираемого с проектом.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 12 2008, 17:38
Сообщение #8


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Сергей Борщ @ Feb 12 2008, 22:14) *
С библиотекой скорее всего и не получится, ибо компилятор не может гарантировать, что при вызове такой функции в качестве параметров будут переданы константы.


Неужели нет какого-нибудь механизма? Было бы очень соблазнительно иметь возможность передавать порты в качестве параметров при инициализации библиотечных модулей...
Вот из faq:
Код
void
set_bits_func_correct (volatile uint8_t *port, uint8_t mask)
{
    *port |= mask;
}


То есть, если в библиотеке держать ссылку на порт (на два порта) и маску, то всё получится?
Типа:
Код
static volatile uint8_t *led_port;  // порт на вывод
static volatile uint8_t *led_dport; // порт направления
static uint8_t led_mask;

void init_led(volatile uint8_t *p, volatile uint8_t *dport, uint8_t mask)
{
  led_port = port;
  led_dport = dport;
  led_mask = mask;
  *dport |= mask;
  *port |= mask;
}

void led_on(void)
{
  *led_port |= led_mask;
}

void led_off(void)
{
  *led_port &= ~led_mask;
}


Немного накладно конечно...

Сообщение отредактировал AHTOXA - Feb 12 2008, 17:39


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 12 2008, 18:03
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(AHTOXA @ Feb 12 2008, 19:38) *
То есть, если в библиотеке держать ссылку на порт (на два порта) и маску, то всё получится?
C ссылкой может и получится, но ссылка - это C++, а не С. В вашем примере в ОЗУ выделяется место, в котором хранится указатель на порт и компилятор при всей своей способности к оптимизации обязан считать из него адрес собственно порта. К тому же объявив указатель статическим, вы исключили возможность присвоить ему что-либо за пределами этого (библиотечного) файла. К сожалению, в С нет типа данных "константный адрес", который тут бы подошел (правда это можно обойти через приведения типа). Но главное - компилятор не имееет (насколько я знаю) механизма подстановки аргументов команд sbi, cbi на этапе линковки, только на этапе компиляции. Поэтому любая попытка передать адрес порта "извне" приведет к генерации команд lds/in, andi(ori), sts/out вместо sbi, cbi. Может быть можно как-то через инлайн-ассемблер это сделать, но я пока не представляю как и не имею (пока) необходимости разбираться. Я предпочитаю библиотеки в виде исходных текстов - так их легче хранить в репозитории smile.gif


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 12 2008, 18:53
Сообщение #10


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Сергей Борщ @ Feb 12 2008, 23:03) *
В вашем примере в ОЗУ выделяется место, в котором хранится указатель на порт и компилятор при всей своей способности к оптимизации обязан считать из него адрес собственно порта. К тому же объявив указатель статическим, вы исключили возможность присвоить ему что-либо за пределами этого (библиотечного) файла.


Так это-то как раз хорошо:-) Чтобы я (или не я) не мог лазать в этот порт иначе как через функции библиотеки.

Цитата
- компилятор не имееет (насколько я знаю) механизма подстановки аргументов команд sbi, cbi на этапе линковки, только на этапе компиляции. Поэтому любая попытка передать адрес порта "извне" приведет к генерации команд lds/in, andi(ori), sts/out вместо sbi, cbi.


Да, получается накладнее. Зачастую это приемлемо. Зато — библиотека! Откомпилил, протестил и забыл:-)

Цитата
Я предпочитаю библиотеки в виде исходных текстов - так их легче хранить в репозитории smile.gif


Да я тоже в исходных текстах храню. Но эта куча дефайнов... Да и код лишний линкуется. (Я читал топик про способ этого избежать, но пока не пробовал.)


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 12 2008, 20:48
Сообщение #11


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(AHTOXA @ Feb 12 2008, 20:53) *
Так это-то как раз хорошо:-) Чтобы я (или не я) не мог лазать в этот порт иначе как через функции библиотеки.
А как вы им начальные значения присвоите кроме как из этого же исходника, т.е. на этапе компиляции библиотеки?
Цитата(AHTOXA @ Feb 12 2008, 20:53) *
Да я тоже в исходных текстах храню. Но эта куча дефайнов... Да и код лишний линкуется. (Я читал топик про способ этого избежать, но пока не пробовал.)
Ну, куча-не куча, ровно столько же сколько и для библиотеки, если только она не привязана намертво к каким-то ногам. А если привязана - то они точно также переносятся в исходник библиотеки. Лишний код не линкуется - один раз настройте правильно компилятор и линкер и все. Из библиотеки лишний код линкуется точно также wink.gif


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 12 2008, 21:11
Сообщение #12


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Сергей Борщ @ Feb 13 2008, 01:48) *
А как вы им начальные значения присвоите кроме как из этого же исходника, т.е. на этапе компиляции библиотеки?


Дык, я же написал:
Код
led_init(PORTB, DDRB, 1);

Это будет в main(), библиотеку перекомпилировать не надо:-)


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 13 2008, 08:33
Сообщение #13


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(AHTOXA @ Feb 12 2008, 23:11) *
Дык, я же написал:
Все, теперь понял. Я изначально зациклился на получении в библиотеке команд sbi, cbi, ну в крайнем случае lds/sts, но никак не на указателях в явном виде. Как-то это расточительно - всю свою сознательную жизнь кристалл будет вынимать из одной и той же ячейки одно и то же значение указателя только из-за того, что у программиста не сложилось вшить этот адрес непосредственно в команду. И ведь понимаю, что это из серии asm vs C, но ничего с собой поделать не могу sad.gif


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 13 2008, 08:55
Сообщение #14


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Сергей Борщ @ Feb 13 2008, 13:33) *
И ведь понимаю, что это из серии asm vs C, но ничего с собой поделать не могу sad.gif


Это ещё что! Говорят, некоторые на C++ программируют! :-)
А если чуть серьёзнее, то я не думаю, что для меги 128 и не очень быстрой периферии (типа ЖКИ) это даст сколько-нибудь заметный оверхед.
Надо будет попробовать, вдруг понравится:-)


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 13 2008, 08:57
Сообщение #15


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Сергей Борщ @ Feb 12 2008, 13:46) *
А чтобы сделать что-то "без пролога/эпилога и вообще вызова подпрограммы", функцию можно определить как static inline __attribute__((__always_inline__)).


Дык с этим аттрибутом Winavr все равно умудряется иногда сформировать подпрограмму. Когда подключал работу с eeprom, заметил это, хотя чтение вызывалось всего один раз. Поэтому не стал разбираться, а задал вопрос.

Повторюсь, что вопрос вызван ошибкой в проектировании и явился следствием долгого писания на асме. ИМХО, правильная портируемая библиотека должна на своем нижнем уровне, работающем с железом, как раз и иметь все варианты через #ifdef..#endif, следовательно, подлежать самой частой перекомпиляции. На примере с RS-485 на данном уровне достаточно экспортировать функции
настройки / работы с буферами, на котором сидят прерывания / единую кодировку ошибок.

И все это с выбором номера порта.

А протоколы - это уже другая песнь, но если не хватает ресурсов, проще, например, работу с 9-ти битной адресацией МК, мультимастеры и прочие дебри решать на данном "полужелезном" уровне. В данном случае "нисходящее проектирования" - отличный способ водить себя за нос, как сказал бы Эйнштейн. smile.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 13 2008, 10:25
Сообщение #16


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(_Pasha @ Feb 13 2008, 10:57) *
Дык с этим аттрибутом Winavr все равно умудряется иногда сформировать подпрограмму.
Это для меня тоже является загадкой. Ведь ясно же ему написано: always. Если вы добавьте компилятору опцию -Winline, то он начнет выдавать предупреждения, что не смог встроить, потому что исчерпал параметр max-inline-insns-single. Можно добавить опцию --param max-inline-insns-single=50 (или побольше), тогда он встраивает все, что хотелось, но вдобавок умудряется встроить и обычные функции, встраивать которые совсем не хотелось.

Цитата(AHTOXA @ Feb 13 2008, 10:55) *
Это ещё что! Говорят, некоторые на C++ программируют! :-)
Пишу, причем после этого написать что-то на чистом С уже тяжело.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 13 2008, 10:49
Сообщение #17


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Сергей Борщ @ Feb 13 2008, 01:48) *
Лишний код не линкуется - один раз настройте правильно компилятор и линкер и все. Из библиотеки лишний код линкуется точно также wink.gif


Попробовал. Не получилось:-)
Делаю как описано вот в этом топике.
Код
cflags    := -c -mmcu=$(cpu) $(include_dirs) -MD -funsigned-char -ffunction-sections -fdata-sections -Os -Wall -g
ldflags    := -mmcu=$(cpu) -Wl,-Map=$(mapfile),--cref,--gc-sections


Компилятор - msp-gcc, вроде самый свежий.
Вылетает на компиляции первого же файла:
Код
--- compiling adc.c
cc1: warning: -ffunction-sections may affect debugging on some targets
src/adc.c:15: Internal compiler error in unique_section, at ./config/msp430/msp430.c:2035
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 13 2008, 13:06
Сообщение #18


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(AHTOXA @ Feb 13 2008, 12:49) *
Вылетает на компиляции первого же файла:
Код
src/adc.c:15: Internal compiler error in unique_section, at ./config/msp430/msp430.c:2035
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
О! А я думал мы про WinAVR smile.gif
Это вам надо напрямую к Diwilу обращаться, mspgcc - его творение.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 13 2008, 14:13
Сообщение #19


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Сергей Борщ @ Feb 13 2008, 18:06) *
О! А я думал мы про WinAVR smile.gif


Ну и про него тоже :-) Просто текущий проект на MSPшке, вот и решил попробовать :-)

Цитата
Это вам надо напрямую к Diwilу обращаться, mspgcc - его творение.


А где он обитает? В конференции про MSP?

ЗЫ. Попробовал под WinAVR - работает! Выиграл примерно килобайт из 16 на меге16. Замечательно!


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
msalov
сообщение Feb 13 2008, 14:31
Сообщение #20


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(AHTOXA @ Feb 13 2008, 16:13) *
Ну и про него тоже :-) Просто текущий проект на MSPшке, вот и решил попробовать :-)
А где он обитает? В конференции про MSP?

Тут есть его e-mail.

Сообщение отредактировал gotty - Feb 13 2008, 14:34
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 13 2008, 14:48
Сообщение #21


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(AHTOXA @ Feb 13 2008, 16:13) *
А где он обитает?
Тут, на форуме. Можно напрямую письмо послать.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 10:18
Рейтинг@Mail.ru


Страница сгенерированна за 0.01582 секунд с 7
ELECTRONIX ©2004-2016