Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.93/41: Рейтинг темы: голосов - 41, средняя оценка - 4.93
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607

Watchdog на основе таймеров POSIX

29.12.2019, 22:41. Показов 9222. Ответов 65
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день, решил написать watchdog для сервера и чтобы не тратить зазря процессрное время решил реализовать это на основе таймеров POSIX, а не через создание отдельного потока.

Почитал документацию и остались некоторые вопросы:

1)Как должна быть организована проверка что сигнал пришёл от созданного мною таймера, а не от стороннего приложения ?
Сечас в обработчик приходит _si->si_pid == 0

2)Как сделать сброс таймера т.е. чтоб начинал считать по новому ? это всётаки watchdog.

3)Как подружить мой watchdog и std::getline(cin, str_command ?

4)Надо ли вызывать предыдущие обработчики если я их не создавал ?

5)Надо ли делать задержку после вызова timer_settime ?

6)Какой тип таймера выбрать ? CLOCK_REALTIME меня смущает что ктото мжет перевести время.

код внизу

watchdog.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include "../include/error.h"
#include "../include/watchdog.h"
 
// (с) http://man7.org/linux/man-pages/man2/timer_create.2.html
#define CLOCKID CLOCK_REALTIME
#define SIG SIGRTMIN + 10
 
IWatcher* callback = nullptr;
 
typedef void (*TSigFunc1)(int, siginfo_t *, void *);
typedef void (*TSigFunc2)(int);
TSigFunc1 prev_handler1 = nullptr;
TSigFunc2 prev_handler2 = nullptr;
pid_t current_pid = getpid();
 
void IWatcher::reset()
{
    //
}
 
static void signal_handler(int _sig, siginfo_t * _si, void * _uc)
{
    bool result = false;
    if ((_sig == SIG) && (_si))
    {
        if ((callback) && (_si->si_pid == current_pid))
        {
            //errspace::show_errmsg("caught valid signal");
            //(*callback)(_si);
            result = true;
        }
    }
    if (!result)
    {
        //errspace::show_errmsg("caught invalid signal");
    }
    //if (prev_handler1) prev_handler1(_sig, _si, _uc);
    //if (prev_handler2) prev_handler2(_sig);
    //signal(_sig, SIG_IGN);
}
 
timer_t timerid;
 
bool start_wd(std::size_t _msecs, IWatcher* _cback)
{
   static constexpr auto billion = 1'000'000'000;
   static constexpr auto million = 1'000'000;
   callback = _cback;
   bool result = false;
   struct sigevent sev;
   struct itimerspec its;
   long long freq_nanosecs;
   sigset_t mask;
   struct sigaction sa;
   struct sigaction old_sa;
   // Establish handler for timer signal
   sa.sa_flags = SA_SIGINFO;
   sa.sa_sigaction = signal_handler;
   sigemptyset(&sa.sa_mask);
   if (sigaction(SIG, &sa, &old_sa) == -1)
   {
       errspace::show_errmsg("Failed to setup watchdog: Establish handler");
       return result;
   }
   prev_handler1 =  old_sa.sa_sigaction;
   prev_handler2 =  old_sa.sa_handler;
   // Block timer signal temporarily
   sigemptyset(&mask);
   sigaddset(&mask, SIG);
   if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1)
   {
       errspace::show_errmsg("Failed to setup watchdog: Blocking signal");
       return result;
   }
 
   // Create the timer
   sev.sigev_notify = SIGEV_SIGNAL;
   sev.sigev_signo = SIG;
   sev.sigev_value.sival_ptr = &timerid;
   if (timer_create(CLOCKID, &sev, &timerid) == -1)
   {
       errspace::show_errmsg("Failed to setup watchdog: create timer");
       return result;
   }
 
   // Start the timer
   freq_nanosecs = million*_msecs;
   its.it_value.tv_sec = freq_nanosecs / billion;
   its.it_value.tv_nsec = freq_nanosecs % billion;
   its.it_interval.tv_sec = its.it_value.tv_sec;
   its.it_interval.tv_nsec = its.it_value.tv_nsec;
 
   if (timer_settime(timerid, 0, &its, NULL) == -1)
   {
       errspace::show_errmsg("Failed to setup watchdog: set time");
       return result;
   }
   // ????
   // std::this_thread::sleep_for(std::chrono::milliseconds(_msecs*2));
   /* Sleep for a while; meanwhile, the timer may expire
      multiple times */
 
   //printf("Sleeping for %d seconds\n", atoi(argv[1]));
   //sleep(atoi(argv[1]));
 
   // Unlock the timer signal, so that timer notification can be delivered
   if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
   {
       errspace::show_errmsg("Failed to setup watchdog: Unblocking signal");
       return result;
   }
    result = true;
    return result;
}
 
void stop_wd()
{
    sigset_t mask;
    struct sigaction action;
 
    // Block timer signal temporarily
    sigemptyset(&mask);
    sigaddset(&mask, SIG);
    if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1)
    {
        errspace::show_errmsg("Failed to reset watchdog: Blocking signal");
        return;
    }
    timer_delete(timerid);
    action.sa_handler = SIG_DFL;
    action.sa_flags   = SA_RESETHAND;
 
    if (sigaction(SIGINT, &action, NULL) == -1)
    {
        errspace::show_errmsg("Failed to reset watchdog: reset handler");
        return;
    }
 
    // Unlock the timer signal, so that timer notification
    //   can be delivered
    if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
    {
        errspace::show_errmsg("Failed to reset watchdog: Unblocking signal");
        return;
    }
}
main.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include "../include/common.h"
#include "../include/error.h"
#include "../include/watchdog.h"
#include "../include/mng_thread.h"
 
class Watcher : public IWatcher
{
public:
    template<typename ...Args>
    Watcher(Args... _args)
    {
        auto tpack = std::make_tuple(_args...);
    }
protected:
    virtual void operator ()(siginfo_t *si)
    {
        //printf("Caught signal %d\n", sig);
        //print_siginfo(si);
        //#define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
        //                           } while (0)
        errspace::show_errmsg("watchdog timeout");
        timer_t tidp;
        int _or;
 
        tidp = si->si_value.sival_ptr;
 
        //printf("    sival_ptr = %p; ", si->si_value.sival_ptr);
        //printf("    *sival_ptr = 0x%lx\n", (long) tidp);
 
        _or = timer_getoverrun(tidp);
        //if (_or == -1)
        //    errExit("timer_getoverrun");
        //else
         //   printf("    overrun count = %d\n", _or);
    }
};
 
int main(int argc, char *argv[])
{
    static Watcher w{};
    IWatcher* iw = &w;
 
    const char * FUNCTION = __FUNCTION__;
    try
    {
        using std::cout;
        using std::cin;
        using std::endl;
        cout << "Server is started" << endl;
        std::string str_command;
        while(1)
        {
            LOG << "enter command:";
            if (std::getline(cin, str_command))
            {
                LOG << "command:" << str_command << " was got";
                if (str_command == "q") break;
                if (str_command == "e") throw 0;
                if (str_command == "s")
                {
                    start_wd(1000, iw );
                }
                if (str_command == "p") stop_wd();
            }
            str_command = "";
        }
    }
    catch (...)
    {
        errspace::show_errmsg(FUNCTION);
    }
    return EXIT_SUCCESS;
}
#endif
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.12.2019, 22:41
Ответы с готовыми решениями:

WatchDog
Есть устройство на меге16 (пока на ней) которое тупо запоминает в EEPROM во сколько на одном из пинов порта появилась единица. Не не знаю...

Пробуждение по watchdog
Доброго времени суток. На старом АТ90S нужно уйти в сон, проснуться по watchdog, убедиться что событие не произошло, и опять уйти в сон. ...

WatchDog в Python
Добрый день! Интересует возможность использования watchdoga в Python. Есть ли реализация или модуль в Python, похожий на сторожевой...

65
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
09.01.2020, 17:03
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от squareroot Посмотреть сообщение
Мой нерабочий это несколько тысяч строк кода
Ну это вполне естественно. У многих так.
Обычно, в таких ситуациях делают минимальный пример, в котором воспроизводится проблема большого кода.
Если во время подготовки такого примера внезапно выясняется, что он работает, то проблема, очевидно, в окружении в большом проекте. А это, в свою очередь, означает, что при невозможности проект этот показать, идти на форум с этой проблемой бессмысленно. Угадать в чем проблема можно только случайно. Если же проблема воспроизводится и на маленьком примере, и вы все равно не поняли как ее решить, то вот этот код уже можно постить на форум. Шансы, что вам после этого помогут - 100%.

