XCP on TCP na NUCLEO-H723ZG: měření, stimulace a kalibrační mapy

Ve složce Examples vedle QInsight.exe jsou dva projekty této ukázky, jeden pro každý obraz firmwaru z QFW SDK:

ProjektObraz firmwaruKapitola SDK
Qenex_TcpClient_XCP_NucleoH723_Maps_FreeRTOS.qprojexamples/nucleo_h723zg, preset Debug (FreeRTOS + lwIP)Integrace: XCP on TCP
Qenex_TcpClient_XCP_NucleoH723_Maps_BareMetal.qprojexamples/nucleo_h723zg_baremetal, preset Debug (bez RTOS, lwIP RAW API)Integrace bez RTOS

Oba projekty jsou obsahově shodné — stejný driver, události, proměnné, skripty i pracovní plocha; liší se pouze adresami pěti proměnných, které v obou obrazech leží jinde (čítač uwTick a čtyři maticové objekty). Z pohledu QInsight se deska chová v obou případech stejně.

Na rozdíl od simulačních ukázek zde QInsight komunikuje se skutečným zařízením: deskou NUCLEO s XCP slavem, připojenou po Ethernetu. Na jednom projektu jsou vidět všechny režimy protokolu XCP on TCP — DAQ, polling se zápisem, STIM a přenos proměnných Matrix v block módu — a k tomu chování driveru TCP Client, když se spojení přeruší.

Plocha „Nucleo H723 live + maps“ za běhu — sinusovky z desky, mapa zapalování, Watch Table a křivka momentuPlocha „Nucleo H723 live + maps“ za běhu — sinusovky z desky, mapa zapalování, Watch Table a křivka momentu

Co ukázka předvádí

  • DAQ měření — firmware generuje tři sinusovky (sine1–sine3) a jejich hodnoty vysílá sám z event kanálu demo10ms každých 10 ms; QInsight nevysílá žádné dotazy.
  • Polling kalibračních parametrů — amplitudy a periody všech tří sinusovek se čtou každých 500 ms a dají se kdykoli zapsat; firmware na změnu reaguje okamžitě.
  • STIM streaming — periodický skript počítá pomalou sinusovku v procentech a QInsight ji proudem STIM paketů posílá do desky na adresu sine1_value; ve stejném event kanálu, kterým deska měří.
  • Přepínač sine1_bypass — rozhoduje, kdo signál sine1_value vlastní: 0 = interní model desky, 1 = master přes STIM.
  • Rozdělení raw/value — sine1_raw je výstup interního modelu (počítá se každý cyklus, i během bypassu), sine1_value je publikovaný signál. V grafu jsou obě křivky vedle sebe, takže je bypass vidět na první pohled.
  • Mapu čtenou na vyžádání — mapa předstihu 16 × 16 (float, 1072 B) je navázaná na událost On Request: nečte se periodicky, celý blok načte až tlačítko Read v Matrix controlu.
  • Křivku čtenou pollingem — osmibodová křivka momentu (32 B) se čte každých 500 ms jako jeden blok.
  • Velkou mapu 64 × 64 — 16 640 B, největší blok, který QInsight po XCP přenese; čte se na vyžádání řadou UPLOAD burstů.
  • Kalibraci buněk — ve Write Mode se editují buňky i breakpointy os; do desky se zapíší jen změněné buňky (sousední buňky se sloučí do jednoho bloku DOWNLOAD).
  • Zpětnou vazbu z firmwaru — skalár qfwDemoMapOut („Map lookup“) firmware každých 10 ms počítá jako součet jedné buňky z každého maticového objektu, takže zapsaná buňka se ve Watch Table hned projeví.

Co potřebujete

  • Desku NUCLEO-H723ZG s jedním ze dvou obrazů ukázkového firmwaru QFW SDK (tabulka výše) a k němu odpovídající projekt. Oba obrazy obsahují demo signály, maticové objekty z app/src/demo_map.c a slave hlásí block mód.
  • Ethernetové spojení s deskou. Projekt počítá s adresou 192.168.2.20, port 5555 — upravte ji v nastavení driveru podle své sítě (PC musí být ve stejné podsíti).
  • Adresy proměnných odpovídající vašemu sestavení firmwaru. Adresy jsou absolutní (address extension 0) a pocházejí z ELF souboru: nástroj tools/elf_vars_scan.py z balíčku SDK je s konfigurací nucleo_h723zg.vars.json (resp. nucleo_h723zg_baremetal.vars.json) ze složky příkladu vyčte a vytvoří soubor pro import do QInsight (Home → Project Configuration → Variables → Import); pole exportuje jako proměnné Matrix s adresou osy X v popisu. Po každém překladu firmwaru adresy obnovte a v projektu přepište — jinak QInsight čte a stimuluje nesprávná místa v paměti. Postup popisuje kapitola Adresy proměnných pro QInsight.

Projekt

Projekt obsahuje jeden driver TCP Client s protokolem XCP on TCP, čtyři události, sedmnáct proměnných, dva skripty a pracovní plochu Nucleo H723 live + maps se čtyřmi controly.

Driver a protokol

Jeden driver TCP Client, pod ním jedna instance protokolu XCP on TCP — deska je TCP server, QInsight klient.

Nastavení driveru:

ParametrHodnotaVýznam
ip192.168.2.20adresa desky
port5555TCP port XCP slavu
connectionTimeoutMs1500jak dlouho čekat na navázání spojení — záměrně krátce: po vytažení kabelu první pokus obvykle začne, když se linka ještě vyjednává, a další pokus následuje po reconnectDelayMs
reconnectDelayMs1000prodleva mezi pokusy o znovupřipojení
reconnectAttempts3po třech neúspěšných pokusech v řadě driver další pokusy ukončí (výchozí -1 opakuje pokusy bez omezení)
keepAliveMs5000po 5 s bez provozu ověří TCP keepalive stav spojení — zjistí odpojený kabel

Nastavení protokolu:

ParametrHodnotaVýznam
requestTimeoutMs1000timeout odpovědi na jeden XCP příkaz
requestRetries2opakování příkazu po timeoutu (navíc k prvnímu pokusu)
daqTimestampsslavečasová osa DAQ vzorků podle hodin desky (µs značky z QFW SDK)

Timeouty protokolu se týkají jen výměny příkaz/odpověď; navázání a obnovu TCP spojení řídí driver.

Block mód se nenastavuje — protokol ho zjistí při připojení a zapíše do logu, např. XCP: block mode — slave yes, master yes (MAX_BS 255, MIN_ST 0 × 100 µs). Na TCP (MAX_CTO 248) je mapa 1 KB jeden UPLOAD burst pěti paketů.

Události

Čtyři události, které rozhodují o režimu každé proměnné:

UdálostTypExtra ParamsPoužití
Daq_demo10msPeriodic 10 msdirection="DAQ";daqId="0"DAQ — deska vysílá sinusovky sama z kanálu demo10ms
Stim_demo10msPeriodic 10 msdirection="STIM";daqId="0"STIM — master každých 10 ms streamuje sine1_stim do téhož kanálu
Poll500msPeriodic 500 ms—polling parametrů, přepínače bypass, čítače uwTick, křivky a qfwDemoMapOut
OnRequestOnRequest—mapy čtené tlačítkem Read

DAQ i STIM míří na jeden a tentýž event kanál firmwaru (daqId 0). Deska přijaté STIM pakety ukládá a zapisuje je do paměti uvnitř triggeru události — ve stejném okamžiku, kdy vzorkuje DAQ. U DAQ události perioda nic neřídí (jen dokumentuje cyklus kanálu, QInsight ji porovná s údajem z desky), u STIM události je to skutečný interval vysílání.

Skalární proměnné

Třináct skalárních proměnných; všechny float kromě uwTick (uint) a sine1_bypass (byte). Address extension je všude 0. Adresy v bloku gDemoSignals jsou v obou obrazech stejné, liší se jen uwTick:

ProměnnáAdresaSměrUdálostPrezentace (konverze)
sine1_value0x2400005CreadDaq_demo10msSine value −10…10 (PassThrough)
sine1_raw0x24000058readDaq_demo10msSine value (PassThrough)
sine2_value0x24000074readDaq_demo10msSine value (PassThrough)
sine3_value0x2400008CreadDaq_demo10msSine value (PassThrough)
sine1_amplitude0x24000050readWritePoll500msAmplitude 0…10 (PassThrough)
sine1_period0x24000054readWritePoll500msPeriod 0,05…60 s (PassThrough)
sine2_amplitude0x24000068readWritePoll500msAmplitude (PassThrough)
sine2_period0x2400006CreadWritePoll500msPeriod (PassThrough)
sine3_amplitude0x24000080readWritePoll500msAmplitude (PassThrough)
sine3_period0x24000084readWritePoll500msPeriod (PassThrough)
sine1_bypass0x24000060readWritePoll500msBypass 0/1 (PassThrough)
sine1_stim0x2400005CwriteStim_demo10msStim level 0…100 % (StimPercent)
uwTickFreeRTOS 0x24000124 / bez RTOS 0x2400011CreadPoll500msHAL tick, ms (PassThrough)

Za povšimnutí stojí:

  • sine1_stim a sine1_value mají stejnou adresu — stimulace píše přímo do místa, které deska publikuje; liší se jen směrem a událostí.
  • Konverze StimPercent (multiplier=5, offset=50) mapuje raw rozsah ±10 na 0–100 %: zadaných 75 % dá raw 5,0, 50 % je nula. Zápis se zadává v inženýrské hodnotě a QInsight ji před odesláním invertuje (viz Konverze a prezentace).
  • uwTick je milisekundový čítač HAL z STM32 — leží mimo blok gDemoSignals a dokazuje, že po XCP je dosažitelná libovolná globální proměnná z ELF.
  • Výchozí hodnoty sinusovek podle firmwaru: sine 1 amplituda 1,0 / perioda 1 s, sine 2 amplituda 5,0 / 3 s, sine 3 amplituda 0,5 / 10 s. Periodu pod 0,05 s firmware ořízne.

Maticové proměnné

Čtyři proměnné kalibračních dat, všechny little-endian, address extension 0:

Proměnná (Label)Tvar a typyVelikostAdresa FreeRTOSAdresa bez RTOSSměrUdálost
qfwDemoMap (Ignition map)mapa 16 × 16 float; osa X ushort (rpm), osa Y byte (load)1072 B0x240142800x24008FC0readWriteOnRequest
qfwDemoCurve (Torque curve)křivka 8 bodů ushort, osa X ushort (rpm)32 B0x240146B00x240093F0readWritePoll500ms
qfwDemoBigMap (Injection map 64x64)mapa 64 × 64 float; osy X a Y ushort16 640 B0x240146D00x24009410readWriteOnRequest
qfwDemoMapOut (Map lookup)skalár float4 B0x240187D00x2400D510readPoll500ms

Adresa matice ukazuje na začátek bloku, tedy na osu X; v paměti následuje osa Y a data po řádcích (viz Proměnné typu Matrix u XCP).

Prezentace os a dat:

PrezentaceRozsahJednotkaPoužití
RpmAxisPres0–8000rpmosa X všech tří matic
LoadAxisPres0–100%osa Y qfwDemoMap
LoadTenthAxisPres0–100%osa Y qfwDemoBigMap — konverze LoadTenth (×0,1), raw je v desetinách procenta
AdvancePres0–40degdata qfwDemoMap
TorquePres0–300Nmdata qfwDemoCurve
InjectionPres0–1100mgdata qfwDemoBigMap
MapOutPres0–2500—qfwDemoMapOut

Výchozí hodnoty ve firmwaru: mapa zapalování má osu X 800–6800 rpm a osu Y 0–90 %, křivka osu X 1000–6600 rpm a hodnoty 120–225 Nm, velká mapa osu X 500–6800 rpm.

Skripty

init.py v režimu Startup připraví stav generátoru — čas, rozkmit a frekvenci stimulační sinusovky:

import math
t = 0
a = 40
f = 1/5

script.py v režimu Periodic (period=20;unit=ms) posouvá čas o 20 ms a zapisuje novou hodnotu v procentech:

t += 0.02
sine1_stim.EngValue = 50 + a * math.sin(2 * math.pi * f * t)

Výsledkem je sinusovka 10–90 % s periodou 5 s, tedy raw ±8. Skript píše EngValue; inverzní konverzi provede QInsight, STIM list pak každých 10 ms streamuje poslední raw hodnotu — skript běží pomaleji než stream, takže každou hodnotu deska obdrží dvakrát. Oba skripty jsou jen pro runtime, ne pro replay (viz Přístup k proměnným). Skripty sdílejí jeden prostor, takže a a f z init.py můžete za běhu měnit v okně Python Interpreter.

Workspace

Plocha Nucleo H723 live + maps má čtyři controly:

  • Graph — sine1_value (červená), sine1_raw (oranžová), sine2_value (modrá) a sine3_value (zelená); osy s automatickým měřítkem.
  • Watch Table (obnova 250 ms) — všechny skalární proměnné kromě sine1_raw, včetně qfwDemoMapOut, se sloupcem Write pro zápis po řádcích.
  • XY Graph — sine1_value na ose X proti sine3_value na ose Y, stopa 10 s.
  • Matrix se třemi záložkami: mapa qfwDemoMap (s tlačítkem Read, protože je na události On Request; zapnutá barevná škála 0–32,5), křivka qfwDemoCurve (bez tlačítka Read — obnovuje se pollingem) a velká mapa qfwDemoBigMap (s tlačítkem Read). Díky virtualizované tabulce se i mapa 64 × 64 zobrazuje a posouvá plynule.

