реклама на сайте
подробности

 
 
> TEventFlag. порт под msp430, возвращаемое значение IsSignaled()
Sergey Bold
сообщение May 20 2009, 07:55
Сообщение #1





Группа: Участник
Сообщений: 7
Регистрация: 20-05-09
Из: Харьков
Пользователь №: 49 299



Здравствуйте.

Пробую использовать в проекте на msp430 scmRTOS.
Возник вопрос.
Использую событие TEventFlag, проверяю установленно или нет, ну и далее там.

======== Пример ==============
Код
extern OS::TEventFlag g_SF_Initialization;

OS_PROCESS void TTaskZonesDetection::Exec()
{
//    ждем пока наш модуль не будет сконфигурирован
      if( !g_SF_Initialization.IsSignaled() )
    {
        g_SF_Initialization.Wait();
    }

============================

Функция g_SF_Initialization.IsSignaled() всегда возвращает "false", даже если событие установлено.
Немного проясняет листинг, сперва идёт сравнение, потом восстанавливается регистр SR, где флаги после сравнения.
Естественно флаги портятся, и команда JEQ выполняется как душе угодно.

======== Листинг ==============
Код
26          OS_PROCESS void TTaskZonesDetection::Exec()
   \   __code __task void OS::process<OS::pr4, (word)56U>::Exec()
   \                     ??Exec:
     27          {
   \   000000   2183         SUB.W   #0x2, SP
     28          //    ждем пока наш модуль не будет сконфигурирован
     29                if( !g_SF_Initialization.IsSignaled() )
   \   000002   81420000     MOV.W   SR, 0x0(SP)
   \   000006   32C2         DINT
   \   000008   0343         NOP
   \   00000A   D293....     CMP.B   #0x1, &g_SF_Initialization + 2
   \   00000E   2241         MOV.W   0x0(SP), SR
   \   000010   0524         JEQ     ??Exec_3
     30              {
     31                  g_SF_Initialization.Wait();
   \   000012   0E43         MOV.W   #0x0, R14
   \   000014   3C40....     MOV.W   #g_SF_Initialization, R12
   \   000018   B012....     CALL    #??Wait
     32              }

==========================================

IAR пробовал и 3.41 и 4.20.1 - ведут себя одинаково.
Только если выключить всю оптимизацию, в листинге будет правильно работающий код,
но тогда scmRTOS не работает, нужны inline - функции.
Как заставить компилятор генерить работоспособный код?
Или что-то я не понимаю?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
dxp
сообщение May 21 2009, 05:35
Сообщение #2


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(Sergey Bold @ May 20 2009, 14:55) *
Пробую использовать в проекте на msp430 scmRTOS.
Возник вопрос.
Использую событие TEventFlag, проверяю установленно или нет, ну и далее там.

[...]

IAR пробовал и 3.41 и 4.20.1 - ведут себя одинаково.
Только если выключить всю оптимизацию, в листинге будет правильно работающий код,
но тогда scmRTOS не работает, нужны inline - функции.
Как заставить компилятор генерить работоспособный код?
Или что-то я не понимаю?

Странно. У меня иной результат:

Код
OS_PROCESS void TProc1::Exec()
{
    for(;;)
    {   
        if(!ef.IsSignaled())
            ef.Wait();
    }     
}



Результат:

Код
</P><P>############################################################################
###
#                                                                             #
#                                                       21/May/2009  12:27:53 #
# IAR C/C++ Compiler V4.20.1.20017/W32, Evaluation edition for MSP430         #
# Copyright 1996-2008 IAR Systems AB.                                         #</P><P></P><P>
          OS_PROCESS void TProc1::Exec()
__code __cc_version2 __task void OS::process<OS::pr0, (word)200U>::Exec()
                  ??Exec_4:
          {
000000   2183         SUB.W   #0x2, SP
000002   063C         JMP     ??Exec_6
              for(;;)
              {
                  if(!ef.IsSignaled())
                  ??Exec_5:
000004   2241         MOV.W   @SP, SR
                      ef.Wait();
000006   0D43         MOV.W   #0x0, R13
000008   3C40....     MOV.W   #ef, R12
00000C   B012....     CALL    #??Wait
                  ??Exec_6:
000010   81420000     MOV.W   SR, 0(SP)
000014   32C2         DINT
000016   0343         NOP
000018   D293....     CMP.B   #0x1, &ef + 1
00001C   F323         JNE     ??Exec_5
00001E   2241         MOV.W   @SP, SR
000020   F73F         JMP     ??Exec_6
              }



И я не понял, зачам там такое использование. Ведь если посмотреть внутрь TEventFlag::Wait(), то можно увидеть:


Код
    TCritSect cs;

    if(Value)                                           // if flag already signaled
    {                                                  
        Value = efOff;                                  // clear flag
        return true;
    }
    else
    {


т.е. эта проверка, что событие не "просигналено", выполняется внутри самой функции Wait, зачем его еще снаружи проверять?


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение May 21 2009, 06:40
Сообщение #3


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(dxp @ May 21 2009, 08:35) *
... проверка, что событие не "просигналено", выполняется внутри самой функции Wait, зачем его еще снаружи проверять?

Тем более, что эти две отдельные операции не атомарны, т. е. после проверки сигнал снова может быть просигнален в другом процессе.
Смысл этого (проверки на "не просигнален") может быть в том, чтобы в случае else делать какую-то другую работу, а не повисать в ожидании, но это не отменяет предыдущего утверждения.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 19:16
Рейтинг@Mail.ru


Страница сгенерированна за 0.01398 секунд с 7
ELECTRONIX ©2004-2016