AHTOXA 15 30 октября, 2009 Опубликовано 30 октября, 2009 · Жалоба У меня вопрос про arm-kgp, в части Cortex-M3. Компиляю им проект под scmRTOS, на плюсах. Есть класс-критическая секция: class TCritSect { public: TCritSect () : StatusReg(__get_interrupt_state()) { __disable_interrupt(); } ~TCritSect() { __set_interrupt_state(StatusReg); } private: TStatusReg StatusReg; }; И есть некая использующая эту критическую секцию функция класса: INLINE byte GetCount() const { TCritSect cs; return count; } То есть, идея такая: при входе в функцию создаётся объект TCritSect, при создании запрещаются прерывания, потом выполняется тело функции, и при выходе из неё объект TCritSect разрушается, восстанавливая состояние прерываний. Так вот, её вызов компилится при помощи arm-kgp в следующий код: mrs r3, PRIMASK cpsid i msr PRIMASK, r3 ldrb r0, [r0, #8] bx lr Здесь две первые строчки - конструктор TCritSect (сохранение PRIMASK и запрет прерываний), третья строчка - деструктор TCritSect (разрешение прерываний), и только четвёртая строчка - чтение переменной. То есть, работает не так, как мне бы хотелось. CodeSourcery g++ компилит это вот так: mrs r3, PRIMASK cpsid i ldrb r0, [r0, #6] msr PRIMASK, r3 bx lr , то есть, как мне нужно - запрет прерываний, чтение переменной, восстановление прерываний. Вопрос в следующем: как они этого добились? Делали специальный патч, или просто задали какие-то параметры при сборке? Вернее, вопрос состоит в другом: а нельзя ли сделать как они? :) ЗЫ. Вопрос о том, как положено по стандарту - неясен, долгие баталии по этому поводу не дали однозначного ответа. Но, имхо, для эмбеддед приложений второй вариант предпочтительней. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба ЗЫ. Вопрос о том, как положено по стандарту - неясен, долгие баталии по этому поводу не дали однозначного ответа.Эт с какой точки зрения смотреть. С моей - если count (который изменяется где-то независимо от данного участка кода) объявлен как volatile, то всё должно быть нормально в данном случае, так как порядок доступа к volatile-переменным нарушаться не может, а если не volatile, то компилятор вправе двигать - звучит достаточно однозначно :-). И count должен быть volatile в любом случае, а TCritSect обеспечивает только атомарность доступа к нему. Насколько я помню, по итогам обсуждения системный счётчик тиков в scmRTOS стал volatile :-) Неужели тут count квалифицирован как volatile и всё равно бяка? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба Эт с какой точки зрения смотреть. С моей - - звучит достаточно однозначно :-). Я потерял ссылку на это обсуждение, потому цитировал по памяти:) И count должен быть volatile в любом случае, а TCritSect обеспечивает только атомарность доступа к нему. Ну, атомарность тут обеспечивается архитектурой процессора. То есть, в данном случае критическая секция и не нужна. Насколько я помню, по итогам обсуждения системный счётчик тиков в scmRTOS стал volatile :-) Неужели тут count квалифицирован как volatile и всё равно бяка? Это TChannel.GetCount(). То есть, там на самом деле не return count; а return Cbuf.get_count(); Где Cbuf - TCbuf, и в нём byte get_count() const { return count; } ... volatile byte count; То есть, таки volatile. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба byte get_count() const { return count; } ... volatile byte count; То есть, таки volatile. Тогда, на мой взгляд, это баг. Чтение count и запись назад в статус менять местами нельзя. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба Тогда, на мой взгляд, это баг. Согласен. А не напомните ссылочку на то обсуждение? --- Хотя... Запись статуса реализована как INLINE inline void __set_interrupt_state(TStatusReg status) { __asm__ __volatile__ ( "MSR PRIMASK, %0\n" : : "r"(status) ); } Мне не совсем понятно, является ли в этом случае PRIMASK volatile? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба Согласен. А не напомните ссылочку на то обсуждение?Да оно как-то частично по аськам... Выплеснулось на "исходники.ру", сейчас попробую найти INLINE inline void __set_interrupt_state(TStatusReg status) { __asm__ __volatile__ ( "MSR PRIMASK, %0\n" : : "r"(status) ); } Мне не совсем понятно, является ли в этом случае PRIMASK volatile? Хм... а поставьте-ка в clobbered list "memory" в качестве барьера... upd: вопрос и обсуждение на "исходниках.ру" http://forum.sources.ru/index.php?showtopi...amp;hl=volatile а история аськи уже утеряна upd2: хм, а там модераторы работают, знатно тему почистили, в конце выстрижены все посты кроме моих ответов с примерами кода Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба Хм... а поставьте-ка в clobbered list "memory" в качестве барьера... Да, так всё в порядке. Непонятно только, откуда сборка от CodeSourcery сразу знала про волатильность PRIMASK? :) Интересная штука с размером кода получается. Для arm-kgp-elf при внесении "memory" в clobbered list размер моего проекта подрос с 14200 до 14368. А вот для arm-none-eabi- - наоборот, сократился с 15924 до 15812. Первое понятно, отключилась какая-то оптимизация. А вот второе просто удивительно:) upd: вопрос и обсуждение на "исходниках.ру" http://forum.sources.ru/index.php?showtopi...amp;hl=volatile Ага, оно. Большое спасибо! --- Да, забыл главное написать. 2 klen - вопрос снят, ваша сборка -- лучшая:) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба Да, так всё в порядке.Ну, в общем-то, этот "ломовой" способ должен бы работать и при всех не-volatile (т.е. шо PRIMASK, шо count). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба Да, забыл главное написать. 2 klen - вопрос снят, ваша сборка -- лучшая:) стараимсо! Кстате, как Вы это измеряете? собрал компиллер и бинутилс с поддержкой link time optimization (LTO) - но чето пока никак не пойму как это работает, код в 10 раз больше в бинарь суется(мож это и не код). разберусь - выложу свежак. главно что заработало, дальше посмотрим че не так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба Ну, в общем-то, этот "ломовой" способ должен бы работать и при всех не-volatile (т.е. шо PRIMASK, шо count). Ну а как ещё сказать компилеру, что PRIMASK волатильный? Поправил порт для кортекса на всякий случай, закоммитил. стараимсо! Кстате, как Вы это измеряете? На глазок:) Вот на два поста выше привёл размер кода в сравнении с CodeSourcery. собрал компиллер и бинутилс с поддержкой link time optimization (LTO) - но чето пока никак не пойму как это работает, код в 10 раз больше в бинарь суется(мож это и не код). разберусь - выложу свежак. главно что заработало, дальше посмотрим че не так. Посмотрим:) Но самое главное в новых фичах -- это чтоб их можно было отключить:) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 16 ноября, 2009 Опубликовано 16 ноября, 2009 · Жалоба свежак для мелких arm полный мультитлиб http://www.klen.org/Files/DevTools/kgp_arm_full_20091116.7z обрезок от полного до cortex-m3 http://www.klen.org/Files/DevTools/kgp_arm...-m3_20091116.7z напоминаю, что эти тулсы только компилируя с опцией -mcpu=cortex-m3 мои проекты уменьшились на 1% :) есть подержка LTO, но както оно странно (не)работает, короче ее не использовать, а то в флеш не вместится результат. брат друг и товаришь по форуму Doka сообщил что ему требуется все тоже самое на хосте x86-64. учитывая что сборка происходит на убунте, если требуется кому, могу выкладывать архивы для нинукса. только свисните. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Jat 0 18 ноября, 2009 Опубликовано 18 ноября, 2009 · Жалоба Уважаемый klen! Спасибо большое за Вашу работу по GCC. Сейчас это лучшая сборка по ARM. И хочется, чтобы работа с битовыми полями была лучше. Если приведенный ниже пример поможет Вам - буду рад. Пример кода (перекодировка по табличкам) Cortex-M3 -Os extern unsigned char const k[8][16]; typedef union { struct { unsigned y0: 4; unsigned y1: 4; unsigned y2: 4; unsigned y3: 4; unsigned y4: 4; unsigned y5: 4; unsigned y6: 4; unsigned y7: 4; } y; unsigned int x; } var; unsigned int func( var v ) { v.y.y0 = k[0][v.y.y0]; v.y.y1 = k[1][v.y.y1]; v.y.y2 = k[2][v.y.y2]; v.y.y3 = k[3][v.y.y3]; v.y.y4 = k[4][v.y.y4]; v.y.y5 = k[5][v.y.y5]; v.y.y6 = k[6][v.y.y6]; v.y.y7 = k[7][v.y.y7]; return v.x; } GCC: (Sourcery G++ Lite 2009q3-68) 4.4.1 20 func: 24 0000 1A4B ldr r3, .L3 25 0002 00F00F02 and r2, r0, #15 26 0006 9A5C ldrb r2, [r3, r2] @ zero_extendqisi2 27 0008 62F30300 bfi r0, r2, #0, #4 28 000c C0F30312 ubfx r2, r0, #4, #4 29 0010 9A18 adds r2, r3, r2 30 0012 127C ldrb r2, [r2, #16] @ zero_extendqisi2 31 0014 62F30710 bfi r0, r2, #4, #4 32 0018 C0F30322 ubfx r2, r0, #8, #4 33 001c 9A18 adds r2, r3, r2 34 001e 92F82020 ldrb r2, [r2, #32] @ zero_extendqisi2 35 0022 62F30B20 bfi r0, r2, #8, #4 36 0026 C0F30332 ubfx r2, r0, #12, #4 37 002a 9A18 adds r2, r3, r2 38 002c 92F83020 ldrb r2, [r2, #48] @ zero_extendqisi2 39 0030 62F30F30 bfi r0, r2, #12, #4 40 0034 C0F30342 ubfx r2, r0, #16, #4 41 0038 9A18 adds r2, r3, r2 42 003a 92F84020 ldrb r2, [r2, #64] @ zero_extendqisi2 43 003e 62F31340 bfi r0, r2, #16, #4 44 0042 C0F30352 ubfx r2, r0, #20, #4 45 0046 9A18 adds r2, r3, r2 46 0048 92F85020 ldrb r2, [r2, #80] @ zero_extendqisi2 47 004c 62F31750 bfi r0, r2, #20, #4 48 0050 C0F30362 ubfx r2, r0, #24, #4 49 0054 9A18 adds r2, r3, r2 50 0056 92F86020 ldrb r2, [r2, #96] @ zero_extendqisi2 51 005a 62F31B60 bfi r0, r2, #24, #4 52 005e 03EB1073 add r3, r3, r0, lsr #28 53 0062 93F87030 ldrb r3, [r3, #112] @ zero_extendqisi2 54 0066 63F31F70 bfi r0, r3, #28, #4 55 006a 7047 bx lr GCC: (Klen's GCC package (KGP) for ARM/elf platform) 4.5.0 20091115 (experimental) 10 func: 13 0000 F3B5 push {r0, r1, r4, r5, r6, r7, lr} 14 0002 1E4B ldr r3, .L2 15 0004 00F00F0C and ip, r0, #15 16 0008 C0F30311 ubfx r1, r0, #4, #4 17 000c 13F80C60 ldrb r6, [r3, ip] @ zero_extendqisi2 18 0010 5918 adds r1, r3, r1 19 0012 C0F30322 ubfx r2, r0, #8, #4 20 0016 91F810C0 ldrb ip, [r1, #16] @ zero_extendqisi2 21 001a 9A18 adds r2, r3, r2 22 001c C0F30351 ubfx r1, r0, #20, #4 23 0020 C0F30335 ubfx r5, r0, #12, #4 24 0024 C0F30344 ubfx r4, r0, #16, #4 25 0028 1C19 adds r4, r3, r4 26 002a 0091 str r1, [sp, #0] 27 002c C0F30367 ubfx r7, r0, #24, #4 28 0030 03EB1071 add r1, r3, r0, lsr #28 29 0034 92F82020 ldrb r2, [r2, #32] @ zero_extendqisi2 30 0038 5D19 adds r5, r3, r5 31 003a 66F30300 bfi r0, r6, #0, #4 32 003e 95F83050 ldrb r5, [r5, #48] @ zero_extendqisi2 33 0042 6CF30710 bfi r0, ip, #4, #4 34 0046 94F840C0 ldrb ip, [r4, #64] @ zero_extendqisi2 35 004a 009C ldr r4, [sp, #0] 36 004c 62F30B20 bfi r0, r2, #8, #4 37 0050 0191 str r1, [sp, #4] 38 0052 65F30F30 bfi r0, r5, #12, #4 39 0056 1919 adds r1, r3, r4 40 0058 91F85020 ldrb r2, [r1, #80] @ zero_extendqisi2 41 005c DB19 adds r3, r3, r7 42 005e 6CF31340 bfi r0, ip, #16, #4 43 0062 DDF804C0 ldr ip, [sp, #4] 44 0066 93F86010 ldrb r1, [r3, #96] @ zero_extendqisi2 45 006a 62F31750 bfi r0, r2, #20, #4 46 006e 9CF87030 ldrb r3, [ip, #112] @ zero_extendqisi2 47 0072 61F31B60 bfi r0, r1, #24, #4 48 0076 63F31F70 bfi r0, r3, #28, #4 49 007a FCBD pop {r2, r3, r4, r5, r6, r7, pc} Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 1 декабря, 2009 Опубликовано 1 декабря, 2009 · Жалоба свежак теперь тулсы будут собиратся c EABI, это дает лучший код. че это такое и очем речь можно по диагоняли посмотреть тут http://infocenter.arm.com/help/topic/com.a...0036B_bsabi.pdf www.klen.org/Files/DevTools/kgp_arm_eabi_20091127.7z 2_Jat с EABI стало лучше, Вами предложенный код компиляется на 2 инструкции длинне чем у Sourcery G++ Lite 2009q3-68. это скотино зачемто сохраняет в стек регистры которые можно неиспользовать. отсюда удлиннение. курю и думаю. кстате это к работе с битами никакого отношения не имеет. толко к registers usage. Работа с битами очень даже хорошо для кортеха генерится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 59 1 декабря, 2009 Опубликовано 1 декабря, 2009 · Жалоба 2 klen а для AVR вы сборки не делаете? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 1 декабря, 2009 Опубликовано 1 декабря, 2009 · Жалоба 2 klen а для AVR вы сборки не делаете? делаю Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться