"C is a lie"?

Fórumok

A BSD Now 244. száma/adása "C is a lie" címmel idéz egy cikket az ACMQueue-ból, miszerint "a C nem egy alacsonyszintű programozási nyelv", merthogy a mai számítógépek nem holmi "gyors PDP-11-esek".

Mivel nem tanultam műszaki területen, így a cikkben található részletek többsége nem igazán érthető számomra, de azt a részt még nagyjából érteni vélem, hogy a mai processzorok már nem olyan absztrakt gép-modellt kínálnak, mint a PDP-11, amikor még igaz volt az, hogy a C hardver-modellje elég jól fedte a PDP-11 felépítését. Viszont ha igaz, amit a cikkben állítanak, akkor hazugság, de minimum tévedés lenne az, amikor a mai C-programozós könyvek és blogok azt állítják, hogy azért is jó C-t tanulni, mert akkor tudni fogod, hogy mikor mi történik (majdnem) gépi szinten? Azért ez elég komoly kijelentés.

Fel tudtok világosítani? Valóban "hazugság a C" (ebben az értelemben)?

Hozzászólások

Ki állítja azt, hogy a C-ből látszik, mi történik gépi szinten? Már a legegyszerűbb nyelvi eszközökből is eléggé vegyes dolgok születnek fordítás után a sok optimalizáció miatt. A syscall-ok és a libc is rengeteg mindent elfed. Annyi igaz, hogy közelebb van a gépi szinthez, mint egy Java vagy Python.

Ember számára olvashatóan csak assemblyből (legyen az bármilyen processzor) derül ki, hogy mi történik gépi szinten. És a mikrokód és az egyre bonyolultabb architektúrák miatt még az alatt is van sok rejtett részlet.

"assemblyből (legyen az bármilyen processzor) derül ki, hogy mi történik gépi szinten"

Maximum egy 386-oson. Aztán megjött az out-of-order execution, cache, branch prediction, memóriaabsztrakciók, multicore és milliónyi más egyéb trükk, amivel megpróbálták gyorsítani a processzorokat az idők folyamán. És akkor még nem esett szó arról, hogy van még egy OS is közted és a vas között. Ami egyébként futhat egy virtuális gépen.

Más kérdés, hogy átlag, üzleti feladatok megoldása esetén ezek igazából sokszor irrelevánsak.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

C hardver-modellje elég jól fedte
Ez szerintem pont fordítva van. A C rejti el - javarészt - a hardvert a programozó elől.
Tehát az alap libek és makrók segítségével nem kell tudnod hol a memória, melyik részét hogyan kell cimezned, milyen széles a memória, van-e FPU és pont hogyan kell használni. Ennek ellenére előfordulhat, hogy nem std műveletekhez inline assemblert kell használni, ha nincs rá makró. (pl. cache sor törlés)
Régen a C-t "struktúrált assemblernek" is neveztük. ;)

Speciel én ki szoktam használni a byte order (endianess) és szószélesség ismeretét a program gyorsítására, de ehhez tényleg kell ismerni a gép felépítését.

> Ez szerintem pont fordítva van. A C rejti el - javarészt - a hardvert a programozó elől.
Akkor ezt is félreértettem. Egyrészt, mert nem értek a dologhoz, másrészt olyan kommentelő is volt egy másik cikknél, aki elmondása szerint évtizedekkel ezelőtt sokat programozott assemblyben mindenféle masinákon, aztán amikor megtanult Céül, "szinte látta" az assembly kódot, ami a C-fordító majd előállít.

> Régen a C-t "struktúrált assemblernek" is neveztük. ;)
Jól sejtem, ez kb. ugyanaz, mint hogy "a C az egy magas szintű / hordozható assembly", ill. hogy "a C az egy alacsony szintű magas szintű nyelv"? :D

- - -
TransferWise

Ez addig működött, amíg egy processzor architektúrára fordítgatott az ember, és nézegette, hogy mi lett az eredmény,
cümmögve, hogy hát, én ennél assembly-ben hatékonyabban meg tudnám csinálni. Közben fejlődtek egy csomót a fordítók,
illetve bejött mindenféle egyéb architektúra, úgy hogy ennek lassan vége is van...

Nagy kő esett le! A kérdés is fura volt, a választ sem éreztem tökéletesnek, de teljesen jól vetted a lényeget.

Nálam a jelenség hasonló: Hardverfejlesztő voltam és vagyok is - a firmware assemblerben készült (az "assebly" elnevezés csak jóval később jelent meg), csak közben tettem 20 év kitérőt AIX-re, ahol POWER5-ig C-ben programoztam. Olyan jó volt az IBM fordítója, hogy abszolút érelmetlen lett volna a régi technikát alkalmazni: Megírom C-ben, majd az assembler outputot "kézzel optimalizálom".
Ennek ellenére a kritikus részeket vizsgáltam lista alapján. Ahhoz is fel kellett kötni a gatyát, mert a lista csak "straight line execution"-ként adta meg a várható átlagos futásidőt, ami a valós futásnál a hyperthreading és a 8 párhuzamos végrehajtó egység miatt jobbra-rosszabra változhatott. Érdekes volt látni, hogy egy 64 bites load 64 bitre fordítva egy utasítás és 1 órajel, 32 bitre fordítva két utasítás és 1+0=1 órajel. Mindenesetre az előéletem a tárolás értelmezését könnyebbé tette. A multitheading programozását meg nehezebbé. Egészen addig, míg egy kolléga nem szólt rám: Programozd úgy, mint az interruptot! A következő másodperctől nem volt probléma. :)

"a C az egy magas szintű / hordozható assembly"
Ilyet csak a hardverhez nem értő rossz szoftveresek mondanak. ;-D
Vagy csak ez is egy elavult mondás.
A mai (régi is) "magasszintű nyelvek támogatására készült" processzorok esetében esélytelen az, hogy assemblerben fogalmazol meg egy megoldást. A magas szintű nyelv egyik oldalról úgy definiálható, hogy a típuskezelés és ellenőrzés fejlettebb. Az alap assemblerben szinte minden rád van bízva, míg a C már egy csomó dolgot ellenőriz.
A C katasztrófája a mikrokontrollereknél csúcsosodik. Kényelmes, magasszintű de gyakran legalább 3-5x lassabb kódot eredményez. A C használhatósága a hardvertől függ. Pl.:
- az Arduino sokregiszteres (régiesen mondva Motorola 68000-szerű), szoftver stack-es.
- a PIC 8 bites családokig 1 regiszteres, limitált hardver stack-es. Ekkor a stack, stack frame szoftveres emulációval készül, így látszólag támogatja a magasszintű nyelvet. Ráadásul normális C fordító és lib sincs hozzá.
Tehát van az a hardver, amihez a C már nem megfelelő. Ennek ellenére használják, mert jobbára hordozható és akiknek bonyolult az assembler, (ami száznál jóval kevesebb utasítást tud,) azok könnyedébben boldogulnak.

A c kódnál van még egy baromi fontos rész, embedded fejlesztésnél is. Külön tudod választani az "üzleti logikát" és a hardware manipulációt. Ha ez megvan,
akkor az üzleti logikát körbe tudod rakni tesztekkel a fejlesztői gépen, magas szintű nyelven, és meg tudsz róla bizonyosodni, hogy azt csinálja, amit
szeretnél. Ez nagyon nagy könnyebbséget tud jelenteni akkor, ha mondjuk valami szabályozót/fuzzy logikát/stb. ír az ember.

Uzleti logika... uhh kiakadtam. :)

Mar csak a LOB hianyzik, hogy valaki megemlitse. Persze ertem en, hogy az embedded eleg szeles kort fed le, de azert megis, itt mikrokontrollerekrol vo't szo, nem valami szuper embedded atomreaktor vezerlesorol; ja, azt nem is c/c++-ban irjak, mert erosen tuzveszelyes, ja nem is, robbanasveszelyes kornyezet.

Hát, ne akadj ki. A mikrovezérlő ma már nem egy AVR8 vagy PIC16 szériát jelent.

Amikor 1MB programmemória és 256 kB RAM van egy nagyobb 32 bites mikrovezérlőben, ami mellesleg belépő Pentium2 tempóval szalad, szóval ez már nem az a kategória, ami kb. csak 3 LED + 2 relé meghajtására alkalmas.
Rádióamatőr területen az ilyenekbe többek között komplett jelfeldolgozás alapú rádióvevő blokkot programozunk bele. Igen erősek és mégis egycsipes mikrovezérlőkként kapod meg.
Innentől kezdve a feladat dönti el, hogy mennyire egyszerű vagy összetett üzleti logika kerül bele. A mai hardver elbírja.

Ha csinálsz egy szabályozót, vagy bármi "komolyat" egy led villogtatáshoz képest, az "üzleti logika" lesz. Ezt szeretné az ember
szépen, hw függetlenül kipróbálni, letesztelni, stb. Ha jó, akkor vagy mehet direkt a mikrokontrollerre (ha mondjuk C-ben van írva),
vagy át lehet írni mondjuk assembly-be.

Esetleg ha a szabályozásról külső adatkapcsolaton keresztül meghatározott módon tájékoztat és onnan authentikált felhasználóval valami bonyolultabb átparaméterezést kaphat. Végülis elfér a mai mikrovezérlőben.
Mint előzőleg írtam, amikor 512 kB akár 2 MB programmemóriád van és 128 kB akár 1 MB RAM-od, belső ethernet kontrollered, sőt HDMI-CEC interfészed is van. Lásd még: https://www.st.com/resource/en/datasheet/stm32h743bi.pdf
Ez utóbbi akkora mikrovezérlő, amiben "életművet" lehet C-ben alkotni.

És még csak nem is a méreten múlik, egy atmega128-ason is simán lehet akár GUI is, meg komoly állapotgép ami megvalósítja a programot.

Nekem az a tapasztalatom, hogy egészen alacsonyan van a határ, ahonnan kezdve már megéri PC-n szimulálni a mikrovezérlős programunkat. Egyszerűen azért mert egyszerűbb PC-n futtatni regressziós teszteket, illetve hibakeresést csinálni is.

Csak a köré épített hardware-t munkás szimulálni. Egyszerűbb valódi hardware-en dolgozni. Mikrokontroller jellemzően hardware-t vezérel, ott pedig hőmérséklet van, zaj van, nyomás, sebesség, szöggyorsulás, meg efféle jóságok vannak. Inkább belátom, hogy jó a programom, vagy kipróbálom élőben, mint elkezdjem szimulálni.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Software-esek túlságosan modellekben gondolkoznak. Sokszor nem azt kell debugolni, hogy rossz a program, hanem a rendszer képességeivel kell összecsiszolni az egészet. Semmire nem megyek a szimulációval, ha lényegében jó a program, de éppen a mechanikát debugolom. Arra keresem a választ, hogy az adott mechanikát, annak tömegeivel, súrlódásaival, egyenetlenségeivel hogyan tudom optimálisan hajtani, de úgy, hogy a tápegység is bírja villannyal.

Szóval itt semmire sem jó a szimuláció. Önmagában jó programot írni bárki tud, de a feladathoz illeszkedőt már nem. ;)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Amiket említesz, nem is szoftveres feladatok. De attól még a szoftver jóságát is tudni kell verifikálni, és az kizárólag szoftveres feladat, aminek az inputjait ugyanúgy lehet szimulálni. Miért lenne baj azzal, ha a szoftveresek szoftveres dolgokban gondolkodnak? Nem az ő feladatok a mechanikai illesztés.

Ez mérnöki feladat. Szerintem nagyon rossz az a megközelítés, amikor egy programozó felteszi a kezét, hogy ehhez már semmi köze, mert ebben áram folyik. (Mellesleg mégis hogyan fut az a program, mi realizálja? Ööö... hm... izé...) Vagy a villamosmérnök, amikor azt mondja, hogy ez már mozog, itt nyomaték meg szögsebesség van, jöhet a gépész. Nálunk a cégnél a határterületekhez hozzászól mindenki, s itt nem okoskodásról beszélek. Kell látni a feladatot, nem élesek a határvonalak, valamennyi mechanikai ismerete van a villamosmérnöknek is, de a gépész száján is kiesik az amper kifejezés néha, s a programozó sem bújik el mindig a struktúrái és metódusai mögé.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Attól, hogy hozzászól, még nem feladata. Nem fogok megkérni egy villamosmérnököt arra, hogy formálisan verifikálja nekem a szoftverét, mert ő nem ebben a legjobb. Van más szakterület, ahol az ő addigi, saját tudásába befektetett egy pár évtizedet ki lehet használni, és az nem az lesz mondjuk, hogy hogyan kell szoftver verifikálni.
Hasonlóképpen, hiába van egy műszaki informatikusnak fizikai és elektromossági alapismerete, nem az ő feladata lesz az, hogy méretezze a kábeleket, mert az ő idejét, és a tudását máshol lehet jól használni.

Ugyanúgy, ahogy egy sebész is pontosan tudja, hogy hogyan működik az idegrendszer és bizonyos biokémiai folyamatok, nem lesz belőle anaszteziológus, vagy belgyógyász.
Vagy éppen ahogy egy villamos tervező építészmérnök is tud statikát számolni, de ő jobban ismeri a vonatkozó szabványokat és jogszabályokat ahhoz, hogy inkább csak a gyengeáramú rendszereket tervezze meg.

Nem arról van szó, hogy valaki ódzkodik attól, hogy "hát ez nem az én dolgom, mert áram folyik benne", hanem arról, hogy nem a szoftveresnek a feladata ezt csinálni, az ő idejét és tudását máshol sokkal hatékonyabban ki lehet használni.

Tudod, az ismert ábra:
https://img.memecdn.com/heaven-vs-hell_o_2976043.jpg

Lehet, hogy mindenki ért egy kicsit a másik munkájához, de nem mindegy, melyik munkát kire bízod.

+1. Tegye mindenki azt, amihez ért. Nálunk pl. matekosok vannak még a csapatban. Ők azért vannak, hogy megoldjanak üzleti problémákat és találjanak rájuk megoldást, mi meg azért, hogy köréjük rakjuk az architektúrát, rendszert, biztosítsuk az algoritmusaik számára az adatokat, stb. De ugyanígy, ha nekünk van valami infrás kérdés, akkor is alapvetően inkább az infra csapatot kérdezzük/kérjük, mert valószínűleg gyorsabban és hatékonyabban oldják meg a problmémákat.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Mondjuk ha nem érted a matekosokat és határozottan elzárkózol tőlük, mert az "nem a te dolgod", akkor nem raksz te semmit köréjük vagy amit köréjük raksz, azt rövid idő múlva odacsapják a fejedhez. Igenis kell tudni a határterületeken mozogni, sokszor jó mélyen behatolva a másik szakma mezsgyéire ahhoz, hogy ne küszködni járj a munkahelyedre, hanem dolgozni, termelni.

Nem sokat értettél a hozzászólásaimból. A programozó is egy szakma, meg a villamosmérnök, s a többi is. Most hardware közeli programozásról beszéltünk, nem a hardware-t elfedő operációs rendszer fölötti programozásról.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Nyilván, hiszen van, hogy nálunk landol az, hogy egy matekosok által írt kalkulátort optimalizáljunk, mert nekik nem az a dolguk, hogy CPU cache lokalitással pöcsöljenek, hanem azzal, hogy kitalálják, hogy hogyan fogják megoldani a domain specifikus problémát, mert utóbbit ők, előbbit egy szoftveres fog hamarabb jobban, jól megoldani. (Assemblyben "jól megoptimalizálom" huszárok kedvéért: konkrét példa ráadásul egy ilyen szörnyen magas szintű nyelv esetén jött elő, mint C#.) Meg volt olyan is, hogy megmondták, hogy az adott részfeladatot ezzel vagy azzal az algoritmussal fogom tudni jól megoldani ilyen módon, mert a sprintben így volt idő elosztani a feladatot.

Ettől függetlenül nálunk még mindig az a mondás, hogy egy matekos _alapvetően_ ne kezdjen el DB-t tervezni, architektúrát kitalálni, mert nem az a dolga. Nyilván csinálnak néha olyat is (most pont egy olyan sprint volt, hogy kellett nekik, mert egy olyan servicet kellett írni a többi köré/mellé/tudom is, hogy hova), csak akkor meg sűrűbben kérdezgetik az abban tapasztaltabb kollégákat, hogy jó lesz-e ez így.

De erről szól a csapatmunka.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Nem érzek túl nagy ellentmondást a véleményünk között, talán súlypontjában igen. A szakosodással egyetértek, én sem software-esként, s nem is gépészként létezem a munkahelyemen. Viszont sok határterület van, ami olyan, hogy ha ki-ki vegytisztán akarja a feladatokat, akkor azt senkinek sem kellene elvégeznie. Gondold csak végig, írod a kódot - eddig software-es feladat -, közben figyelsz arra, hogy valamelyik tok ne disszipáljon túl, vagy a tápegység ne üljön le - ez már villamosmérnöki -, miközben a mechanikát ne törd össze, mert a mozgás végére jutottál - ez viszont gépész feladat lenne. De azért mégis csak egyetlen ember írja meg ezt a kódot. Nyilván, aki írja a kódot - mondjuk villamosmérnök -, konzultál gépész kollégákkal is.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Valamiért úgy tűnik, néhányan feltétlenül külön szeretnék választani a "hardvereseket" és "szoftvereseket", holott a mikrokontrollerek programozása inkább villamosmérnöki mint informatikusi feladat; nem is pont ugyanazokra a dolgokra kell odafigyelni mint egy PC program esetén.

Nem a NYÁK-tervezésnél / élesztésnél áll meg a villamosmérnök feladata.

"holott a mikrokontrollerek programozása inkább villamosmérnöki mint informatikusi feladat"
Miért lenne ez igaz? Semmi indoka nincs. A microcontroller egy ugyanolyan általános utasításkészletű logikai gép, mint bármelyik CPU, semmilyen villamosmérnöki ismeret nem kell ahhoz, hogy például SDIO interfészt programozzál le egy microcontrollerre. Ellenben ha többszálú RTOS-t akarsz futtatni rajta (FreeRTOS, Mynewt, Zephyr) mert épp több más kontrollerrel tudna beszélgetni aszinkron módon, akkor bizony a villamosmérnöki ismeretek kevesek lesznek.

A microcontroller ugyanolyna logikai gép, mint egy általános CPU (sőt, általános CPU-k vannak bennük, Turing-teljes gépek), csak épp a memóriát kézzel kell számolni sokszor. Nem nagy dolog, nem látom, milyen villamosmérnöki ismeret az, ami miatt ők inkább értsenek ehhez.

Önmagában a programozáshoz nem kell, de vedd figyelembe azt is, hogy a villamosmérnök mint olyan is egy tág fogalom, ahogy az informatikus úgy általában is az.
Tartom azt, hogy a mikrokontroller programozása alapvetően villamosmérnöki feladat, de ezzel nem azt mondom, hogy más ne tudna rá programot írni.

Ez is egyfajta határterület és nem biztos, hogy csak programozni kell azt az eszközt.

Firkálok egy kapcsolási rajzot, vannak rajta mindenféle nanofaradok meg microhenry-k. ohmok, gyors dióda, power MOSFET, adok hozzá típusjelzéseket, nézheted a katalóguslapokat, írhatod a programot, de baj ne legyen belőle. Majd' elfelejtettem, a tápfeszültség 300 V fölött van. Hidd el, van, ami nem klasszikus programozói feladat, mert úgy van megtervezve a hardware, hogy lehet villanást okozni. Hogy miért? Mert ha mindenre hardware-es időzítés volna, lehet, már nem is nagyon kellene a mikrokontroller. Így viszont, ha félreérti valaki a működést, tud olyan kódot írni, ami tönkreteszi az egészet.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Miért, ha a software-es írja, s ő megy el a cégtől, az mennyivel jobb? Amit írsz, azon az érthető kommentelés és a dokumentálás segít, meg a lehetőség szerint öndokumentáló, olvasható kódolás. Bár assembly-ben én futásidőre és memóriára optimalizálok, itt némileg bukik a jól olvashatóság. Azért törekszem rá valamelyest.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Akkor miért nem egy fizikus csinálja? :)

De most itt nem arról volt szó, hogy fizikai folyamatot nem ért egy szoftveres, hanem arról az állításodról, hogy jajúristen, hardver, ne nyúljon hozzá szoftveres.

De elárulok egy titkot: egy szoftveres alapból nem szakember a:
- számlázában
- raktározásban
- fuvarozásban, szállítmányozásban
- e-kereskedelemben
- orvoslásban
- közlekedésben
- stb.

És mégis tucatszám tudnak készíteni szoftvereket ezen területekben. Jól.

Bámulatos, mi?

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Nem arról beszéltem, hogy a tesztelés felesleges, hanem arról beszéltem, hogy van, amit élesben lehet tesztelni. Részint azért, mert nem is az az igazi kérdés, jó-e önmagában a program, hanem az, hogy az adott hardware-t hogyan is volna igazán jó vezérelni. Tehát a rendszert kell tesztelni. A valódit, nem pedig annak bármilyen idealizált és egyszerűsített modelljét.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ami szintén programozás, tehát a programfejlesztés módszertanait érdemes rá használni. Elhiszem, hogy neked bonyolult szimulálni, a szoftvermérnök meg pont azt akarja látni, hogy a kód azt csinálja, amit kell, és ha változtatott rajta, akkor gyorsan (értsd, mondjuk 10 sec) meg tudjon győződni róla, hogy továbbra is azt csinálja, amit korábban elvárt tőle. Csak mivel te ehhez nem értesz, ezért magas lóról osztod az észt, hogy ez bonyolult, nem lehet, és egyébként sincs értelme, ahelyett, hogy elgondolkodnál azon, hogy lehet, hogy mégiscsak.

Ráadsul -- érzésre -- mivel a legtöbb ilyen mikorkontrolleres cucc egyszerű bemenetek hatására csinál dolgokat, ezért pont szimulációval lehet a vezérlést viszonylag egyszerűen olyan szinten végignézni, és mindenféle kornekcasekre felkészülni, ahogy hardveresen sose fogod egyszer sem, mert ott kb örülsz, hogy végre összehákoltad a happy path-t. És amikor majd a szoftveres szemmel igencsak kóklány kódok, amiket csinálnak nagyon sokszor az ilyen vezérléseknél, majd jól összefossák magukat, a rendesen tervezett és tesztelt meg nem, akkor lehet majd fejvakarni.

De persze én szoftvermérnök se vagyok, úgyhogy lehet, hogy tengeralattjáró vezérlést is búvárruhában, repülésvezérlést meg a szárnyon ücsörögve csinálnak :D

Másról beszélünk. Engedd el azt, hogy a software-nek kell a specifikációt tudnia. Nem! A berendezésnek kell. Semmire nem mész egy hibátlan software-rel, amelyik nem veszi figyelembe - mert nem tapasztaltad meg valós környezetben - a fizikai valót, a hardware-t. A software-t a hardware-hez kell igazítanod. Arra írod. Vedd úgy, hogy valami izgő-mozgó, szuszogó, csöpögő, melegedő, hűlő, világító, hangot adó és fogadó valamit kapsz a kezedbe, s ez a specifikáció. Ezzel kell valamit kezdened. Az lényegtelen, milyen kódot írsz, az a fontos, hogy a berendezés legyen jó. A hardware-t éleszted a kódoddal, nem pedig ideális modellre írsz hibátlan programot.

Ugyanitt póniló beszerzése folyamatban. :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

"amelyik nem veszi figyelembe - mert nem tapasztaltad meg valós környezetben - a fizikai valót"

De mit nem tapasztaltál meg?

"A software-t a hardware-hez kell igazítanod. Arra írod."

....Igeeen, köszönjük nyilvánvaló kapitány, és?

" Vedd úgy, hogy valami izgő-mozgó, szuszogó, csöpögő, melegedő, hűlő, világító, hangot adó és fogadó valamit kapsz a kezedbe, s ez a specifikáció."

....Igeeeeen, éééééééés? Akkor mi van?

Ezek mind mérhető dolgok bizonyos hibahatáron belül. De légyszi ne akard már nekem bemagyarázni, hogy azokat meg nem lehet rögzíteni, hogy reprodukálható módon lehessen egy szimulációban használni, mint bejövő jel. Ha fizikai vason reprodukálni tudsz vele egy jelenséget, akkor egy szimulációban is tudnod kell. És egyébként is, egy ilyen minta kiváló alapanyag egy regressziós teszthez.

Vagy mi az a fene nagy feketemágia? Rálehelsz és túlmelegedik, emiatt a mikrokontrollered hirtelen nem összeadni, hanem kivonni kezd? Még ezt is lehet egy jó mért adattal szimulálni.

Félreértés ne essék: nem azt mondom, hogy nem kell a vason tesztelni egyáltalán, de eddig még egyetlen egy konkrét érvet nem kaptunk tőled, hogy mitől olyan fene nagy feketemágia, amit te művelsz.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Nem akartam túl konkrét lenni, de ha teszem azt, összetörsz egy nagy áttételű fogaskerék blokkot, ezt hogyan szimulálod software-es környezetben? Épp az a kérdés, mit találj ki, hogy ez a baleset ne forduljon elő, majd járatod a valós hardware-en sokat, hogy igazold, valóban nem töröd össze a mechanikát. A software-ben lehet, hogy csak konstansokat - nyomaték, áram, sebesség, feszültség - kell változtatnod, de az is lehet, hogy újra kell gondolnod az egészet, s pozíció szabályozást kell csinálnod az eddigi vezérlés helyett.

Nem az a kérdés, hogy tudsz-e hibátlan programot írni. Tegyük fel, hogy tudsz. Az a kérdés, hogy tudsz-e megbízhatóan, stabilan működő berendezést készíteni.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Most szabályozásról vagy vezérlésről beszélünk?

Egyébként ez nekem egyrészt egy méretezési problémának tűnik eddig, aminek viszont köze nincs a szoftverhez, hanem ahhoz, hogy tudd, hogy meddig mehetsz el vagy mekkora tűrőképességű fogaskerék blokkot válassz. Ezt nyilván nem egy szoftveresnek kell megmérnie, de még azon se vagyok meggyőződve, hogy a fogaskerék-blokk méretezése villamosmérnöki feladat lenne.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Az gépészmérnöki feladat. Vélhetően azért választottak ilyet, mert optimum volt méret, ár, elérhetőség, terhelhetőség szempontjából, de ha falnak mész vele - tehát a mozgás pálya végéig -, legyalulod a fogakat.

Értem, hogy méretezési meg specifikációs, meg implementációs probléma, de ezt valakinek meg kellene csinálni, ki kellene találni, hogyan lehet jól csinálni, aztán meg kell valósítani. Az, hogy vezérlés vagy szabályozás legyen, szintén eldöntendő.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

> Másról beszélünk.

Dehogy beszélünk másról.

> Engedd el azt, hogy a software-nek kell a specifikációt tudnia. Nem! A berendezésnek kell.

Nem mondod... És? Abban nincs software?

> Semmire nem mész egy hibátlan software-rel, amelyik nem veszi figyelembe - mert nem tapasztaltad meg valós környezetben - a fizikai valót, a hardware-t.

Egyrészt, az a software, ami nem azt csinálja, amit kell neki, az definíció szerint nem lehet hibátlan :) De ha ezen a kis logikai benézésen túllendülünk, akkor még mindig ott van, hogy senki nem mondta, hogy nem kell hardwaren is tesztelni.

> A software-t a hardware-hez kell igazítanod. Arra írod. Vedd úgy, hogy valami izgő-mozgó, szuszogó, csöpögő, melegedő, hűlő, világító, hangot adó és fogadó valamit kapsz a kezedbe, s ez a specifikáció. Ezzel kell valamit kezdened.

Megintcsak, igen, és? A szimulált adatos meg mockos teszt pont ugyanúgy használható, ahogy bárhol máshol. A szoftvernek az a dolga, hogy ha ez és ez történik, akkor ezt és ezt csinálja. Akkor is, ha egy ldap szervertől jövő választ kell feldolgozni, akkor is, ha egy stdinen érkező adatot kell olvasni, meg akkor is, ha egy pinről leolvasott jelszinttel kell valamit kezdeni. Teljesen mindegy, hogy szimulált ldap válasz, vagy szimulált tüske állapot van. Amit az ilyen tesztekben tudatosan megfogalmazol, hogy a vezérés ilyen is ilyen esetekben ezt és ezt csinálja, arról tudod belátni, hogy az valóban úgy van. Ha valóságban mégsem ez történik, akkor szar a modelled, meg kell értened mi történik valójában, mert valószínűleg szar a kódod is, hiszen nem értetted meg jól a speckót :)

> Az lényegtelen, milyen kódot írsz, az a fontos, hogy a berendezés legyen jó.

Dehogy mindegy. A kód minősége adja neked azt, hogy amikor majd hozzá kell nyúlni, akkor hozzá lehessen. Úgy, hogy ne cse

> A hardware-t éleszted a kódoddal, nem pedig ideális modellre írsz hibátlan programot.

Ki beszélt itt ideális modellről? Mármint rajtad kívül. Ráadásul mindig vicces látni, mikor az egyik oldalról azzal jönnek a villamosmérnökök, hogy itt rend van kérem, meg rendes speckója minden alkatrésznek, ahol jól le van írva pontosan, hogy mi lehet, a másik oldalról meg aztán előadjátok, hogy de ezeket a jó speckókat még csak véletlenül sem lehet ám a hardware helyett használni.

Az a baj, hogy láthatólag fogalmad sincs róla, hogy mennyit fejlődött a szofverfejlesztés módszertana az elmúlt 20 évben, ezért nem is érted, hogy miért kellenek reprodukálható tesztek, hogy mennyivel jobb szoftvert lehet írni, ha ilyeneket használsz, és inkább előadod, hogy ez a ti területeteken nem menne, mert az annyira speciális, meg ahhoz nem értenek a szofveresek úgysem. Rossz hírem van, lófaszt speciális.

További vicces, hogy kijelented: "Ez mérnöki feladat. Szerintem nagyon rossz az a megközelítés, amikor egy programozó felteszi a kezét, hogy ehhez már semmi köze, mert ebben áram folyik." Majd ezek után mikor a szoftveres elkezdené nem feltenni a kezét, akkor meg jössz azzal, hogy de azt úgy nem lehet. Mert te természetesen az ő területéhez is kiválóan értesz a magadén túl.

Azért pluszban különösen aranyos, mert a szoftveripar már régestelen rég felismerte (igazából szerintem mindig is tudta), hogy ő modellekkel dolgozik, amik olyan valós problémákat oldanak meg, amikhez a programozó nem ért, ezért viszonylag széles tárháza van annak, hogy hogyan lehet ezeket a domain specifikus információkat az ehhez értőkkel együtt dolgozva értelmezni, legyen az villamosmérnök vagy banki folyamatokat szabályozó jogász. Ennek meg elengedhetetlen része, hogy jól figyeljen arra, amit mondanak neki. Majd jössz te, és jól előadod, hogy de ők ezt úgyse értik. Aha, hát persze.

Nagyon szépen elbeszélgettek a témán, de azért halkan megjegyezném, hogy mindkét fél mondandójában van némi igazság.

Én is szoktam egyes kódrészleteket PC-n vizsgálni, de könnyen kerül elő olyan feladat, ahol egyszerűen nem tudod megoldani a fizikai működés szimulációját.
Egyszerűen azért, mert millió más dolog befolyásolja.
Pl. egy külső elektronika, amire nem igazán van ráhatásod, az egyes eszközök működése során tapasztalt együtthatások (pl. adott eszközök zavarják egymást /pl. fény, hang, rezgések, sebességek vagy időzítések/, ezért kizárásokat kell csinálni, esetleg bizonyos eszközöket lekapcsolni energiamenedzsment vagy általuk okozott zavarok miatt).

Ha jól működik a szoftver, az egy nagyon jó dolog (és működjön is jól), de a hardvernek kompletten kell jól működnie, amibe a szoftver _is_ beletartozik ugyan, de a komplett áramkörnek kell azt csinálnia, amire szánták.
Lehetőleg a külső bizonytalansági tényezőkkel együtt, minél inkább hibatűrően.

Nagyon sok információ csak akkor derül ki, amikor a hardveren dolgozol.
Lehet szimulálni és tesztelni egyes kódokat, de a komplett rendszert jó eséllyel nem.

Lehet olyan helyzet is, ahol mikroszekundumok meg nanoszekundumok számítanak, és nem másik, magasabb szintű rendszerhez kapcsolódsz, hanem egy áramkörhöz, aminek megvan a maga késleltetése (nem, nem ugyanakkora, de valamilyen szinten specifikált), az időzítéseket pedig tartani kell.
Bizonyos teszteket nem szoftveresen kell végezni, hanem ráakasztunk egy oszcilloszkópot és megnézzük a fizikai viselkedését az áramkörnek, az időzítéseket, jelszinteket, és a potenciális hibaforrásokat, amik lehet, nem is feltétlen okoznak az adott pillanatban problémát, de jó eséllyel fognak más körülmények között.

Másfelől PC-n másképpen célszerű szervezni a programot mint egy mikrokontrolleren.
Más a cél és mások a lehetőségek is.

Ha lehet, fogadjuk el azt, hogy a szoftveresnek is van részben igaza (persze, teszteljünk és írjunk jó kódot), de a hardveresnek is (komplett hardvert [is] kell tesztelni, és a rendszernek kell jól működnie).
Nem fekete és fehér a dolog, így mindenkinek igaza van és egyben senkinek sincs igaza.

"Ha lehet, fogadjuk el azt, hogy a szoftveresnek is van részben igaza (persze, teszteljünk és írjunk jó kódot), de a hardveresnek is (komplett hardvert [is] kell tesztelni, és a rendszernek kell jól működnie)."

Nagyon szépen elbeszélgettél a témán te is, de a lényeg ez az utolsó mondat. Itt a "szoftveres" táborból senki nem állította, hogy ne kellene tesztelni komplett hardwaren is. A szál onnan indult, hogy kiröhögték azt, aki azt merte mondani, hogy az üzleti logikát jól külön lehet választani, és külön, hw nélkül tesztelni.

Az már csak járulékos, hogy láthatólag fogalmuk sincs az uraknak arról, hogy az miért is lenne jó.

Az ember igyekszik az egyes logikailag különálló funkciókat szétválasztani, ez igaz.
Más kérdés, mit is akarunk csinálni.

Pl. van egy szenzorunk, amivel I²C interfészen kommunikálunk.
Vannak az eszköznek regiszterei, amivel beállítani lehet néhány dolgot és vannak regiszterei, amiből ki tudsz olvasni hőmérséklet értékeket.

Van egy kijelződ is, ami SPI interfészen kommunikál, szintén megvannak a maga regiszterei és beállításai.

Csinálsz egy logikát, ami a kiolvasott számokat színkombinációvá alakítja.

Van egy olyan logikád is, ami a hőmérsékletek kiolvasásait indítja, beállítja a megjelenítési (színhőmérséklet) tartományt és a megfelelő képpontokat megfelelő színűre állítja a kijelzőn.

Az alap logikát - milyen legyen a szín, mi alapján állítjuk be a limiteket, tudod tesztelni.
Az alap vezérlés könnyen átlátható.

...de a kijelzőt és a szenzort pl. hogyan szeretnéd emulálni?
Nem lehetetlen, de nem éri meg a ráfordítást.

Hogyan deríted ki egy szimulációval, hogy a kijelző valóban azt mutatja, amit szeretnél, vagy a szenzorból valóban ki tudtad olvasni ezeket az adatokat?
Nem arra gondolok, hogy elméletileg mit kellene mutatnia, hanem arra, hogy mi van rajt a valóságban.
Esetleg azt, hogy elég-e a kijelzőt az áramkör éledése után x vagy y idővel táp alá helyezni, esetleg a reset láb állapotát bekapcsolást követően mekkora ráhagyással váltsd át.
...vagy valamelyik kijelző vezérlője módosult annyit, hogy szétesik rajt a kép, esetleg két azonos hardver mégsem annyira azonos.

Megvan ugyanakkor a kijelzőt és szenzort kezelő, alacsonyabb szintű kód is, egészen az interfészek vezérléséig. Ezek egyrészt kontrollerspecifikusak lehetnek, másrészt nemigen tudod őket máshol tesztelni mint a konkrét hardveren, amelyiken fejleszted.

Annak nincs értelme, hogy két alapvető funkciót teljesen újraírj szoftverből azért, hogy az "üzleti logikát" teszteld, ha azt a teljes rendszerhez képes viszonylag kis kódrészletet amúgy le tudod tesztelni külön.
A fenti példának viszonylag kis része az, ami PC-n is tesztelhető.

...de hiába működik jól a program, ha pl. az I²C kommunikáció le tud akadni vagy nem képes arra a sebességre, amit szeretnél elvárni tőle.
Ezt nem PC-s szimulációval fogod kideríteni.

A fenti gondolatot nem azért írtam, mert annyira bonyolult lenne a megvalósítás, de van egy olyan sanda gyanúm, hogy azok a kritikák, amit az egyik fél megkap a másik rálátásával kapcsolatban az adott problémakörre, azt a másik fél is megkaphatná egész nyugodtan a másik részről, hasonlóan jogosan.

Mindegy is, valójában teljesen fölösleges volt ezt ideírnom.

Semmi kétség. Nyilvánvalóan minden szabványnak megfelel a rendszer, komoly csapatmunkával és az előírt legbiztonságosabb nyelven készült, valamint az összes unit, regressziós, meg amit csak szeretnél hibátlanul futott.
Mindössze nem működik.

Dolgoztam már ilyen rendszerben. (De AHHOZ a részéhez semmi közöm!) A céget képviselő főfőszakértő cigiszünetben négyszemközt megjegyezte: Nem látott még ilyen rendszert, ami minden szabványnak ennyire megfelelne! És ennyire működésképtelen lenne!

Bár nem biztonsági szoftver volt, ezért mindenkinek egyszerű volt a dolog. Az adatgazda/üzemeltető egy levélben leírta, hogy az előírt biztonsági beállítások mellett nem tudja garantálni a működést. Igaz, azok nélkül sem. ;)

> Semmi kétség. Nyilvánvalóan minden szabványnak megfelel a rendszer, komoly csapatmunkával és az előírt legbiztonságosabb nyelven készült, valamint az összes unit, regressziós, meg amit csak szeretnél hibátlanul futott.
Mindössze nem működik.

Azért azon nem csodálkoznék nagyon, ha egy biztosítóberendezés szoftverét speciel az ilyeneknek semmi értelmét nem látó, csak a hardwaren lehet fejleszteni villamos (vagy vonat) mérnök csinálta volna.

> Semmi kétség. Nyilvánvalóan minden szabványnak megfelel a rendszer, komoly csapatmunkával és az előírt legbiztonságosabb nyelven készült, valamint az összes unit, regressziós, meg amit csak szeretnél hibátlanul futott.
Mindössze nem működik.

Azért azon nem csodálkoznék nagyon, ha egy biztosítóberendezés szoftverét speciel az ilyeneknek semmi értelmét nem látó, csak a hardwaren lehet fejleszteni villamos (vagy vonat) mérnök csinálta volna.

"Pl. van egy szenzorunk, amivel I²C interfészen kommunikálunk.
Vannak az eszköznek regiszterei, amivel beállítani lehet néhány dolgot és vannak regiszterei, amiből ki tudsz olvasni hőmérséklet értékeket.

Van egy kijelződ is, ami SPI interfészen kommunikál, szintén megvannak a maga regiszterei és beállításai.

Csinálsz egy logikát, ami a kiolvasott számokat színkombinációvá alakítja.

Van egy olyan logikád is, ami a hőmérsékletek kiolvasásait indítja, beállítja a megjelenítési (színhőmérséklet) tartományt és a megfelelő képpontokat megfelelő színűre állítja a kijelzőn.

Az alap logikát - milyen legyen a szín, mi alapján állítjuk be a limiteket, tudod tesztelni.
Az alap vezérlés könnyen átlátható."

Jep, kb pontosan innen indult a szál, és lett kiröhögve a kolléga, hogy ugyanmár.

"...de a kijelzőt és a szenzort pl. hogyan szeretnéd emulálni?
Nem lehetetlen, de nem éri meg a ráfordítást."

Hát, speciel az i2c meg az spi olyan gyakoriak, hogy ha ilyesmivel foglalkoznék, akkor ezekre jó eséllyel -- ha nem találok készen -- akkor rászánnám az időt, hogy csináljak rá mockot. Mert elég gyanús, hogy megérné, nem olyan rettenetesen bonyolult dolgok.

"Hogyan deríted ki egy szimulációval, hogy a kijelző valóban azt mutatja, amit szeretnél, vagy a szenzorból valóban ki tudtad olvasni ezeket az adatokat?
Nem arra gondolok, hogy elméletileg mit kellene mutatnia, hanem arra, hogy mi van rajt a valóságban."

Azzal a szimulációval, aminek ezek csak bemeneti meg kimeneti adatok, azzal sehogy, mivel nem is az a célja neki. Ha kétségeim vannak afelől, hogy a kijelző adott bemenet hatására nem azt csinálja, amit kell neki, vagy a szenzor nem szolgáltat adatot úgy, ahogy kellene, akkor tesztelem a kijelzőt, meg a szenzort.

"...vagy valamelyik kijelző vezérlője módosult annyit, hogy szétesik rajt a kép, esetleg két azonos hardver mégsem annyira azonos."
Dehát van spec sheet, ami minden rajta van a valóságból, hiszen itt nagy nagy rend vagyon. Szarkazmust félretéve, mi köze van a szofverrész tesztelésének ahhoz, hogy szar-e az alkatrész?

"Annak nincs értelme, hogy két alapvető funkciót teljesen újraírj szoftverből azért, hogy az "üzleti logikát" teszteld, ha azt a teljes rendszerhez képes viszonylag kis kódrészletet amúgy le tudod tesztelni külön.
A fenti példának viszonylag kis része az, ami PC-n is tesztelhető."

Egyrészt két tökéletes példát hoztál azokra a funkciókra, amit ha hajlandóak lennétek szoftverfejlesztésre alkalmas eszközöket bevezetni, akkor minden teszt keretrendszerben benne lennének, másrészt nem akkora para, a szükséges részeket megcsinálni.

Másrészt meg dehogy nincs értelme. Ezeknek az automatizált teszeteknek pont az az egyik jelentős része, hogy sokkal jobban belásd, hogy mit is kell pontosan csinálnia a programodnak -- ez annál a tipikus trial and error workflownál amit tolni szoktatok, és itt is propagáltok igen jelentős előnyökkel jár. T.I. egyrészt észreveszed, hogy az átalakításod elbaszott valamit, amit 12 iterációval ezelőtt oldottál meg. Másrészt sokkal könnyebben tudsz olyan szélsőségeket kipróbálni, amiket a hardwaren döcögős, és sokáig tart.

A másik jelentőssége ennek, hogy a tesztek megemlékeznek arról, hogy mit is várt a szerzője ettől a rendszertől. És akkor majd ha javítani, átalakítani, változtatni kell, akkor nem az lesz, hogy muszáj valahonnan előtúrni Gyulát, aki csinálta, vagy megint alapjaitól megérteni az egészet, és durván végigszopni a fejlesztést nulláról, amihez kell annak a három srácnak az egyike, aki meg tudja ezt csinálni az országban. Most ezek elég tipikus sztorik, amikor villamosmérnökök mesélnek arról, hogy hogyan mennek náluk a dolgok.

"A fenti gondolatot nem azért írtam, mert annyira bonyolult lenne a megvalósítás, de van egy olyan sanda gyanúm, hogy azok a kritikák, amit az egyik fél megkap a másik rálátásával kapcsolatban az adott problémakörre, azt a másik fél is megkaphatná egész nyugodtan a másik részről, hasonlóan jogosan."

Goto 10, nekem úgy tűnik, hogy az egyik fél itt csak az, aki mindenáron ragaszkodik ahhoz, hogy a ő jól tudja, hogy hogy kell csinálni, ás a másik ismeretei nem applikálhatóak. A másik fél nem akarja azt mondani, hogy ő ért a domain specifikus dolgokhoz.

"Ezeknek az automatizált teszeteknek pont az az egyik jelentős része, hogy sokkal jobban belásd, hogy mit is kell pontosan csinálnia a programodnak -- ez annál a tipikus trial and error workflownál amit tolni szoktatok, és itt is propagáltok igen jelentős előnyökkel jár. T.I. egyrészt észreveszed, hogy az átalakításod elbaszott valamit, amit 12 iterációval ezelőtt oldottál meg. Másrészt sokkal könnyebben tudsz olyan szélsőségeket kipróbálni, amiket a hardwaren döcögős, és sokáig tart."

Na igen. Pont két sprinttel ezelőtt volt egy olyan bugom, hogy beraktam valamibe egy cachelést, ami tartalmazott egy negatív cachet is, mert az volt a feladat, hogy valamin gyorsítani kellett. Kód fordult, unit tesztek futottak, kézzel kimérve működni is látszott. Tolom be a PR-t. Aztán a build szerver visszaköhög, hogy elcsesztem, mert egy rakat integrációs teszt elbukott. (Bevallom, azokat néha lusta vagyok helyileg is futtatni, "build szerveren úgy is elhasal" elven.) Kiderült, hogy egy teljesen másik kódrészen, amihez hozzá se nyúltam baromira nem jó, hogy időben azelőtt beírom a negatív cacheban, hogy nincs, mint mielőtt maga az adat feltöltődne, hogy aztán a későbbi lekérésnél már fals eredményt kapjak.

És ez teljesen automatikusan jött ki. Nyilván a tesztet meg kell írni, ami nem kis munka. De ez a minőség ára.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Az I2C meg az SPI csak egy interface, gyakorlatilag _bármi_ lehet mögötte.
Nem határoz meg gyakorlatilag semmit a feladat lényegi részéből, ahogyan önmagában az UART, RS232 vagy RS485 interface sem mond semmit arról, ami mögötte van.
Ebből a szempontból nem számít, mennyire gyakoriak, mert csak a kommunikáció felületét adják (vannak paramétereik és egyéb jellemzőik, de mögötte egy valós eszköz van, amivel beszélgetni szeretnél, és itt most ez a lényeg).

Nem valószínű, hogy kifejezetten egy adott kijelzőhöz vagy más szenzorhoz találnál előre megírt tesztkörnyezetet, és értelme sem sok van.
Ha feldolgozó kódot tesztelni akarsz, akkor generálsz hozzá adatokat vagy rögzíted és beadagolod neki, ezzel nincs problémám.

...de, ha ezen a teszten túl vagy, akkor valós hardveren kell beszélgetni, mert ott fognak előjönni az esetleges problémák is.
Nem idealizálni kell a hardvert szoftverré, mert nem ettől fog jól működni (a hardver nem szoftver, nem úgy viselkedik).

Még egyszer: rendben van az, hogy tesztelem a szoftvert, nincs ezzel gond.
A feladat fontos része viszont a hardver tesztelése is... és fogadjuk el, hogy adott esetben a kijelzőn akarom látni az eredményt, mert nem a szoftveres teszteken fog kiderülni, ha nem bírja sebességet, időzítéseket, gyakori kommunikációt, külső zavarokat, beállításokat (inicializálást), elforgatást, saját display RAM-kezelését.
...de lehet adott szenzor kommunikációs sebesség, pollozás miatt is zajos, lehet, hogy módosítani kell hardveres szűrésen, stb.

A fenti példában hozott kijelzővel az egyik probléma, hogy sokféle létezik, részben hasonló kezelésekkel, kisebb-nagyobb inkompatibilitásokkal.
...és a kijelzőnek (vagy bármi másnak) kell jól működnie, nem csak a teszteknek.
...és vannak olyan részletek is, amik nem feltétlen vannak konkrétan benne a specifikációban...

Egyébiránt fel lehet építeni egy programot úgy is, hogy senki sem akarjon hozzányúlni, és úgy is, hogy jól érthető legyen.
Mikrokontrolleren is, villamosmérnök által is.

Másfelől meg el kell keserítselek, de nem csak az egyik fél ragaszkodik minden áron ahhoz, hogy ő jól tudja, hogy hogyan kell csinálni, és a másik ismeretei nem applikálhatóak.
A másik fél is ezt teszi, és egyik végletnek sincs igaza.

A fenti példát csak azért írtam le, hogy megpróbáljak kisebb rálátást adni pár dologra, de nem sikerült.
Ami valószínűleg nem ment át: a hardver nem szoftver, sohasem fog olyan mértékben egzaktul működni, mint egy tesztelt és ellenőrzött kód _önmagában_.

Az I2C meg az SPI csak egy interface, gyakorlatilag _bármi_ lehet mögötte.
Itt kezdődik a szoftveres látásmód, meg a tévedések vígjátéka.
Talán ezért I2C az egyik, TWI (TwoWire) a másik. A wiki szerint: In some cases, use of the term "two-wire interface" indicates incomplete implementation of the I²C specification. Not supporting arbitration or clock stretching is one common limitation, which is still useful for a single master communicating with simple slaves that never stretch the clock.
Lefordítom: Az egyik egy komplex protokoll, a másik meg arra való, hogy a szoftveres kiprüntyögtesse pl. egy szenzorból a bájtokat. Általában az összes I2C lib ez utóbbit fícsört valósítja meg.
A harmadik meg az AM2320, ami I2C-re ültetett MODBUS (eddig jó), ÉS 3 nem szabványos időzítés, amit csak extra timerrel lehet megoldani. Már, ha nem szoftver loopokkal szeretnél késleltetni. Elrettentő példa a fenti elvek szerint rpi-re készült driver (ott van valahol github-on), ami gyorsabb rpi-n futtatva érthetetlen módon nem működik. :-D
Sajnos ez is olyan eset, amikor kicsit tovább kellett volna olvasi az adatlapot, megérteni és implementálni. A regressziós teszt nyilvánvalóan elolvasta volna az adatlapot egészan a végéig. ;)

De maradjunk csak a mikrokontrollereknél! Pl. Core i7, C#, Windows, USB. Mondom a kollégának, hogy: Csinálj egy thread-et, ami az 1db USB blokkot bufferbe írja, amikor megérkezik.
Pár hónap múlva rájött, hogy néhány blokkocska elveszik. Meg is néztem a fw oldalt, de olyan ravasz módon íram meg, hogy még az adatvesztés se derült volna ki. :) Tehát nálam nem lehetett a hiba. De az egymondatos előírást sem valósította meg. Aztán mégis.
No, ekkor a két - nem is 20 éves - szoftver guru letöltött valami CPU lassító szoftvert, ronggyá lassították a Core i7-et, de még mindig működött! Aztán beletörődtek.

Neeem. Nem a saját vállamat veregetem.
Ezek a légbőlkapott izék megtörtént esetek, amikor trehány szoftveresek azt hitték, hogy a hardver is szoftver. :)
Engem szoftveres akkor sértett meg (mert még fiatal voltam:)), amikor kijelentette: Nektek assembler programozóknak könnyű! Addig tesztelitek a programot, amíg jó nem lesz.

Igen sok év telt el azóta. Erre azt állítod, csak az a szoftver lehet jó, amit (valamely fejlett eljárással) tesztelünk. Az én időmben még meg tudták írni jóra is. (Tán ezt hívják manapság unit test-nek? :))

Persze a fenti szoftveres kijeletésre egyszerű volt a válasz: Ne hülyéskedj! Ha nem tervezem meg az algoritmust, vagy pontatlanul programozom, akkor általában valami eltörik, vagy kigyullad. Akkoriban mechanika vezérléseket programoztam. Egy ilyen programnak úgy 70 százaléka hibakezelés. Ezzel nem csak én teszteltem le a programot, hanem működés közben is állandó ment teszt. Egy bizonyos szint után el lehet jutni oda, amikor egy kész 'if' ág után az 'else' ágba nem tudsz mit írni. Abból lesz a vészleállás.

"Ezek a légbőlkapott izék megtörtént esetek, amikor trehány szoftveresek azt hitték, hogy a hardver is szoftver. :)"
Az, hogy láttál hülye szoftverest, az érvnek azért elég gyengus.

> "Igen sok év telt el azóta. Erre azt állítod, csak az a szoftver lehet jó, amit (valamely fejlett eljárással) tesztelünk."
Citation needed, sose állítottam ilyet. Azt mondjuk most is állítom, hogy ha az itt körvonalazódó "addig baszogatom sok iterációban, amíg jó nem lesz" fejlesztést követitek, akkor ha a köztes lépések által megcsinált dolgokat nem ellenőrzöd vissza, akkor igen jó eséllyel igazgatás közben párat el fogsz belőle baszni. Ja nem, mert ugye ti mind zsenik vagytok, lásd lent.

> "Az én időmben még meg tudták írni jóra is."
Persze persze, régen mindenki tévedhetetlen zseni volt. Te főleg, azt tudjuk mindig.

> "Tán ezt hívják manapság unit test-nek? :))"
Nem.

> "Ne hülyéskedj! Ha nem tervezem meg az algoritmust, vagy pontatlanul programozom, akkor általában valami eltörik, vagy kigyullad."

Most akkor ti megterveztek mindent előre jól, vagy minden hw kicsit más, és sokat kell maszírozni, mire elindul? Vagy mindig, amelyik épp kényelmesebb, hogy ellent lehessen mondani?

Az, hogy láttál hülye szoftverest, az érvnek azért elég gyengus.
Nana! Lassacskán, de közelítünk. ;) Tehát a légbőlkapottból már lehet valóság is, csak ritka a hülye szoftveres (szerinted), de tán még a hülye szoftveres is programfejlesztési technológiákkal dolgozik. Meg még a hardveres is, csak nem szoftvert ír. Pontosan ezért olyan szabályokat követve, ami nem szoftver fejlesztési technológia. Bár jómagam is meg vagyok kissé lőve. Amióta az újabb assembler fordítókat is szoftveresek írják, azóta csak töredékét tudják a régi fordítókhoz képest.

Pardőz. Tényleg szimuláció meg tekknológija volt és nem teszt. :(
Azt mondjuk most is állítom, hogy ha az itt körvonalazódó "addig baszogatom sok iterációban, amíg jó nem lesz" fejlesztést követitek...
Mintha pont azt írtam volna, hogy gondosan megtervezett, pontosan programozott. Furán olvasol. ;)
Vagy arra az idézetre gondoltál, amit egy hardverhez nem értő szoftveres mondott?

Persze persze, régen mindenki tévedhetetlen zseni volt. Te főleg, azt tudjuk mindig.
Hálistennek tényleg a szakma nagyjaival dolgoztam. A második részre meg vagy harminc éve van egy frappáns mondásom: Lehet, hogy zseni vagyok...De sokkal valószínűbb, hogy több a nálam butább és trehányabb ember. :-D
Második magyarázat: Olyan buta vagyok, ráadásul annyira nem bízok magamban, hogy ezidáig csak precízen kivitelezett dolgok kerültek ki a kezem közül. Bár ezt a szoftveresek vajmi kevéssé értik. Hosszas vitát kellett folytatnom egy szoftvermérnökkel, hogy miért nem vagyok hajlandó frissíthető (javítható!) firmware-t készíteni. Pedig a magyarázat egyszerű. A gyártmányaink működése olyan triviális, hogy hiba esetén még nem is lehet belőle gyártmány. Ha meg nincs hiba, akkor nincs mit javítani. Másodlagos magyarázat: Én értem amit csinálok, ők nem mindig.

Balesetek azért adódnak. Főnökünk egyszer megkaparintott egy félkész példányt. Bedobozolta, kiöntötte, eladta. :-D Vagy amikor megkértem egy új funkció kipróbálására, akkor is ugyenez történt. A mérést én nem tudtam elvégezni, mert nem cipelek fel kézben a harmadikra egy motort. Input, amivel tesztelhettem volna meg azért nem volt, mert hiszen arra készült ez a műszer, hogy mérjünk vele.
Workaround az van! Csak 3db prototípus készül. Egyen fejlesztek, a másik kettő a szoftveres kollégánál, akinek van motorja, így tud tesztelni. Ha elkészültünk, de csak akkor a főnök megkaphatja a harmadikat tesztelésre.

Az unit testnél ott volt ám a szmájli.

Most akkor ti megterveztek mindent előre jól, vagy minden hw kicsit más, és sokat kell maszírozni, mire elindul? Vagy mindig, amelyik épp kényelmesebb, hogy ellent lehessen mondani?
Ez roppant bonyolult dolog. Mármint egy olyannak elmagyarázni, akinek a mosógép és a fosógép tökmindegy, de ugyanazt jelenti: HARDVER - viszont egyikhez sem ért, csak okoskodik. Minden bizonnyal összekeverted az áramkör élesztését az általa megvalósított feladat megoldásával.

Először ki kell választani az MCU-t a feladatra, majd az ármkört, a nyomtatott áramkört és a működést megtervezni. Szükséges az adatlap+errata. Az errata listájában szerepelnek a "rosszul működik", vagy az "egyáltalán nem működik" tételek. A hibákra lehet workaround, de van amikor nincs. Persze az ilyet kerülni kell.
Az élesztésnél először elkészül a portok inicializálása, amely részben a hardver tervezésekor is meghatározott, de a reset és újraindulás esetére is intézkedni kell. Utána általában beállítom a fő timert, hozzá a megszakítást és ellenőrzöm hátha elszámoltam. A végén elkezdem írni a programot, ami általában nyúlfaknyi, mert eseményvezérelt rendszereket készítek. Különösen új eszköznél vagy revizíó váltáskor meg kell vizsgálni a használt perifériák helyes működését, mert előfordulhatnak nem specifikált hibák. Sajnos 3 eszközben eddig 8 hibát sikerült elcsípni.
Ezek után belekerül az inicializálás részbe az összes használt periféria ás a hozzá tartozó megszakítások. A megszakítás rutinokat "kitöltögetem" és lényegében kész a program.
A teszteléshez elkészítem a minimális interfészt, majd a program elkészültével a teljeset - dokumentáció szerint, és átadom a szoftveresnek némi magyarázattal.
Ezzel a módszerrel lehet biztosítani, hogy bármilyen hiba ne az ügyfélnél derüljön ki.

> mosógép

Miért van az, hogy az összes mosógép vezérlése egy UX katasztrófa és olyan, mintha egy egyetemi VHDL beadandót nyomkodnám? Halom gomb meg össze-vissza LED-ek sorozata, értelmetlen opciók sorozata, rejtélyes piktogramokkal...

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Vedd figyelembe, hogy régebben egyszerűbb volt minden rendszer, mivel az IT sem uralta a munka akkora területét mint ma. Ma nagyságrenddel komplexebb rendszereket írnak, így több a hibalehetőség is. Sok hiba nem is a szoftveres miatt kerül be, hanem a trehány igény megfogalmazása és az azt követő igénytelen szervezés miatt. Ma ráadásul gyorsabb reakciót várnak a szoftveresektől, nincs ilyen fél évig hegyezünk valamit dolog. Ezzel csak azt akarom mondani, hogy a mai szoftveresek is csak annyira hülyék, mint a régiek, csak más eszközökkel csinálják a kárt. Ahogy a hardweresek is.

Nekem nem kell a TWI-t részletezned, volt vele elég szívásom, mire mindent a helyére tettem, hogy jól működjön a szükséges szenzorokkal, I2C felismeréssel együtt.
MSP430 sokkal jobb volt ebből a szempontból, de STM32-n sem volt gondom - igaz, ez utóbbinál magasabb szintű library van alatta...

Próbáltam a csatlakoztatott eszközökre fókuszálni, de valóban lehetnek még további kérdések a kommunikációval kapcsolatban.

"Az I2C meg az SPI csak egy interface, gyakorlatilag _bármi_ lehet mögötte.
Nem határoz meg gyakorlatilag semmit a feladat lényegi részéből, ahogyan önmagában az UART, RS232 vagy RS485 interface sem mond semmit arról, ami mögötte van."

Nem mondod? És? Képzeld, szoktunk interfaceket mockolni. Természetesen rá kell illeszteni a tesztben azt, ami -- a szükséges mértékben ! -- szimulálja azt a valamit a túloldalon.

"Másfelől meg el kell keserítselek, de nem csak az egyik fél ragaszkodik minden áron ahhoz, hogy ő jól tudja, hogy hogyan kell csinálni, és a másik ismeretei nem applikálhatóak.
A másik fél is ezt teszi, és egyik végletnek sincs igaza.

A fenti példát csak azért írtam le, hogy megpróbáljak kisebb rálátást adni pár dologra, de nem sikerült.
Ami valószínűleg nem ment át: a hardver nem szoftver, sohasem fog olyan mértékben egzaktul működni, mint egy tesztelt és ellenőrzött kód _önmagában_."

El kell keserítselek, de nem. Az a fantom másik fél, akinek ti állandóan a szájába adjátok, hogy nem kell hardweren tesztelni, nem érti, hogy a hardware az nem olyan egzakt*, nem létezik. Az ellenben, aki már sokszor leírta, hogy ez nem így van, természetesen kell, az meg igen, csak valószínűleg átlátszó betűkkel ír, vagy én nem tudom. A példáid meg pontosan arra jók, hogy megmutassák, hogy ha volna némi nyitottság arra, hogy a területetekre próbáljatok egy társterület működő módszertanait adoptálni, akkor lehet, hogy kiderülne, hogy tud segíteni, olyan helyen is, ahol te nem gondolnád. Az SPI meg I2C tipikusan ilyen. És valószínűleg én több olyat láttam, mint te automata tesztet.

* egyébként muhaha, hidd el, hogy sokkal egzaktabb, tipikus félreértés ez a specikiáció dolog, egy átlag sw project összetenné a kezét olyan speckóért, amit ti kaptok. És pontosan ugyanolyan kisebb nagyon inkompatibilitásokkal, bejövő változásokkal, meg menet közben a részletek kitalálásával dolgozunk az esetek döntő többségében mint ti. (Talán még többel is, mivel egy virtuális gépet kissebb szopó eltörni, mint egy fogaskereket, vagy leégetni a teszthwt.) És potenciálisan lényegesen nagyobb komplexitású problématérben.
Ezért van, hogy mi már nem nagyon vagyunk el az ilyen munkametodika nélkül, ti meg még eldöcögtök. Ettől még lenne egy csomó dolog, amit érdemes lenne alkalmazni (és ironikus módon egyébként biztosan teszitek is, hiszen ez az egész sem onnan indult, hogy jött egy szoftveres, hogy de miért nem teszteltek, hanem valaki benyögte, hogy azért jó a c, mert így tudja tesztelni külön a szoftveres részt.

Nem látom értelmét.

Valószínűleg Te mindent tudsz arról, hogy egy másik szakmában milyen problémák merülhetnek fel, mit kell megoldani.
Én egy szóval nem mondtam, hogy szükségtelen tesztelni, még azt sem méregettem, hogy kinek van nagyobb több problémája valamivel.

Teljesen fölösleges újra és újra ugyanazt kerülgetni, semmi lényeges újdonság nem lát napvilágot.

Zátonyra futott a beszélgetés és nincs értelme folytatni - ezt akartam mondani.

Abban segíts már, hogy ezt "Valószínűleg Te mindent tudsz arról, hogy egy másik szakmában milyen problémák merülhetnek fel, mit kell megoldani." honnan veszed? Hányszor írjam még le, hogy ez nem így van? Azért futott ugyanis zátonyra a beszélgetés, mert ezt akarjátok mindenáron belemagyarázni, miközben alapvetően egyet értünk.

"Én egy szóval nem mondtam, hogy szükségtelen tesztelni,"
Nem is állítottam ilyet. Mások azért ezen az állásponton vannak, mint látható.

"még azt sem méregettem, hogy kinek van nagyobb több problémája valamivel."
Egész konkrét kijelentésedre reagáltam. Ráadásul nem tudom, hogy ezt miért veszed támadásnak. Egyszerűen arra szerettem volna felhívni a figyelmed, hogy nem úgy van, ahogy a fejetekben él, és a munkamódszerek meg a problémák is hasonlóak "pure" szoftvernél is.

Nézd, engem egyesek arról is próbáltak győzködni, hogy a mikrokontroller hardware-es debugger funkciója milyen jó. Nem sikerült erről meggyőzni, mert valós idejű folyamatokat nem állíthatok meg. Amit egy ilyen debuggerrel meg lehet találni, azt ránézésre is észreveszem a kódban. Amit az ember benéz, az épp a valósidejűséggel szokott összefüggeni. A kód megfelelő helyén történő ideiglenes módosításával debugolok, meg is találom a hibát. Meg persze oszcilloszkóppal.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A software-es teszt metódusoknak is vannak korlátai. Garancia semmire sincs. Ami a legrosszabb, hogy jön néhány nagy energiájú gamma-foton, s meglehet, a RAM egyik bitje megváltozik. Ezzel csak azt akartam mondani, hogy tényleg semmi sem biztos.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A kérdésre válaszolj. Nem azt kérdeztem, hogy hogyan fog működni A Berendezés, ha ráesik egy meteor, hanem arról, hogy _TE_ vagy egy kollégád mit tesz azért, hogy meggyőződj arról, hogy miközben megpatkolsz egyvalamit nem rontasz el mást.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Kezdem sejteni, mi a probléma. Az, hogy még mindig oprendszer fölött gondolkodsz, ahol 523 mélységben hívják egymást függvények, s ott ilyen előfordulhat.

Ezzel szemben mikrokontrolleren van olyan, hogy mindösszesen 2 - tehát kettő - a stack mélysége, vagy 8, esetleg 16. Szóval azért nem fog elromlani, mert vagy emlékszel, melyik az a három hely, ahonnan a módosított rutint hívod, vagy rákeresel a nevére CTRL-F-fel.

Azaz büntetlenül megváltoztathatom egy szubrutinom paraméter átadását is akár, mert pillanatok alatt megtalálom az összes hívást.

Értem, hogy operációs rendszer fölött, kész library-kat használva ez nem járható út, de többen, akik ezzel foglalkozunk, mondjuk nektek, hogy ez más műfaj, mint magas szinten programozni. A problémák, a hibalehetőségek is egészen mások.

Én még csak kész library-kat sem használok. Egyetlen include van a forrásom elején, ami az adott MCU regisztereinek, bitjeinek a nevét include-olja. Innentől kezdve egy üres semmi az editorban. Én így kezdek neki a kód írásának, s nem lesz nagyon bonyolult. Jellemzően néhány száz vagy néhány ezer assembly sor.

Mondok két lehetséges hibát. Az egyik, hogy egyetlen bit 1-be vagy 0-ba írása read-modify-write módon történik. Miközben egy port 5-ös bitjét 1-be állítod, beolvasod az egész port-ot, 1-be állítod az érintett 5-ös bitet, majd visszaírod.

Ha a kimeneti latch-ben mondjuk a 2-es biten 0 volt, a port bemenetként van programozva, a bemenetén magas logikai szint, tehát 1 van, úgy az 5-ös bitet 1-be állító utasítás beolvassa az egész portot, köztük a 2-es biten lévő 1-et is, majd a visszaíráskor szépen ki is írja a kimeneti latch-be az 1-et. Még nincs baj, mert a 2-es bit bemenet. Ha most kiforgatod ezt a bitet - tehát az eddigi nagy impedanciás bemenetből kis impedanciás kimenetet csinálsz, amelyik a kimeneti latch tartalmát fogja hajtani -, kimenetként magas szintet fog hajtani, holott korábban vélhetően azért volt 0 a kimeneti latch-ben, hogy alacsony szintet hajts majd a 2-es biten. Mindez egy figyelmetlenül használt bit állító utasítástól, aminek látszólag semmi köze sem volt a 2-es bitedhez. Tehát más logikai szint lesz a kimeneteden, mint amit oda írtál, s a kódban látszólag nincs olyan utasítás, amelyik azt a bitedet felülírná!

Hasonlóképp hiba, ha portra írás utáni utasításban olvasod ugyanazt a portot, például épp egy ilyen read-modify-write típusú utasítással, ami ráadásul felületesen szemlélve kizárólag írásnak tűnik. Azért gond, mert a 4 órajeles gépi ciklus második órajelében olvas, a negyedikben ír, így a kimeneten a következő utasítás olvasásáig még nem lett stabil a megváltozott logikai szint, ha túl hamar olvassuk azt vissza, különösképp, ha a lábon van kapacitív terhelés is. Szebben szólva nem lesz betartva a setup time-ra előírt követelmény. Így aztán nem az jön vissza a portról, amit az imént kiírtunk, hanem a korábbi állapot. De lehet, hogy csak némely biteken.

Ez a hiba viszont nem fog előjönni, s nem is hiba, ha a mikrokontrollert lassan hajtod, mondjuk 4 MHz-ig. Ha ennél gyorsabban járatod, vagy úgy kell elhelyezni a portot író utasításokat, hogy köztük legyen valami, vagy NOP-ot kell közéjük írni, vagy nem a portot, hanem a lath-et kell írni, de járható az is, hogy tükörregisztert csinálsz neki RAM-ban, ott bűvészkedsz, s az eredményt mindig csak írod a portra.

Aztán sok szerencsét ahhoz a szimulációhoz, ami összehozza, hogy 6 MHz-ig minden jól működik, nagyobb órajelfrekvencia esetén viszont hiába kapcsolsz egy port bitet 0-ból 1-be, néhány száz ns múlva visszabillen 0-ba. Viszont bőven van még tartalék sebességben, mert mondjuk 32 MHz-ről járatható legfeljebb ez a kontroller.

VaZso már említette, hogy a hardware nem software, s nyilván ilyenekre gondolt.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

> Szóval azért nem fog elromlani, mert vagy emlékszel, melyik az a három hely, ahonnan a módosított rutint hívod, vagy rákeresel a nevére CTRL-F-fel

Jajj de utalom, ha emlekezni kell valamire, vagy netan keresni. Manual melo. Nem azert vannak szamitogepek, hogy az ember emlekezzen. Arra vannak, hogy levegyek az emberrol a felesleges terhet.

De nyilvan jo dolog azzal szorakozni, hogy az ember emlekezzen arra, hogy mit nem kene eltorni, es annak milyen corner-case-ei vannak, ahelyett, hogy valami ertelmes dologgal foglalkozna helyette...

Jó, ez igaz. Én úgy csinálom, hogy ha hozzányúlok, javítom a kommentet is. Minden rutinom elején leírom, az mire való, mi az inputja, mi az outputja, mit ront - tehát mit ír felül -, s ha az kritikus, akkor a futásidőt is akár. Aztán az összes hívásnál hozzáigazítom az új verzióhoz a környezetet. Ha ez nyűgös lenne, akkor vagy kompatibilis átalakítást csinálok, vagy egy teljesen új rutint, ami hasonlít az előzőhöz, de kicsit más új feature-ökkel.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Aztán majd hozzányúl a következő kollégád is péntek délután háromnegyed ötkor és szarik a kommentre, mert siet haza, mert a barátnője épp nagyon felizgult a harmadik kollégád meg ez alapján elrontja fél évvel később az egészet.

Nem véletlen alakult ki a clean code és nem véletlen van, hogy ha valami még csak proof-of-concept jelleggel készül, akkor visszadobunk olyan kódot, amit kommentezni kell, hacsak nem tényleg olyan, hogy nincs más megoldás, hogy érthetővé tegyük. (1%).

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Senki nem beszélt oprendszerekről meg librarykról, ezt továbbra is te akarod idecibálni. Ahogy 8-10-16 elemű stackról se.

Unit tesztek jellemzően picik, lehetőleg minél kisebbek. Unit teszt lehet akár az is, hogy egy konstruktort tesztelsz, ami vár egy objektumot és null-t adsz neki, hogy megdobja-e az ArgumentNullExceptiont-t.

Ennyi a teszt:


[Fact]
public void Is_Foo_throws_an_ArgumentNullException_if_ctor_get_null()
{
  var ex = Assert.Throws<ArgumentNullException>(() => { new Foo(null); )
  Assert.Equal("arg", ex.ParameterName);
}

És egy ekkora kódot tesztelsz vele:


public Foo(Bar bar)
{
  this.Bar = bar ?? throw new ArgumentNullException(nameof(bar));
}

Itt nincs se library, se oprendszer, se millio szintű stack. Eleve unit tesztnél egy libraryt már illik kimockolni, pont azért, hogy ne legyen külső függősége a tesztnek.

Hogy miért? Mert egyrészt a teszt specifikálja a viselkedést és betartatja a specifikációt. Akkor is, ha három év múlva valaki hozzányúl.

Amiről te beszélsz az már inkább integrációs teszt, amikor viszont az egész rendszert meghajtod, ha kell komplett környezetet felhúzva. Értsd: amikor készítesz egy pull requestet, a build szerveren kicheckoutolódik a komplett kód, lefordul az érintett service, lefutnak rá az unit tesztek, dockerben felhúzza a teljes integrációs tesztkörnyezetet az érintett service(k)hez adatbázisszerverestül, tesztadatostul, függőségektől (amik nem librarykban, hanem önálló szolgáltatásokban mérhetőek önálló dokker konténerekben) és lefuttatja az integrációs tesztjeinket, amiket ráadásul tudatosan nem C#-ban írtunk, mert hiába egy C# liben keresztül használjuk (jellemzően) az API-jainkat, nem akartunk elfedni ezzel valami olyan hibát, ami a webes API-n nem jön ki.

A nem lesz nagyon bonyolultra meg itt a példa, mire eljutottan a hozzászólásomban oda, hogy leírjam ezt a triviális konstruktort már elfelejtettem, hogy az ArgumentNullException-t akartam vele tesztelni, mert a DI-ból jövő paramétereket nem szoktuk ellenőrizni (csapat konvenció, személy szerint nem értek vele egyet, de ez van).

Amiről te beszélsz az meg nem egy triviális immutable kód, hanem egy tranziens jelenségekkel terhelt állapotgép. Pont az, amit rühell minden (értelmesebb, C-n túli világot is látó) szoftverfejlesztő, főleg mióta multicore CPU-k vannak mindenütt és pont az, ami miatt a szoftveres világ elmozdult az immutabilitás és a share nothing felé rengeteg téren. (Nyilván logikailag értelmezhetően.)

És teljesen mindegy, hogy 100 soros-e a kód vagy 100 ezer. Ha te megváltoztatsz egyetlen egy függvény viselkedését is, akkor megváltoztatod vele az összes függő dolog viselkedését is. Mondod, hogy lehet, hogy "csak három helyről van hívva". Mi van, ha átveszi tőled valaki a projektet? Tudni fogja, hogy csak három helyről van hívva? Biztos, hogy mindig minden funkcióját használni fogja az eszköznek és nem fog olyan történni, hogy nem nézi meg, hogy az adott függvényt még három másik helyről is hívja valami egy ritkán használt funkcióban az illető meg megkapja, hogy nézze meg az egyiknek a hibáját, mert kiderült, hogy úgy mégse jó? Ilyenkor mi az a védelmi mechanizmus, ami garantálja, hogy azzal, hogy azt a függvényt módosítja, nem fogja elrontani a másik kettőt? A "tudom" meg a "látszik" nem játszik, triviális dolgokat nem vesznek néha észre az emberek és még csak nem is azért, mert hülyék lennének, hanem, mert fáradt, beteg, dekoncentrált, megzavarta egy másik kolléga, akármi.

"Aztán sok szerencsét ahhoz a szimulációhoz, ami összehozza, hogy 6 MHz-ig minden jól működik, nagyobb órajelfrekvencia esetén viszont hiába kapcsolsz egy port bitet 0-ból 1-be, néhány száz ns múlva visszabillen 0-ba. "

Azon túl, hogy továbbra sem látom be, hogy miért lenne lehetetlen egy ilyen szimulátor létrehozása, továbbra sem az a kérdés, hogy milyen szimulátort írsz vagy nem írsz, hanem az, hogy mivel garantálod, hogy a munkád helyesen működik és akkor is helyesen fog működni, ha azon valaki módosít.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Azt ugye tudod, hogy egy mikrokontrolleren _NEM_ objektumorientált kód szokott futni?
A nyelv sem C#, de még csak C++ sem igazán, vagy, ha mégis, akkor is gyakorlatilag elfelejtve a magasabb szintű eszközeit.
Ez egy teljesen más világ, más problémákkal.

C vagy Assembly kódot képzelj el, ahol lehetőleg nem hívunk fölöslegesen n mélységű függvényeket (nem pazaroljuk a stack-et), nem másolgatunk fölöslegesen objektumokat (nem pazaroljuk a RAM-ot), sok esetben még a memóriafoglalás nagy része sem dinamikus.

Nem magas szintű a programozási nyelv és nem dob Exception-öket, vagy legalábbis nem úgy kell elképzelni.

Az objektumkezelés, exceptionök egy magasabb szintű eszköztár részei, aminek megvan a maga helye és logikája, segíti a programozó munkáját, de egyszerűen nem erre a területre való.

A tranziens jelenségek, versenyhelyzet olyan jelenség, amiket kezelni kell ezen a szinten, mert nincs, ami ezt elfedje.
Helyesebben van, de azt neked kell megcsinálni.

Ráadásul ezzel azt is kérdezed, hogy pl. az adott fejlesztő az Assembly makróinak viselkedését hogyan teszteli, amik segítségével az adott műveleteket elvégzik a regiszterekkel...
...ez is más világ.

Továbbá nagyon nem mindegy, milyen mikrokontrolleren kell futnia a kódnak, mert nagyon mások lehetnek a lehetőségek is a fentiekre.
Egy erősebb MCU-n akár kicsit szabadabban is lehet kezelni a dolgokat és elő lehet szedni olyan kérdéseket, amikről ti is írtok, de nem kizárt az sem, hogy okkal választ az ember erősebb (és drágább) MCU-t, ki akarja használni azt, hogy erősebb az eszköz, gyorsabb lesz a végrehajtás, és még mindig valamilyen szinten korlátos lesz.

A modernebb mikrokontrollerrel is el lehet végezni ugyanazt a feladatot, de, ha egy tizedannyiba kerülő kontroller szintjére esünk vissza a megnövekedett memóriaigény és erőforrásigény miatt, akkor nem biztos, hogy erre volt szükségünk... emellett a fogyasztást is célszerű kézben tartani, különösen, ha elemről / akkumulátorról üzemel az adott eszköz.

Tényleg mások a felmerülő problémák és szóba jöhető megoldások...

"Tényleg mások a felmerülő problémák és szóba jöhető megoldások..."

Nem, egyáltalán nem más, csak nem akarod megérteni, hogy mi az a probléma, amire rákérdezek.

"Azt ugye tudod, hogy egy mikrokontrolleren _NEM_ objektumorientált kód szokott futni?"

Mert onnan indultunk, hogy ez mégis ki a tökömet érdekel? Szakadjatok már el attól, hogy milyen kód fut. Hogy C#, JavaScript, C, C++, Basic, Assembly vagy LOGO kód fut-e az kurvára mindegy. Az az érdekes, hogy funkcionálisan teljesíti-e az elvárásokat. Ezt mi fogja neked garantálni? Az, hogy OOP-e a kód vagy egy ASM kód az egy teljesen lényegtelen huszadrangú kérdés.

Az alapvető kérdés továbbra is az, hogy: mi fogja neked garantálni, hogy ha változtatsz valamin, akkor az eszköz még mindig azt teszi, amit elvárunk tőle? Teljesen mindegy, hogy mit változtatsz, hogy kódot vagy hardvert, az érdekel, hogy továbbra is azt és úgy teszi-e, ahogy elvárom. Ebbe beleérhetem az általatok milliószor felemlegetett fogyasztást is.

Erre válaszolj és ne azzal fárassz, hogy miben más egy mikrokontroller meg egy rest service kódja, mert azzal - bármilyen meglepő - én is tisztában vagyok.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Értem, hogy arra szeretnél kilyukadni, hogy az adott szoftvert teszteled.
Erre írtam, hogy lehet teszteket írni (pl. egy adott funkció magasabb szintű library-jéhez).

Alapvetően a program nem akkor készül el, amikor már működik, hanem akkor, amikor különféle hibakezeléseket is tartalmaz (nem csak mikrokontrollerek esetén természetesen).
Hardvernél pl. élesztéshez kapcsolódhat (kapcsolódik) egy erre a célra megírt programrész is, ami segít letesztelni a bemeneteket / kimeneteket, rávizsgál a szenzorokra, stb. (itt hardverműködést tesztelünk).
...de készülhet külön hardver is arra, hogy egy adott eszköz kimeneteit / bemeneteit le tudd tesztelni.

Külső hardverek meglétére, működésére pedig a normál szoftverfutás is szokott tesztelni, ill. adhat hibaüzenetet, ha nem tud kommunikálni valamivel (hardver hiba).

Most arra vagy kíváncsi, hogy az alacsonyabb szintű, hardveres kezeléseket hogyan teszteled?
...mert ezt már nehezen tudod a hardver nélkül, de jellemzően nem is igazán változtatsz rajtuk.

Fogyasztást leginkább megmérni tudod, nem szoftverből tesztelni.

Hardware közelében ráadásul a hibakezelés sem triviális. Van, hogy annyi, hogy gyakorlatilag software reset-tel rituális öngyilkosságot követ el az eszköz, netán hagyod felborulni az egészet, aztán majd felsőbb szintekről észreveszik, hogy nem kommunikál. Nem tudod kiírni a kijelzőre, hogy hiba történt, mert nincs kijelző, de ha lenne, akkor meg nincs beavatkozó szerv a felhasználó kezében. Azaz ne legyen rossz, ne legyen hiba, vagy watchdog, esetleg software reset a megoldás.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

"Értem, hogy arra szeretnél kilyukadni, hogy az adott szoftvert teszteled."

TE akarod leszűkíteni csak szoftverre. Integrációs tesznél mi sem egy kis részegységet tesztelünk (arra ott az unit teszt), hanem a komplett egészt. Ha feltűnt volna már többször említettem, hogy van az unit teszt és van az integrációs teszt, mindkettő másra van.

" ...mert ezt már nehezen tudod a hardver nélkül, de jellemzően nem is igazán változtatsz rajtuk."

Uhum, nálunk is úgy szokott kezdődni, hogy "ez teljesen fix, nem fog rajta változtatni az ügyfél!".

"Fogyasztást leginkább megmérni tudod, nem szoftverből tesztelni."

Igen és, ahol ez kritikus, hogy van garantálva?

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Nem. Én azt mondom, hogy tesztelhetünk szoftvert, de komplett hardver tesztelése / vizsgálata nélkül nem megy, ezért futnia kell annak a rendszernek hardveren.

Alacsony szintű függvényeken az ügyfél nem módosíttat.
Azt te írod meg, azért, hogy magasabb szinten kezelni tudd a hardvert.
Ha úgy tetszik, másik réteg.
Ezen a magasabb szinten már lehet mindegy, hogy MSP430, AVR, STM32 vagy mégis milyen kontrolleren fut az egész.

Nyilván nem mindegy, de a hardverkezeléseket úgy írom meg, hogy ne legyen óriási probléma másik kontrolleren feléleszteni.
Persze ez C kód, Assemblynél nem is igazán jöhet szóba másik kontrollerre átállni.

Fogyasztás hogy van garantálva? Úgy, hogy körültekintően programozol.
Átgondolod, mennyi időnként célszerű a bemenő adatokkal (pl. hőmérséklet vagy páratartalom méréssel) foglalkozni, átgondolod, milyen órajelen célszerű járatni a kontrollert, szükség esetén menet közben változtatod az órajelet attól függően, mennyire bonyolult számításokat kell végezni, különféle készenléti állapotok közül a megfelelőt választod és ébreszted külső interrupttal, timerből időzítve, esetleg RTC-vel generált interrupttal, stb.

Mindezek közben számolsz.

Ismered az elemet / akkumulátort (annak kapacitását), és úgy méretezed a rendszert (az előzőek figyelembe vételével, az elemet/akkumulátort is beleértve), hogy a szükséges időtartamig képes legyen működni.
Akár évekig egy elemről.

Nincs garantálva a fogyasztás. Neked kell garantálni azt, hogy megfelelő tápforrásról megfelelő időtartamig működjön, vagy megfelelő időtartamra elegendő forrást biztosíts neki... vagy azt megtervezni, hogy pl. napelemes töltéssel megfelelően hosszú áthidalási időt biztosíts.

Tervezés kérdése, és ennek megfelelően programozod a hardvert is.

Én valahol ott szálltam bele ebbe az egész témába (topic), amikor azt olvastam, hogy szoftveresnek kell a firmwaret írnia és nem a villamosmérnök feladata.
Erre írtam, hogy nem a NYÁK-tervezésben merül ki a dolog, többek között a fentiek miatt is.

Hátha nem láttál még ilyet, ezért felraktam egy egyszerű programot.

A megrendelő specifikációja.
A faházban, hogy ne penészedjen a fürdőszoba szükséges lenne egy olyan funkció:
- A villany leoltása után működjön tovább a ventillátor.
- A működés időtartama legyen állítható 2 vagy 4 percre.

Megoldás.
Az MCU GPIO.GP0 portján jumper váltja a 2/4 percet.
A tápegységből jövő 50Hz-es szinkronjelet figyeljük. Ha kimarad, akkor a szerkezet "visszakapcsolja" magát, és persze a ventillátort is. Ekkor indul a beállított időzítés.
A tápegység pufferének akkorának kell lennie, hogy a feszültség kimaradás észlelési idő (max. 10ms) + a kapcsoló elem (SSR) bekapcsolási idő (max 10ms) idejére elegendő áramot tudjon biztosítani az áramkörnek (elhanyagolható) és a kapcsolóelemnek, még a kondenzátor megengedett öregedése (kapacitás csökkenés) esetén is.
Az SSR meghajtásához egy port terhelhetőségénél nagyobb áram szükséges, ezért a GP4 és GP 5 portokat párhuzamosan kell kötni.

Az ármkör.
Tudom, ronda és gazdaságtalan. :(

A program.
Hossza 89 utasítás, és 3 bájt adatot használ. (Ötnek tűnhet, de az utolsó kettőt nem használja.)

Felépítése 5 lépésből álló fázisregiszteres vezérlés. Főprogram nincs. Interruptok: timer és az 50Hz fel- és lefutó élének figyelése.

Lehet bemockolni ;), de minimum mutass rá legaláb egy ojjektumra!
Meséld el, milyen hibalehetőségek lehetnek! (Elgépelés nem ér! Az rögtön kiderül.)

Szakadjatok már el az OOP-től és értsétek már meg a problémát: Azt mond meg, hogy mi fogja garantálni azt, hogy ha egyszer ehhez hozzányúl egy új junior kolléga bármihez is, akkor még valóban a fenti specifikációt fogja megvalósítani a rendszer.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Nincs itt semmi OOP!
Neked, mint minden szoftvertudományok tudójának egy igen egyszerű kérdést tettem fel:
Meséld el, milyen hibalehetőségek lehetnek!
Az lényegtelen, hogy junior kolléga nyúl hozzá, vagy 35 évnyi gyakorlattal én vagyok hülye a programozáshoz. Itt egy konkrét feladat és az általam helyesnek tartott megoldása. Mit kellene tennem helyette?

Gondolom nem tudod olvasni az asm kódot, ezért egy majdnem működő C forrást is odatettem.
A hardver inicializálást kihagytam, mert még megzavarna. ;)

Ez egy FSM szerkezet. Ilyennek a használatára (meg még sok mindenre) nem juniorokat, hanem még iskolába járókat 1-2 hét alatt kiképeztünk. A harmadik héten már termeltek. Valószínűleg ehhez a kódhoz is minden probléma nélkül hozzá tudnának nyúlni. Ez a kódolási technológia önzáró, hibamentes és konkurencia mentes programozást tesz lehetővé.

No, szóval hogyan csinálná ezt sokkal jobban egy guru?

Ha szerinted nincs semmi hogylehetőség abban, hogy valakinek dolgoznia kell a kóddal, hardverrel és figyelnie kell, akkor nincs miről beszélnünk.

Amúgy bármilyen hihetetlen, attól, hogy nem kódolok ASM-ben, még tudok assembly kódot olvasni. Még egy C# kódnál is meg lehet nézni, hogy mire fordul egy gombnyomással. Sőt, bármilyen hihetetlen néha tesszük is.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

A NextState macro-t szándékosan tetted üressé? Szerintem ott a STATE incrementálása lenne, meg valami olyan vizsgálat, hogy ha elérte az 5-öt, töröljük 0-ba. Vagy valamit rosszul néztem? Mondjuk elég felületesen futottam át. Amúgy kár, hogy fényképet mutattál, s nem kapcsolási rajzot.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ettől kezdve legyen a neved Sólyomszem! ;)
Copypaste hiba. :( Pedig pont azért emeltem ki, hogy a kevésbé hozzáértők egyszerűbben olvassák. De mint látod, a hozzáertő számára nem zavarta az érthetőséget. Javítva.

A működés elve: Ha elérte az ötöt, akkor megáll. Nyilvánvalóan sokféle módon működhetne, de ez most így működik. Ha valami baromarcú össze-vissza kapcsolgatja a villanyt, akkor talán kicselezheti. De ezt majd a szimulátorral. :-D

Kedvedért felraktam a
- rajzot, (Azért kerültem el, mert csak kézi vázlat.)
- szimulációt,
- kikapcs/bekapcs ábrát.
És igen, tudom, hogy HV típussal 3 alkatrészt megtakarítottam volna, csak az éppen nem volt alattam a boltban.

Szabad kritikát megfogalmazni?

Amikor kapacitív reaktanciával csinálok tápot, mindig teszek bele soros ellenállást, mert feszültség csúcsnál bekapcsolva iszonyatosan nagy áram indul el. A nullátmenetet kivéve minden esetben elméletileg dirac-delta, gyakorlatilag iszonyú pofont kap az a Zener-dióda ott.

A másik, hogy azt a MOSFET-et kihagytam volna. A PIC clamp-diódái megfogják a szintet - kivéve -MCLR, de nem oda kell kötni -, s egy nagy ellenállással azt a pontot közvetlenül portra lehet kötni. Mármint azt, ahol a gate van most.

Eszembe nem jutna négyzethálós papírra rajzolni, mindig üres A4-esre rajzolok, munkahelyen is. Vagy tervező programmal számítógépen. De gondolkodni papír fölött szoktam.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Jogos a kritika. Bár a szimulátorban a következő értékek jönnek ki 325V csúcsról indítva:
- Disszipáció < 30W, ami 22us múlva lecseng. Az éppen ezért választott ZY12 - Non repetitive peak power dissipation (<1ms) = 60W.
- Csúcsáram 13A, lecsengés kb. ugyanannyi.
A nem ideális alkatrészek miatt a csúcsok kisebbek. Ez a tranziens jóval rövidebb, mint a kapcsoló szikrázása, a százas izzóról nem is beszélve. Szóval csúnya, de semmi gond vele.

A FET - szebb a jel alakja. ;) Ráadásul elég drága az SSR is. Ha van hálózati szinkron, akkor egy huszadannyiba kerülő triac is megtette volna... Ez nem termék, csak gyorsan összedobtam.

A fostalicska tervezőprogramot azóta lecseréltem. Nekem a kockás papír a kedvencem. Meg régen a rajzolók néha a ceruzás rajzból húzták pauszra. Ugye nem szerkesztenéd a 12mm-es invertert körzővel. ;)

Szerintem garantálni ti sem tudjátok ezt, csak a dolgok abba az irányba haladnak - és ez jó -, hogy a hibás program írásának valószínűsége egyre kisebb legyen. Épp úgy, mint a különböző ISO minőségbiztosítási szabványokban.

Mikrokontrolleres környezetben konstruktorról beszélni lehet ugyan, mert valóban vannak elég nagy MCU-k is, de például egy 6 lábú SOT23 tokban lévőt szerintem nem fogsz C++-ban vagy C#-ban programozni. Ehhez kevés a programtár és a RAM is bennük. Nekiesel assembly-ben, ha ahhoz nem értesz, esetleg natív C-ben, de ennél absztraktabb nyelvet ne képzelj hozzá. Persze valami egyszerű interpretert írhatsz hozzá, s utána egyes részeit, a vezérléseket félig-meddig valamilyen saját script nyelven írhatod, ami nyilván nem lesz általános, de legalább onnantól tömören lehet fogalmazni, s talán csökken az elszúrás lehetősége is, mert a már jól implementált eljárásaidat hívogatja a parancsértelmeződ.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Most már meg kell kérdeznem: szellemi fogyatékos vagy, szövegértési problémáid vannak vagy csak ennyire minimálisan sem megy az absztrakt gondolkodás (ez esetben minek nyúlsz szoftverhez)? Szakadj már el a tetves konstruktortól a C#-tól és attól, hogy mi volt a példa.

Felfogtam, hogy mikrokontrolleren nincs C++ meg C#. Nem ez volt a lényeg, hanem, hogy ha nincs teszt, semmi, de semmi nem garantálja, hogy az a kód (és most kurvamindegy, hogy egy ctor vagy egy összead vagy egy mikrokontroller vezérlése), ami ott fut az azt csinálja, amit elvárnak tőle. Mert jön a következő emberke és azt mondja, hogy tök fölösleges oda az az az ellenőrzés és kitörli. Vagy mert merge során valaki elront valamit. Vagy mert valaki gonoszkodni akar. Akármi.

Lehetett volna ott két int összeadását végző művelet ellenőrzése is, hogy nagyobb-e, mint mulla, érdektelen, hogy mi volt a kód. Az volt a lényeg, hogy van-e rá teszt vagy sem és ellenőrzi-e valami automatikusan, hogy később nem rontja-e el valaki vagy sem.

"Szerintem garantálni ti sem tudjátok ezt"

És nyilván, tökéletes megoldás nincs.

"hibás program írásának valószínűsége egyre kisebb legyen"

Nem csak az írása, hanem, hogy karbantartáskor ne ronts el valami olyat, ami már működik. És, hogy legyen valami, ami kikényszeríti a specifikációt. Ezt kellene már megérteni, nem a tetves konstruktoron rugózni.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Más szemlélet ez, mondjuk, de néhányan nem értitek. Ha egy firmware elkészül, akkor az készen van. Nem tartjuk karban, nem piszkáljuk, nem nyúlunk hozzá. Az jó. Az annyira erősen hardware közeli, hogy magának a hardware-nek az integrált része. A módosítása olyan, mintha az áramkört terveznéd át, alkatrészt cserélnél, nyákot vágnál. Azt megírják, utána használják. Ha hozzányúl valaki, nagy körültekintéssel teszi. Vagy triviális, mi miért van, vagy ha nem az, mert mondjuk valamiféle mérési eredmény következménye, akkor ez oda van írva kommentben. Az olyasmi, amiről írsz, nehogy törlésre kerüljön egy látszólag felesleges vizsgálat vagy időzítés.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

"Ha egy firmware elkészül, akkor az készen van."

Na persze... Akkor miért van nagyjából 97 millió találat a googleban a firmware update szóra?

" Ha hozzányúl valaki, nagy körültekintéssel teszi. "

Érdektelen. Mi a garancia, hogy jól készült el? Mi a garancia, hogy az tényleg jó? Elárulok egy titkot: általában a szoftverfejlesztők is körültekintéssel végzik a munkájukat.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Ami például egy SOHO router-ben van, az én fogalmaim szerint nem firmware, az egy komplett operációs rendszer kernellel, felhasználói programokkal. A találatodban ez is ott lesz. Firmware alatt én valóban alacsony szintű vezérlést értek. Például egy mosógép, egy fázishasításos teljesítmény vezérlést, egy mikrohullámú sütő, egy főzőlap vezérlését. A felhasználó itt nem érdekes, mert ezek olyan szintűek, amihez semmi köze. Az a gyártó döntése, hogy diszkrét elektronikával, CPLD-vel, FPGA-val vagy mikrokontrollerrel oldja meg a feladatot. Ha a sebesség vagy a probléma speciális mivolta nem indokolja, a legflexibilisebb, legolcsóbb, legkényelmesebb megoldás a mikrokontroller lesz. Erre kell valamit írni, s a vita onnan indult, hogy ez nem software-es programozói feladat, hanem elsősorban villamosmérnök dolga.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Pedig össze sem beszéltünk locsemege huptárssal, mégis korábban ezt írtam: Hosszas vitát kellett folytatnom egy szoftvermérnökkel, hogy miért nem vagyok hajlandó frissíthető (javítható!) firmware-t készíteni. Pedig a magyarázat egyszerű. A gyártmányaink működése olyan triviális, hogy hiba esetén még nem is lehet belőle gyártmány. Ha meg nincs hiba, akkor nincs mit javítani. Másodlagos magyarázat: Én értem amit csinálok, ők nem mindig.

Hidd el, amikor eladunk egy kis szerkezetet, arra nem értelemezhető a windowsupdate fogalma. Vagy flesseltél már mosógépet? ;)
És félre ne értsd, nem csak a < 100 utasításból álló játékprogramról beszélek. Így van ez a >12kB programmal is.

Ennek ellenére van verziószám, növekszik is néha, de az alapfunkció soha nem változik. Az ügyfél ennek ellenére a kisebb verziójú szerkezettel is ugyanazt tudja elvégezni.
Példaként a mosógép is mindig mos. Legfeljebb továbbfejlődött a diagnosztika, így a szerelő pontosabb hibakódot kap. De ez is csak egy erőltetett példa, a valóságban nincs ilyen.

"...de a kijelzőt és a szenzort pl. hogyan szeretnéd emulálni?
Nem lehetetlen, de nem éri meg a ráfordítást."

Szenzort: felvett adatokkal, randomgenerált adatokkal, előre összeállított szintetikus tesztadatokkal, stb.
Kijelzőt: nézem, hogy mi esett ki.

De most egységtesztelés vagy integrációs tesztről van szó?

"...vagy valamelyik kijelző vezérlője módosult annyit, hogy szétesik rajt a kép, esetleg két azonos hardver mégsem annyira azonos."

Esetleg jobban kellett volna az interfaceket meghatározni az egyes kütyük között?

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

A "kütyük" közötti interface-szel nincs gond.
Kisebb-nagyobb inkompatibilitások, eltérések, sajátosságok viszont vannak.

Nem kell nagyon messzire menni.
Néhány hónapja egy mikroszámítógépet élesztettem, ami viszonylag új termék volt még, két ilyen kisgépet vettünk.
Volt egy patch, ami az u-boot forrásán elvégezte a board-specifikus módosításokat, ezt lefordítottam, feltettem rá és felkerült egy alap Debian telepítés is a gépre.

Elindult a rendszer, működött szépen, de nem működött túl jól, ugyanis sokszor csak második-harmadik indításra bootolt fel rajt a rendszer (így persze használhatatlan, mivel nem indítható megbízhatóan).
Némi szívást követően megpróbáltam ugyanezt a rendszert a másik kisgépen is, ott viszont minden alkalommal felbootolt.

Megnéztem a rajt lévő UART-on kapott üzeneteket, ill. beleástam kicsit magam az u-boot forrásába, kiderült, hogy memória allokációs problémája van.
Megkerestem a DRAM inicializációját és beletettem egy 10us-os késleltetést, így sikerült elérni, hogy mind a két lap, minden alkalommal bootoljon.

Megírtam a patch feljécében talált e-mail címre, hogy a kérdéses helyre egy legalább 10us-os késleltetést kellene betenni.
Ő megadta egy másik srác elérhetőségét (ill. cc-zte neki is az üzenetet).
A másik srác végül viszonylag gyorsan megállapította, hogy ő volt az a bűnös (ő írta így), aki gyakorlatilag ugyaninnen kiszedett egy 100us-os késleltetést a kódból.
A jelzést megköszönte, a késleltetést visszaállította, minden jól működik.

A tanulság?
Két hardver sohasem teljesen egyforma (ezért tesztelünk sokszor hardveren).
Ha pedig hardver inicializáció előtt vagy után várakozás van a rendszerben, az a legtöbb esetben okkal van ott.

Ezen a ponton talán kereshetjük, hogy mennyire lenne jó, ha a szoftveres kicsit jobban értene a hardverekhez, de most ezt ne firtassuk.
Azt azért zárójelben megjegyezném, hogy mikrokontrollerek környezetében sokkal többször fut össze az ember olyan, fentihez hasonló problémákkal, amik elektronikai ismeretet igényelnek.

Lehet tesztelni a kódokat, de az ilyen és ehhez hasonló hibák nem ezeken a teszteken fognak kibukni.
Más hibák előjönnek, nem hülyeség maga a szoftveres teszt.

...de a hardware az hardware és nem software, ezt is látni kellene.

Ez mind remek, csak szoftvernél ilyen esetben az a kérdés merül fel, hogy hogyan bukjon ki legközelebb, ha máshol nyúlsz bele a rendszerbe. Mert az nem opció, hogy mindig mindent kézzel újra végigtesztelj minden egyes módosítás után.

És az, hogy valami elindul még nem garancia arra, hogy jól is működik.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Igen, erről szólna a szoftveres teszt.

Persze, az elindulás nem garancia arra, hogy jól működik,vagy arra, hogy mindig működik.
Ezért kell a hardvert is körültekintően kezelni - erről akart szólni a fenti hozzászólás.
(Van a hardverelemek között is szórás - nem teljesen ugyanolyan a RAM, nem feltétlen azonos idő alatt áll fel a táp, stb.)

Ha eközben a hőmérséklet is változik, akkor még nagyobb eltérések lehetnek.

Ilyen hibának valószínűleg semm köze a szoftverhez, RAM-hoz és hőmérsélethez - hacsak nem a specifikált hőmérsékleten kívül fordul elő a hiba.
Valószínűleg instabil a táp indulás után. Hardveresen ezt egy kis csippel oldják meg, ami késlelteti a RESET elvételét. Ebben az esetben egy kritikus ponton szoftveresen késleltettél, ami megfelel egy időzítő kondenzátor növelésének. Csak mint érdekesség, ez a fukció pl. egy PIC-ben több irányból is támogatott:
- nem szükséges külső RESET időzítő RC tag, hanem saját timerrel oldja meg,(Ehhez tartozhat egy specifikált minimális tápfeszültség emelkedési sebesség.)
- BROWNOUT - amivel megadhatod a működéshez elvárt feszültséget - ha nem elég, akkor RESET. Müködik "menet közben" is.
- HVLD (High/Low-Voltage Detect), amivel megadhatsz egy külső megfigyelendő feszültségtartományt. Ha a beállított irányban eltér a feszültség, kapsz egy megszakítást. Ezzel lehet detektál pl. olyan feszültségcsökkenést, amikor a MCU működik, de valamelyk perifériának már nem elég a feszültség.

Lehet a táp instabil induláskor, de ez nem saját hardver.
Emellett a proci resetjének nyomkodása sem mindig segített rajt (néha igen), bár azt nem tudom, kapcsolgat-e ilyenkor is valamilyen tápot külön.

Persze, szokott lenni a procikban BROWNOUT meg társai, meg nyilván Watchdog is.

No meg vannak dolgok, amiknek lehet hardveres és szoftveres megoldása is, vagy akár hardveres problémát szoftveresen kell kiküszöbölni...

Akár igazad is lehetne. ;)
Csak egy dologban tévedtél, ami a félreértést okozza: Hiába írsz a tökéletes tesztelési módszerekről, a frmware soha nem lesz software. Bár egyes részleteit lehet szoftveres módon tesztelni, de általában nem.
A fw, - tipikus példa a BIOS - egy interfész a hardver és a szoftver között. A szoftver, algoritmus készülhet bárhogy és lehet tesztelni a legmodernebb módszerekkel és általában nem villamosmérnök írja.
A mikrokontrollert definiáljuk úgy, hogy egy picike CPU, picike programtárral és perifériákkal körberakva. A teljes hw állhat csak a mikrokontrollerből, de lehet további hardver kiegészítése is. A fw áll egy önálló részből és lehet interfésze a külvilág felé.
Ha a "mikro"kontroller elegendő tárolót tartalmaz komoly sw befogadására, akkor feltétlenül igazad van. Ilyen esetben célszerű a szoftver részt különállóan kezelni. Ha valaki a két részt összekeveri, akkor pórul jár - vagy nagyon ért hozzá. ;)
A fw készítésekor egyes esetekben a gondosan megtervezett nyomtatott áramkör minőségét kell vizsgálni: az alapvető és a programozott működés közben keletkező zajok hatását, amit néha lehet "sw" úton javítani. Utána jön az első alapfeladat, amikor "az adatlapokhoz illesztjük a működést". Ez olyan, mint a sw alap függvényeinek elkészítése. Az eddigi feladatokat szoftveres soha nem végzi, mert sem az elektronikához sem az adatlapokhoz nem ért.
Ezek után jöhet a feladat megfogalmazása és rendszerbe helyezése. Meg kell határozni az interrupt forrásokat, esetleg multiplexelést. A működést szétszabdalni és megírni. Regressziós tesztek szükségtelenek, mert az így kialakított vezérlési séma mindig önzáró, az egyes függvények (nevezzük most így) diszjunkt módon működnek. Ha hiba van, akkor nem működnek, de a hiba keresése fokozatos élesztésnél nem bonyolult.
A következő lépés a külső interfész(ek) beillesztése - ha van ilyen.
A végén a szoftveres megkapja az interfész specifikációt és dolgozhat - akár belső, akár külső a szoftver.

Igazam is lehetne, de nincs, mert van olyan subset szerinted, amit nem kell, vagy nem lehet. Értem. Bár magad is elismered, hogy "Ha a >>mikro<<kontroller elegendő tárolót tartalmaz komoly sw befogadására, akkor feltétlenül igazad van. ilyen esetben célszerű a szoftver részt különállóan kezelni.", és ugye az egész kanyar innen indult, azzal bizonyos üzleti logika dologgal, magyarán nevesítve azt, hogy nem általad kifogásként hozott példákra kell ezt csinálni.

> Regressziós tesztek szükségtelenek,

A hardcore szoftveres válasz erre az, hogy ez kizárólag akkor igaz, ha soha többet nem kell hozzányúlni, és belátni, hogy még mindig jó, mert a hardcore szoftveres nem hiszi magát tévedhetetlen istennek, mint a villamosmérnök. Természetesen van az a rész, ahol egy éppeszű ember úgy dönt, hogy megéri a kockázatot, hogy ha hozzá kell nyúlni, akkor macerásabb és hosszabb lesz, mert várhatóan nem kell hozzányúlni, vagy nem lehet vele annyit spórolni, ha mégis. De azért ezek a merev kijelentések, hogy nincs értelme szoftvert tesztelni egy tipikus mikrokontrolleres vezérlést, azok továbbra is röhejesek.

És akkor még nem is beszéltünk arról, hogy kezdjük el úgy írni a firmware-t - sőt, már a hardware tervezést is így kell kezdeni -, hogy fellapozzuk az adott mikrokontroller errata dokumentációját, amelyben leírják, hogy mi nem működik úgy, ahogyan kellene. Aztán vagy van workaround, vagy nincs.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

No igen, amikor valamelyik ATXMEGA valamelyik portján a komplett hardveres I2C (akarom mondani TWI) használhatatlan, de amúgy csak némelyik revízióban (azt meg keresheted a tokozáson felülről, vagy némelyiknél az IC hasán).

...vagy valamelyik szenzor adatlapja leírja, hogy I2C-t vagy SPI-t is támogat, majd jóformán oldaljegyzetben közlik, hogy SPI esetén mindezt csak egy master, egy slave esetén tudja, mert a MISO lábat nem képes tri-state állapotba tenni. Így "javítunk" hardvert adatlapban (feltételezem, hogy nem ilyennek szánták, egyébként a CS lábnak sem lenne sok értelme).

...vagy amikor egy rakat LED-et úgy adnak el (gyártanak le), hogy fordítva van rajtuk a jelölés.
Jelzésre javítják... az adatlapban (hasonló mint a fenti eset).

Vannak szép dolgok. :)

Nem is de kellene...
Itt egy tipikus szoftver feladat: Microchip’s 200W DC/DC LLC Resonant Converter Reference Design

Bizony van specifikáció, de kíváncsi lennék, hogy egy szoftvermérnök(*) melyik testnyílásába helyezné el a feladatot.

* A szoftvermérnök az az entitás, aki a mikrokontrollerek programozására van kiképezve. A feladat másik részét a hardveres csinálja. Állítólag.

Az egész vita tárgya jelenségnek van néhány problematikája: A feladat nem darabolható a szakterületek között. Pl. a fenti tápegységet nem tudja elkészíteni a legkiválóbb szoftveres sem, ha nem érti a tápegység működését.

Van egy másik példa a saját munkámból. Mérek egy szenzorral, ahol az analóg jelet több féle zaj terheli. Erre teszek egy elsőfokú szűrőt, majd ADC-vel és egy adott periódusidővel mintavételezem.
A specifikáció pedig az lenne, ha megadom:
- zaj1 amplitúdót és eloszlást,
- zaj2 amplitúdót és eloszlást,
- mintavételi frekvenciát és apertúrát,
- előírom a maximális hibát, vagy hiba minimalizálását a mért jel sávszélességének csökkenése nélkül.
Nosza, melyik szoftveres oldja meg ebből a feladatot?!

A való világban pedig megkérem a szoftverest (aki a további feldolgozást és megjelenítést írja), hogy keressen adott típusú szűrőket (C# libet) és megadom a hangolást. És ezt azért tudom megtenni, mert szűrőket is láttam már, de még hanglemezt is digitalizáltam. A szoftveres meg a kisimult görbe ellenére sem tudja mit csinált.

Igen, az az AN1114-es application note nem rossz kaland - illetve de, az - a legtöbb valóban software-esnek. A valóban alatt azt értem, hogy az úgy nem ér, hogy mellesleg villamosmérnök, mert épp arról szól ez a szál, hogy ezeket a programokat bizony jellemzően villamosmérnök írja, s ez így van jól. Sterilen software-es szerintem fontolgatná a felmondását ilyen specifikációtól, vagy csapkodná az asztalt, hogy na jó, de azt mondjátok, hogy milyen inputból milyen outputot vártok. Ami azért így jól hangzik, csak erre tényleg az AN1114 a válasz. :) Az se rossz, amikor a mágnesezési görbénél járnak, mert onnantól nem is lineáris a rendszer, s már a szuperpozíció sem igaz.

Félreértés ne essék, tisztelem a software-es kollégák tudását, de jellemzően rájuk operációs rendszer fölött van szükség, magas absztrakciós szinten, amikor egy rakás adatot fel kell dolgozni, statisztikát kell számolni, főbb vezérléseket kezdeményezni. Az viszont a villamosmérnök dolga, hogy egy fentről jövő parancsra pontosan mi történjék hardware közelében, vagy az ilyen-olyan sokszor passzív, tehát nem intelligens szenzorról jövő jelek valamilyen előfeldolgozás után milyen formátumban legyenek felküldve.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

" tehát nem intelligens szenzorról jövő jelek valamilyen előfeldolgozás után milyen formátumban legyenek felküldve."

Miért is lenne ez egy villamosmérnöki feladat? Mondod, hogy jajaj, szegény szoftveresek elsírják magukat meg jajajaj, úgy sem lehet megcsinálni, de miért is? Mi az a fene nagy megoldhatatlan dolog, amit lehetetlenség? Érveket is mondjál, ne csak állításokat.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Nem, nem ért mindenhez, de a formátumok kitalálása azért elég sokszor ott landol. Lévén, hogy egy szoftver fogja előállítani, feldolgozni, továbbítani, megrágni, szétcsócsálni, tárolni, stb. azt jellemzően.

Másrészt ezért raknak domain specifikus tudáshoz értő embereket még a csapatba vagy a csapat mellé.

Szerintem elenyészően kevés szoftverfejlesztő van képben az aktuális számlázási jogszabályokkal, mégis készülnek számlázó szoftverek is.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Nem, nem ért mindenhez, de a formátumok kitalálása azért elég sokszor ott landol. Lévén, hogy egy szoftver fogja előállítani, feldolgozni, továbbítani, megrágni, szétcsócsálni, tárolni, stb. azt jellemzően.
Jellemzően a 10 bites ADC-ből olvasott int adatot azonnal rakja float-ba. Aztán a 873 értéket szépen meg is jeleníti: 872.99999997 ;)

Szerintem elenyészően kevés szoftverfejlesztő van képben az aktuális számlázási jogszabályokkal, mégis készülnek számlázó szoftverek is.
Elfelejtetted befejezni a gondolatot: Olyanok is.

Itt a kettősség: A hardveres ne írjon szoftvert, mert hülye hozzá! Ugyanakkor a szoftveres írhat olyat, amihez lövése sincs.

Csak azért implementáljak lebegőpontos aritmetikát assembly-ben, hogy pontatlanul ábrázolhassam a számaimat? Hát Margit, nooormális? :) Amúgy a 873 lebegőpontosan is pontos lesz, hiszen 1.101101001*29. Azért legalább 3 byte-os mantisszát hadd feltételezzek. ;)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Inkább fogadd el, hogy a C# olyan, hogy mi hülyék vagyunk hozzá. :-D
A jelenség meg úgy derül ki, hogy a mérés megjelenik egy grafikonon. Ha egy pont fölé húzod az egeret, akkor kiírja a hozzá tartozó értéket. Az a lib, amit szoftver professzorunk használ, csak lebegőpontos értékkel tud dolgozni.
A lib kiválasztása úgy történik, hogy letölti és kipróbálja. Ha nem működik, akkor másikat tölt le.
Talán van a megjelenítésnek is kerekítési és formázási opciója, de ahhoz vagy olvasni kéne, vagy a lib nem teljesen dokumentált. (Bár ópenszósz, így bele is lehetne írni.)

Ebből is beláthatod, hogy rossz szoftverfejlesztési technológiával dolgozol! Ráadásul igénytelenül, mert szar amit írsz, se nem szimulálod, se nem teszteled fejlett módszerekkel. ;)

Az iróniából érzem, hogy olvasod a szálat, csak keveset szólsz hozzá. Mondjuk az igaz, idejében figyelmeztettél, hogy eléggé esélytelen lesz ezt az egészet megértetnem keményvonalas software-esekkel. Mármint azt, hogy miért kell bizonyos környezetben mérnöknek programozni. Igazad volt. De legalább megpróbáltam. :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Az infósok egy jelentékeny része is kap erős villamosmérnöki tudást. Én pl olyan 70% körüli átfedésekkel kaptam a Kandó villanykart, akkor lehet, hogy mégis scsak ér nekem is belepoff?

Egyébként meg persze kaptak, de az igazság az, hogy amiről itt beszélünk, azt az infósok is a melóban kapják és értik meg leginkább, a munkatapasztalattal. Akinek ilyenje nincs, az jó eséllyel max annyira érti, amennyire én a villamos dolgokat, ami nyilvánvalóan kevés. Ráadásul nem lenne baj, hogy beleszól, ha látszana rajta, hogy legalább nagyjából sejti, miről beszél a másik, de az eléggé látszik, hogy nem ez a helyzet. Illetve még ez sem lenne baj, ha nem hinné, hogy ennek ellenére a másik amit mond, az biztos nem tartalmaz semmi megfontolandót.

Egyébként meg az itt nyilatkozó urakból legalább kettő ugyan lehet, hogy kapott ilyesmit, de elég régen, és azóta sok víz lefolyt a dunán. Ha még emlékeznek is rá, ma egy csomó dolgot már másképpen csinálunk, mert fejlődött a szakma.

Nekem még mindig elvi problémám van az egésszel, de ezt már említettem korábban. Nevezetesen az, hogy hiába írsz tesztelt, igazoltan jó software-t, ha az nem lesz alkalmas a berendezés hibátlan üzemeltetésére. Igen, takarózhatsz azzal, hogy akkor nem volt jó a speckó, de az ügyfelet marhára nem érdekli, hogy rossz specifikáció, vagy hibás implementáció miatt vacak az, amit kapott. Még egy I2C-nél is ott van a vezetékek kapacitása, a zavarérzékenység, amit vagy áthidalsz kisebb sebességgel, vagy fölé húzol valamilyen réteget csomagismétléssel szükség esetén, már persze, ha lehet, mert ha valami hibás vezérlést hajt végre, abból lehet baj.

Akárhova is fejlődött a szakma, alacsony szinten rendszerben, időzítésekben, nyomatékban, áramban, sebességben, nyomásban, zajban kell gondolkodni, a hibátlan software nagyszerű, csak kevés.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Jó, de miért nem lesz képes a hibátlan üzemeltetésre?

Egyébként ha szétnéznél egy picit a lenézett szoftveresek felé is, már több évtizede az a mondás, hogy hibátlan szoftver nincs, tervezzél hibatűrő rendszereket. Mostani microservice-s cloud scale architektúráknál meg aztán főleg az az alap kiindulópont, hogy bármi szar lehet. Ugyanígy nem véletlen van, ahova redundáns rendszereket tesznek.

----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

Nagyon félreérthettél valamit, ha azt gondolod, hogy lenézem a software-eseket. Pusztán arról beszéltem, hardware közelében más megközelítés a szerencsés, szemben azzal az esettel, amikor a hardware-t elfedő operációs rendszer fölötti rétegben programoz valaki.

Mondok példát. Tegyük fel, van egy fél hidad, legyen ez akár valamiféle push-pull MOSFET meghajtó, vagy már a teljesítmény kimeneted. Rápillantva a kapcsolási rajzra, eltűnődsz, hogy az egyik bipoláris tranzisztor telítésig van vezérelve, s idő, amíg a töltéshordozókkal elárasztott kollektor-bázis rétegből kihúzod a töltést. MOSFET esetén pedig a drain-gate kapacitás miatt húzod ki a gate-ből a töltést árammal, miközben nem változik a gate feszültség (Miller-effektus). Itt gondolnod kell arra, hogy hamarabb zárod le az éppen vezetésben lévő félvezetőt, mint vezetésbe vezérled az eddig kikapcsoltat, mert ellenkező esetben rövid ideig ugyan, de rövidre zárják a tápfeszültséget, amelybe bele is pusztulhat a félvezető. Sokáig viszont nem lebeghet az adott pont, tehát kb. csak néhány száz ns lehet az az idő, amennyivel hamarabb kikapcsolod az éppen nyitott félvezetőt az éppen zárt bekapcsolása előtt.

Én örülök, ha ezekre az apróságokra minden programozó odafigyel, aprólékosan implementálja, mert kevesebb teljesítmény félvezetőt kell majd kicserélni a berendezésben. Mondom, más az, ha a software-es egyben villamosmérnök is, mert akkor biztosan oda fog erre figyelni.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Azt értem, hogy neked elvi problémád van, csak azt nem értem, hogy ki állított bármi olyat, hogy kizárólag így kell tesztelni, vagy hogy ettől biztosan hibátlan lesz a szoftver. Olyat sem, hogy például ettől a fizikai méretezések jók lesznek, vagy hogy azt is így kellene csinálni. Az ilyen jellegű tesztek azért vannak, hogy a te munkafolyamatodat segítsék. Nem azzal, hogy hibátlan lesz tőlük a szoftver, hanem azzal, hogy segítenek belátni, hogy azt csinálja, amit szeretnél, hogy csináljon.

Ezen a mondatodon látszik legjobban, hogy nem érted az egészet: "Akárhova is fejlődött a szakma, alacsony szinten rendszerben, időzítésekben, nyomatékban, áramban, sebességben, nyomásban, zajban kell gondolkodni, a hibátlan software nagyszerű, csak kevés." Ugyanis persze, hogy abban kell gondolkodni. Szó nincs itt arról, hogy ez megváltozott volna. Arról van szó, hogy miközben ezekben gondolkodunk, aközben hogyan haladunk a munkánkkal, hogyan nem viszünk be hibákat később, vagy más által csinált részekbe, hogyan marad más számára is átlátható a kód. Nem arról, hogy hirtelen már másban kellene gondolkodni. A változásoknál meg olyasmikre gondolj -- bár ez a ti kontextusotokban pont nem a legjobb példa, és nem is tesztelés -- de még nekem is azt tanították, hogy legyen rendesen kommentelve, itt a szálban is előjött. Ezzel szemben ma már egy "szoftveres" reviewn húzni fogja rá az orrát, és el fogja mondani, hogy ha ide ezt le kellett írni, akkor nem jól olvasható az a kód, szervezzük egy kicsit át, nevezzünk el még egy függvényt, valamit csináljunk, hogy magyarázkodás helyett a kód legyen olvasható.

Ez az egész teljesen ortogonális arra nézve, hogy itt időzítésekben meg miben kell gondolkodni.

(Az meg nekem is tényleg kérdésem, hogy hogy lehet a hibátlan szoftver kevés. A hibátlan szoftver pont azt csinálja, amit kell neki)

Szerintem a vitánk abból fakad, hogy számodra a software írása valami olyasmi, hogy kapsz egy pontos specifikációt, megtervezed, implementálod, teszteled, átadod, s akkor az jó. Ezzel szemben én azt állítom, hogy hardware közelében a specifikáció sem egzakt, az is képlékeny, részben mérés, kísérletezés következménye, így akár röptében változik, s ha valami nem váltotta be a hozzáfűzött reményeket, újra kell gombolni a kabátot.

A végén lévő kérdésedre is ez a válasz. Ha a specifikálást, algoritmizálást, mérést, iterációs lépéseket, mint újra specifikálás is a software írásának tekinted - én annak, hiszen szerves része az egésznek -, akkor valóban igaz, hogy csak az a jó software, amellyel majd eladásra kerül a gép. Ugyanakkor, ha a software-t önálló entitásként kezeled, akkor lehet az ugyan hibátlan, nem fagy szét, megvalósítja a specifikációt, a berendezés mégsem működik, mert a specifikációt finomítani kell a mérési eredmények, tapasztalatok szerint. Azaz, a program hibátlan a specifikációhoz képest, viszont a specifikáció hülyeség a berendezés szempontjából, így rosszul működik az egész.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

"Szerintem a vitánk abból fakad, hogy számodra a software írása valami olyasmi, hogy kapsz egy pontos specifikációt, megtervezed, implementálod, teszteled, átadod, s akkor az jó."

Nem, a vitánk abból fakad, hogy szerinted számomra ilyen a szoftver írása. Annak ellenére, hogy ilyet soha nem mondtam. Azt viszont sokszor, hogy szerintem nem ilyen, hanem olyan, hogy "Ha a specifikálást, algoritmizálást, mérést, iterációs lépéseket, mint újra specifikálás is a software írásának tekinted - én annak, hiszen szerves része az egésznek".

Tudniillik ez az egész tesztelős mizéria nagyrészt pontosan az ilyen munkfolyamatok támogatására való. Ahogy azt már leírtuk párszor. Utoljára éppen ezen hozzászólásod felett, amire válaszoltál. Csak képtelenek vagytok elolvasni, vagy nem tudom. Senki nem állította, hogy a "software-t önálló entitásként kezeled". Mármint rajtatok kívül.

Ja, és még valami. Írod, hogy nem software-es feladat. Na jó, de akkor ki írja meg a software-t? A software nem egy vegytiszta valami, ami lebeg az éterben, hanem gyakorlati problémákat old meg. Jó, vélhetően villamosmérnök fogja megírni. De akkor ő prüszköljön, hogy

a) nem programozó,
b) nem gépész?

Az egész berendezést valamilyen program vezérli, s abba beletartozik a megszoruló csapágy hibakezelésének esete is, meg az is, hogy honnan tekinted megszorulónak a csapágyat, s meddig veszed úgy, hogy ez még normál terhelés, valamint hogyan detektálod mindezt, s mit csinálsz, ha baj van.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

"Jó, vélhetően villamosmérnök fogja megírni. "
Miért kéne a villamosmérnöknek megírnia? Vélhetően a szoftvert a szoftvermérnök készíti el. Építőmérnök sem csinál geodéta feladatokat, ha van a csapatban földmérő. Pedig tanul geodéziát az építőmérnök is.

A megszoruló csapágy, stb. stb. az a program szempontjából egy bemenő adat. Magyarul, az ugyanúgy ki lehet szervezni, kint, hw függetlenül le lehet
tesztelni, stb. Senki nem beszélt arról, hogy nem kellene integrálni az egyes elemeket (akár nagyon korán), mi azt mondjuk, hogy ha van lehetőség,
akkor a belső működést érdemes külön kódba rakni, amit aztán rendesen körbe lehet tesztelni.

Ki mondta, hogy a köré épített hw-t akarjuk szimulálni. Van egy sw kódod, van valami bemenete, van valami kimenete, és van egy elvárt működés (X bemenetre Y kimenetet kell adni). Esetleg van valami visszacsatolás is (szabályzó). Az ide kerülő kódot meg lehet csinálni teljesen külön, körbe lehet tesztelni, meg lehet nézni, hogy
különböző bemenetekre hogyan működik.

A hőmérséklet, zaj, nyomás, sebesség, stb.-nek semmi köze nincs ahhoz, hogy a kódod jól (specifikációnak megfelelően) működik, vagy sem.

Én ugyanezt hallgattam fél évig egy hardver experttől, aki vadászta a bugokat az algoritmusában az igazi hardveren (szenzoradatok, analóg jelek digitalizálása és "real time" elemzése FFT-vel - helyesebben Goertzel-filterrel, mindegy).

Végül kilépett a cégtől. Megnyertem a feladatot, hogy fejezzem be a vackát és debugoljam ki. Sajnos én szoftveres vagyok, így nem hittem el hogy nagyon melós lenne a hardvert megfelelően szimulálni, ezért kigyomláltam az algoritmust a firmwareból, valamint nekiálltunk adatfolyamokat rögzíteni a valódi hardverrel, amit aztán beadagolthattunk az algoritmusnak egy tesztkörnyezetben.

Mivel a tesztkörnyezet innentől nem egy 48Mhz-s Cortex M0 volt, ami valós időben várt a bemenetre, hanem egy 3Ghz-s i7 ami egy tömbből olvasott be egy rakás számot, hirtelen az analízis futási és debug turnaround ideje lement húsz percről tíz másodpercre, ráadásul konzisztens bemeneti adatokkal hirtelen elkezdtük tudni reprodukálni azokat eseteket ahol az algoritmus szétesett, anélkül hogy fél napig futtatni kellett volna az egész teszthóbelevancot. Két nap múlva megvolt a bugfix arra, amit az eredeti írója a hardverhez ragaszkodva fél évig vadászott, ráadásul unit tesztelve, reprodukálhatóan. Aztán a meglévő rögzített adatblokkok alapján csináltunk még vagy további kétszázat némi randomizálással, ami további pár másik gyenge pontot is kidobott az algoritmusban.

No de mindegy. Nyilván ez csak egy elszigetelt eset volt, és amúgy az igazi hardveren tesztelni sokkal jobb...

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Igazad van. De ez esetben csak annyi volt a fontos, hogy az algoritmusnak nem kellett a DMA buffer megtelésére várni, mert az adat ott volt kéznél. Mivel a DMA fix frekvenciával olvasott az ADC-ből, ezért X méretű DMA buffer feldolgozása maga volt az időzítés is. Nyilván amikor adatokat gyűjtöttünk azt ugyanolyan sebességgel tettük, mintha az algoritmus futna a háttérben, így effektív a tesztkörnyezetben sem változott az időzítés, mert minden ciklus ugyanannyi adatot dolgozott fel, mintha a valós hardveren futna - csak nem kellett várni az adatra.

Nyilván ha valamit kontrollálni kell és szigorű a kimenet időzítése is a bemenethez képest, akkor erre is kell figyelni, esetünkben csak adatbeolvasás és elemzés volt. De ettől még az elv nem változik.

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Az időzítést is szimulálni kell. Szabályzónál például tipikus egy periódusidő választása. Ezen periódus szerint adagoljuk az inputot, és ezen periódus szerint írjuk (valós esetben frissítjük az aktuátort) a kimenetet. A periódusidő élesben péládul 20ms, szimulációkor pedig ahogy a csövön kifér.

Egyszer csináltam egy időzítés szimulációt egy teljes program alá. Annyira bonyolult lett, hogy az utódom odajött hozzám, hogy egy napig bogarászta, de végül megértette :-).

Természetesen igazad van.
De. ;)
Azért hallgasd meg a másik felet is! Feljebb írtam: Néha kipróbálom az algoritmust awk-ban, utána az awk megy a forrásba, amit átírok assemblerre. Tehát a hardveres számára sem idegen a szoftveres úton végzett besegítés. Nyilvánvalóan egy bonyolult algoritmust normális ember nem assemblerben kezd bepötyögni.
Volt már fordított helyzet is, amikor az algoritmus elkészült, valós adatokon is lefuttattam, sőt excelben ;) ellenőriztem is az eredményt. A feladat egy (max 4) görbe elemzése volt. Természetesen az assemblerbe átírás után az utolsó lépés a "taszkcsere" megírása volt, mivel a nem általános célú, kicsit megtelt agyú rendszerben ez már nem volt triviális. Aztán csináltam hozzá egy "realtime injektort", mivel a pici memóriába nem fért bele a teszt adatmennyiség. A teszt vége az volt, amikor a mikrokontroller ugyanazt az eredmény adta ki, mint a szoftver.
Lehetett volna szimulátoron futtatni, de az meg nincs, vagy ugyanezeket a bravúrokat az IDE felé kellett volna biztosítani. Esetleg felcipelni egy jó nagy motort a 3. emeletre, és ott bőgetni. ;)
Lényegében a thread a szimulációról szólt, de az általában a feladat csak szoftverrel leírható nem azonosidejű részeinél alkalmazható hatékonyan.

Csak a köré épített hardware-t munkás szimulálni.

Hát, jól kell tudni meghúzni az absztrakció határát...

vagy kipróbálom élőben, mint elkezdjem szimulálni.

Sajnos vagy nem, de már nagyon messze vagyunk attól a szinttől egy mikrokontrollerben, ameddig a "kipróbálom élőben" elég a szimulációhoz.

Egy sima, egyszerű PID fűtésszabályzót hogy a retekbe tesztelsz élőben?

És ezzel jól meg is mondtad a semmit. ;)
Mondjuk: Az ellenállás egy szép elméleti dolog, aminek lehetnek hardveres megvalósításai. Van matematikája is.

Az igaz, a PID rejtelmeit még ma is kutatják. Ennek ellenére nyugodtan állíthatom, hogy a szoftveres megvalósítás a legutolsó, amivel PID készült. Így az állítás feltétlenül igaz.

Eközben majd' 40 éve tanultam egy feladatot megoldani hidraulikával, kis- és nagynyomású pneumatikával, mikroprocesszorral, és lehetne sorolni a végtelenségig. Láttam működés közben analóg számítógépet, és tanulmányoztam hibrid számítógépet. (Ezek jobbára nem szoftveres megoldások.)

Az igazi szerkezetre egy példa az 500Ft-os: PIC16F1615
Ha belepillantasz az adatlapba, akkor a 32. fejezet egy komplett, több üzemmódú PID szabályzót ír le, méghozzá hardverbe építve.

Itt meg egy nagyon egyszerű PID szabályzó méretezése 1 db erősítővel. Ilyeneket láthatsz a hőfokszabályzós forrasztópákától a kapcsolóüzemű tápok visszacsatolásáig. A PID szabályzás elemei felismerhetők a hűtőszekrényben vagy egy gázkályhában, de ide sorolnám az ún. traktor szabályzót is (mechanikus). Az utóbbit azért hívják így, mert képes szabályozni (P) az egyébként egyenetlen járású Diesel motort. A motor lefulladna, ha a traktor döccen egyet a barázdán. Ekkor hirtelen megnöveli az adagolást (D), majd fokozatosan visszaveszi (I).

Hát nem csodálatos?

Úgy gondolom, hogy a felsorolt nem szoftver elemekkel akár a PID paramétereinek megállapításához és hangolásához szükséges elemek is elkészíthetők. Minden szoftver nélkül.

És ha el is olvasod a lapot, ez szépen leírja, hogy ez a hardver nem csinál mást, mint megvalósítja a PID algoritmust.
Mint ahogy mindenre lehet, ami kiszámítható, célhardvert csinálni.

Attól még a PID nem lesz hardver, az egy dolog, hogy te csak így tudod elképzelni. Pedig aztán szoftveres PID vezérlés az rengeteg helyen van. Például, ha már évforduló van: az Apollo Guidance Computerben a PID vezérlés szoftveres volt, nem volt rá célhardver.
https://www.ibiblio.org/apollo/hrst/archive/1137.pdf
Itt tök faszán bemutatják a szoftvert, igaz, archaikus (már ha egy 50 éves doksi az IT-ben archaikusnak nevezhető) nyelvezettel.
Nem volt rá célhardver, mert drágább lett volna minden vezérlendő elemre célhardvert építeni, mint megcsinálni egy szoftveres PID vezérlést, ami minden szükséges elemet tud valós időben vezérelni, általánosan.

Az egy dolog, hogy PID vezérlést ma a legtöbb helyen hardveresen oldanak meg, mert baromi olcsó a hardver ma már, az egy dolog. Attól még a PID algoritmus szerinti vezérlés nem lesz mindenképpen hardver, ahogy állítottad.

No, iderakom egymás alá, hátha kisebb szögben befogod. ;)

A pid szabályzó egyébként hardver, csak lehet szimulálni szoftverrel is.
Tehát állítom: hardver.
Miért lenne hardver? A PID szabályozás egy szép elméleti dolog, aminek lehetnek hardveres megvalósításai is.
Tehát állítod: nem hardver, hanem elmélet.

Mármitn a PID szabályzó - az ő testi mivoltában egy elmélet???

Tyúk - tojás - tyúk - tojás. Avagy a gravitáció is egy elmélet. Az alma sem esett le, amíg nem volt elmélet, esetleg szoftveres megvalósítással.

Pedig egy olyan szép cikket olvastam arról, hogy azt sem tudták mi az, meg hogyan működik, meg még elmélete, sőt algoritmusa is van. Aztán mégis sikerült számtalan PID szabályzót készíteni csak úgy ráérzésre. Sok száz évvel ezelőtt is! Tehát a PID szabályzó általában fizikai mennyiségek alapján fizikai mennyiséget szabályoz valamilyen fizikai eszközzel. A szabályzó egyes elemeit (ma már/gazdaságosság/flexibilitás miatt) szoftverrel lehet szimulálni az azóta kidolgozott (és egyre fejlődő) algoritmusok szerint. Ennek abszolút semmi köze ahhoz, hogy mit tudok elképzelni, mindössze csak időrend.

(A kedvemért most ne vegyük figyelembe az elvont mennyiségeket, mint pl. a tömegek hangulatának szabályzását. ;))

Ha most visszatekersz oda, ahova a fenti megállapításomat tettem, akkor rájössz a valódi jelentésére: Nehogy má' ne lehessen belőni a szoftvert a konkrét fizikai mennyiség megléte nélkül. (Ti. a kazán nem kapcsol be nyáron.)

Öööö... hát mivel egy funkcióról beszélünk, így lehet csinálni hardverben is, meg lehet csinálni szoftverben is, ahogy mondjuk audio processzort is lehet csinálni hardverben is, meg szoftverben is.
Mind a két verziónak vannak előnyei és hátrányai is, mint szinte minden másnak, és ennek megfelelően mind a kettő létező dolog.

Ami a hardverkozeliseget illeti, szerintem PC-n (illetve inkabb olyan vason amin komolyabb OS fut, (Windows, Linux, etc.)) gyakorlatilag nem igaz (marmint nem hardverkozeli) - bar egy RPi, vagy pl. valami mas SBC eppen hatareset.

Embedded rendszerek eseten kicsit mas a helyezt. Altalaban ismeri az ember a hardvert amire feljleszt, sokszor egeszen a melyere le kell menni megnezni hogy mi tortenik, ami akar direkt iras / olvasas a periferiak regisztereibe/-bol.

De azert ott is van kulonbseg, meg akkor is ha ma mar a 8 bites (pl. 8051-es) forditok is erosen optimalizalnak, egy 32 bites (ARM, MIPS) meg durvan.

Az '51-esnel siman megnezi az ember, hogy milyen assembly-t generalt a C fordito, sokszor szukseg is van ra debugolas kozben, de oszinten, az ARM Cortex-M assembly-t (pl. egy GCC-vel forditottat) mar eleg maceras "visszafejteni" (legalabbis nekem).

Szoval szerintem ez ennel osszetettebb kerdes, minthogy kategorikusan ki lehessen jelenteni.

/sza2
--
Digital? Every idiot can count to one - Bob Widlar

Én azt gondolom, hogy az eredeti cikkszerző unatkozott. Teljesen értelmetlen kérdésfeltevés és ugyanilyen értelmetlen erről vitázni. A 'C' lényege: standard utasításokkal olyan közel menni a hardverhez, amennyire csak lehetséges. Hogy ez a közelmenés az egyes architektúrákon mennyire sikerül, az egy másik kérdés, arról lehet értelmesen beszélgetni, mint ahogy az ebben a topikban történik.

A 'C' tartalmazza azokat az elemeket, amelyek nélkül nem nagyon lehetne programnyelvről, illetve (fizikai megvalósulásukban) processzorról beszélni, továbbá az architektúra specifikus esetekre engedélyezi az inline assembly-t. Senki nem akadályoz meg senkit abban, hogy olyan speciális assembly könyvtárat hozzon létre, amely C nyelv szintaxisának megfelel és C fordítóval tesz futtathatóvá.

> Sol omnibus lucet.

A C-t low-levelnek hívhatjuk abban az értelemben, hogy elég közel van a assembly-hez, és ezáltal a gépi kódhoz. Annál persze magasabb szinten van, nem kell/lehet közvetlenül a regisztereket írni, illetve az sem pontosan definiált, hogy pl egy int pontosan hány bites, de mindez az absztrakció azért kell, hogy képes legyen azonos C kód többféle architektúrára lefordulni.
Ugyanakkor low level, mert minimális extra szolgáltatásokat ad, nincs memóriakezelés, kivételek, stb-stb.

Mindez egyébként szinte semmit nem változott az elmúlt 30 évben, a C nem lett magasabb szintű, nem távolodott el az assembly-től vagy a gépi kódtól/ISA-tól.
Ami viszont sokat változott az elmúlt 30 évben, az az, hogy a processzor belső működése változott rengeteget, és már csak szimulálja azt a soros működést amit az ISA definiál.

Ennek persze az az eredménye, hogy a C modell "eltávolodott" a processzor valódi működésétől, de ez nem a C hibája, mert nincs igazán "lejjebb".

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o

"nem kell/lehet közvetlenül a regisztereket írni" - Ezzel azert vitatkoznek. Ha ez tenyleg igy lenne C-ben nem lehetne programot irni (pl. hardware drivereket). Amirol Te beszelsz az inkabb az, amikor a programodat egy reteg elvalasztja a fizikai hardware-tol (pl. OS, kernel).

A C ugyan nem szabja meg, hogy az int hany bites, de egy adott rendszerben igenis jol definialt (illetve megkotes, hogy legalabb 16 bitesnek kell lennie). Egyebkent az, hogy az int merete nem kotott, pont gatja a hordozhatosagnak szerintem, mert nagyon nem mindegy, hogy egy for ciklussal 2^16, 2^32 vagy 2^64-ig tudsz elszamolni. En ahol lehet a C99-es (pl.: uint32_t) tipusokat hasznalom, igy legalabb egyertelmu.

"C nem lett magasabb szintű, nem távolodott el az assembly-től" - hat, nem tudom, azert az ujabb es ujabb C szabvanyok eleg sok ujdonsagot adtak hozza, de persze kerdes, mit ertunk az alatt, hogy nem lett magasabb szintu, vagy, hogy tavolodott-e az assemblytol - es bar ez nem a C nyelv jellemzoje, de a C forditok is folyamatosan fejlodtek a CPU-kkal, MCU-kkal egyutt.

/sza2

--
Digital? Every idiot can count to one - Bob Widlar

Elsokorben ket dolgot javasolnek:
- olvasd el megegyszer azt a reszt amire reagaltal (a mondat elejetol)
- olvasd el az egesz hozzaszolast (de legalabb az elso bekezdest)

(esetleg olvass eggyel vissza, hogy mire reagaltam az en hozzaszolasomban)

Miutan ez megvan, probald meg ertelmezni az olvasottakat ;-)

/sza2
--
Digital? Every idiot can count to one - Bob Widlar

Ami viszont sokat változott az elmúlt 30 évben, az az, hogy a processzor belső működése változott rengeteget, és már csak szimulálja azt a soros működést amit az ISA definiál.

Ezzel semmi probléma. Távolról nézve a végrehajtás továbbra is sorrendben történik. Közelebbről meg lekezeli a fordító, mert az is fejlődött a processzorokkal együtt. Belülről nézve meg kb. 16 éve olvastam, hogy a Motorola készített új fordítót, amivel harmadára csökkent a futásidő. Ehhez a fordító "már előre kitalálta" a dinamikus rename regiszterek használatát (96 a 128-ból), és ehhez igazította a kódot.
Ez aztán az igazi fordító, ami tényleg elrejti a hardver runtime működését.

Ami jelentősen változott a CPU-kban, de végülis már 2 évtizede, hogy akkor jól lehetett számolni időzítéseket assembly-ben, ma kizárólag CPU timer jöhet szóba bármiféle időzítéshez. Ma az utasítások pillanatnyi végrehajtási ideje több látszólag független tényezőtől függ. Sőt ma a futásidőben gyakran valójában nem a CPU fog vissza, hanem a memóriára való várakozás. Tapasztalat, hogy a gyorsabbra megírt kód sem fut le sok proci esetén gyorsabban, mert a memória fogja vissza. Gyorsabb ARM-oknál ez a jelenség erőteljesebben érezhető, ezt több általam írt teszttel kimutattam.

Egyébként C esetén még mindig jól érezhető, hogy körülbelül milyen assembly kódot fog fordítani. Bár ehhez tényleg ki kell ismerni a C fordítót, mert igen összetett lett az optimalizációs eljárása. De sok gyakorlattal kiismerhető.

Hááát...is. ;)
Mondjuk én a régebbi POWER platformot ismerem.
Nagyon régen az MMU úgy működött, mint ahogy a 286-osnál.(*) A PowerPC SMT esetén (1995, max 8 CPU, 32b) már egy külső switch kezelte a memóriát, amely egy ciklus alatt akár 4 helyről is olvasott a 256 bit széles memóriából. A POWER4 (2004-ig, multicore, multichip, 64b) tervezési alapelve szerint minden ciklusban kell érkeznie adatnak, míg POWER5 (2004-től) esetén a memóriát a maximális sávszélességgel kell kezelni. Akkor is, ha a CPU lassabb. Az MMU már a CPU része - nem külső switch és 8r/4w pipeline alkalmazásával oldja meg a memória kezelését.
Meg ott az 5db FPU, mert csak így lehet biztosítani, hogy a CPU minden órajelre kaphasson eredményt.
Hát ezért mondom, hogy az IBM szerverek "hamonikus tervezésűek". Nincs kitüntetett elem, minden gyors.
A sávszélesség 1,8GB/s - ami rossz multiprogramozással 0,8GB/s értékre eshet vissza. Ez a '95-ös adat, amit az AMD dupla CPU-s szerverben már 2006-ban túlszárnyalt. ;)
Manapság a POWER9 lassanként elavulttá válik...

Az időzítéseket csak A PIC C libjei számolják ciklusokkal. ;) A POWER-hez évjárattól függetlenül pont ilyen célból tartozik beépített timer < 200ns felbontással. Pontos futásidőt nem is lehet mással mérni.

(*) Még 33MHz-es (!) POWER szerveren futtattunk egy rendezési feladat tesztjét. Az írója morgott, hogy mit hencegtünk a géppel, mikor egy pc gyorsabb. A megoldás: Nem vettük figyelembe a memória fizikai "belapozásának" idejét, ami a valós feladat futásidejénél mindegy lett volna. No, ezt kihagyva közel 0 lett a futásidő. :)

Egyébként C esetén még mindig jól érezhető, hogy körülbelül milyen assembly kódot fog fordítani.
Eddig igaz. Inkább az a kérdés, hogy hány thread-ben hogyan viselkedik? Érzésem szerint itt is az IBM lesz az örök győztes olyan kettes szorzóval.

subscribe

-----
„Egy jó kapcsolatban a társunkat az ő dolgában kell támogatni, nem a miénkben.”
rand() a lelke mindennek! :)
Szerinted…

C alacsony szintű? Nézzük például a memóriamenedzsmenten keresztül:
https://image.slidesharecdn.com/class9-inked-140218130958-phpapp02/95/w…

Az alacsony szintű programnyelv a nyelv+runtime által biztosított automatizmus helyett rád bíz rengeteg hardverközeli lehetőséget. Ez három dolgot jelent:
- több dologról kell automatizmus hiányában gondoskodnod
- korlátlan lehetőséget ad számodra, így például bare metal programmingra vagy oprendszer írásra is alkalmas
- egyúttal biztonsági kockázatot hordoz, hiszen a programozó bármit elkövethet bármiféle automata felügyelet nélkül

Tudni kell, minek mik a korlátai. Egyrészt PC-n, meg egyéb, sok fogaskereket tartalmazó berendezésen nem feltétlenül kell tudnod, mi történik hardware közelében. Elintézi a fordító, futásidő és memória van számolatlanul.

Másfelől mikrokontroller esetében már a C kód is sokkal hardware közelibb lesz, különösképp, ha erre figyelsz is, vagy kikapcsolod az optimalizálást. Továbbá mikrokontrollert programozz assembly-ben, s akkor biztosan az történik majd, amit szeretnél.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

"de minimum tévedés lenne az, amikor a mai C-programozós könyvek és blogok azt állítják, hogy azért is jó C-t tanulni, mert akkor tudni fogod, hogy mikor mi történik (majdnem) gépi szinten?"

Ez a kijelentes szerintem a C vs Java/Python/PHP/stb. kontextusban teljesen megallja a helyet. Akik e topicban melyebben belemennek, igazuk van, csak valoszinuleg szamodra nem relevans azon a szinten. Szerintem a te kerdesed: mint valaki, aki szeretne komolyan foglalkozni programozassal, 0-rol indulva, C tanulasa nyujt-e barmilyen elonyt. De lehet, hogy felreertelek...

----------------------
"ONE OF THESE DAYS I'M GOING TO CUT YOU INTO LITTLE PIECES!!!$E$%#$#%^*^"
--> YouTube csatornám

A minden nyelven is programozni tudó kolléga 10 nap után felsikoltott: Beolvasott egy fájlt és sikerült bájt pontosan ugyanazt kiírnia! A program C#-ban készült - aminek annyi köze van a C-hez, mint a java-nak.
Ha nem akarsz így járni, akkor mindenképpen érdemes az alapokkal megismerkedni.

De magyarázza el ezt egy nálam sokkal okosabb fickó: Vissza az alapokhoz. Megtalálod az angol eredetit is...

Akrobatika?! :-D
Akkor nézzél meg néhány processzort, hogyan éri el a memóriát:
- 6805 - van egy A (akkumulátor) és egy X (index) regisztere
- PIC16/PIC18 családok
Van egy W (munka) regisztere, a RAM "file" szervezésű.
Direkt címezheted a memóriát - vagy a BSR (bank select register) segítségével, már ha a megfelelő bankra állítottad. Vagy 1..3 db FSR (file select register) segítségével indexelten. De a ROM (flash) egy másik TBLPTR (table pointer) segítségévél, más utasítással olvasható, de csak két lépésben.
- 80x86, ahol pl. a szegmens+index+offset+konstans címről olvashatsz, de ez talán nem is a legbonyolutabb.
A függvénynek átadott paramétereket a BP (base pointer) + offset, a lokális változókat BP - offset helyről olvashatod.

Mindezek helyett csak egy absztrakt pointert látsz, a többit a C elfedi. Ugye, így már megéri?

Csak adott peremfeltételek megléte esetén.
Valós mód is normális üzemmódja a CPU-nak, csak ma már nem nagyon használják.
Az Intel leírás szerint a "Védett mód" az a 32 bites eredeti védett mód.
"When operating in protected mode, some form of segmentation must be used. There is
no mode bit to disable segmentation. The use of paging, however, is optional."

Intel CPU-knak x86-os vonal 3(+1)+1(2) üzemmódja van.
IA-32(32 bites vonal)
3(+1) üzemmód:

  1. Valós mód
  2. System Management Mode
  3. Védett mód, ez a normál üzemmódja. "native operating mode of the processor"
  • 3/b Virtuális 8086 mód / védett módon belül egy külön mód

Intel 64 esetén
3(+1)+1(2) üzemmód:

  1. Valós mód
  2. System Management Mode
  3. Védett mód, ez a normál üzemmódja. "native operating mode of the processor"
  • 3/b Virtuális 8086 mód / védett módon belül egy külön mód
  • IA-32e mód / ennek 2 almódja van
    1. compatibility mód
    2. 64-bit mód

    So, van 32 bites(1) és 64 bites(4/2) védett mód. A kettő között jelentős a különbség.
    Az 4/1 compatibility mód szegmentálás szempontjából megegyezik a 32 bites védett üzemmóddal.

    32 bites védett mód
    Ebben az esetben van szegmentálás. Persze dönthetsz úgy, hogy flat módnak megfelelően állítod be őket és akkor tényleg úgy tűnhet, mintha nem lenne, de ettől még van.
    A lapozás használata csak lehetőség, vagy bekapcsolod és használod vagy sem.
    Magyarán van:
    1) normál szegmentálás, nincs lapozás
    2) normál szegmentálás, van lapozás
    3) flat-módú szegmentálás, van lapozás

    64 bites védett mód
    Itt is van szegmentálás, csak éppen eléggé behatárolva.
    Az alap szegmens regiszterek a teljes memória területre vannak beállítva(Flat mode) és nem is módosíthatók és nincs határellenőrzés/segment limit check.(sajnos)
    Van két szegmens regiszter, melyek módosíthatóak, bár itt sincs határellenőrzés(FS, GS)
    In 64-bit mode, segmentation is generally (but not completely) disabled, creating a flat 64-bit linear-address space.
    The FS and GS segments are exceptions.
    Note that the processor does not perform segment limit checks at runtime in 64-bit mode.

    Hát igen, a C \0 végű stringje szép örökség, a bugok egyik komoly forrása.
    A szintén bare metal programmingra is alkalmas Rust esetén a String típusnál ezért áttértek a capacity és len mezőket tartalmazó struktúrán keresztüli automatikus megoldásra: https://www.safaribooksonline.com/library/view/programming-rust/9781491…
    A számlálók praktikusan usize típusúak, ami az adott rendszer képességeire elég. Legyen az 8 bites mikrovezérlő vagy 64 bites modern architektúra.

    Legyen az 8 bites mikrovezérlő vagy 64 bites modern architektúra.
    Szerintem itt kezdődnek a problémák. Különösen a magasszintű nyelveknél megpróbálnak mindent tipizálni, ami jó, mert a hülye is könnyedén ír benne programot. Persze legalébb 10x annyi erőforrással.
    Intermezzo: Arra a kérdésre, hogy "Mekkora lehet a log maximális sorhossza?", nagytudású kollégám (egy másik, és mivel fingja sem volt a válaszról), küldött egy MSDN linket. Miszerint Windows alatt a string maximális hosszát a diszk mérete határozza meg. :-D

    No, így is lehet. Valójában nem az architektúra, hanem a feladat határozza meg az optimális kezelést. Nemegyszer Pascal(esetleg + Z) :-) stringben tároltam az adatokat, mert nagyságrendekkel gyorsabban lehet keresni.
    A számlálók praktikusan ... (pointerek) az átlagos adathossz szorozva a várható mennyiséggel, természetesen megfelelően/a következő egész bájt szélességre/valamilyen int-re felkerekítve.

    A bugok forrása meg a program írója.

    Igaz, hogy a feladat határozza meg, hogy milyen hosszú string kell. Viszont ma már a feladat alapján választunk 8 vagy 32 bites mikrovezérlőt is. Ma már nem próbáljuk a 256 hosszú adathalmazt "okosban" feldolgozni 8 bites mikrovezérlővel, amiben 128 byte RAM van csak.
    Ha a feladat mérete 8 bites filléres mikrovezérlő felé terel, ott elég a 8 bites pointer és 8 bites számláló.

    Amiket írtam, az kifejezetten nem mikrokontroller környezetről szólt, hanem akár több százmilliós mennyiségű string kezelésről.

    Aztán ki a rosseb akar mikrovezérlővel stringeket feldolgozni?
    A választást meg még a sorozat nagysága is befolyásolja. Pl.:
    - MCU 500Ft
    - MCU + crypto chip 680Ft
    - MCU (16 bites + crypto engine) 1500Ft
    A százas sorozatnagyságtól már olcsóbb, ha az 500Ft-os eszközön fut még az AES256 is, meg pl. mérés közben a göbék vizsgálata. Igaz, a fennmaradó RAM vagy FLASH nem igazán számottevő. ;)
    Az utóbbinál - erdekességként - három-négyszer újraíródik az összes RAM, amíg előáll valami eredmény. Ezért kicsit más az algoritmus, mit 16GB memória esetén. ;)
    A választás roppant fontos és időtrabló is lehet, de megéri, mert évekkel később sem találtam hasonló eszközt.

    Aztán ki a rosseb akar mikrovezérlővel stringeket feldolgozni?

    Látom még nem láttál trendi IoT startupot belülről, ahol először feldefiniálják az összes kommunikációs csatornát JSON sémával... Boldog ember vagy.

    Mert a backend NodeJS vagy környéke, és a backend "kolléga" nem tudja hogy épül fel egy little endian szám binárisan, let alone float, így ha nem kapja meg JSON-ban az értékeket akkor pánikba esik. És még ennél is van rosszabb, mikor ugyanezt előadják ad-hoc, séma nélkül, vagy megpróbálnak rá valami custom dolgot okozni...

    -=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

    Hát, ezen röhögőgörcsöt kaptam. Aztán kicsit pityeregtem is.
    Jajjjjdehogynemtudom.

    Van egy szerverünk, ahol a gyártáshoz peccselem a FW-t, hogy egyedi legyen. Mindezt egy < 400 soros script (bash, awk, xxd és openssl van benne, no meg mysql sorok), amely egyben a Windows alatt futó flash program parancsinterfésze is. Eccer hív az egyik kolléga, hogy a másik kolléga feltaláta a websocketurl alapú adatbáziselérést. De lebeszélte. De nem sikerült, mert fél óra múlva fel is hívott. És nem is értette miért nem akarok lokálban futó scriptben (amit már fél éve használunk) websocketurl-t alkalmazni.

    Készítettem egy bonyolult kalibrátor eszközt: BME280 illesztve USB-re, amit a saját protokollunk szerint visszaadja egy stringben a nyomás értékét. Mikor egyeztettük a formátumot, mindegy volt a válasz. Úgy is JSON definíciót írok hozzá.
    Mondom: Itt a gyártó C forrása a BME280 mért értékeinek korrekciójához. Hát akkor dllimport, stbstb - bonyi. Az lett a vége, hogy a nyers adatok kalibrálás közben átkerülnek egy VPS-re, ahol az awk-ba átírt C program megfejti és visszaküldi. Szerintem egy "eccerű ember" ekkora impotencia láttán már eldobja a kanalat. ;) Ja és A PROGRAM pedig C#-ban készül.

    Azért látok egy roppant előnyét az egésznek: Ha szétszáll az adatbázis kapcsolat definíciója, akkor legalább 2 nap a helyreállítása. ;)

    "ki a rosseb akar mikrovezérlővel stringeket feldolgozni?"

    Generálni egész jól lehet őket. Feldolgozni tényleg rosszabb.

    Hőnyomtatóval egész jó kis riportokat lehet készíteni mikrovezérlővel is. Stringeket generálni még egész jól lehet.

    Az általam készített RTemplate-et például fel lehet úgy paraméterezni, hogy a template string konstansai a mikrovezérlő program memóriájából jönnek, így egy ATMega128 is lekezel 128 kBájtnyi template-et (a helyen a lényegi programmal osztozva). Amiből azért már sok kijön.

    A hőszabályzós projektemben például egy SD kártyára szöveges alapú logot tervezek, amit közvetlenül fel lehet olvastatni a grafikon megjelenítő programból.

    Amire vigyázni kell, hogy egy sima string bemásolódik a RAM-ba, ezellen körül kell venni trükkös makrókkal, hogy a konstansok csak a program memóriába kerüljenek be.

    Eleve a 255 bájtos maximális hossz (egy bájton volt az index). Plusz valahol láttam egy mérést, ami szerint az strlen()-t kivéve a sztring-műveletek gyorsabbak voltak a C-stílusú sztringekkel.

    -----
    „Egy jó kapcsolatban a társunkat az ő dolgában kell támogatni, nem a miénkben.”
    rand() a lelke mindennek! :)
    Szerinted…

    Jó, akkor segítek. Pascal <> Turbo Pascal. :)

    A Delphi (és a Free Pascal) úgy húsz éve (sacc, lehet több) tud reference counted stringeket, "AnsiString" néven, amik tárolják a hosszukat is, így nem kell a zeró terminálásra hagyatkozni - ami amúgy mellesleg safety okokból szintén van, pl. a egy AnsiStringet egy char *-t váró OS függvénynek átadsz, simán működik -, copy-on-write szemantikájuk van, stb.

    Mellesleg a legújabb inkarnációban ugyanezt megfejelték Unicode és általános kódlap támogatással, valamint natív támogatás van a Windowsok WideString (16 bit / karakter) típusához is.

    Köhm... Jóhogy nem az 1992-s TP7-t hasonlítjuk már egy GCC9-hez. :)

    Amúgy a "mérés", az mit jelent. Milyen platformon, milyen libc-vel, milyen hosszűságű stringeket, stb. Mert ugye az megvan, hogy függetlenül attól h. mi a syntax sugar odafent a nyelvben, a stringműveleteket minden nyelv egy jó nagy adag library támogatással oldja meg, max. rálapátol egy adag safety checket, hogy ne cseszd el. (A C is, csak ott nincs rá syntax sugar és nem ellenőriz neked a fordító semmit, nesze strcpy() aztán OMBM.)

    -=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

    Fúúúúú, mingyá ledobom az ékszíjat az indokolatlan Rust marketingtől... Mintha amit leírtál a Rust találta volna fel, és az egyetlen lenne ami képes rá, és nem lennének huszonéve nyelvek vagy megoldások erre.

    -=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

    Höhh, de jó, hogy ebből egy szót se értettem... :)
    Asszittem a portal játékról van szó. Cake is a lie. :D

    Fun-fact: Az Armv8.3 tartalmaz Javascript specifikus hívásokat.

    > Improved Javascript data type conversion
    > Armv8.3-A adds instructions that convert a double-precision floating-point number to a signed 32-bit integer with round towards zero. Where the integer result is outside the range of a signed 32-bit integer (DP float supports integer precision up to 53 bits), the value stored as the result is the integer conversion modulo 232, taking the same sign as the input float.

    Amiben nincs „void *”, az nem is igazi programozási nyelv! :)

    -----
    „Egy jó kapcsolatban a társunkat az ő dolgában kell támogatni, nem a miénkben.”
    rand() a lelke mindennek! :)
    Szerinted…

    Ez így van. Láttam ilyet is olyat is. Ugyanakkor explicite is használhatsz NOP-ot 'C'-ben közvetlen asm utasítással. Erről jut eszembe egy érdekes szitu. Egy M68070-es cuccot élesztettem, semmi OP nem volt rajta, először a módregisztereket kellett beállítani, hogy egyáltalán történjen valami (ha jól emlékszem). Dőltek a mérési adatok valahonnan és DMA-val kellett elvenni őket. Két DMA volt rajta és felváltva kellett használni, amíg az egyik bufferbe írt a mérőhardver, addig a másikból ki lehetett lapátolni az adatokat. Valamiért a két DMA nem egyforma sebességgel működött, ezért kellett egy kiegyenlítő ciklus, amiben NOP-ok (egy órajel!) voltak. Szóval a NOP-nak néha van szerepe.

    (Amit hiányolok a 'C'-ben hogy nincs SETBIT, CLI, STI utasítás, néha jó lenne.)

    > Sol omnibus lucet.

    Ebben van igazság. A cli és sti az gyakorlatilag minden processzoron van. A SETBIT valóban architektúra függő. Ugyanakkor a C része a bitléptetés (de a rotáció nem!) és nem vagyok benne biztos, hogy ez minden architektúrán létezik. Nyilván a fordító lerendezi, de ezzel az erővel a SETBIT-et is lerendezhetné.

    > Sol omnibus lucet.

    "Ugyanakkor a C része a bitléptetés (de a rotáció nem!)"
    Hát igen, itt is felsejlik, hogy a C nem volt más eredetileg, mint egy magas szintű assembly a PDP-11-hez.
    "Nyilván a fordító lerendezi, de ezzel az erővel a SETBIT-et is lerendezhetné."
    Ezért lehetne ezeket mondjuk libraryba tenni. Ne a nyelv része legyen, hanem oldja meg egy library.

    Ha jól emlékszem a modern fordítók (talán pl. GCC5 és újabb) felismeri a bitrotációs kódmintákat és ROL/ROR-t fordít belőle... Ami viszont valóban nem szép és alátámasztja, hogy "C is a lie"... :)

    De ezen kívül van ahol van rá valami compiler intrinsic is, AFAIR, ha feltétlenül ROL/ROR-t akarsz belőle, és nem tudod rábízni a fordítóra, valamilyen okból, de ez általában annyira marginális dolog, hogy bőven elég rá valami erősen célzott target-függő intrinsic.

    -=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

    Kösz a tippet! Már megérte a topic. Tényleg rotálásra fordít.

    
    unsigned int rotaljunk(unsigned int d) {
        return (d>>31 | d<<1);
    }
    
    És a gcc-7.3 kimenete (-O2):
    rotaljunk:
            movl    %edi, %eax
            roll    %eax
            ret
    

    Tök jó az optimalizálása, pont ezt várom el tőle a lassú, szolgai végrehajtás helyett.
    Természetesen eredményhelyesen, ahogy a proci out-of-orderes feldolgozójától is a gyors, de eredményhelyes végrehajtást várom el.

    Ja, de működik a "fix méretű" C stdint típusokkal is, pl. ugyanez uint??_t-vel is simán megy, és a fordító ettől függően fordít rolq, roll, rolw, rolb-t... (Most próbáltam ki GCC 8-cal.)

    Nyilván amelyik architektúrán nincs meg a mindenféle forgatás hardveresen, ott meg úgyis mindegy, ott majd összehozza valahogy ahogy tudja, a lényeg hogy az eredmény stimmeljen.

    -=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

    Teljesen igazad van, csak 32 és 64 bites rendszeren működik a fenti kód. Erre nagyon kell vigyáznom, ha őskövület 8 vagy netán 16 bites architektúrával van dolgom. Egyébként uin32_t -t kellett volna használnom.

    A C előnye az assembly-hez képest, hogy a legtöbb esetben ugyanolyan gyors futású kódot alkotnak a mostani C fordítók, mintha te írnád assembly-ben, ugyanakkor az I/O kezelő részek kivételével maga az algoritmus x86, x86-64, ARM, ARM64, MIPS, MIPS64, Sparc, ... 32 és 64 bites architektúrákon egyaránt lefordulnak.

    
    ARM:
    rotaljunk:
    	ror	r0, r0, #31
    	bx	lr
    
    MIPS - például az otthoni OpenWRT-s routeredre:
    rotaljunk:
    	jr	$31
    	ror	$2,$4,31
    

    A cli és sti az gyakorlatilag minden processzoron van.

    68k-n pont nincs CLI és STI utasítás, ott a Status Regiszter System byte-jában a megfelelő bitek beállításával vagy törlésével lehet törölni vagy engedélyezni az interruptokat. Ami mellesleg csak Supervisor privilégumszinttől elérhető a legtöbb 68k-n (68010-től felfelé mindenen, a sima 68k-n pont nem, és pont emiatt nem teljesíti a Popek-Goldberg virtualizációs követelményeket az eredeti 68k).

    És itt már fel is sejlik, hogy miért lenne rossz ötlet ez nyelv szinten, hiszen pl. 68k-n az interruptokat prioritási szinttől függően lehet kimaszkolni, máshol meg csak egy általános letiltás/engedélyezés van. (A lényeg - ez sem egységes az architektúrák között, most mindegy hogy melyik mit és hogyan tudja, erre akarok célozni.)

    -=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

    Őszinte leszek: nem emlékeszem hogyan kezelte az M68070-es a megszakításokat. A példa, amit hoztam azt kívánta megmutatni, hogy egyes asm szintű utasítások bekerültek a nyelvbe, mások meg nem, amit nem tartok következetes dolognak. Hajlok arra, hogy persicsb fórumtársnak van igaza ebben a kérdésben, tudniillik, hogy egy, a nyelv születésekor létező architektúra képződik le a C nyelvi utasításokban.

    > Sol omnibus lucet.

    Az M68070-en (ami gondolom egy SCC68070 akar lenni, mert a Motorola sosem csinált 68070-et AFAIK, az egy Phillips által gyártott 68000 alapú SoC volt), nem 7 órajel a NOP? :)

    Amúgy embedded célokra teljesen normális, hogy felmakrózod a cuccot, és akkor lehet CLI/STI, meg amit akarsz, ennek pont nem kell a nyelv részének lenni...

    -=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

    Az van, hogy a C egy szar nyelv a rengeteg olyan dologra, amire használják. Jobb meg sokszor azért nincs vagy nem tud terjedni, mert van a C és sokan foggal-körömmel regaszkodnak hozzá, miközben nem látják a hátrányait.

    ----------------
    Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™

    +1

    Én egy olyan nyelvre vágynék, ami valahol a C és a Java között lenne, típus és túlcímzés biztos lenne alapból, statikusan fordítana (nincs JIT, vagy legalább elérhető opció az Ahead of Time fordítás), és lehet vele dinamikus foglalás nélkül is értelmes programokat írni.

    Hab lenne a tortán, ha valahogy együtt tudna működni egy Garbage Collector és egy malloc-szerű foglalási mechanizmus, amik közül a programozó választhat, hogy az adott feladatra melyiket használja.

    (De lehetne kikényszeríteni nem biztonságos kasztolást, meg túlcímzést is, ha arra van szükség - hasonlóan a Java Unsafe-hez)

    A túlcímzés helyett azt kellett volna mondanom, hogy tetszőleges pointer+méret-re pointer létrehozás kell arra az esetre, ha oprendszert akarnék írni. Ugyanezen célból kellhet az ellenőrizetlen kasztolás is. De ezek csak szélsőséges esetek, amiket egy speciális libbel le lehet fedni.

    Ada-ról már sokat hallottam, de még sosem néztem meg, majd most.

    A Pascal már nem emlékszem miért nem jött be, pedig tanulóként írtam benne pár programot. Aztán mégis inkább C-s lettem. Talán csak a hype miatt? Van Pascal fordító mikrovezérlőkre?

    ha oprendszert akarsz írni, akkor az adott nyelv runtime-ját (malloc, GC stb) neked kell megírnod, vagy legalább azokat a támogató syscallokat, amelyeket az OS biztosít amúgy. Szóval nem lesz az alapból :)

    Ezért is jó a C mint rendszerprogramozási nyelv. Ahol van stack, ott lehet C-ben írt binárist futtatni (persze még mindenféle magasszintű C-s funkcionalitás, pl. stdio és társai) nélkül.

    Van Pascal fordító mikrovezérlőkre?

    Az FPC tud AVR-re fordítani, meg van ARM Embedded (Cortex M & friends) támogatás is, egy csomó boardra. Nyilván olyan széleskörű mikrokontroller támogatása nincs, mint C-nek, de az infrastruktúra ott a fordítóban és a default libben, hogy relatív könnyen lehessen továbbiakat hozzáadni.

    -=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

    Rust-ot nézted? Igaz malloc helyett vektor típusa van, ami automatikusan duplázva allokál.
    Ezért ismerkedem én is vele, hogy legyen egy hatékony futású nyelv, amely képességben a C és a Python között áll.
    Unsafe {} itt is van. :)
    Update ha OS-t akarnál benne írni, itt a példa: https://github.com/redox-os/redox

    https://dlang.org/blog/2017/08/23/d-as-a-better-c/

    https://dlang.org/blog/2018/06/11/dasbetterc-converting-make-c-to-d/

    https://dlang.org/blog/2018/06/20/how-an-engineering-company-chose-to-m…

    ----
    „Kb. egy hónapja elkezdtem írni egy Coelho-emulátort, ami kattintásra generál random Coelho-kompatibilis tartalmat.”

    https://theartofmachinery.com/2017/02/28/bare_metal_d.html

    https://github.com/JinShil/stm32f42_discovery_demo

    https://news.ycombinator.com/item?id=17585357

    ----
    „Kb. egy hónapja elkezdtem írni egy Coelho-emulátort, ami kattintásra generál random Coelho-kompatibilis tartalmat.”