|
|
  |
STM32F407: Ethernet, HAL + Lwip |
|
|
|
Jan 12 2017, 15:38
|
Местный
  
Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672

|
Цитата(k000858 @ Jan 12 2017, 02:11)  Пока подозрения на ошибку в Ethernet драйверах... Есть убеждение, что HAL от STM использовать можно только как референс. Использовать его в собственных приложениях - тоже пожалуйста, но тогда или молиться или смириться. Извините за ответ, которого Вы не спрашивали.
--------------------
|
|
|
|
|
Jan 13 2017, 13:13
|
Местный
  
Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672

|
Цитата(k000858 @ Jan 12 2017, 22:43)  спасибо за советы. определенный смысл в них конечно есть, но задача стоит несколько другая. необходимо в существующем проекте найти источник утечки памяти или другую причину такого поведения. явно проблемы на стеке. Можно искать пропавшие вещи под фонарем - там светлее, но все-таки, наверное, лучше там, где утеряны. У меня давно нет никаких проблем с Ethernet, но у меня собственный HAL. Насколько я помню, STM HAL в принципе не годится(не годился, так как несколько лет в него не заглядывал, а индусы пишут быстро, а переписывают еще быстрее).
--------------------
|
|
|
|
|
Jan 16 2017, 14:22
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
В зависимости от текста... Как правило непредсказуемыми последствиями... Здесь давече была тема про атомарный доступ к таким переменным. Не хочу вступать в полемику, так как в программировании, одну и туже задачу можно десятком способов решить... Я обычно решаю так: Есть задачи А, Б, С. Например задача А выставляет какой то запрос флагом фА. Задачи Б и С могут его прочитать, но не сбросить! Задача Б по флагу фА подтверждает запрос выставив флаг фБ. По флагу фБ задача А сбрасывает флаг фА. То есть Одна задача только читает, вторая только пишет. Найболее яркий пример реализации в протоколе centronix. Если всё же не избежать взаимных колизий, то использую защищённую секцию, либо средства самой ОС. Ну в зависимости, от частоты события... === Ну приведу классическую работу с кольцевым буфером: 1. При поступлении символа либо пакета, в прерывании двигается хвост очереди tail. 2. В задаче, после обработки пакета - двигается голова очереди head. Вроде всё класс. Но вам требуется определить размер доступных данных... Ну типа так.. len = tail - head; if(len <0) len += sizebuf; .... И здесь видно, что во время операции len = tail - head, значение tail может измениться в прерывании (например пришёл пакет, и указатель сдвинулся по кольцу). В результате вы можете получить значение совершенно неверное. Дабы это предотвратить, вы должны например запретить прерывание на эту операцию. Либо приостановить планировщик, если речь не о прерывании, а о задачах.
Для FreeRTOS: taskENTER_CRITICAL() — вход в критическую секцию taskEXIT_CRITICAL() — выход из критической секции vTaskSuspendAll() - Приостановка планировщика xTaskResumeAll() - возобновления работы планировщика
Если приложение написано верно, то таких мест будет крайне мало... У меня их единицы. Но всё же они есть.
|
|
|
|
|
Jan 16 2017, 14:24
|

Профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831

|
Цитата(k000858 @ Jan 16 2017, 07:44)  такое есть. чем это чревато? Курим интернеты, думаем, делаем соотв. выводы  Лично рекомендую нафик уходить с голого C на C++ и использовать вместо глобальных объектов синглтоны. Особенно для толстых проектов.
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Jan 16 2017, 21:16
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(Forger @ Jan 16 2017, 17:24)  Лично рекомендую нафик уходить с голого C на C++ и использовать вместо глобальных объектов синглтоны Ещё раз обращаю внимание, что это не конструкция языка... Это не оператор, не тип данных ... Это одна из реализаций задачи средствами языка... Таких куча. И в Си тоже. Вот ребята обсуждали https://electronix.ru/forum/index.php?showtopic=139522 В теме есть законченные, грамотные решения. Причём весьма лаконичные. IAR, например, предлагает typedef i-type sig_atomic_t; в библиотеке <signal.h> Цитата The type is the integer type i-type for objects whose stored value is altered by an assigning operator as an atomic operation (an operation that never has its execution suspended while partially completed). You declare such objects to communicate between signal handlers and the rest of the program. . А переходить на другой язык, только потому что не знаешь как решить задачу в рамках этого ... ну извините.
|
|
|
|
|
Jan 16 2017, 21:51
|

Гуру
     
Группа: Свой
Сообщений: 4 869
Регистрация: 28-02-08
Из: СПБ
Пользователь №: 35 463

|
QUOTE (Forger @ Jan 16 2017, 18:24)  Курим интернеты, думаем, делаем соотв. выводы  Лично рекомендую нафик уходить с голого C на C++ и использовать вместо глобальных объектов синглтоны. Особенно для толстых проектов. С++ и его достоинства перед С, ... думаю не для STM c его осами и ограниченностью памяти. C++ даст только увеличение объема кода, подъест ресурсы которые и так ограничены. Хотя если задачка простенькая то пофигу на чем писать под STM хоть на С#. Правильно pitt пишет в STM HAL в принципе не годится, у меня тоже свой. Все отлажено и работает в серийном изделии. А тот что выложен, у всех глючит и будет глючить по понятным причинам. Он для начинающих и лентяев. И что ещё за шторм устройства Ethernet трафиком? Дураку, понятно что простых DoS атак STMы никак не потянут, даже старшие.
|
|
|
|
|
Jan 17 2017, 06:50
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (Aner @ Jan 16 2017, 23:51)  С++ и его достоинства перед С, ... думаю не для STM c его осами и ограниченностью памяти. C++ даст только увеличение объема кода, подъест ресурсы которые и так ограничены. Опять двадцать пять. Снова повторение одних и тех же мантр. Вы можете свои слова подтвердить хоть одним примером, когда хоть какое-то действие, алгоритм и т.д. даст "увеличение объема кода, подъест ресурсы" только потому, что написана на плюсах вместо голых сей? Криворукость программиста не рассматриваем, мы знаем, что "настоящие программисты пишут на Паскале на любом языке". Уже много лет как перешел на плюсы не только на STM32 "c его осами и ограниченностью памяти" но и, страшно сказать, на AVR(!) и не вижу описываемых вами ужасов. Вот совсем не вижу. А преимущества плюсов вижу и постоянно использую.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 17 2017, 08:29
|

Профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831

|
Синглтон я указал как самый популярный способ избежать глобальных переменных и отучить себя раз и навсегда от этой дурной привычки. Я давно уже перевел все свои активные проекты на модульную структуру (на чистом C невозможно это сделать вменяемо, читаемо и легко переносимо). Размер кода хоть и больше, но и быстродействие выше за счет более разумного построения проекта. На размер кода мне покласть - щас даже самый убогий и нищий ARM контроллер имеет на борту хотя бы 16к памяти. Помню, что в чистом С я проклял все на свете при поисках багов, связанных с глобальными ресурсами (да и не только). К слову, в свое время я создал обертку под RTOS (тогда было под TNKernel), дабы отвязаться от выбранной RTOS во всех новых проектах. Настолько привык, что отвыкнуть уже не сумею А недавно за пару вечеров сделал туже обертку под FreeRTOS, благо они наконец-то сделали возможность создавать сервисы и задачи статически (v 9.0.0). Подтолкнуло к этому еще и то, что под FreeRTOS есть уже готовая сборка Segger System View (крайне рекомендую). Segger заранее все сделал под эту ось, допиливать ничего не пришлось, все заработало с полпинка При отладке толстых проектов очень полезная и удобная. Я в восторге! Так все мои существующие проекты собрались под эту (новую для меня) RTOS, при этом во всех этих проектах не было изменено не единой строчки кода! Это - как пример модульного подхода к построению проектов: сначала проектируем, потом кодируем. Важное дополнение, категорически не использую нигде динамическую память: malloc, free (и т. п. штатное зло) перегружено во всех проектах пустыми функциями с соотв. ассертами. Не использую исключения C++ (принудительно заблокированы опциями компилятора). Но без применения виртуальных функций и других крайне полезных вещей C++ уже никогда не откажусь. Модульный подход приучает сразу правильно проектировать сложный проект. Для примера хочу показать, как выглядит содержимое Application.cpp (заместо тупого main.c): Код #include "Application.hpp"
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// int main(void) { Kernel::getInstance().initialize(CORE_FREQUENCY_HZ, RTOS_SYSTEM_TIMER_FREQUENCY_HZ); Kernel::getInstance().run(); }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Kernel::initializeModules(void) { WatchDog::getInstance().initialize(); Communication::getInstance().initialize(); Inputs::getInstance().initialize(); MotionControl::getInstance().initialize(); Leds::getInstance().initialize(); Settings::getInstance().initialize();
WatchDog::getInstance().setPriority(30); MotionControl::getInstance().setPriority(1); Inputs::getInstance().setPriority(2); Communication::getInstance().setPriority(3); Settings::getInstance().setPriority(6); Leds::getInstance().setPriority(10); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Kernel::runModules(void) { WatchDog::getInstance().run(); Communication::getInstance().run(); Inputs::getInstance().run(); MotionControl::getInstance().run(); Leds::getInstance().run(); Settings::getInstance().run(); }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Kernel::initializeHardware(void) { // здесь инциализируется только таблица векторов и тактовый генератор, не более того! } Каждый из модулей (в данном случае они все - синглтоны), может иметь внутри себя одну или несколько задач (потоков) или вовсе их не иметь. Взаимодействуют модули друг с другом исключительно через соотв. открытые методы. В этих методах уже используются сервисы RTOS или другие способы синхронизации. Такой подход ПОЛНОСТЬЮ исключает существование глобальных объектов и тем более глобальных переменных. Очень легко переносить модули из одного проекта в другой или создавать новый проект на базе существующих. Одинаковые или похожие модули из разных проектов постепенно унифицируются тем самым эволюционируют. Постепенно, некоторые неизменные модули выносятся в отдельные заранее скомпилированные библиотеки (например, RTOS).
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|