Странные косяки в операционке при задержке >30мс (каша в регистрах)

Тема в разделе "WASM.OS.DEVEL", создана пользователем Arisu, 28 ноя 2007.

  1. Arisu

    Arisu Алиса Селезнёва

    Публикаций:
    0
    Регистрация:
    10 апр 2007
    Сообщения:
    89
    Значит занимаюсь я сейчас переносом одной промышленной ОС реального времени на новую платформу и по ходу дела наткнулся на страшный и непонятный мне баг, с которым я ничего не могу поделать.

    Сам баг: при попытке сделать ожидание больше 30мс приводит к срыву башни у процессора. Он фактически начинает пропускать вызов функцй, или возвращать неверные значения, в регистрах, стеке и локальных переменных начинает творится чёрти что. И причем ничего этого за хвост схватить нельзя т.к. единственное средство отладки - это вывод на экран, который после бага тоже начинает работать так: "хочу вывожу, хочу - не вывожу" (вывод на прямую в видеопамять). Т.е. ничего толком и не проверить.

    Функция задержки - написана вручную, код внизу сообщения.

    Место в оси: баг происходит ДО захода в реальное время. Т.е. диспетчер задач уже включен, но он следит за временем только тасков, а место, в котором я словил баг - это первичная настройка и инициализация всякой системной фигни, и она происходит не в реальном времени. Т.е. за ней диспетчер не следит.
    Никаких других потоков кроме этого не запущено. Обработчик прерываний - асинхронный. т.е. не считается потоком.
    Фактически баг происходит в одной единственной нити кода и что тут может сломаться на пустом месте из за обычного ожидания - кардинально неясно.

    Что я пробовал:
    1) отключал прерывания перед запуском ожидания (и через cli и 21 порт)
    2) отрубал обработчик прерываний системного таймера нашей оси
    3) заменял функцию ожидания на простые операции умножения (ну малоли функция косячит)

    ничего не помогло.

    Вот функция ожидания, но я уверен что проблема совсем не в ней. Я склоняюсь что косяк из за прерываний от системного таймера (т.к. всё остальное я вроде убивал).

    Код (Text):
    1. void Delay( WORD Msec )
    2. {
    3.     DWORD i;
    4.     DWORD TicksToWaitlo;
    5.     DWORD TicksToWaithi;
    6.     DWORD Ticks1lo;
    7.     DWORD Ticks1hi;
    8.     DWORD Ticks2lo;
    9.     DWORD Ticks2hi;
    10.        
    11.        
    12.         TicksToWaitlo = (DWORD)Msec * ((DWORD)SysCpuFreqMhz * 1000L);
    13.         TicksToWaithi = 0;
    14.         Ticks1lo = 0;
    15.         Ticks1hi = 0;
    16.         Ticks2lo = 0;
    17.         Ticks2hi = 0;
    18.    
    19.         if ( Msec <= 0 ) return;
    20.    
    21.         asm db 0x0f, 0x31 //rdtsc
    22.         asm db 0x66
    23.         asm mov word ptr Ticks1lo, ax
    24.         asm db 0x66
    25.         asm mov word ptr Ticks1hi, dx  
    26.        
    27.         while ( 1 ) {
    28.             asm db 0x0f, 0x31 //rdtsc
    29.             asm db 0x66
    30.             asm mov word ptr Ticks2lo, ax
    31.             asm db 0x66
    32.             asm mov word ptr Ticks2hi, dx
    33.        
    34.             if ( ( (Ticks2hi - Ticks1hi) >= TicksToWaithi ) &&
    35.            ( (Ticks2lo - Ticks1lo) >= TicksToWaitlo ) ) return;
    36.         }
    37. }
     
  2. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    Arisu

    А не может эта ось использовать какой-нить там таймер ACPI или ещё что-нибудь в этом роде, и при больших задержках просто-напросто не отрабатывать какие-то действия вовремя?
     
  3. Arisu

    Arisu Алиса Селезнёва

    Публикаций:
    0
    Регистрация:
    10 апр 2007
    Сообщения:
    89
    я ещё не досконально изучил систему, но как я уже писал выше: к моменту где мне нужно сделать задержку - ни одина из задач, которые критичны ко времени ещё не запущины.
    Да, есть диспетчер, но он ничего не делает т.к. его очередь пуста.

    И потом любое нарушение реального времени в этой системе приводит к безопасному необратимому состоянию, но никак не к каше в регистрах и стеке
     
  4. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    Arisu

    Ну так ACPI используется и при инициализации системы, а не только при обычной работе... А вообще гадать тяжело, даже если имеется кофейная гуща :)
     
  5. bugaga

    bugaga New Member

    Публикаций:
    0
    Регистрация:
    1 июл 2007
    Сообщения:
    361
    Код (Text):
    1. asm db 0x66
    2. asm mov word ptr Ticks2lo, ax
    3. asm db 0x66
    4. asm mov word ptr Ticks2hi, dx
    Ну на подобном "коде" любое глюкалово возможно :)
     
  6. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    А это чудо на чём написано, не на Borland C 3.1, случайно?
     
  7. Arisu

    Arisu Алиса Селезнёва

    Публикаций:
    0
    Регистрация:
    10 апр 2007
    Сообщения:
    89
    на нём родимом ))). ось 16-и битная, как вы уже догадались.

    ну да. в принципе тонны чужого кода без комментариев и какой либо документации именно кофейную гущу и напоминает ). но мне нужно заставить это работать.

    я пока только придумал как мне избежать задержки в 30мс в том месте и проскочить дальше. Но в итоге эта система перестанет называтся "отказоустойчивой" и "повышенной стабильности" )) т.к. в ней будет жить баг, который может никогда и не пройзойдёт, но он там будет.
     
  8. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Я бы на всякий случай мэджик с rdtsc вынес в отдельную функцию. И глянул бы дизасм кода. Благо Borland C 3.1 умеет генерить асмовый код.
    А перед rdtsc и после сохранения значения сделал бы pusha/popa.
     
  9. Arisu

    Arisu Алиса Селезнёва

    Публикаций:
    0
    Регистрация:
    10 апр 2007
    Сообщения:
    89
    SadKo
    асм код я смотрел. там всё вроде бы логично. регистры сохранять попробую конечно, ведь я меняю старшую часть и потом она может где-то "всплыть", но как я уже писал выше - не важно как устроена задержка. Даже если это простые математические операции - система всё равно рушится на глазах.

    SII
    ОС использует только системный таймер. ACPI таймера нет.
     
  10. bugaga

    bugaga New Member

    Публикаций:
    0
    Регистрация:
    1 июл 2007
    Сообщения:
    361
    арси.. а што за компиль какими ключами компилишь на какой тачке проверяешь.. походу с кодом все хорошо..
     
  11. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Посмотри. Может, где счётчик какой переполняется. Может стек. Пожет имеет место повторная входимость в прерывания.
     
  12. bugaga

    bugaga New Member

    Публикаций:
    0
    Регистрация:
    1 июл 2007
    Сообщения:
    361
    Хм... для 16-битново сакса BCC 5.0 компиль сделал весьма хороший код, мну ево немонжко видоизменил чтоб заюзать в комовом сэмпле.

    Видимо проблема можит крыццо, в использовании в некоторых местах межсегменных длинных сall-ов, а подпрогамма делает вмест retf делает retn... Тут да вэлкам то глюкалово не снившийся даже в протектед моде..

    а! вота код:
    Код (Text):
    1. .model tiny
    2. .386
    3. .code
    4. @Delay  proc    ;far
    5.    ;                             AX           DX
    6.    ;    void _fastcall Delay(WORD Msec, WORD SysCpuFreqMhz)
    7.    ;   
    8.     push    bp
    9.     mov bp,sp
    10.     sub sp,26
    11.     push    si
    12.     push    di
    13.     mov word ptr [bp-2],ax
    14.     mov cx,dx
    15.    ;   
    16.    ;    {
    17.    ;   
    18.    ;    DWORD i;
    19.    ;    DWORD TicksToWaitlo;
    20.    ;    DWORD TicksToWaithi;
    21.    ;    DWORD Ticks1lo;
    22.    ;    DWORD Ticks1hi;
    23.    ;    DWORD Ticks2lo;
    24.    ;    DWORD Ticks2hi;
    25.    ;   
    26.    ;   
    27.    ;    TicksToWaitlo = (DWORD)Msec * ((DWORD)SysCpuFreqMhz * 1000L);
    28.    ;   
    29.     movzx   edx,cx
    30.     movzx   ebx,word ptr [bp-2]
    31.     imul    edx,ebx
    32.     imul    edx,large 1000
    33.     mov dword ptr [bp-6],edx
    34.    ;   
    35.    ;    TicksToWaithi = 0;
    36.    ;   
    37.     mov dword ptr [bp-10],large 0
    38.    ;   
    39.    ;    Ticks1lo = 0;
    40.    ;   
    41.     mov dword ptr [bp-14],large 0
    42.    ;   
    43.    ;    Ticks1hi = 0;
    44.    ;   
    45.     mov dword ptr [bp-18],large 0
    46.    ;   
    47.    ;    Ticks2lo = 0;
    48.    ;   
    49.     mov dword ptr [bp-22],large 0
    50.    ;   
    51.    ;    Ticks2hi = 0;
    52.    ;   
    53.     mov dword ptr [bp-26],large 0
    54.    ;   
    55.    ;   
    56.    ;    if ( Msec <= 0 ) return;
    57.    ;   
    58.     cmp word ptr [bp-2],0
    59.     jbe short @1@14
    60.    ;   
    61.    ;   
    62.    ;    asm db 0x0f, 0x31 //rdtsc
    63.    ;   
    64.     db   00fH, 031H
    65.    ;   
    66.    ;    asm db 0x66
    67.    ;   
    68.     db   066H
    69.    ;   
    70.    ;    asm mov word ptr Ticks1lo, ax
    71.    ;   
    72.     mov  word ptr [bp-14], ax
    73.    ;   
    74.    ;    asm db 0x66
    75.    ;   
    76.     db   066H
    77.    ;   
    78.    ;    asm mov word ptr Ticks1hi, dx
    79.    ;   
    80.     mov  word ptr [bp-18], dx
    81. @1@7:
    82.    ;   
    83.    ;   
    84.    ;    while ( 1 ) {
    85.    ;    asm db 0x0f, 0x31 //rdtsc
    86.    ;   
    87.     db   00fH, 031H
    88.    ;   
    89.    ;    asm db 0x66
    90.    ;   
    91.     db   066H
    92.    ;   
    93.    ;    asm mov word ptr Ticks2lo, ax
    94.    ;   
    95.     mov  word ptr [bp-22], ax
    96.    ;   
    97.    ;    asm db 0x66
    98.    ;   
    99.     db   066H
    100.    ;   
    101.    ;    asm mov word ptr Ticks2hi, dx
    102.    ;   
    103.     mov  word ptr [bp-26], dx
    104.    ;   
    105.    ;   
    106.    ;    if ( ( (Ticks2hi - Ticks1hi) >= TicksToWaithi ) &&
    107.    ;   
    108.    ;   
    109.    ;               ( (Ticks2lo - Ticks1lo) >= TicksToWaitlo ) )return;
    110.    ;   
    111.     mov edx,dword ptr [bp-26]
    112.     sub edx,dword ptr [bp-18]
    113.     cmp edx,dword ptr [bp-10]
    114.     jb  short @1@7
    115.     mov edx,dword ptr [bp-22]
    116.     sub edx,dword ptr [bp-14]
    117.     cmp edx,dword ptr [bp-6]
    118.     jb  short @1@7
    119. @1@14:
    120.    ;   
    121.    ;    }
    122.    ;    }
    123.    ;   
    124.     pop di
    125.     pop si
    126.     leave  
    127.     ret
    128. @Delay  endp
    129.  
    130. start:
    131.         mov ax, 1000h
    132.         mov dx, 1000h
    133.         call @Delay
    134.         mov ax, 4C00h
    135.         int 21h
    136. end start
    Возможно что лутшим решенеем будет использование Watcom C, так как компилял глюкаловом от бордель-янда, FreeDOS... Таг бы мош и все бы ничево, тока FAT32 драйвером пофигачились все данные на винту... Когда как тот же релиз на Watcome, работает очень стабильно. Мну бы дажи сказал - пуленепробиваемо.. оть...
     
  13. Sedov

    Sedov New Member

    Публикаций:
    0
    Регистрация:
    6 дек 2007
    Сообщения:
    8
    В языках высокого уровня сохраняй регистры перед использованием их в коде на асме.

    Код (Text):
    1. Код:
    2. void Delay( WORD Msec )
    3. {
    4.     DWORD i;
    5.     DWORD TicksToWaitlo;
    6.     DWORD TicksToWaithi;
    7.     DWORD Ticks1lo;
    8.     DWORD Ticks1hi;
    9.     DWORD Ticks2lo;
    10.     DWORD Ticks2hi;
    11.        
    12.        
    13.         TicksToWaitlo = (DWORD)Msec * ((DWORD)SysCpuFreqMhz * 1000L);
    14.         TicksToWaithi = 0;
    15.         Ticks1lo = 0;
    16.         Ticks1hi = 0;
    17.         Ticks2lo = 0;
    18.         Ticks2hi = 0;
    19.    
    20.         if ( Msec <= 0 ) return;
    21.  
    22.                  asm db 0x66 ;<---
    23.                  asm push ax ;<---
    24.                  asm db 0x66 ;<---
    25.                  asm push dx ;<---
    26.  
    27.         asm db 0x0f, 0x31 //rdtsc
    28.         asm db 0x66
    29.         asm mov word ptr Ticks1lo, ax
    30.         asm db 0x66
    31.         asm mov word ptr Ticks1hi, dx  
    32.                
    33.                           asm db 0x66 ;<---
    34.                  asm pop dx   ;<---
    35.                  asm db 0x66  ;<---
    36.                  asm pop ax   ;<---
    37.        
    38.         while ( 1 ) {
    39.                  asm db 0x66 ;<---
    40.                  asm push ax ;<---
    41.                  asm db 0x66 ;<---
    42.                  asm push dx ;<---
    43.  
    44.             asm db 0x0f, 0x31 //rdtsc
    45.             asm db 0x66
    46.             asm mov word ptr Ticks2lo, ax
    47.             asm db 0x66
    48.                                       asm mov word ptr Ticks2hi, dx
    49.  
    50.                  asm db 0x66  ;<---
    51.                  asm pop dx    ;<---
    52.                  asm db 0x66  ;<---
    53.                  asm pop ax    ;<---
    54.                    
    55.             if ( ( (Ticks2hi - Ticks1hi) >= TicksToWaithi ) &&
    56.            ( (Ticks2lo - Ticks1lo) >= TicksToWaitlo ) ) return;
    57.         }
    58. }