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

|
Господа, помогите тормозящему. Надо получить библиотеку для RS-485 (это я так упражняюсь). Все бы ничего, но есть ножка, переключающая прием/передачу, и расположение ее не определено. Ясно, что #define здесь не годится. Объявление Код extern uint8_t Flow_Port, Flow_Pin_Mask; Тоже неприемлемо, потому что мы пытаемся получить инструкции sbi/cbi Значит, надо объявить extern inline функцию. Как правильно это сделать - не могу найти. Помогите,пожалуйста.
|
|
|
|
|
 |
Ответов
|
Feb 11 2008, 12:42
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Feb 11 2008, 13:10
|
;
     
Группа: Участник
Сообщений: 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
|
|
|
|
|
Feb 12 2008, 10:46
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Feb 12 2008, 16:48
|

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

|
Цитата(Сергей Борщ @ Feb 12 2008, 15:46)  сделайте Код #define FLOW_PIN D,4,H // PORTD.4 переключает направление Так ведь для библиотеки это не пойдёт?
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Feb 12 2008, 17:38
|

фанат дивана
     
Группа: Свой
Сообщений: 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
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Feb 12 2008, 18:03
|

Гуру
     
Группа: Модераторы
Сообщений: 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. Может быть можно как-то через инлайн-ассемблер это сделать, но я пока не представляю как и не имею (пока) необходимости разбираться. Я предпочитаю библиотеки в виде исходных текстов - так их легче хранить в репозитории
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Feb 12 2008, 18:53
|

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

|
Цитата(Сергей Борщ @ Feb 12 2008, 23:03)  В вашем примере в ОЗУ выделяется место, в котором хранится указатель на порт и компилятор при всей своей способности к оптимизации обязан считать из него адрес собственно порта. К тому же объявив указатель статическим, вы исключили возможность присвоить ему что-либо за пределами этого (библиотечного) файла. Так это-то как раз хорошо:-) Чтобы я (или не я) не мог лазать в этот порт иначе как через функции библиотеки. Цитата - компилятор не имееет (насколько я знаю) механизма подстановки аргументов команд sbi, cbi на этапе линковки, только на этапе компиляции. Поэтому любая попытка передать адрес порта "извне" приведет к генерации команд lds/in, andi(ori), sts/out вместо sbi, cbi. Да, получается накладнее. Зачастую это приемлемо. Зато — библиотека! Откомпилил, протестил и забыл:-) Цитата Я предпочитаю библиотеки в виде исходных текстов - так их легче хранить в репозитории  Да я тоже в исходных текстах храню. Но эта куча дефайнов... Да и код лишний линкуется. (Я читал топик про способ этого избежать, но пока не пробовал.)
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Feb 12 2008, 20:48
|

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

|
Цитата(AHTOXA @ Feb 12 2008, 20:53)  Так это-то как раз хорошо:-) Чтобы я (или не я) не мог лазать в этот порт иначе как через функции библиотеки. А как вы им начальные значения присвоите кроме как из этого же исходника, т.е. на этапе компиляции библиотеки? Цитата(AHTOXA @ Feb 12 2008, 20:53)  Да я тоже в исходных текстах храню. Но эта куча дефайнов... Да и код лишний линкуется. (Я читал топик про способ этого избежать, но пока не пробовал.) Ну, куча-не куча, ровно столько же сколько и для библиотеки, если только она не привязана намертво к каким-то ногам. А если привязана - то они точно также переносятся в исходник библиотеки. Лишний код не линкуется - один раз настройте правильно компилятор и линкер и все. Из библиотеки лишний код линкуется точно также
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Feb 13 2008, 10:49
|

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

|
Цитата(Сергей Борщ @ Feb 13 2008, 01:48)  Лишний код не линкуется - один раз настройте правильно компилятор и линкер и все. Из библиотеки лишний код линкуется точно также  Попробовал. Не получилось:-) Делаю как описано вот в этом топике. Код 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.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Feb 13 2008, 13:06
|

Гуру
     
Группа: Модераторы
Сообщений: 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  Это вам надо напрямую к Diwilу обращаться, mspgcc - его творение.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Feb 13 2008, 14:13
|

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

|
Цитата(Сергей Борщ @ Feb 13 2008, 18:06)  О! А я думал мы про WinAVR  Ну и про него тоже :-) Просто текущий проект на MSPшке, вот и решил попробовать :-) Цитата Это вам надо напрямую к Diwilу обращаться, mspgcc - его творение. А где он обитает? В конференции про MSP? ЗЫ. Попробовал под WinAVR - работает! Выиграл примерно килобайт из 16 на меге16. Замечательно!
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
Сообщений в этой теме
_Pasha WINAVR: ламерский вопрос Feb 11 2008, 11:59         AHTOXA Цитата(Сергей Борщ @ Feb 13 2008, 01:48) ... Feb 12 2008, 21:11          Сергей Борщ Цитата(AHTOXA @ Feb 12 2008, 23:11) Дык, ... Feb 13 2008, 08:33           AHTOXA Цитата(Сергей Борщ @ Feb 13 2008, 13:33) ... Feb 13 2008, 08:55            gotty Цитата(AHTOXA @ Feb 13 2008, 16:13) Ну и ... Feb 13 2008, 14:31   _Pasha Цитата(Сергей Борщ @ Feb 12 2008, 13:46) ... Feb 13 2008, 08:57    Сергей Борщ Цитата(_Pasha @ Feb 13 2008, 10:57) Дык с... Feb 13 2008, 10:25 _Pasha Подумал и понял свою ошибку.
Это ошибка анализа за... Feb 11 2008, 16:57
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|