Forger 26 8 февраля, 2019 Опубликовано 8 февраля, 2019 · Жалоба 1 hour ago, ViKo said: Я же не могу сам обработчик прерывания спрятать в класс? Можете, вот одно из решений В прерывании по приему заполняем кольцевой буфер, семфорим наверх, что что-то в буфере изменилось. В фоне задач (под такие проекты лучше использовать RTOS) разгребаем уже кольцевой буфер. В фоне задач можно легко работать с таймаутами, а это сильно упрощает жизнь. При передаче - анологично, но уже все наоборот. В медленных интерфейсах буфером может быть просто "volatile uint8_t", который является частью класса. Сами очереди (кольцевые буферы) будут являются частью класса задачи, наравне с экземпляром порта и обработчиком прерываний. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 8 февраля, 2019 Опубликовано 8 февраля, 2019 · Жалоба 2 минуты назад, k155la3 сказал: Я не привязывал бы прием символа к ООП. На уровне прерываний имеет смысл отслеживать перерывы в передаче, заполнение буфера и анализ на заголовок пакета (если конечно, у Вас "пакетный" обмен данными а не "поточный"). Эти флаги - "отображать" на класс frame_IO. Куда относить буферы приема и передачи? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 8 февраля, 2019 Опубликовано 8 февраля, 2019 · Жалоба А почему не реализовать отдельный файл-драйвер приемника и не выдавать семафор в задачу парсера? У меня, например, все делается примерно так 1. ПК кодирует отправляемое сообщение с помощью какого-либо фреймера (например, использованием байт-стаффинга) и отправляет на МК. 2. МК по приему первого разделительного символа резервирует одну ячейку в кольцевом буфере для хранения длины принятого сообщения (иногда удобно разграничивать классы приходящих сообщений по их длине). 3. В том же обработчике приходящие символы раскодируются обратно и складываются в кольцевой буфер. Когда приемник видит завершающий символ, записываем в зарезервированное место кольцевого буфера (см. п. 2) длину сообщения. 4. Выдаем семафор задаче-обработчику входящих сообщений. Задача-парсер вычитывает управляющую структуру почтового ящика, видит в нем непрочитанное сообщение (по крайней мере одно), видит первым элементом буфера размер сообщения, вычитывает это сообщение, парсит и вызывает соответствующий обработчик. В приемном прерывании также не забываем в случае переполнения кольцевого буфера откатить указатели назад и сделать отметку в управляющей структуре буфера о произошедшей неприятности. Зачем тут ООП? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 8 февраля, 2019 Опубликовано 8 февраля, 2019 · Жалоба 10 minutes ago, ViKo said: Куда относить буферы приема и передачи? Буферы (или указатели на буферы) можете "уложить" в класс frame_IO. В нем - функции и переменные для работы с кольцевыми (если кольцевые) буферами. "На выходе" класса его "интеллектом" должны формироваться инф. флаги - буфер приема пуст - буфер передачи пуст - переполнение - есть признак (сигнатура) заголовка пакета в буфере приема . . . . итд Работать с этими данными должен следующий по уровню класс (с его "интеллектом" - функциями), к примеру если есть признак заголовка пакета, то проверять целостность пакета (класс packet). Quote Еще вот что. Мне не нужно ничего наследовать. Я не пишу универсальных программ. Никаких базовых классов и т.п. Я просто хочу видеть свою программу более структурированной. Но не усложненной. Наследование - основной плюс в ООП. Вопрос не в универсальности (хотя не без этого), а как раз в том, что вы спрашиваете - "Однако, не могу понять, как следовать этой вере.". Вера в абстракциях, которые дает ООП. 1. В "объект" объединяются логически связанные данные и методы их обработки. 2. Полученные объекты также объединяются/связываются по томуже принципу. Вы соглашаетесь с 1. и не хотите использовать 2. IMHO Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 8 февраля, 2019 Опубликовано 8 февраля, 2019 · Жалоба Э-э... делегатов не хочу. Для меня это неоправданное усложнение. Так же и двойные буферы. RTOS тоже не хочу. До этого была, сейчас хочу попроще. Во всяком случае, на данном этапе. У меня взаимодействие с компом простое: принял команду - выполнил - ответил. И ничего кроме. Так вижу работу сейчас. Возможно, позже усложнится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 8 февраля, 2019 Опубликовано 8 февраля, 2019 · Жалоба Только что, ViKo сказал: RTOS тоже не хочу. Тогда посмотрите в сторону обычных событийных систем: event-driven system. И ООП тут как собаке пятая нога Вот весь мой main() такого подхода: #include "EDS.h" #include "Hardware.h" int main(void) { EDS_Init(); HW_MCUInit(); HW_PeriodicTimerStart(); while(1) { if(EDS_GetEvent()) EDS_EventHandler(CurrentEvent); } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 8 февраля, 2019 Опубликовано 8 февраля, 2019 · Жалоба 7 минут назад, Arlleex сказал: Тогда посмотрите в сторону обычных событийных систем: event-driven system. И ООП тут как собаке пятая нога Но это EDS не запрещает использовать классы? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 8 февраля, 2019 Опубликовано 8 февраля, 2019 · Жалоба 13 minutes ago, ViKo said: Э-э... делегатов не хочу. Для меня это неоправданное усложнение. Вы увидели страшное слово, но к вашей задаче оно не имеет отношения )) Quote Так же и двойные буферы. А где вы их увидели? Quote RTOS тоже не хочу. С этого и надо было начинать )) Коли RTOS не нужно, то значит проект очень простой и ООП действительно тут как собаке пятая нога )) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 8 февраля, 2019 Опубликовано 8 февраля, 2019 · Жалоба Только что, ViKo сказал: Но это EDS не запрещает использовать классы? EDS - это всего лишь механизм построения программы без операционной системы. Внутри - как Вам угодно. У меня EDS основан на том же кольцевом буфере. При возникновении прерывания по UART принимаю в буфер этот символ, а в main() - извлекаю его и отправляю декодеру EDS_EventHandler(). Декодер простейший void (*HandlerArray[])(void) = { &Callback_PeriodicTimeout, &Callback_ExchangeRxData, &Callback_ExchangeTxData }; void EDS_EventHandler(u32 CurrentEvent) { void (*Callback)(void) = HandlerArray[CurrentEvent - 1]; Callback(); return; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 8 февраля, 2019 Опубликовано 8 февраля, 2019 · Жалоба Если Вам для контроллера - смотрите scmRTOS. Cама RTOS на CPP. Использовал, "работает" :) (в смысле посмотреть реализацию кода). Не помню, правда, как там вектора прерываний оформлены. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 8 февраля, 2019 Опубликовано 8 февраля, 2019 · Жалоба 1 минуту назад, Arlleex сказал: Внутри - как Вам угодно. О том и спрашиваю. Какой класс создать, чтобы не глобальными буферами и указателями оперировать? 3 минуты назад, k155la3 сказал: Если Вам для контроллера - смотрите scmRTOS. Cама RTOS на CPP. Я, возможно, когда-нибудь свою RTOS придумаю, простейшую. Но пока меня удовлетворяет Кейловская. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 8 февраля, 2019 Опубликовано 8 февраля, 2019 · Жалоба 12 minutes ago, ViKo said: О том и спрашиваю. Какой класс создать, чтобы не глобальными буферами и указателями оперировать? Обработчик прерываний - обычная C-функция, поэтому все равно в ней придется обращаться к неким глобальных объектам (пусть даже и static). Поэтому без глобальных объектов в таком решении уж никак не обойтись. Quote Я, возможно, когда-нибудь свою RTOS придумаю, простейшую. Но пока меня удовлетворяет Кейловская. Изобретать велосипед - это очень увлекательное и познавательно занятие :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 8 февраля, 2019 Опубликовано 8 февраля, 2019 · Жалоба 11 minutes ago, ViKo said: Я, возможно, когда-нибудь свою RTOS придумаю, простейшую. Но пока меня удовлетворяет Кейловская. Вы не поняли. Я предлагаю ознакомиться с исходником этой оси, напредмет использования в ней OOP. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 8 февраля, 2019 Опубликовано 8 февраля, 2019 · Жалоба 1 минуту назад, k155la3 сказал: Вы не поняли. Я предлагаю ознакомиться с исходником этой оси, напредмет использования в ней OOP. А, верно, можно посмотреть на классы. Ок. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 8 февраля, 2019 Опубликовано 8 февраля, 2019 · Жалоба scmRTOS //------------------------------------------------------------------------------ #pragma vector=SYSTEM_TIMER_VECTOR OS_INTERRUPT void OS::system_timer_isr() { scmRTOS_ISRW_TYPE ISR; #if scmRTOS_SYSTIMER_HOOK_ENABLE == 1 system_timer_user_hook(); #endif Kernel.system_timer(); #if scmRTOS_SYSTIMER_NEST_INTS_ENABLE == 1 ENABLE_NESTED_INTERRUPTS(); #endif } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться