Перейти к содержанию
    

Всем привет.

 

Кто изучал драйвер Ethernet'а, идущий с HAL библиотеками (вариант для FreeRTOS: ETHERNET прерывание релизит семафору, которая парсится в отдельной realtime задаче ОС)? Что будет при переполнении указанного количества приёмных буферов? Ошибка DMA обработается, но не будет ли DMA записывать данные дальше (портить память) или это исключено т.к. указывается в размер буферов в настройках DMA?

 

Имею следующую ситуацию: устройство с Ethernet в параллельной задаче (с меньшим приоритетом чем Ethernet) копирует данные (memcpy функцией) с внутренней FLASH контроллера. При шторме устройства Ethernet трафиком, в какой то раз данные копируются неправильно (временно нарушается адресация флэш - откуда копировать, но до конца процесса восстанавливается), в результате часть данных получается битыми.

 

Пока подозрения на ошибку в Ethernet драйверах либо LwIP стеке (v1.4.1).

 

То есть многократное срабатывание прерывания Ethernet + работа задачи по сохранению принятого по Ethernet пакету приводит к сбою работы memcpy

 

Нехватка памяти для RTOS и его задач контролируется соответствующими отладочными функция FreeRTOS

 

Может у кого то будут умные мысли, как можно сузить круг поиска бага?

Как еще подиагностировать. Повторить ситуацию непросто, получается ни каждый раз.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пока подозрения на ошибку в Ethernet драйверах...

 

Есть убеждение, что HAL от STM использовать можно только как референс. Использовать его в собственных приложениях - тоже пожалуйста, но тогда или молиться или смириться.

Извините за ответ, которого Вы не спрашивали.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сам долго мучился с HAL, пока не скачал книгу

Mastering STM32

Carmine Noviello

""A step-by-step guide to the most complete ARM Cortex-M

platform, using a free and powerful development

environment based on Eclipse and GCC

""

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

спасибо за советы. определенный смысл в них конечно есть, но задача стоит несколько другая. необходимо в существующем проекте найти источник утечки памяти или другую причину такого поведения. явно проблемы на стеке.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

спасибо за советы. определенный смысл в них конечно есть, но задача стоит несколько другая. необходимо в существующем проекте найти источник утечки памяти или другую причину такого поведения. явно проблемы на стеке.

Можно искать пропавшие вещи под фонарем - там светлее, но все-таки, наверное, лучше там, где утеряны. У меня давно нет никаких проблем с Ethernet, но у меня собственный HAL.

Насколько я помню, STM HAL в принципе не годится(не годился, так как несколько лет в него не заглядывал, а индусы пишут быстро, а переписывают еще быстрее).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Судя по всему, у вас проблемы с синхронизацией между задачами. Либо второй вариант - где-то используется глобальная переменная, доступная на запись из нескольких задач. Туда ройте.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

где-то используется глобальная переменная, доступная на запись из нескольких задач. Туда ройте.

такое есть. чем это чревато?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В зависимости от текста... Как правило непредсказуемыми последствиями...

Здесь давече была тема про атомарный доступ к таким переменным. Не хочу вступать в полемику, так как в программировании, одну и туже задачу можно десятком способов решить...

Я обычно решаю так:

Есть задачи А, Б, С. Например задача А выставляет какой то запрос флагом фА. Задачи Б и С могут его прочитать, но не сбросить! Задача Б по флагу фА подтверждает запрос выставив флаг фБ. По флагу фБ задача А сбрасывает флаг фА.

То есть Одна задача только читает, вторая только пишет. Найболее яркий пример реализации в протоколе centronix.

Если всё же не избежать взаимных колизий, то использую защищённую секцию, либо средства самой ОС. Ну в зависимости, от частоты события...

===

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

1. При поступлении символа либо пакета, в прерывании двигается хвост очереди tail.

2. В задаче, после обработки пакета - двигается голова очереди head.

Вроде всё класс. Но вам требуется определить размер доступных данных... Ну типа так..

len = tail - head;

if(len <0) len += sizebuf;

....

И здесь видно, что во время операции len = tail - head, значение tail может измениться в прерывании (например пришёл пакет, и указатель сдвинулся по кольцу). В результате вы можете получить значение совершенно неверное. Дабы это предотвратить, вы должны например запретить прерывание на эту операцию. Либо приостановить планировщик, если речь не о прерывании, а о задачах.

 

Для FreeRTOS:

taskENTER_CRITICAL() — вход в критическую секцию

taskEXIT_CRITICAL() — выход из критической секции

vTaskSuspendAll() - Приостановка планировщика

xTaskResumeAll() - возобновления работы планировщика

 

Если приложение написано верно, то таких мест будет крайне мало... У меня их единицы. Но всё же они есть.

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

такое есть. чем это чревато?

Курим интернеты, думаем, делаем соотв. выводы :)

Лично рекомендую нафик уходить с голого C на C++ и использовать вместо глобальных объектов синглтоны.

Особенно для толстых проектов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Лично рекомендую нафик уходить с голого 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.
.

А переходить на другой язык, только потому что не знаешь как решить задачу в рамках этого ... ну извините.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Курим интернеты, думаем, делаем соотв. выводы :)

Лично рекомендую нафик уходить с голого C на C++ и использовать вместо глобальных объектов синглтоны.

Особенно для толстых проектов.

С++ и его достоинства перед С, ... думаю не для STM c его осами и ограниченностью памяти. C++ даст только увеличение объема кода, подъест ресурсы которые и так ограничены. Хотя если задачка простенькая то пофигу на чем писать под STM хоть на С#.

 

Правильно pitt пишет в STM HAL в принципе не годится, у меня тоже свой. Все отлажено и работает в серийном изделии. А тот что выложен, у всех глючит и будет глючить по понятным причинам. Он для начинающих и лентяев.

 

И что ещё за шторм устройства Ethernet трафиком? Дураку, понятно что простых DoS атак STMы никак не потянут, даже старшие.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С++ и его достоинства перед С, ... думаю не для STM c его осами и ограниченностью памяти. C++ даст только увеличение объема кода, подъест ресурсы которые и так ограничены.
Опять двадцать пять. Снова повторение одних и тех же мантр. Вы можете свои слова подтвердить хоть одним примером, когда хоть какое-то действие, алгоритм и т.д. даст "увеличение объема кода, подъест ресурсы" только потому, что написана на плюсах вместо голых сей? Криворукость программиста не рассматриваем, мы знаем, что "настоящие программисты пишут на Паскале на любом языке". Уже много лет как перешел на плюсы не только на STM32 "c его осами и ограниченностью памяти" но и, страшно сказать, на AVR(!) и не вижу описываемых вами ужасов. Вот совсем не вижу. А преимущества плюсов вижу и постоянно использую.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А преимущества плюсов вижу и постоянно использую.

Сергей, но по сабжу применение синглтонов, явно не то преимущество, согласитесь.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Синглтон я указал как самый популярный способ избежать глобальных переменных и отучить себя раз и навсегда от этой дурной привычки.

Я давно уже перевел все свои активные проекты на модульную структуру (на чистом 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).

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...