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

simark1979

Участник
  • Постов

    94
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные simark1979


  1. 6 hours ago, jcxz said:

    __no_init обычно используется для объявления неинициализируемых переменных в ОЗУ. Не стоит использовать её для const-объектов flash. Ваши объявления - неверные. имхо.

    .......................

    .......................

    
    define region FLASHC_regionC = mem:[from 0x08040000 to 0x0817FFFF]; //PMU/FLASH (cached)
    define block IMAGE_HEAD with fixed order {section .intvec, section .checksum, section .codehead, section .intvecTail, section .codeSignature};
    place in FLASHC_regionC {ro, first block IMAGE_HEAD, last section .codetail, ...};

    где FLASHC_regionC - регион для образа программы во флешь.

    Обратите внимание как объявлены codeSignature и codehead.

    Прибивание гвоздями к абсолютным адресам каких-то переменных/констант в исходниках/хидерах - плохая практика. Наступите на грабли (или уже наступили). Для размещения объектов в памяти в IAR служит .icf-файл. Его и надо использовать. Как можно заметить - у меня нет ни одного абсолютного адреса вне пределов .icf-файла.

    Я извиняюсь, возможно не совсем четко сформулировал проблему.
    Задача ведь не только в том, чтобы правильно разместить по адресу, но и вычитать 
    С размещением переменных я Вас понял, размещаем в именованной секции.
    Подскажите как теперь её вычитать.
    А как вычитать теперь её?

  2. 5 hours ago, jcxz said:

    Очевидно, что app_version у Вас находится не по адресу 0x0807FFF8, а по 0x0807FFFA.

    Сейчас обнаружил, дело в том, что пока я сейчас я кладу и читаю из одной и той же программы (для простоты отладки)

    Прикол в том, что если я пытаюсь вычитать её по другому адресу, допустим так

    __no_init fw_version_t mainApp_fw_info @ 0x0807fffa;

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

    1094697036_flash2.PNG.5fcc0401cdacb360cb4ae61b1ff6acb4.PNG

    То ли это нельзя делать из одной и той же программы, то ли я что-то не понимаю.

    Я то думал, что адрес в __no_init fw_version_t mainApp_fw_info @ 0x0807fffa; влияет только на адрес чтения, а оказывается и на адрес размещения тоже, несмотря на спецификатор __no_init

     

     

     

     

  3. Всем привет.

    Помогите разобраться с размещением/чтением структуры из флэш по абсолютному адресу.

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

    Итак по порядку

     

    // 1. Определена структура

    typedef struct {
      uint8_t  major;
      uint8_t  minor;
    } fw_version_t;

     

    // 2. Объявлена переменная

    #pragma location = "FW_INFO"
    __root const fw_version_t app_version = 
    {
      .major   = 2,
      .minor   = 8,
    };

     

    // 3. В линкере определена область FW_INFO

    /* Размер секции для хранения структуры c информацией о версии прошивки, она размещается перед контрольной суммой прошивки*/
    define symbol __FW_INFO_size__  = 4;
    define symbol __FW_INFO_start__ = __CRC32_addr__ - __FW_INFO_size__;
    define symbol __FW_INFO_end__   = __CRC32_addr__;


    define region FW_INFO_region = mem:[from __FW_INFO_start__ to __FW_INFO_end__];
    place in FW_INFO_region { readonly section FW_INFO };

     

    // 4. После прошивки переменную вижу во флэш

    В *.map следующая запись "P3":  place in [from 0x807'fff8 to 0x807'fffc] { ro section FW_INFO };

    1961754355_flash.PNG.a5a570d061d6204da53d9a77e3843228.PNG

    // 5. Объявляю переменную по абсолютному с абсолютным адресом указанным в map файле.

    __no_init fw_version_t mainApp_fw_info @ 0x0807fff8;

     

     

    ----------------------------------------------------------------------------------------------------

    Но в результате в структуре оказываются не те значения, которые ожидались.

    в mainApp_fw_info.major читается 0xff из 0x0807fff8

    в mainApp_fw_info.minor читается 0xff из 0x0807fff9

     

    Я так понимаю, неправильно разместил структуру или её читаю.

    Подскажите, что сделал не так?

     

     

     

     

     

     

  4. 3 hours ago, l11acmep said:

    Есть библиотека emWin от Segger. которую ST под свои МК немного переделали.

    Называется STemWin.

    В интернете есть ссылка на оригинал.

    Попробуй.

    Сам пользую. Довольно удобная, хотя кое-где нужен особенный подход. ;)

    Спасибо, подскажите, а на маленьком монохромном экране использовали?

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

  5. Всем привет)
    К stm32 прикрутил glcd с разрешением 128*64 и библиотеку u8g2.
    Теперь встал вопрос по созданию меню.

    Когда-то для строчного экрана писал меню сам, но получилось довольно громоздко.

    Поделитесь опытом, кто как делал меню, может посоветуете готовые библиотеки.

    Гугление особо ничего не дало, кроме ардуинных решений особо ничего не накопал.

  6.  

    44 minutes ago, shodan_x said:

    Просто в глаза бросилось что кто-то в 2019-м году все еще не использует git/svn, не более того.

    Из моего поста не следовало, что я им не пользуюсь, пользуюсь уже лет 6-7 (ранее github, теперь gitlab)
    Я вас наверное удивлю, многие действительно не используют и более того не знают об этом.
    Некоторые не могут освоить смартфоны, некоторые до сих пор только на ассемблере пишут,
    Люди разные и способность к обучению с возрастом теряется.

  7. 6 hours ago, shodan_x said:

    Бекапы их тоже не гарантируют, однако вы их рекомендуете )))

    Не понятно, чего Вы пристали к месту и способу резервирования данных.
    Хоть на флэшку, хоть на HDD, хоть на SSD, хоть в git/svn.
    Какое это имеет значение в конце концов, пост был о другом.
     

  8. После открытия для себя функций по работе с группами бит, вот что придумалось:
    В потоке вызываем xEventGroupWaitBits() с бесконечным ожиданием.
    Чтобы проскочить эту функцию, нужно выставить все биты в группе.
    Каждый контролируемый поток с помощью xEventGroupSetBits должен выставить свой уникальный бит в группе.
    Перед возвратом из xEventGroupWaitBits(), все биты в группе сбросятся автоматом.

    Таким образом нужно, чтобы все функции: (watchdog_taskAlive__ui(), watchdog_taskAlive__ph_sensor_reader(), watchdog_taskAlive__rx_sensor_reader())
    были вызваны хотя бы один раз. Чем чаще будут вызовы этих функций, тем сильнее можно сократить реакцию на зависание.

    В зависимости от конфига FreeRTOS, в одну группу можно запихать до 32-х бит. по умолчанию CubeMx так и делает, если этого недостаточно, делайте иерархию из групп.


    Код не оптимизирован для наглядности)
    #include "watchdog.h"
    #include "stm32f2xx_hal.h"
    #include "stm32f2xx.h"
    #include "stm32f2xx_it.h"
    #include "cmsis_os.h"
    #include "string.h"

    #define BIT_0    ( 1 << 0 )
    #define BIT_1    ( 1 << 1 )
    #define BIT_2    ( 1 << 2 )

    EventGroupHandle_t xTasksWatchdogEventGroup;

    void task_Watchdog_control(void const * argument)

      MX_IWDG_Init();
      xTasksWatchdogEventGroup = xEventGroupCreate();

      for(;;)
      {
        xEventGroupWaitBits(
                            xTasksWatchdogEventGroup,   /* The event group being tested. */
                            BIT_0 | BIT_1 | BIT_2,      /* Здесь перечисляем какие биты ждем */
                            pdTRUE,                           /* Указываем, что при выходе из функции, биты нужно сбросить */
                            pdTRUE,                           /* Указываем, что возврат из функции произойдет, только после выставления всех битов*/
                            portMAX_DELAY );         /* Выставление битов ждем бесконечно долго */

        HAL_IWDG_Refresh(&hiwdg);

      }
    }

    void watchdog_taskAlive__ui() {  xEventGroupSetBits(xTasksWatchdogEventGroup, BIT_0);}

    void watchdog_taskAlive__ph_sensor_reader(){  xEventGroupSetBits(xTasksWatchdogEventGroup, BIT_1);}

    void watchdog_taskAlive__rx_sensor_reader(){  xEventGroupSetBits(xTasksWatchdogEventGroup, BIT_2);}

     

  9. 4 minutes ago, haker_fox said:

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

    Если честно, я не в теме, что такое TCB, нужно изучить)

  10. А как такой вариант?
    В своём цикле каждая задача обновляет свой индивидуальный таймстамп (taskX_timestamp), который равен xTaskGetTickCount() ,
    И есть task_watchdog, которая проверяет чтобы разница между xTaskGetTickCount() и taskX_timestamp, не превышала какой-то порог
    Если этот порог по какой-то задаче превышен, застреваем в бесконечном цикле, и не дергаем IWD, который потом сбросит контроллер.
    Естественно, данные о времени между задачами передаем правильным способом

    Дополню:
    если какую либо задачу нужно прибить, пишем в его timestamp значение намного больше текущего xTaskGetTickCount() либо где-то сбрасываем флаг слежения за данным потоком, это не даст ложно сбросить контроллер

  11. 12 hours ago, jcxz said:

    Заведите одну задачу, которая будет проверять (пинговать) остальные задачи. И если все они нормально отвечают, то только тогда сбрасывайте WDT. У меня именно так сделано.

    И приоритет её не важен, лишь бы только она не тормозилась свыше допустимого другими задачами.

    Сторожевик ещё никого от багов в ПО не спасал. Так как пока не придумали сторожевиков, умеющих искать баги в коде.

    А что вы понимаете под пингованием задачи? И как вы это делаете?

    Разумеется, собака не для поиска багов, но может спасти...всё-таки не случайно родились трейсеры для RTOS, иногда баги бывают крайне сложные и неочевидные, редко проявляющиеся.
    Еще слышал, что программа может сбиться в результате влияния электромагнитных помех на RAM и "ходить" по ложному пути, хотел бы узнать, есть ли такая опасность или выдумки?

  12. 13 hours ago, Forger said:

    Изначально вопрос звучал совсем другой: 

    Подскажите как правильно организовать сброс сторожевика?

     

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

    Определитесь уже :)

     

    Кстати, в статье по ссылке все расписано вполне доступно.

     

    Да, наверное не совсем точно сформулировал вопрос.
    Интересует конечно, как контролировать собаку из кода
    В статье расписано, но хотел бы узнать, кто и как это делает, может есть другие подходы.

  13. У меня ПО работает вроде надежно, сомнений пока не имею.

    но зарекаться не буду)

    читал https://barrgroup.com/Embedded-Systems/How-To/Advanced-Watchdog-Timer-Tips

    с чего решил, что контролировать вотчдог с одного потока не достаточно надежно

  14. 27 minutes ago, Forger said:

    Использую такое решение:

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

    Поторопился сбросить - ресет, завис в другой задаче - ресет.

     

    А если заткнется другая задача?
    ИМХО это не спасет от косяков в ПО

     

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