Добавлено через 43 секунды
Цитата Сообщение от squareroot Посмотреть сообщение
Вы не против если я вернусь к этой теме чуть позже ?
Это же ваше дело, не мое Как угодно.
0
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607
09.01.2020, 17:07  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Это же ваше дело, не мое Как угодно.
Я беспокоюсь что Вам будет некомфортно возвращаться к этой теме, когда пройдёт время.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
09.01.2020, 17:10
Цитата Сообщение от squareroot Посмотреть сообщение
Я беспокоюсь что Вам будет некомфортно возвращаться к этой теме, когда пройдёт время.
Не стоит
0
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607
13.01.2020, 06:47  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Мне бы для начала ваш, "нерабочий", увидеть, чтобы можно было запустить у себя.
Если убрать всё лишнее, то вот:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
typedef void (*TCalbackWD )(siginfo_t *si) noexcept;
 
class TWatchDogImpl
{
public:
    bool start_wd(std::size_t _msecs, TCalbackWD _cback)
    {
     if (is_started) return false;
       static constexpr auto billion = 1'000'000'000;
       static constexpr auto million = 1'000'000;
       //callback = _cback;
       msecs = _msecs;
       bool result = false;
    #ifdef POSIX_TIMER
       isWDTimeout = false;
       struct sigevent sev;
       sigset_t mask;
       struct sigaction sa;
       struct sigaction old_sa;
       // Establish handler for timer signal
       sa.sa_flags = SA_SIGINFO;
       sa.sa_sigaction = signal_handler;
       sigemptyset(&sa.sa_mask);
       if (sigaction(SIG, &sa, &old_sa) == m_error_code)
       {
           errspace::show_errmsg("Failed to setup watchdog: Establish handler");
           return result;
       }
       prev_handler1 =  old_sa.sa_sigaction;
       prev_handler2 =  old_sa.sa_handler;
       // Block timer signal temporarily
       sigemptyset(&mask);
       sigaddset(&mask, SIG);
       if (sigprocmask(SIG_SETMASK, &mask, nullptr) == m_error_code)
       {
           errspace::show_errmsg("Failed to setup watchdog: Blocking signal");
           return result;
       }
 
       // Create the timer
       sev.sigev_notify = SIGEV_SIGNAL;
       sev.sigev_signo = SIG;
       sev.sigev_value.sival_ptr = &m_timerid;
       struct itimerspec its;
       if (timer_create(CLOCKID, &sev, &m_timerid) == m_error_code)
       {
           errspace::show_errmsg("Failed to setup watchdog: create timer");
           return result;
       }
 
       // Start the timer
       long long freq_nanosecs;
       freq_nanosecs = million*_msecs;
       its.it_value.tv_sec = freq_nanosecs / billion;
       its.it_value.tv_nsec = freq_nanosecs % billion;
       its.it_interval.tv_sec = its.it_value.tv_sec;
       its.it_interval.tv_nsec = its.it_value.tv_nsec;
 
       if (timer_settime(m_timerid, 0, &its, nullptr) == m_error_code)
       {
           errspace::show_errmsg("Failed to setup watchdog: set time");
           return result;
       }
       /* Sleep for a while; meanwhile, the timer may expire
          multiple times */
        //std::this_thread::sleep_for(std::chrono::milliseconds(msecs*2));
 
       // Unlock the timer signal, so that timer notification can be delivered
       if (sigprocmask(SIG_UNBLOCK, &mask, nullptr) == m_error_code)
       {
           errspace::show_errmsg("Failed to setup watchdog: Unblocking signal");
           return result;
       }
    #else
        //
    #endif
        result = true;
        is_started = true;
        return result;
    }
    void stop_wd()
    {
        if (!is_started) return;
        bool result = false;
    #ifdef POSIX_TIMER
        sigset_t mask;
        struct sigaction action;
        struct itimerspec its;
        // Stop the timer
        its.it_value.tv_sec = 0;
        its.it_value.tv_nsec = 0;
        its.it_interval.tv_sec = 0;
        its.it_interval.tv_nsec = 0;
        // Block timer signal temporarily
 
        sigemptyset(&mask);
        sigaddset(&mask, SIG);
        if (sigprocmask(SIG_SETMASK, &mask, nullptr) == m_error_code)
        {
            errspace::show_errmsg("Failed to reset watchdog: Blocking signal");
            return;
        }
 
 
        if (timer_settime(m_timerid, 0, &its, nullptr) == m_error_code)
        {
            errspace::show_errmsg("Failed to setup watchdog: set time");
            return;
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(msecs));
        errno = 0;
        action.sa_handler = SIG_DFL;
        action.sa_sigaction = nullptr;
        action.sa_flags   = SA_RESETHAND;
 
        if (sigaction(SIG, &action, nullptr) == m_error_code)
        {
            errspace::show_errmsg("Failed to stop watchdog: reset handler");
            return;
        }
 
        // Unlock the timer signal, so that timer notification
        // can be delivered
 
        if (sigprocmask(SIG_UNBLOCK, &mask, nullptr) == m_error_code)
        {
            errspace::show_errmsg("Failed to reset watchdog: Unblocking signal");
            return;
        }
        // error here
 
 
        if (timer_delete(m_timerid) == m_error_code);
        {
            perror("timer_delete error:");
            errspace::show_errmsg("Failed to stop watchdog: delete timer");
        }
    #else
        //
    #endif
        is_started = false;
    }
    void reset_wd(const native_handle_type& _th)
    {
    }
 
