anonymous@RULINUX.NET~# Last login: 2024-12-23 12:38:07
Регистрация Вход Новости | Разметка | Пользователи | Галерея | Форум | Статьи | Неподтвержденное | Трекер | Правила форума | F.A.Q. | Ссылки | Поиск
[#] [Добавить метку] [Редактировать]
Скрыть

[AVR-GCC] Проблемы с доступом к переменным из соседнего объектного файлика

Есть библиотечка для работы с UART'ом, состоящая из двух файлов с uart.h и uart.cpp В uart.h как водится дефиниции располагаются, например:

  1.  extern volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
  2.  ...
  3.  extern void uart_putc(unsigned char data);
  4.  

А в uart.cpp, соответственно, имплементация:

  1.  void uart_putc(unsigned char data)
  2.  {
  3.   unsigned char tmphead;
  4.   tmphead = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
  5.   while ( tmphead == UART_TxTail );/* wait for free space in buffer */
  6.   UART_TxBuf[tmphead] = data;
  7.   UART_TxHead = tmphead;
  8.   /* enable UDRE interrupt */
  9.   UART0_CONTROL |= _BV(UART0_UDRIE);
  10.  
/* uart_putc */

}

Всё работает просто зашибись.

Теперь я хочу вышеприведённую функцию сделать инлайновой. Для этого пишу в uart.h следующее:

  1.  
  2.  static inline bool uart_putc_nowait(unsigned char data){
  3.   unsigned char tmphead = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
  4.   if(tmphead == UART_TxTail) return false; // do NOT wait for free space in buffer
  5.   UART_TxBuf[tmphead] = data;
  6.   UART_TxHead = tmphead;
  7.   // enable UDRE interrupt
  8.   UART0_CONTROL |= _BV(UART0_UDRIE);
  9.   return true;
  10.  

} И делаю тестовую программку, которая инициализирует UART и поочереди выводит буквы то старым то новым способом.

Копулятор успешно программку копулирует, но вот при исполнении полученного бинарника оказывается, что первый вызов штатной ф-ии uart_putc() происходит успешно, а потом инлайновый вызов просто портит память и заканчивается ничем (хотя говорит что в буфер байт отложил успешно), все последующие "нормальные" вызовы так же более не работают. Есть мнение что avrgcc почему-то генерит объектный код для main.cpp (откуда вызываются putc-функции) и uart.cpp с разными адресами для буфера и сопутствующих переменных и при линковке это нихера не выравнивается. Вот выдержка из map-файла:

  1.  ...
  2.  
  3.  .data 0x0000000000800060 0xc load address 0x0000000000000510
  4.   0x0000000000800060 PROVIDE (__data_start, .)
  5.   *(.data)
  6.   .data 0x0000000000800060 0x0 /usr/lib/gcc/avr/4.5.3/../../../../avr/lib/crts4433.o
  7.   .data 0x0000000000800060 0x0 ./config.o
  8.   .data 0x0000000000800060 0x0 ./intervalometer.o
  9.   .data 0x0000000000800060 0xc ./main.o
  10.   .data 0x000000000080006c 0x0 ./utl.o
  11.   .data 0x000000000080006c 0x0 ./lib/uartlib/uart.o
  12.  
  13.  ...
  14.  

Вопрос - как заставить инлайн работать?

anonymous(*) (2011-09-22 14:35:00)

[Ответить на это сообщение]
avatar
Скрыть

Re: [AVR-GCC] Проблемы с доступом к переменным из соседнего объектного файлика

Блядь.. Туксоед мы чо, уже на новом движке? Чо с форматированием кода?

anonymous(*)(2011-09-22 14:37:43)

avatar
Скрыть

Re: [AVR-GCC] Проблемы с доступом к переменным из соседнего объектного файлика

подправил как мог

vilfred(*)(2011-09-22 14:46:35)

Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
avatar
Скрыть

Re: [AVR-GCC] Проблемы с доступом к переменным из соседнего объектного файлика

> uart.cpp
Укурок, чтоли? Замени на .c и не насилуй свой проц.

anonymous(*)(2011-09-22 14:48:33)

avatar
Скрыть

Re: [AVR-GCC] Проблемы с доступом к переменным из соседнего объектного файлика

> static inline bool uart_putc_nowait(unsigned char data)
Читай ман про ключевое слово static.

anonymous(*)(2011-09-22 14:49:55)

avatar
Скрыть

Re: [AVR-GCC] Проблемы с доступом к переменным из соседнего объектного файлика

> extern void uart_putc(unsigned char data);
Про extern тоже не помешает прочесть. И код у тебя какой-то странный, каша какая-то (к форматированию это не относится, хотя всё равно скинь на какой-нибудь пастебин, а то мало ли вильфред наформатировал).

anonymous(*)(2011-09-22 14:56:17)

avatar
Скрыть

Re: [AVR-GCC] Проблемы с доступом к переменным из соседнего объектного файлика

> Укурок, чтоли? Замени на .c и не насилуй свой проц.
Чо не так?

> Читай ман про ключевое слово static.
Да пох, без static оно тоже не работает.

> Про extern тоже не помешает прочесть. И код у тебя какой-то странный, каша какая-то
И шрифт тоже хуёвый. Соображения по существу какие-нибудь есть?

anonymous(*)(2011-09-22 15:11:37)

avatar
Скрыть

Re: [AVR-GCC] Проблемы с доступом к переменным из соседнего объектного файлика

> мало ли вильфред наформатировал
Там только закрывающая фигурная скобка выпадает за пределы блока code, в целом похоже на правду.

anonymous(*)(2011-09-22 15:13:49)

avatar
Скрыть

Re: [AVR-GCC] Проблемы с доступом к переменным из соседнего объектного файлика

> Чо не так?
Я не увидел у тебя ничего из С++, поэтому не понимаю, зачем ты применяешь компилятор от плюсов для простого кода для Си.

> И шрифт тоже хуёвый.
Ну при чём тут шрифт? Вот как ты думаешь, что делает вот этот кусок твоего кода:

> while ( tmphead == UART_TxTail );/* wait for free space in buffer */
? И ещё я не понял, где у тебя обозначенный в заголовке "доступ к переменным из соседнего объектного файлика"?

anonymous(*)(2011-09-22 15:37:41)

avatar
Скрыть

Re: [AVR-GCC] Проблемы с доступом к переменным из соседнего объектного файлика

> первый вызов штатной ф-ии uart_putc() происходит успешно, а потом инлайновый вызов просто портит память и заканчивается ничем (хотя говорит что в буфер байт отложил успешно), все последующие "нормальные" вызовы так же более не работают.
И ващё, смотри ассемблерные листинги и бери в руки avr-gdb+simulavr (WinAVR, если религия позволяет) и смотри что у тебя конкретно не так.

anonymous(*)(2011-09-22 15:42:06)

avatar
Скрыть

Re: [AVR-GCC] Проблемы с доступом к переменным из соседнего объектного файлика

s/WinAVR/AvrStudio/;

anonymous(*)(2011-09-22 15:43:29)

avatar
Скрыть

Re: [AVR-GCC] Проблемы с доступом к переменным из соседнего объектного файлика

> Я не увидел у тебя ничего из С++, поэтому не понимаю, зачем ты применяешь компилятор от плюсов для простого кода для Си.
Ну, мне так захотелось.

> Вот как ты думаешь, что делает вот этот кусок твоего кода:
>> while ( tmphead == UART_TxTail );/* wait for free space in buffer */
Я думаю, что он ждёт пока освободится буфер. В инлайновой реализации именно это место выкинуто потому что она используется в обработчике прерывания и у неё ни времени ждать нет ни буфер никогда не освободится если прерывания не разрешить, а разрешить их там нельзя.

> И ещё я не понял, где у тебя обозначенный в заголовке "доступ к переменным из соседнего объектного файлика"?
Пример определения этих переменных я привёл, остальные заданы точно так же. По сути вопроса согласен - скорее правильнее утверждать, что это функции из uart.cpp не там смотрят эти переменные в главной программе.

> И ващё, смотри ассемблерные листинги и бери в руки avr-gdb+simulavr (WinAVR, если религия позволяет) и смотри что у тебя конкретно не так.
Дык что не так понятно: они в разных местах один и тот же свой буфер ищут. У меня для теста в main.cpp реализована точная копия uart_putc() приведённой выше, называется void test_putc(void), не инлайновая и не использует модификаторов и точно так же не работает - сравнить листинги обеих функций легко - видно что они в разные места смотрят:

uart_putc():

  1.  000004a0 :
  2.   4a0: 20 91 b3 00 lds r18, 0x00B3
  3.   4a4: 2f 5f subi r18, 0xFF ; 255
  4.   4a6: 2f 71 andi r18, 0x1F ; 31
  5.   4a8: 90 91 b4 00 lds r25, 0x00B4
  6.   4ac: 29 17 cp r18, r25
  7.   4ae: e1 f3 breq .-8 ; 0x4a8
  8.   4b0: e5 eb ldi r30, 0xB5 ; 181
  9.   4b2: f0 e0 ldi r31, 0x00 ; 0
  10.   4b4: e2 0f add r30, r18
  11.   4b6: f1 1d adc r31, r1
  12.   4b8: 80 83 st Z, r24
  13.   4ba: 20 93 b3 00 sts 0x00B3, r18
  14.   4be: 55 9a sbi 0x0a, 5 ; 10
  15.   4c0: 08 95 ret
  16.  

test_putc():

  1.  0000027a :
  2.   27a: 20 91 91 00 lds r18, 0x0091
  3.   27e: 2f 5f subi r18, 0xFF ; 255
  4.   280: 2f 71 andi r18, 0x1F ; 31
  5.   282: 90 91 92 00 lds r25, 0x0092
  6.   286: 29 17 cp r18, r25
  7.   288: e1 f3 breq .-8 ; 0x282
  8.   28a: e3 e9 ldi r30, 0x93 ; 147
  9.   28c: f0 e0 ldi r31, 0x00 ; 0
  10.   28e: e2 0f add r30, r18
  11.   290: f1 1d adc r31, r1
  12.   292: 80 83 st Z, r24
  13.   294: 20 93 91 00 sts 0x0091, r18
  14.   298: 55 9a sbi 0x0a, 5 ; 10
  15.   29a: 08 95 ret
  16.  

anonymous(*)(2011-09-22 16:05:39)

avatar
Скрыть

Re: [AVR-GCC] Проблемы с доступом к переменным из соседнего объектного файлика

> s/WinAVR/AvrStudio/;
Подозреваю там и секаса с доступом к переменным не было бы :) Однако хочется avr-gcc.