Vedle plochy jsou v rozložení otevřené oba skripty a Python interpreter.

Co uvidíte a co vyzkoušet

  1. Connect. Driver se připojí, protokol naváže XCP session, zjistí block mód, nastaví DAQ i STIM list a graf se rozběhne: tři sinusovky z desky a k nim sine1_raw shodná se sine1_value. Watch Table a křivka momentu se naplní do 500 ms; tabulka mapy zapalování zůstává prázdná — je na události On Request. STIM streamuje od začátku — dokud je bypass 0, deska ho ignoruje.
  2. Read. Stiskněte Read na záložce mapy zapalování — načte se celý blok 1072 B (jeden SET_MTA a UPLOAD burst) a zobrazí se jako heat mapa.
  3. Write Mode. V kontextovém menu mapy zapněte Write Mode, upravte několik buněk (Tab přechází na další buňku) a stiskněte Write. Zapíší se jen změněné buňky. Novou hodnotu control ukáže až po dalším Read — zobrazuje jen to, co vrátí deska.
  4. Map lookup. Po zápisu buňky, kterou firmware sčítá, se ve Watch Table změní hodnota Map lookup.
  5. Křivka. Zapište bod křivky momentu (Write Mode na její záložce) — nejbližší polling po 500 ms novou hodnotu potvrdí.
  6. Velká mapa. Na záložce Injection map 64x64 stiskněte Read: 16 640 B se načte řadou UPLOAD burstů po 255 B. Zapněte barevnou škálu (Color scale) v nastavení controlu a mapu si prohlédněte jako heat mapu.
  7. Bypass zapnout. V tabulce zaškrtněte Write u sine1_bypass, zadejte 1 a potvrďte Enter. sine1_value v tom okamžiku přestane kopírovat sine1_raw a začne sledovat sine1_stim — pomalou sinusovku ±8 ze skriptu. Oranžová křivka sine1_raw pokračuje dál: interní model se počítá nadále, jen se nepublikuje. XY graf se změní, protože osa X dostala jiný signál.
  8. Ruční stimulace. Skript přepisuje sine1_stim každých 20 ms, ruční hodnota by tedy platila jen krátký okamžik. V Python Interpreteru nastavte a = 0 (nebo před dalším Connect v Home → Project Configuration → Scripts odškrtněte u script.pyRuntime), zapněte bypass a do sine1_stim zapište 75 % — sine1_value ukáže 5,0; 50 % je nula, 0 % je −10. Zapsaná hodnota se do desky odesílá opakovaně, dokud ji nový zápis nenahradí.
  9. Bypass vypnout. Zapište sine1_bypass = 0 — sine1_value se vrátí k internímu modelu a opět splyne se sine1_raw.
  10. Kalibrace. Zapište např. sine2_amplitude = 8 nebo sine3_period = 2 — křivka se změní okamžitě, polling po 500 ms novou hodnotu potvrdí zpět v tabulce.
  11. Druhá instance QInsight. Otevřete projekt podruhé (nebo jakýkoli jiný klient na port 5555) a spusťte Connect: deska nové spojení okamžitě odmítne (forcibly closed by the remote host v Logs), běžící měření první instance pokračuje nerušeně. Druhý driver zkouší každou sekundu znovu a připojí se, jakmile první relaci ukončíte.
  12. Výpadek spojení. Odpojte od desky ethernetový kabel. Několik sekund zůstává stav beze změny, pak keepalive spojení ukončí a driver přejde do Faulted: v Logs přibývají varování … failed (attempt N/3) …. Po třech neúspěšných pokusech driver ohlásí chybu gave up after 3 reconnect attempt(s), zastaví svůj protokol a skončí ve stavu Stopped — runtime a případné další drivery (logování, simulace) běží dál. Znovu připojte kabel, klikněte na driver v Solution Exploreru a v okně Properties stiskněte Start: driver se připojí, protokol naváže novou XCP session a měření pokračuje bez zastavení runtime (viz Stavy driverů a tlačítko Start). Pokud kabel znovu připojíte dříve, než se limit pokusů vyčerpá, spojení se obnoví samo a počítadlo pokusů se vynuluje. Deska spojení zahodí sama, jakmile jí vypadne vlastní linka (kabel vytažený z desky), takže nové připojení přijme okamžitě — s tímto nastavením je měření zpět zhruba 3,5 s po zasunutí kabelu. Mastera ztraceného za linkou desky (kabel vytažený u switche, zamrzlé PC) odhalí deska svým keepalive do ~5 s — do té doby odmítá nové spojení stejně jako druhou instanci.

Související kapitoly