Skip to content

Slave client CANFestival on STM32F103 in FreeRTOS and HAL lib

Notifications You must be signed in to change notification settings

labastov/STM32_RTOS_CANFestival

Repository files navigation

Тестовый проект СANFestival для STM32F103 на HAL с FreeRTOS в VSCODE


За основу проекта взято

  1. Форк fbsder/canfestival т. к. похоже это самый живой форк оригинала.

  2. Проект ZhiyangZhou24/CANopen-STM32F1 - основные изменения это переделка на поддержку библиотек HAL

  3. При разбирательствах как "ОНО" работает очень помогла статья CAN + CANOpen + CANfestival + STM32. Часть первая.

  4. Для настройки проекта в VScode использованы различные материалы найденные на просторах интернета.

⚠️ Важное примечание: Если нарушены чьи-то авторские права, то это не специально, укажите, тут же исправлю / добавлю ссылку.

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

Краткое описание

  • Шаблон Slave устройства для STM32F103. Проект сделан в VScode. На текущий момент работает:

  • отправка Heartbeat сообщений.

  • получение и отправка SDO сообщений.

  • регулярная отправка PDO сообщений.

  • возможность смены CAN_Id устройства из тела программы или по команде из сети через SDO.

  • перезагрузка по команде NMT.

  • аппаратный CAN фильтр по индивидуальному и групповому адресу (автоматически перестраивается при смене ** can_ID **).

  • реализован обработчик callback функции на изменение параметров PDO/SDO по сети.

  • Подправлен генератор словаря ObjdicEdit, теперь он работает с текущими библиотеками Python. Включена возможность указать ** can_ID ** устройства при генерации словаря.

  • Вывод отладочной информации может быть в main.h и can_driver.h легко отключен или перенастроен с SWD на UART (в этом случае надо через STM32СubeMX активировать соответствующий порт). К контроллеру подключён одноразрядный 7-сегментный индикатор, через него так же можно выводить отладочною информацию (цифры от 0 до F, точку, символ ошибки "Е").

  • Проект тестировался на STM32F103CB, в качестве can драйвера использовался SN65HVD230, корреспондентом на шине являлся модуль mcp2515 -> arduino -> программа CANHacher.

  • В проекте специально включен полный депозитарий библиотеки CANFestival, так как ее вариантов даже на GitHab много. Во многие проекты включены только используемые в них файлы и тяжело определить какой форк использовался в проекте.

  • Проект содержит MX файл, по этому данный шаблон легко использовать для других более сложных проектов.

  • Включен вывод отладочной информации по использованию задачами стека и кучи.

  • Используется библиотека printf-stdarg для подмены стандартных функций printf/sprintf.

Листинг использования памяти по результатам компиляции

Memory region         Used Size  Region Size  %age Used
             RAM:        9432 B        20 KB     46.05%
           FLASH:       37612 B       128 KB     28.70%
   text    data     bss     dec     hex filename
  36268    1340    8100   45708    b28c build/RTOS_CANOpen2.elf

при этом, при работе микроконтроллера:

  • в среднем использование стека для задач:
    • CAN_Tx_Task Free Stack:166
    • CAN_Rx_Task Free Stack:156
  • FreeHeapSize/MinimumEverFreeHeapSize: 1160/536

Отключение вывода диагностической информации не уменьшает использования RAM, но размер программы во FLASH становится заметно меньше.

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

STM32СubeMX

Для таймеров CanFestival используется TIM2 (вы можете использовать другой), в нем для отладки делитель установлен в значение ** 7099 ** (**TIM2. Init. Prescaler = 7100-1 **) вместо значения ** 709 **, т. к в этом случае периоды отправки CAN пакетов увеличивается в 10 раз и это удобно для отладки.

Объектный словарь (Object dictionary)

ObjdicEdit.py

откорректированный ObjdicEdit.py протестирован с:

Python 2. 7. 13 (v2. 7. 13:a06454b1afa1, Dec 17 2016, 20:53:40) [MSC v. 1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.

>>> import wx
>>> wx. __version__

'4. 0. 7. post2'

>>> quit()

также ObjdicEdit.py должен работать в debian10.

slave.od

В настройках объектного словаря ** can_ID ** установлен в значение ** 0x00 *, это позволяет на лету менять сетевой адрес устройства через глобальную переменную ** can_ID ** (в проекте ей задано значение *** 0x04 **, что и будет видно в примерах ниже). которая в свою очередь задается в словаре под индексом ** 0x2000sub0x00 **.

Если вам этого не требуется, то можете удалить данную переменную и задавать адрес устройства через Node ID объектного словаря.

Can_driver

Чтобы не править файлы CANFestival подмена Node ID производится в драйвере can_driver.c. Кроме того, для уменьшения размера используемой памяти между CANFestival и HAL используются сокращенные структуры ** CanRxMsg ** и ** CanTxMsg ** (возможно я не прав, и отказ от них позволит сократить использование памяти).

Как все работает

Общее описание

VSСode

Перед использованием необходимо поправить пути до GCC и OpenOCD в файле .vscode/settings.json после этого во всех скриптах должны правильно отработать ссылки на них. Там же надо установить частоту процессора и проверить значение swoFrequency в файле .vscode/launch.json (при указании в этом поле переменной скрипт не работает).

В STM32СubeMX

(в скобках указаны параметры принятые в проекте):

  • Настраиваем тактирование микроконтроллера (** 72 ** Mhz от 8Mhz кварца).
  • CAN интерфейс, определяем используемые порты (** PA 11|12 **), скорость (500kBPs), использование прерывания при приеме пакетов (для работы требуется только USB_LP_CAN1_RX0_IRQ, если надо отлаживать аппаратный CAN фильтр то включаем CAN1_RX1_IRQ)/
  • включаем таймеры для:
    • CANFestival (TIM2), устанавливаем делитель в значение ** 7099 **,
    • системных тиков (TIM4).
  • включаем SWD.
  • настаиваем прочие порты.
  • Включаем FreeRTOS, в нем:
    • настаиваем одну задачу (CAN_Start_Task) инициирующую все дальнейшие действия на CAN интерфейсе (она инициализирует CANFestival, создаст дочерние задачи и после этого будет удалена).
    • включаем функции необходимые для отслеживания использования стека и Heap.
  • настаиваем STM32СubeMX на генерацию Makefile.
  • в Makefile прописываем пути к библиотекам и *.с файлам, которые он не видит. Необходимо проверить, что TARGET в Makefile совпадает именем папки с проектом иначе не будет работать отладка в VScode Если есть желание можно добавить вывод диагностической информации при компиляции как в проекте (см. Lib/Debug/README.md)

В объектном словаре

Настаиваем требуемые объекты в разделе ** 0x2000 **, при необходимости делаем их mapping в PDO|SDO.

Загрузка устройства

После загрузки узел переходит в состояние Pre_operational отправляет Heartbeat сообщение о загрузке Send a Boot-Up msg в CAN очередь:

ID    0x704    - (0x700 + 0x4) cob_id=  1796
DLC   1 
data  0x00     - 0 - значит bootup

после чего узел приходит в режим ** Operational ** и отправляет следующее Heartbeat сообщение в CAN очередь:

ID    0x704    - (0x700 + 0x4) cob_id=  1796
DLC   1 
data  0x00     - 5 - режим Operational

и сразу за этим данные PDO указанные в индексе 0x1A00

** Heartbeat ** сообщения посылаются каждые 0,5с (период задан в объектном словаре, может быть оперативно изменен по сети).

ID    0x704 (0x700 + 0x04) cob_id= 1796
DLC   1
data  0x05

SD0

Пример запроса температуры по индексу 0х2002sub0х00

0x604 0x08 0x43 0x02 0x20 0x00 0xXX 0xXX 0xXX 0xXX, где:

ID        - 0x604     - 0x600 + Id 0x04
DLC       - 0x08      - всегда должно быть 8
Data [0]  - 0x43      - спецификатор команды, из них
                        биты 4-7  - в этом случае это 0х4 -  запрос чтения (если 0х2 - запрос записи)
                        биты 2-3  - b00 количество байт в сообщении, здесь 0
                        биты 0-1  - х.з. b11  в принципе работает если b00 (т.е в поле 0х40 вместо 0х43)
Data[1-2] - 0x02 0x20 - индекс 0х2002 запись битов идет в обратном порядке
Data[3]   - 0x00      - суб. индекс 0х00
Data[4-7] - неважно

Ответ:

0x584 0x08 0x43 0x02 0x20 0x00 0x00 0x00 0xC8 0x42, где:

ID        - 0x584     - 0x500 + Id 0x04
DLC       - 0x08      - количество бит, но пока все пакеты, что я видел 8
Data [0]  - 0x43      - спецификатор команды странно должно быть 0х60, из них

                        биты 4-7  - в этом случае это 0х4 -  запрос передачи (если 0х2 - запрос записи)
                        биты 2-3  - b00
                        биты 0-1  - х.з. b11  

Data[1-2] - 0x02 0x20 - индекс 0х2002 запись битов идет в обратном порядке
Data[3]   - 0x00      - суб. индекс 0х01
Data[4-7] - 0x00 0x00 0xc8 0x42 полезные данные глобальной переменной Temperature=100 (float) в обратном порядке 

Пример записи температуры по индексу 0х2002sub0х00

0x604 0x08 0x23 0x02 0x20 0x00 0x00 0x00 0xC9 0x42, где:

ID      - 0x604             - 0x600 + Id 0x04
DLC     - 0x08              - всегда должно быть 8 
Data[0] - 0x23              - спецификатор команды, из них:
                            биты 4-7  - в этом случае это 0х2 - запрос записи
                            биты 2-3  - b00 количество байт в записываемом значении здесь 4 бата, поэтому 0, если 2 байта то указываем 0x2B, если 1 байт то 0x2F соответственно
                            биты 0-1  - х.з. почему b11
Data[1-2] - 0x02 0x20   - индекс 0х2000 запись битов идет в обратном порядке
Data[3] - 0x00          - суб. индекс 0х00 Data[4-7] - 0x00 0x00 0xC9 0x42 -новое значение температуры 100.5

Ответ:

0x584 0x08 0x60 0x02 0x20 0x00 0x00 0x00 0x00 0x00

ID - 0x584          - 0x500 + Id 0x04
DLC - 0x08          - количество бит, но пока все пакеты, что я видел 8
Data [0] - 0x60     - спецификатор команды
                        биты 4-7  - в этом случае это 0х6  успешная запись в случае неуспеха 0х80
                        биты 2-3  - b00 
                        биты 0-1  - х.з. b11  
Data[1-2]           - 0x02 0x20 - индекс 0х2002 запись битов идет в обратном порядке
Data[3] - 0x00      - суб. индекс 0х00 Data[4-7] - 0x00 0x00 0x00 0x00 - пустое поле с данными

PDO

Чтобы данные через PDO отправлялись регулярно надо в словаре по индексу ** 0x1800 ** в:

  1. суб индекс ** 0x02 ** записать значение ** 0xFF ** - разрешаем спонтанную передачу.

  2. суб индекс ** 0x05 ** записать значение ** 0x01F4 ** - устанавливаем таймер на 500 mc. (если в данном регистре будет ** 0 **, то сообщение отправится только один раз).

Эти установки можно задать командами по сети (до следующей перезагрузки, т.к. значение возьмется из словаря указанное в прошивке), для этого:

  • разрешаем спонтанную передачу PDO: 0x604 0x08 0x2F 0x00 0x18 0x02 0xFF 0x00 0x00 0x00. В случае успеха получаем: 0x584 0x08 0x60 0x00 0x18 0x02 0x00 0x00 0x00 0x00, если получили: 0x584 0x08 0x80 - проверь число байт с команде на запись, команда должна быть ** 0x2F **.

  • устанавливаем таймер: 0x604 0x08 0x2F 0x00 0x18 0x025 0xF4 0x01 0x00 0x00.

После этого начинаем получать данные с температурой: 0x284 0x04 0x00 0x00 0xC9 0x42.

NMT

Реализована поддержка команд NMT, при этом они работают как при обращении по IDнепосредственно данному узлу, так и широковещательно лявсех узлов сети.

Пример команды для перезагрузки устройства:

ID      - 0x00
DLC     - 0x02          - количество бит
Data[0] - 0x81          - команда перезагрузки устройства
Data[1] - 0x04          - адрес устройства, если 0х00 - широковещательная команда на все устройства соответственно

Функционал реализован через функцию ** NMT_Slave_Node_Reset_Callback_Function() **.

Callback

В основном цикле, при инициализации CAN приложений (файл taskcan.c функция ** CAN_Start_App **) производится регистрация вызовов callback при изменении параметров по сети. В примере реализована всего одна функция callback которая анализирует контекст вызова и в зависимости от этого, производит различные действия (меняет ** can_id ** с пере инициализацией CAN фильтра, либо просто выводит на консоль информацию об изменении переменной ** Dac **).


Возможные баги

Если не отравляются CAN сообщения, а TX почтовый ящик забит, надо проверить слышит ли прием собственную передачу, иначе контроллер думает, что шина занята и блокирует передачу. У меня была неисправна микросхема Can драйвера и в режиме CAN Lookback все работало хорошо, но при переводе в нормальный режим, пакеты перестали отправляться.

Прочее

Проект включает файлы:

  • CANHack-TX-list.txl - список TX сообщений для программы CANHacher.
  • pulseView.pvs - конфигурационный файл для программы PulseView для анализатора протокола CAN.

About

Slave client CANFestival on STM32F103 in FreeRTOS and HAL lib

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published