anonymous(*)(2011-09-22 16:07:20)

avatar
Скрыть

Re: [AVR-GCC] Проблемы с доступом к переменным из соседнего объектного файлика

> lds r18, 0x00B3
Тэээкс. А теперь покажи определение той самой UART_TxHead и соседней UART_TxTail. И в каких файлах они у тебя определены тоже показывай.

anonymous(*)(2011-09-22 16:21:57)

avatar
Скрыть

Re: [AVR-GCC] Проблемы с доступом к переменным из соседнего объектного файлика

> Подозреваю там и секаса с доступом к переменным не было бы :) Однако хочется avr-gcc.
Секас будет одинаковый, ибо С. А вот что куда пишется он тебе наглядно в квадратиках покажет.

anonymous(*)(2011-09-22 16:23:05)

avatar
Скрыть

Re: [AVR-GCC] Проблемы с доступом к переменным из соседнего объектного файлика

> А теперь покажи определение той самой UART_TxHead и соседней UART_TxTail. И в каких файлах они у тебя определены тоже показывай.
Бля, спасибо - в правильное место ткнул :)

Проблема разрешилась - вернул переменные из main (относил их туда попробовать) в uart.cpp, т.е. в uart.c теперь внешние объявления:

  1.   extern volatile unsigned char UART_TxHead;
  2.  

а сами переменные в uart.cpp:

  1.   volatile unsigned char UART_TxTail;
  2.  

Результат: скомпилялось и заработало. Вобщем то, что с самого начала пробовал, только вычистил всё что было сгенерировано до этого. Видимо изначально что-то не перекомпилировалось.

anonymous(*)(2011-09-22 16:58:23)

avatar
Скрыть

Re: [AVR-GCC] Проблемы с доступом к переменным из соседнего объектного файлика

uart.c читать как uart.h

anonymous(*)(2011-09-22 16:59:30)

Этот тред читают 2 пользователя:
Анонимных: 2
Зарегистрированных: 0




(c) 2010-2020 LOR-NG Developers Group
Powered by TimeMachine

Valid HTML 4.01 Transitional Правильный CSS!