|
|
  |
свежак KGP win32/arm/avr/mips/m68k, GNU tools chain |
|
|
|
Oct 30 2009, 20:15
|

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

|
У меня вопрос про 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 , то есть, как мне нужно - запрет прерываний, чтение переменной, восстановление прерываний. Вопрос в следующем: как они этого добились? Делали специальный патч, или просто задали какие-то параметры при сборке? Вернее, вопрос состоит в другом: а нельзя ли сделать как они?  ЗЫ. Вопрос о том, как положено по стандарту - неясен, долгие баталии по этому поводу не дали однозначного ответа. Но, имхо, для эмбеддед приложений второй вариант предпочтительней.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Oct 31 2009, 07:50
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(AHTOXA @ Oct 30 2009, 22:15)  ЗЫ. Вопрос о том, как положено по стандарту - неясен, долгие баталии по этому поводу не дали однозначного ответа. Эт с какой точки зрения смотреть. С моей - Цитата если count (который изменяется где-то независимо от данного участка кода) объявлен как volatile, то всё должно быть нормально в данном случае, так как порядок доступа к volatile-переменным нарушаться не может, а если не volatile, то компилятор вправе двигать - звучит достаточно однозначно :-). И count должен быть volatile в любом случае, а TCritSect обеспечивает только атомарность доступа к нему. Насколько я помню, по итогам обсуждения системный счётчик тиков в scmRTOS стал volatile :-) Неужели тут count квалифицирован как volatile и всё равно бяка?
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Oct 31 2009, 08:22
|

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

|
Цитата(ReAl @ Oct 31 2009, 12:50)  Эт с какой точки зрения смотреть. С моей - - звучит достаточно однозначно :-). Я потерял ссылку на это обсуждение, потому цитировал по памяти Цитата И 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.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Oct 31 2009, 09:35
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(AHTOXA @ Oct 31 2009, 10:22)  Код byte get_count() const { return count; } ... volatile byte count; То есть, таки volatile. Тогда, на мой взгляд, это баг. Чтение count и запись назад в статус менять местами нельзя.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Oct 31 2009, 10:15
|

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

|
Цитата(ReAl @ Oct 31 2009, 14:35)  Тогда, на мой взгляд, это баг. Согласен. А не напомните ссылочку на то обсуждение? --- Хотя... Запись статуса реализована как Код INLINE inline void __set_interrupt_state(TStatusReg status) { __asm__ __volatile__ ( "MSR PRIMASK, %0\n" : : "r"(status) ); } Мне не совсем понятно, является ли в этом случае PRIMASK volatile?
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Oct 31 2009, 14:13
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(AHTOXA @ Oct 31 2009, 12:15)  Согласен. А не напомните ссылочку на то обсуждение? Да оно как-то частично по аськам... Выплеснулось на "исходники.ру", сейчас попробую найти Цитата(AHTOXA @ Oct 31 2009, 12:15)  Код 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: хм, а там модераторы работают, знатно тему почистили, в конце выстрижены все посты кроме моих ответов с примерами кода
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Oct 31 2009, 19:04
|

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

|
Цитата(ReAl @ Oct 31 2009, 19:13)  Хм... а поставьте-ка в clobbered list "memory" в качестве барьера... Да, так всё в порядке. Непонятно только, откуда сборка от CodeSourcery сразу знала про волатильность PRIMASK?  Интересная штука с размером кода получается. Для arm-kgp-elf при внесении "memory" в clobbered list размер моего проекта подрос с 14200 до 14368. А вот для arm-none-eabi- - наоборот, сократился с 15924 до 15812. Первое понятно, отключилась какая-то оптимизация. А вот второе просто удивительно  Цитата Ага, оно. Большое спасибо! --- Да, забыл главное написать. 2 klen - вопрос снят, ваша сборка -- лучшая
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Oct 31 2009, 21:13
|

бессмертным стать можно тремя способами
    
Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912

|
Цитата(AHTOXA @ Oct 31 2009, 22:04)  Да, забыл главное написать. 2 klen - вопрос снят, ваша сборка -- лучшая  стараимсо! Кстате, как Вы это измеряете? собрал компиллер и бинутилс с поддержкой link time optimization (LTO) - но чето пока никак не пойму как это работает, код в 10 раз больше в бинарь суется(мож это и не код). разберусь - выложу свежак. главно что заработало, дальше посмотрим че не так.
|
|
|
|
|
Oct 31 2009, 21:47
|

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

|
Цитата(ReAl @ Nov 1 2009, 02:12)  Ну, в общем-то, этот "ломовой" способ должен бы работать и при всех не-volatile (т.е. шо PRIMASK, шо count). Ну а как ещё сказать компилеру, что PRIMASK волатильный? Поправил порт для кортекса на всякий случай, закоммитил. Цитата(klen @ Nov 1 2009, 02:13)  стараимсо! Кстате, как Вы это измеряете? На глазок  Вот на два поста выше привёл размер кода в сравнении с CodeSourcery. Цитата собрал компиллер и бинутилс с поддержкой link time optimization (LTO) - но чето пока никак не пойму как это работает, код в 10 раз больше в бинарь суется(мож это и не код). разберусь - выложу свежак. главно что заработало, дальше посмотрим че не так. Посмотрим  Но самое главное в новых фичах -- это чтоб их можно было отключить
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Nov 16 2009, 17:35
|

бессмертным стать можно тремя способами
    
Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912

|
свежак для мелких 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. учитывая что сборка происходит на убунте, если требуется кому, могу выкладывать архивы для нинукса. только свисните.
|
|
|
|
|
Nov 18 2009, 08:37
|
Группа: Участник
Сообщений: 8
Регистрация: 6-03-06
Из: Новосибирск
Пользователь №: 15 027

|
Уважаемый klen! Спасибо большое за Вашу работу по GCC. Сейчас это лучшая сборка по ARM. И хочется, чтобы работа с битовыми полями была лучше. Если приведенный ниже пример поможет Вам - буду рад. Пример кода (перекодировка по табличкам) Cortex-M3 -Os CODE 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 CODE 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) CODE 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}
|
|
|
|
|
Dec 1 2009, 09:37
|

бессмертным стать можно тремя способами
    
Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912

|
свежак теперь тулсы будут собиратся c EABI, это дает лучший код. че это такое и очем речь можно по диагоняли посмотреть тут http://infocenter.arm.com/help/topic/com.a...0036B_bsabi.pdfwww.klen.org/Files/DevTools/kgp_arm_eabi_20091127.7z 2_Jat с EABI стало лучше, Вами предложенный код компиляется на 2 инструкции длинне чем у Sourcery G++ Lite 2009q3-68. это скотино зачемто сохраняет в стек регистры которые можно неиспользовать. отсюда удлиннение. курю и думаю. кстате это к работе с битами никакого отношения не имеет. толко к registers usage. Работа с битами очень даже хорошо для кортеха генерится.
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|