|
|
  |
опять про оптимизацию :( глюк нашел вроде |
|
|
|
Feb 4 2009, 11:52
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
во время выполнения FreeRTOS непонятным образом сами собой запрещались прерывания. Путем несложной трассировки выяснил, что происходят они при парном вызове vPortEnterCritical() - vPortExitCritical(), по принципу Код portTickType xTaskGetTickCount( void ) { portTickType xTicks;
/* Critical section required if running on a 16 bit processor. */ taskENTER_CRITICAL(); { xTicks = xTickCount; } taskEXIT_CRITICAL();
return xTicks; } сами процедуры с виду простейшие Код void vPortEnterCritical( void ) { /* Disable interrupts first! */ __disable_interrupt();
/* Now interrupts are disabled ulCriticalNesting can be accessed directly. Increment ulCriticalNesting to keep a count of how many times portENTER_CRITICAL() has been called. */ ulCriticalNesting++; } /*-----------------------------------------------------------*/ void vPortExitCritical( void ) { if( ulCriticalNesting > portNO_CRITICAL_NESTING ) { /* Decrement the nesting count as we are leaving a critical section. */ ulCriticalNesting--;
/* If the nesting level has reached zero then interrupts should be re-enabled. */ if( ulCriticalNesting == portNO_CRITICAL_NESTING ) { __enable_interrupt(); } } }
portNO_CRITICAL_NESTING разумеется = 0 однако, что я получаю при трасировке: Код ??vPortPreemptiveTick_0: 00017E5C 004000E0 DC32 0xE0004000 __disable_interrupt(); vPortEnterCritical: vPortEnterCritical: 00017E60 E10F0000 MRS R0, CPSR 00017E64 E38000C0 ORR R0, R0, #0xC0 00017E68 E121F000 MSR CPSR_c, R0 ulCriticalNesting++; 00017E6C E59F003C LDR R0, [PC, #+60] ; [??DataTable1 (0x17EB0)] =ulCriticalNesting (0x4000F3B8) 00017E70 E5901000 LDR R1, [R0, #+0] 00017E74 E2811001 ADD R1, R1, #0x1
до этого момента все выполняется как надо, адрес в R0, правильное значение в R1
*pxTopOfStack = portNO_CRITICAL_NESTING; Next label is a Thumb label ?Subroutine0: .text_19: 00017E78 6001 STR R1, [R0, #0]
не имеет никакого эффекта, значение не обновляется
return pxTopOfStack; 00017E7A 4770 BX LR
не выполняется вообще соттветственно, дальше выполняется vPortExitCritical:
if( ulCriticalNesting > portNO_CRITICAL_NESTING ) vPortExitCritical: vPortExitCritical: 00017E7C E59F002C LDR R0, [PC, #+44] ; [??DataTable1 (0x17EB0)] =ulCriticalNesting (0x4000F3B8) 00017E80 E5901000 LDR R1, [R0, #+0] 00017E84 E3510000 CMP R1, #0x0
поскольку значение ulCriticalNesting не было инкрементировано, проверка отрицательная, дальше выход
00017E88 0A000007 BEQ ??vPortExitCritical_0 ; 0x17EAC
ulCriticalNesting--; 00017E8C E5901000 LDR R1, [R0, #+0] 00017E90 E2411001 SUB R1, R1, #0x1 00017E94 E5801000 STR R1, [R0, #+0] if( ulCriticalNesting == portNO_CRITICAL_NESTING ) 00017E98 E5900000 LDR R0, [R0, #+0] 00017E9C E3500000 CMP R0, #0x0 __enable_interrupt(); 00017EA0 010F0000 MRSEQ R0, CPSR 00017EA4 03C000C0 BICEQ R0, R0, #0xC0 00017EA8 0121F000 MSREQ CPSR_c, R0 } ??vPortExitCritical_0: 00017EAC E12FFF1E BX LR
... итог - после выхода из vPortEnterCritical значение ulCriticalNesting нулевое, прерывания запрещены, вызов vPortExitCritical не имеет значения. При уменьшении уровня оптимизации все нормализуется. volatile не влияет на исполнение. Поскольку я в ассемблере мягко говоря не силен, одолеть эту задачку мне оказалось не по зубам
|
|
|
|
|
Feb 4 2009, 11:56
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergik_vrn @ Feb 4 2009, 14:52)  Поскольку я в ассемблере мягко говоря не силен, одолеть эту задачку мне оказалось не по зубам Не заметили волшебное превращение ARM в Thumb: Цитата 00017E74 E2811001 ADD R1, R1, #0x1 00017E78 6001 STR R1, [R0, #0] Так в жизни не бывает
|
|
|
|
|
Feb 4 2009, 12:51
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(aaarrr @ Feb 4 2009, 14:56)  Не заметили волшебное превращение ARM в Thumb: ну я вообще-то задумался, откуда там thumb, но понимания от этого не прибавилось  кстати, если процедуру сделать __arm (кстати, в порте под STR710 она именно __arm __interwork), результат не меняется, буква в букву Цитата Так в жизни не бывает  однако, это компилятор такой код генеряет. и, судя по всему, мешает thumb c arm в целях оптимизации (во всяком случае, вызов *pxTopOfStack = portNO_CRITICAL_NESTING; явно не отсюда приплетен. ошибка?
|
|
|
|
|
Feb 4 2009, 13:09
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(Rst7 @ Feb 4 2009, 15:57)  Жестко... А посмотрите в листинг, где еще встречается ?Subroutine0, т.е. кто к ней ходит? прикрепил листинг-файл Цитата И кстати, что за компилятор? Версия, в смысле, ну и прочие параметры настроек. IAR ARM 5.30.1, LPC 2478, оптимизация максимальная(hz), все параметры вызова компилятора есть в листинге
|
|
|
|
|
Feb 4 2009, 15:15
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(Rst7 @ Feb 4 2009, 16:37)  Посмотрел. А что, у нас нынче IAR сам выбирает, какой ему режим делать? Что-то я вижу в листинге помесь arm и thumb, но не вижу ни __arm, ни __thumb...
Но похоже, действительно баг. Рекомендую как пути обхода:
1. Не использовать в одном файле одновременно __arm и __thumb 2. Забить на тумбу в принципе, хотя бы в операционке. ну, собственно, если IAR сам будет выбирать режим, то вариант 1 будет трудно реализовать на практике... пока что влепил #pragma optimize = medium для этих двух функций, полет нормальный. IAR 5.20, кстати, ведет себя аналогично, а вот в 4.41 подобных глюков не было (правда, там процессор STR710)
|
|
|
|
|
Feb 4 2009, 15:40
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(Rst7 @ Feb 4 2009, 18:33)  Поставили бы Вы оптимизацию High Speed, а не Size. попробую при случае. причина такого выбора метода оптимизации проста, проект здоровый, в самом большом варианте еле-еле помещается в ПЗУ контроллера. А разная компиляция - разные глюки  Впрочем, надо будет попробовать все равно
|
|
|
|
|
Feb 5 2009, 08:02
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(Rst7 @ Feb 4 2009, 18:58)  Возьмите следующий камень в линейке. Тем более, что цены на LPC более чем демократичны. Или 2478 - самый здоровый по Flash? Если да, то предлагаю такой способ. Указываете High Speed и руками для каждого файла выбираете ARM или Thumb. Причем, операционку очень желательно в ARM-режиме собирать, веселее будет. А дальше смотреть по месту. сами понимаете, просто так "взять следующий камень" не так просто, как хотелось бы, при серийном производстве. впрочем, 2478 тьфу-тьфу пока по этим параметрам не напрягает, речь была про STR710, а он-таки самый жирный в линейке. насчет предложенного способа - спасибо, попробую, как только образуется дыра в расписании. щас вот бьюсь, в другом месте вылезли глюки в многократно отлаженном на разных процессорах коде  уже подумываю откатиться на 4.41
|
|
|
|
|
Feb 5 2009, 10:08
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(sergik_vrn @ Feb 5 2009, 11:02)  сами понимаете, просто так "взять следующий камень" не так просто, как хотелось бы, при серийном производстве. впрочем, 2478 тьфу-тьфу пока по этим параметрам не напрягает, речь была про STR710, а он-таки самый жирный в линейке. насчет предложенного способа - спасибо, попробую, как только образуется дыра в расписании. щас вот бьюсь, в другом месте вылезли глюки в многократно отлаженном на разных процессорах коде  уже подумываю откатиться на 4.41  попробовал собрать проект с оптимизацией по скорости. размер вырос со 130К до 170К, глюки с data_abort в отлаженном коде пропали. Пока работаю так, дальше посмотрим
|
|
|
|
|
Feb 15 2009, 09:48
|

Знающий
   
Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206

|
Цитата(sergik_vrn @ Feb 12 2009, 17:40)  очередной глюк с data abort в отлаженном коде, при вызове виртуального метода. на этот раз с оптимизацией по скорости. полдня убил, лечится, как обычно, снижением уровня оптимизации в конкретной функции. Чувствую, откачусь я на 4.41, мне такие сюрпризы все нервы съедят  А вы не пробовали урезать проект до минимума, но так, чтобы баг проявлялся, и в багрепорт IAR отписать? Все же при баг-репорте на лицензионность ПО пофиг, тем более вы можете сослаться на то, что работаете с eval версией. Я так отписывал им еще на 4.20, в следующей версии посмотрел на список изменений, мой баг фигурировал как исправленный.
--------------------
Пасу котов...
|
|
|
|
|
Feb 15 2009, 11:04
|

Знающий
   
Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206

|
Цитата(Rst7 @ Feb 4 2009, 19:37)  Посмотрел. А что, у нас нынче IAR сам выбирает, какой ему режим делать? Что-то я вижу в листинге помесь arm и thumb, но не вижу ни __arm, ни __thumb... Это как раз просто - инструкции MRS и MSR существуют только для arm режима, поэтому при вызове функций разрешения и запрещения прерываний принудительно устанавливается режим arm. Судя по всему, функции __disable_interrupt() и __enable_interrupt() инлайнятся, и компилятор ту функцию, из которой они вызываются также переводит режим ARM. Возможно, у него есть какие-то критерии, когда он это будет делать. Предположу, что если размер функции относительно небольшой, то он будет выполнять такую оптимизацию, а если большой - то нет.
--------------------
Пасу котов...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|