    ~TWatchDogImpl()
    {
        if (is_started) assert("watchdog should be spoped manually");
    }
private:
#ifdef POSIX_TIMER
    timer_t m_timerid;
    static constexpr auto m_error_code = -1;
#else
    //
#endif
    static std::atomic_bool isWDTimeout;
    std::size_t msecs = 0;
    static bool is_started;
};
bool TWatchDogImpl::is_started = false;
std::atomic_bool TWatchDogImpl::isWDTimeout = false;
Но проблема, только с кодом возврата timer_delete

Добавлено через 8 минут
Вот более незавтсимы код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
typedef void (*TCalbackWD )(siginfo_t *si) noexcept;
 
class TWatchDogImpl
{
public:
    bool start_wd(std::size_t _msecs, TCalbackWD _cback)
    {
     if (is_started) return false;
       static constexpr auto billion = 1'000'000'000;
       static constexpr auto million = 1'000'000;
       //callback = _cback;
       msecs = _msecs;
       bool result = false;
    #ifdef POSIX_TIMER
       isWDTimeout = false;
       struct sigevent sev;
       sigset_t mask;
       struct sigaction sa;
       struct sigaction old_sa;
       // Establish handler for timer signal
       sa.sa_flags = SA_SIGINFO;
       sa.sa_sigaction = signal_handler;
       sigemptyset(&sa.sa_mask);
       if (sigaction(SIG, &sa, &old_sa) == m_error_code)
       {
           std::cerr << "Failed to setup watchdog: Establish handler";
           return result;
       }
       prev_handler1 =  old_sa.sa_sigaction;
       prev_handler2 =  old_sa.sa_handler;
       // Block timer signal temporarily
       sigemptyset(&mask);
       sigaddset(&mask, SIG);
       if (sigprocmask(SIG_SETMASK, &mask, nullptr) == m_error_code)
       {
           std::cerr << "Failed to setup watchdog: Blocking signal";
           return result;
       }
 
       // Create the timer
       sev.sigev_notify = SIGEV_SIGNAL;
       sev.sigev_signo = SIG;
       sev.sigev_value.sival_ptr = &m_timerid;
       struct itimerspec its;
       if (timer_create(CLOCKID, &sev, &m_timerid) == m_error_code)
       {
           std::cerr << "Failed to setup watchdog: create timer";
           return result;
       }
 
       // Start the timer
       long long freq_nanosecs;
       freq_nanosecs = million*_msecs;
       its.it_value.tv_sec = freq_nanosecs / billion;
       its.it_value.tv_nsec = freq_nanosecs % billion;
       its.it_interval.tv_sec = its.it_value.tv_sec;
       its.it_interval.tv_nsec = its.it_value.tv_nsec;
 
       if (timer_settime(m_timerid, 0, &its, nullptr) == m_error_code)
       {
           std::cerr << "Failed to setup watchdog: set time";
           return result;
       }
       /* Sleep for a while; meanwhile, the timer may expire
          multiple times */
        //std::this_thread::sleep_for(std::chrono::milliseconds(msecs*2));
 
       // Unlock the timer signal, so that timer notification can be delivered
       if (sigprocmask(SIG_UNBLOCK, &mask, nullptr) == m_error_code)
       {
          std::cerr << "Failed to setup watchdog: Unblocking signal";
           return result;
       }
    #else
        //
    #endif
        result = true;
        is_started = true;
        return result;
    }
    void stop_wd()
    {
        if (!is_started) return;
        bool result = false;
    #ifdef POSIX_TIMER
        sigset_t mask;
        struct sigaction action;
        struct itimerspec its;
        // Stop the timer
        its.it_value.tv_sec = 0;
        its.it_value.tv_nsec = 0;
        its.it_interval.tv_sec = 0;
        its.it_interval.tv_nsec = 0;
        // Block timer signal temporarily
 
        sigemptyset(&mask);
        sigaddset(&mask, SIG);
        if (sigprocmask(SIG_SETMASK, &mask, nullptr) == m_error_code)
        {
            std::cerr << "Failed to reset watchdog: Blocking signal";
            return;
        }
 
 
        if (timer_settime(m_timerid, 0, &its, nullptr) == m_error_code)
        {
            std::cerr << "Failed to setup watchdog: set time";
            return;
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(msecs));
        errno = 0;
        action.sa_handler = SIG_DFL;
        action.sa_sigaction = nullptr;
        action.sa_flags   = SA_RESETHAND;
 
        if (sigaction(SIG, &action, nullptr) == m_error_code)
        {
            std::cerr << "Failed to stop watchdog: reset handler";
            return;
        }
 
        // Unlock the timer signal, so that timer notification
        // can be delivered
 
        if (sigprocmask(SIG_UNBLOCK, &mask, nullptr) == m_error_code)
        {
            std::cerr << "Failed to reset watchdog: Unblocking signal";
            return;
        }
        // error here
 
 
        if (timer_delete(m_timerid) == m_error_code);
        {
            perror("timer_delete error:");
            std::cerr << "Failed to stop watchdog: delete timer"
        }
    #else
        //
    #endif
        is_started = false;
    }
    void reset_wd(const native_handle_type& _th)
    {
    }
 
    ~TWatchDogImpl()
    {
        if (is_started) assert("watchdog should be spoped manually");
    }
private:
#ifdef POSIX_TIMER
    timer_t m_timerid;
    static constexpr auto m_error_code = -1;
#else
    //
#endif
    static std::atomic_bool isWDTimeout;
    std::size_t msecs = 0;
    static bool is_started;
};
bool TWatchDogImpl::is_started = false;
std::atomic_bool TWatchDogImpl::isWDTimeout = false;
Добавлено через 5 минут
C++
1
2
3
4
void signal_handler(int _sig, siginfo_t * _si, void * _uc)
{
 
}
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
13.01.2020, 09:21
Цитата Сообщение от squareroot Посмотреть сообщение
C++
1
if (timer_delete(m_timerid) == m_error_code);
Точку с запятой уберите.
0
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607
13.01.2020, 15:22  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Точку с запятой уберите.
Спасибо, уже "глаз замылился"
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
13.01.2020, 15:22
Помогаю со студенческими работами здесь

Watchdog из Arduino
Есть пк, который может зависнуть, или может зависнуть у него сетевуха. Просьба не пинать в сторону, уже все сто раз было, ищи итп... ...

Внешний WAtchdog
Добрый день! Есть рабочее устройство на AVR! Надо к нему прикрепить внешний watchdog, тоесть устройство будет переодически подтягивать...

AvrSudio и watchdog
Не могу дождаться чтобы аврстудия ушла в ресет или прерывание по вочдогу. В реале сбрасывает, а в студии ну никак.

Analog Watchdog (AWD)
Добрый день. Уже третьи сутки бъюсь с analog watchdog, не хочет зараза, нормально работать. Код ниже. В одиночном преобразовании все...

Cortex m0 и watchdog таймер
Всем доброго времени суток!!! Программирую схему на базе ядра cortex m0. Не могу заставить работать watchdog. Вроде делаю всё правильно: ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
66
Ответ Создать тему
Новые блоги и статьи
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20%
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
Уведомление о неверно выбранном значении справочника
Maks 06.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "НарядПутевка", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если в документе выбран неверный склад. . .
Установка Qt Creator для C и C++: ставим среду, CMake и MinGW без фреймворка Qt
8Observer8 05.04.2026
Среду разработки Qt Creator можно установить без фреймворка Qt. Есть отдельный репозиторий для этой среды: https:/ / github. com/ qt-creator/ qt-creator, где можно скачать установщик, на вкладке Releases:. . .
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru