Fórum témák

» Több friss téma
Fórum » ARM - Miértek hogyanok
 
Témaindító: gtk, idő: Jún 26, 2007
Lapozás: OK   140 / 177
(#) rolandgw válasza kapu48 hozzászólására (») Júl 14, 2019 /
 
Idézet:
„// megjött az 5 karakter, esetleg ellenőrzöd?”

A HAL_OK-nak nincs köze a vett karakterszámhoz. Ezt a HAL_UART_RxCpltCallback függvénnyel lehet megoldani és egy segédváltozóval, ami a main-ben lekérdezhető. MX példákban megtalálható.
(#) don_peter válasza rolandgw hozzászólására (») Júl 14, 2019 /
 
Tudsz egy ilyen példát linkelni.. Köszi előre is.
(#) rolandgw válasza don_peter hozzászólására (») Júl 14, 2019 / 2
 
G0-t használok, de gondolom itt is így van. Egyszerű, ha belenézel az stm32xx_hal_uart.c fájlba. A HAL_UART_IRQHandler meghívja a callback-et, ha beérkezett a megadott darabszám. __weak-ként van definiálva a függvény, beírod a programba:
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
  2. {
  3.   /* Set transmission flag: transfer complete */
  4.   UartReady = SET;
  5.  
  6. }
(#) don_peter válasza rolandgw hozzászólására (») Júl 14, 2019 /
 
Közben én is megcsináltam és kipróbáltam, jól működik.
Köszi, már régebben is nézegettem ezt a rutint, de nem értettem pontosan mire is való.
(#) don_peter hozzászólása Júl 19, 2019 /
 
Srácok egy bonyolultabb kérdéssel fordulok hozzátok.
Nem is száz, hogy le tudom írni, de igyekezni fogok.

Készítek egy elektromos kerékpárra egy fedélzeti kijelzőt, amely hivatott az aktuális sebességet is mutatni. Az eredeti kínai kijelzővezérlés bedöglött és emiatt meg kellett néznem hogy működik a sebesség mérése.
Lényegében a motor egy fázisát beereszti egy osztón keresztül a mikrokontroller egyik lábára, feltételezem, hogy egy timert vagy megszakítást használva a motor impulzusainak számolására és megadva a kerék egy fordulatának hosszát ki tudja számolni a sebességet.

Igazából ezen a részen túl vagyok és beállítva egy timer-t külső órajeles módra, majd számolva az impulzusokat ki tudom számolni az aktuális sebességet, de sajna kicsi felbontással.

És most a lényeg:
Egy kollégám említette, hogy elvileg képes lehet az STM32 mikrokontroller, egy úgynevezett GATED módban való működésre, amely adja a lehetőséget, hogy valahogy kapuzni lehessen a bejövő jeleket és ezzel megmérni a két beérkezett impulzus közt eltelt időt.
Ennek meglétével pedig egy viszonylag pontosabb és nagyobb felbontás érhető el, amelyből persze pontosabb sebesség számítható.

A kérdés az, hogy van e már itt valaki, aki használt valamilyen hasonló feladatban ilyen beállításokat és hogy miképpen tudom én ezt megvalósítani, ha egyáltalán lehetséges.

Most ilyen ráncigálós kis modult használok a próbálgatáshoz, melyben egy STM32F103C8 található.
A végleges munkát majd egy 407-es fogja végezni.


A bicikli sebesség tartományát, hogy könnyebb legyen 0-100km/h-ra állítanám.
(Ha nem felel meg az előosztás esetleg, akkor a sebesség függvényében lehetne azt is állítgatni.)

Előre is köszi a segítséget.
A hozzászólás módosítva: Júl 19, 2019
(#) don_peter válasza don_peter hozzászólására (») Júl 20, 2019 /
 
Úgy fest ez egy nem túl népszerű beállítás, de úgy néz ki sikerült beállítanom amit akartam, kár, hogy közben megmértem a motorból érkező jelet és kiderült, hogy valami nagyon nem úgy van ahogyan az én képzeltem. (de ez már más kérdés lesz)

Viszont felmerült két kérdése bennem:
1, ha kapuzni akarok egy timer-t, akkor annak mindenképp lesz egy kimenete?

2, nem vagyok biztos benne, hogy jól számolom az időzítést mikor a timer elő és utóosztásait állítom ezért, ha valaki megtenné, hogy leírná nekem a számolás menetét azt megköszönném.

Én így számolok stm32f103c8-nál.:
1/7200000 == 13.8nS (0.000000013888)
Ha mondjuk akarok egy 500mS-os timer beállítást, akkor így számolnék:
500000/13.88 == 36023
Tehát ha jól számoltam, akkor 1000-es előosztással, 36023szor kell a timer-nek számolnia, hogy pontosan 500mS-onként csorduljon túl.

Jól számolok?
Azért kérdezem, mert PIC esetében volt egy FOSC/4, itt nincs ilyen?
(#) csatti2 válasza don_peter hozzászólására (») Júl 20, 2019 /
 
1, Ezt nem értem. A feladatból nekem az input capture funkció jön le, ahhoz pedig bemenet kell.

2, Több órajel konfiguráció is létezik. A lényeg, hogy a TIM1 az APB2 a többi pedig az APB1 x2 órákhoz vannak kötve. Ha nem kapcsoltál be valamilyen egyéb osztót a timer-ed konfigurációjánál, akkor nagyjából jól számoltál. Azért írom, hogy nagyjából, mert egy gyors áttekintéssel kiderül a 36023-nak kb. semmi értelme és a helytelen kerekítés okozza. A helyes érték a szép kerek 36000 lesz (0,5 * 72 * 10^6 / 10^3 = 36 * 10^3).

Egyébként nem olyan ritka beállítás, amit csinálsz. Én pl. IR távirányító jelét dolgozom fel ilyen input capture-al.
(#) cross51 hozzászólása Júl 20, 2019 /
 
Sziasztok!

Fejlesztgeteg egy saját könyvtárat amit lehető legkisebb protolgatással egyik kontrollerről a másikra lehet vinni.

Jelenleg épp STM32-re csinálgatom a (UART) könyvtárat és olyan problémám van, ha fut az RTOS a háttérben akkor az UART átküld 2-3 byte-ot majd hardfault-al meghal a kontroller.

A könyvtár szálvédett és IT védett ebbe most ha nem muszáj nem keresném a hibát, mert nem itt van a probléma szerintem.

A probléma ott történik mikor az UARTn_IRQHandler-e meghívásra kerül és én elkezdem lekérdezgetni az status és az IT engedélyező biteket.
Ezeket függvényekkel teszem.
A példa kedvéért vegyük azt a függvényt ahol a hiba van
  1. _PERIPHERAL_INLINE bool TransmitterEmptyInterruptStatus() const
  2.                 {
  3.                         return (((USART_TypeDef*)mUsartBaseAddress)->SR & USART_SR_TXE);
  4.                 }

Ahol a _PERIPHERAL_INLINE egy inline __attribute__((optimize(xx))-nek felel meg és ezzel kérdezem le a TXE flag-et a Driver layer-en (az hogy a reg base addr miért így van csinálva az most nem részletezném) és ezzel működik szépen.
Viszont, ha én még hozzá rakom, hogy __attribute__((always_inline)) és a globális optimalizáció O0-ra van belőve akkor jön a hardfault, ha viszont átrakom a globális optimalizációt O0-nál nagyobbra megint megy szépen.
És ezek csak RTOS meglétekor igazak (a könyvtár tud RTOS-al és RTOS nélküls is futni) nélküle megy minden szépen.

Valaki látott már ilyet létezik rá valami magyarázat, hogy miért érdekli az it-t hogy én optimalizációtól függetlenül ezt az egy sort mindig inline szeretném látni?
Vagy ez esetleg a fordítónál hasal el?

Egy másik kérdés IT-re vonatkozóan a kód szépsége miatt gondoltam csinálok egy táblát ami Callback-et tud tárolni (mbed-es Callback-ből származik az implementációja, tehát nem csak egy pointert tárol) viszont ez, hogy elérje az IT kezelő függvényt a Driver-en belül 1 hívás helyett tesz 3-4 hívást ettől kell féljek?
(mert láttam valahol egy doksit ahol két IT közötti váltásnál (tail chaining asszem) spórolnak 12 vagy 6 ciklust (nem tudom pontosan), ha ott volt értelme nem tudom mekkora hiba az előző metodika)
(#) csatti2 válasza cross51 hozzászólására (») Júl 20, 2019 /
 
A hardfault-ot kellene kielemezni, hogy mi is történik ott pontosan. Könnyen lehet, hogy valami alattomos dolog van a háttérben (pl. rossz megszakítás prioritás szint és belenyúl a megszakításba a scheduler, kifutsz a stack-ból ha bele kell fordítani a függvényhivást, stb.).

Itt egy kis kód, amit én bele szoktam biggyeszteni a programjaimba (annak idején a saját RTOS-omhoz írtam, bár azóta átálltam FreeRTOS-ra).

  1. #define NAKED                             __attribute__((naked))
  2.  
  3. // Exception stack frame
  4. typedef struct
  5. {
  6.         uint32_t r0;               // R0
  7.         uint32_t r1;               // R1
  8.         uint32_t r2;               // R2
  9.         uint32_t r3;               // R3
  10.         uint32_t r12;              // R12
  11.         uint32_t lr;               // Link register
  12.         uint32_t pc;               // Program counter
  13.         uint32_t psr;              // Program status register
  14.         uint32_t s0;               // S0
  15.         uint32_t s1;               // S1
  16.         uint32_t s2;               // S2
  17.         uint32_t s3;               // S3
  18.         uint32_t s4;               // S4
  19.         uint32_t s5;               // S5
  20.         uint32_t s6;               // S6
  21.         uint32_t s7;               // S7
  22.         uint32_t s8;               // S8
  23.         uint32_t s9;               // S9
  24.         uint32_t s10;              // S10
  25.         uint32_t s11;              // S11
  26.         uint32_t s12;              // S12
  27.         uint32_t s13;              // S13
  28.         uint32_t s14;              // S14
  29.         uint32_t s15;              // S15
  30.         uint32_t fpscr;            // Floating point status and control register
  31. } StackFrame_t;
  32.  
  33.  
  34. #pragma GCC diagnostic push
  35. #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
  36. void __attribute__((optimize("O0"))) _hardFaultHandlerC(uint32_t *stackFrameAddress)
  37. {
  38.     volatile StackFrame_t *stackFrame;
  39.  
  40.     stackFrame = (StackFrame_t*)stackFrameAddress;
  41.  
  42.     __ASM volatile("BKPT #0");
  43.  
  44.     while (1) {}
  45. }
  46. #pragma GCC diagnostic pop
  47.  
  48.  
  49. NAKED void _hardFaultHandler(void)
  50. {
  51.     __ASM volatile(
  52.       "tst lr, #4             \n\t"     // Test bit 2 of EXC_RETURN code
  53.       "ite eq                 \n\t"
  54.       "mrseq r0, msp          \n\t"     // If 0, stacking used MSP, copy to R0 (main task, IRQ or kernel function)
  55.       "mrsne r0, psp          \n\t"     // If 1, stacking used PSP, copy to R0 (any other task)
  56.       "b _hardFaultHandlerC  \n\t"     // Call C hard fault handler function
  57.     );
  58. }
  59.  
  60. void WWDG_IRQHandler(void)
  61. {
  62.         while (1) {}
  63. }
  64.  
  65. #pragma GCC diagnostic push
  66. #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
  67. void __attribute__((optimize("O0"))) _usageFaultHandlerC(uint32_t *stackFrameAddress)
  68. {
  69.     volatile StackFrame_t *stackFrame;
  70.  
  71.     stackFrame = (StackFrame_t*)stackFrameAddress;
  72.  
  73.     __ASM volatile("BKPT #0");
  74.  
  75.     while (1) {}
  76. }
  77. #pragma GCC diagnostic pop
  78.  
  79.  
  80. NAKED void _usageFaultHandler(void)
  81. {
  82.     __ASM volatile(
  83.       "tst lr, #4             \n\t"     // Test bit 2 of EXC_RETURN code
  84.       "ite eq                 \n\t"
  85.       "mrseq r0, msp          \n\t"     // If 0, stacking used MSP, copy to R0 (main task, IRQ or kernel function)
  86.       "mrsne r0, psp          \n\t"     // If 1, stacking used PSP, copy to R0 (any other task)
  87.       "b _usageFaultHandlerC  \n\t"     // Call C hard fault handler function
  88.     );
  89. }


A stack frame itt egy Cortex-M4F-es maghoz készült. Értelemszerűen módosítani kell a struktúrát ha máson használod. A változóban elérhető lesz a hiba fellépésekor érvényes regiszter értékek, ennek segítségével jobban behatárolható mi is történt.
(#) csatti2 hozzászólása Júl 20, 2019 /
 
Upsz, pici javítás. Az _usageFaultHandler-t nevezd át UsageFault_Handler-re. A _hardFaultHandler-t pedig HardFault_Handler-re.
(#) don_peter válasza csatti2 hozzászólására (») Júl 20, 2019 /
 
A helyzet az, hogy én sem értem pontosan, talán itt van a nagy gond.
Lényegében úgy gondoltam, hogy egy timer számlálóját kívülről egy impulzussal lehetett volna inkrementálgatni. Gondoltam, hogy a motor egy fázisáról levett szál, minden mágnes elhaladásánál generál egy impulzust és ez adta volna gyakorlatilag a timer-nek az órajelet.

Aztán egy másik timer-t meg úgy állítottam volna be, hogy az előző timer két kívülről kapott impulzusa közt eltelt időt mérte volna. Ebből meg már kiszámoltam volna a sebességet, egyéb adatok tudatában.

Mind ezt a hardver intézte volna, valamilyen kapuzással.

Ami viszont most szembe jött velem teljesen felborította ezt az elképzelésemet, mert megmértem a motorból érkező jelet a vissza fejtett kapcsolás alapján egy logikai analizátorral és kikapcsolt állapotban a csatolt jelet mutatja, amit nagyon nem értek.

És itt a kérdés is, melyik topikban tudnak nekem ebben segíteni, hogy megfejtsük miféle jel jön a motorból és hogy miért...

Illetve az órajeles témánál pedig minden perifériának a maximumot állítom, semmit nem osztok külön le. Elvileg 72MHz-van ott ahol annyi tud lenni.
A hozzászólás módosítva: Júl 20, 2019
(#) csatti2 válasza don_peter hozzászólására (») Júl 20, 2019 /
 
Túlgondoltad. Egy db timerrel megoldható a dolog. Simán be kell állítani a timer-t a kívánt precizitásra. Ezután input capture módban érzékelni kell a jel fel/le futását (igény szerint), megszakítás generálásával. A megszakításban ki kell olvasni a timer aktuális értékét, majd az előző érték-ből és az újból kiszámítható az eltelt idő. Tovább finomítható a kód a túlcsordulás megszakítás használatával (hosszabb idők is mérhetőek).

Nézegettem a mérési eredményeid. Elég nagy zagyvaságnak tűnik. Persze elég kis mintavételezéssel vetted fel, nem tud többet a tied? Az én saleae-m akár 500Ms/s-t is bír.
(#) don_peter válasza csatti2 hozzászólására (») Júl 20, 2019 /
 
A megszakítást akartam kihagyni vagy is csak ritkára venni, hogy a főprogramom minél kevesebbszer legyen félbeszakítva. Ezért csak a timer és a kapuzás, valahogy..

Tudna többel is venni az analizátor, de próbáltam nagyobb mintavétellel is, nem volt jobb a jelalak, ez meg így könnyen feltölthető. Könnyebben tudom mutatni, egy 100-200MB-os fájlt nehezebb mozgatni.

Csatoltam egy 7MB-os mentést. Ebben az alap látható az első részében, majd egy gázfröccs, és aztán elengedem a gázt. Ez is elég zagyva, egyszerűen nem értem, hogy ez egy kommunikáció vagy csak egy valamilyen random jel.
Arra gondoltam, hogy nem e a FET-ek kapcsolgatásának a zaját mutatja az analizátor.
A hozzászólás módosítva: Júl 20, 2019
(#) csatti2 válasza don_peter hozzászólására (») Júl 20, 2019 /
 
DMA-val kikerülheted a megszakítást. Akkor a DMA vezérlő fogja kiírni a mért eredményt a kívánt memóriaterületre (vagy pl. körkörös pufferbe).

Az a baj a mostani adatokkal, hogy sok impulzus hossza pontosan megegyezik a mintavételezés frekvenciájával, azaz nehéz eldönteni, hogy most zajt látunk vagy jelet.
(#) don_peter válasza csatti2 hozzászólására (») Júl 20, 2019 /
 
Csinálok egy 24Megásat. Azt hiszem ez a legtöbb ennél a kicsi analizátornál.
(#) cross51 válasza csatti2 hozzászólására (») Júl 20, 2019 /
 
Köszi!

pont CM4F-et használok.

Meg is néztem, nem annyira ismerem az ARM-ok lelki világát még nem rég álltam át PIC32-ről.
De ez mennyire egészséges, hogy a hardfault-ban a kiolvasott pc értéke 10?
(#) csatti2 válasza cross51 hozzászólására (») Júl 21, 2019 /
 
Hmm, nem igazán normális.

Első körben ellenőrizd, hogy a stack frame pointere értelmes helyre mutat-e (nehogy az legyen, hogy vmit kavart a fordítód). Ha igen, akkor nézd meg, hogy mi van a link registerben. Nézd meg vele, hogy milyen utasításból kerültél oda, ahol most vagy. Ha az is hülyeség, akkor lehet, hogy valahogy sérült egy task kontextusa (tárolt regiszter értékek).

Ezt a hibát okozhatja stack túlcsordulás (egy task beleír a mögötte tárolt task területére, mert kevés a neki allokált terület). Ha a fejlesztőkörnyezeted és az RTOS-od támogatja, érdemes lenne bekapcsolnod a stack figyelést. Ilyenkor pl Atollic-nál látható mennyi szabad területe van a különböző task-oknak.

A másik lehetőség, hogy rosszul állítottál be egy megszakítás szintet. Ez azért fontos, mert ha az ütemező megszakítás megszakít egy másik megszakítást (), akkor minden összekavarodhat. Épp ezért az ütemező megszakítás a legalacsonyabb szintű szokott lenni (amilyen szinten és ami alatt semmilyen más megszakítás nem lehet, a szerviz megszakítás pedig a legmagasabban, amin és ami felett más nem lehet).
(#) csatti2 hozzászólása Júl 21, 2019 /
 
Itt egy minta két task közti váltásra a saját RTOS-omból. A scheduler beállítja az új stack pointert (meg még csinál pár apróságot, de az most nem számít). A lényeg, hogy látszik, ahogy beleírja az aktuális stack végére a regiszter állapotokat (ez a kód CM3-as), majd ütemezés után az új task korábban mentett regisztereit helyreállítja. És tippem szerint nálad valami itt borul.

  1. /** \brief Interrupt handler for pending services
  2.  *         Handles context switching between tasks
  3.  *
  4.  * \param void
  5.  * \return NAKED void
  6.  *
  7.  */
  8. NAKED void PendSV_Handler(void)
  9. {
  10.   __ASM volatile(
  11.     "tst lr, #4               \n\t"     // Test bit 2 of EXC_RETURN code
  12.     "ite eq                   \n\t"
  13.     "mrseq r0, msp            \n\t"     // If 0, stacking used MSP, copy to R0 (main task)
  14.     "mrsne r0, psp            \n\t"     // If 1, stacking used PSP, copy to R0 (any other task)
  15.     "stmdb      r0!, {r4-r11}     \n\t"     // Store context registers in stack, write new stack pointer back to R0
  16.     "ittee eq                 \n\t"     // New "if then" block with previous result
  17.     "msreq      msp, r0           \n\t"     // If 0, store new stack pointer in MSP
  18.     "moveq  r0, #1            \n\t"     // If 0, set R0 to 1
  19.     "msrne      psp, r0           \n\t"     // If 1, store new stack pointer in PSP
  20.     "movne  r0, #0            \n\t"     // If 1, set R0 to 0
  21.     "bl _scheduler            \n\t"     // Call scheduler with input argument R0
  22.     "teq r0, #1               \n\t"     // Check if return argument is equal to 1
  23.     "ite eq                   \n\t"
  24.     "mrseq r0, msp            \n\t"     // If 0, copy MSP to R0
  25.     "mrsne r0, psp            \n\t"     // If 1, copy PSP to R0
  26.     "ldmia      r0!, {r4-r11}     \n\t"     // Restore context registers from stack
  27.     "ittee eq                 \n\t"     // New "if then" block with previous result
  28.     "msreq      msp, r0           \n\t"     // If 0, store new stack pointer in MSP
  29.     "moveq lr, #0xFFFFFFF9    \n\t"     // If 0, store 0xFFFFFFF9 as EXC_RETURN code in link register (return to thread mode and use main stack pointer for stacking)
  30.     "msrne      psp, r0           \n\t"     // If 1, store new stack pointer in PSP
  31.     "movne lr, #0xFFFFFFFD    \n\t"     // If 1, store 0xFFFFFFFD as EXC_RETURN code in link register (return to thread mode and use process stack pointer for stacking)
  32.     "bx lr"                             // Return to task
  33.   );
  34. }
(#) cross51 válasza csatti2 hozzászólására (») Júl 21, 2019 /
 
A stack méret nem hiszem, hogy problémás lenne 128k van heap-nek belőve a FreeRTOS config-ba és a task ~10k memóriával jön létre az tény hogy a FreeRTOS fölött van egy saját C++ layer ami több memóriát eszik, de 10k egy uart-os driver nem tud megzabálni (a küldött adat egy Hello World char tömbben raktam globálisra raktam a while fölé, hogy a task-ba pakolja így is úgy is hibát okozott).
A stack túlcsordulós dologgal szórakoztunk az egyetemen, hogy van eset mikor az RTOS még "elkapja" és van amikor instant hardfault, de az előbbiek miatt nem tartom lényegesnek.

Na az utóbbi pont már sokkal inkább azzal pont úgy voltam nem piszkálom (még a preemtion és a sub priority kicsit zavaros, hogy most melyik mi célt szolgál) a priority-it egyszer feljebb toltam de nem néztem mekkora a scheduler prioritása ezt kipróbálom be rakom legnagyobb prioritásra aztán meglátom.
A második válaszod lehet választ is ad miért csak RTOS alatt okoz problémát a dolog.

Még a volatile-ra gyanakodtam, de nem igazán hozott semmit (kb be raktam mindenhova), de az alap gondolat miatt mivel szimultán úgy sincsen írás mivel vagy az it tudja írni a változót/változókat vagy az adott listába fűző uarta-ra író függvény (közben az uart it kikapcsolva)
(#) cross51 válasza cross51 hozzászólására (») Júl 21, 2019 /
 
Ez valami fordítási hiba lesz szerintem.
Állítottam a prioritást max-ra akkor is meg volt a hiba.

Na mondom akkor jöjjön a global interrupt tiltás engedélyezés.
Ez sem működött majd ki vettem az UART-os függvények elöl az always_inline-t és akkor is dobta a hardfault-ot viszont most az interrupt kezelő miatt.
A Interrupt:: Disable függvény nem inline (kikapcsolja a globalt megnézni hogy az engedélyezve van-e az it ki kapcsolja majd vissza tér az it bekapcsolt vagy kikapcsolt értékével) az Interrupt::Restore sem inline (megnézi az előzőleg visszaadott értéket és be kapcsolja vagy kikapcsolja az it-t) viszont az itt hívott Peripheral::Interrupt:: Disable/Enable (mások mint az előbb említett függvények csak a register set/clear-t írják emberileg olvasható nyelvre) is always_inline-al van ellátva és az is hibát okoz...

Szerintem elengedem ezt az optimalizációs mániát berakom simán inline-ra aztán döntse el a fordító mit akar vele csinálni.
A hozzászólás módosítva: Júl 21, 2019
(#) csatti2 válasza cross51 hozzászólására (») Júl 21, 2019 /
 
Nem olyan bonyolult a group priority, sub priority kérdése. A magasabb group priority-s megszakítás megszakíthatja az alacsonyabbal rendelkező megszakítás futását. Az azonosak, illetve alacsonyabbak értelemszerűen nem. A sub priority csak azt dönti el, ha több megszakítás is aktiválódott, melyik fog először végrehajtódni (de a group priority ugyanaz, az a fontosabb).

Biztos van olyan helyzet, ahol a sub priority-vel játszadozás hasznos, de én nem szoktam használni.

A scheduler prioritását ne piszkáld. A saját megszakításaidnál pedig ne használd a legmagasabb és legalacsonyabb prioritásokat.
(#) cross51 válasza csatti2 hozzászólására (») Júl 21, 2019 /
 
Én is úgy láttam, hogy többsége a sub-priority nem használt, csak még sok bennem a PIC32-es logika ott meg hangsúlyos a sub-priority is

Persze az utolsó részt én is tartani szoktam csak akkor használok legmagasabb prioritást, ha valami nagyon nagyon kritikus (pl tápot figyeltem ADC-vel és ennek a komparátor IT-je legmagasabbra volt állítva, hogy "biztos" át tudja kapcsolni az áramkört akkura).
De jelen esetben még a fából vaskarika megy úgyhogy mindent lehet és próbálom a library-t f...-ognak is ki tenni, hogy lássam min csúszik el->mit kell át írjak.

Fejlemény, viszont nem a fordítás okozza a galibát, hanem a Callback amit nem teljesen értek miért. (publikussá tettem a handlert és be vágtam direkte az IT-be, láss csodát a hiba megszűnt)
A működése pár szóban (elég sarkosan):
Van fent tartva hely adott class pointer-ének és függvényének és a callback számára egy belső pointer amin keresztül ezeket típussal együtt meg tudja hívni (mert amúgy a Callback nem tudja milyen típusra hivatkozik, csak a függvény típusát ismeri).

Ha az IT-ben a Callback-et direkt meghívom és ebben always_inline függvény van akkor HardFault ha viszont a callback-ben tárolt mutatókat kimásolom egy memória területre majd én castolom típusosra akkor jól működik.
(#) csatti2 válasza cross51 hozzászólására (») Júl 21, 2019 /
 
Na várjunk csak. Te inline-os függvényt hívtál meg pointerként hivatkozva? Az egyértelmű programozói hiba és kb. semmi értelme.
(#) cross51 válasza csatti2 hozzászólására (») Júl 21, 2019 /
 
Nem nem, a pointeren keresztül hívott függvény (ami az interruptHandler-re mutat és az interruptHandler nem inline függvény) hív meg egy always_inline-os függvényt, ha csak simán inline (a belülről meghívott függvény) nincs vele baj vagy ha az optimalizáció be van kapcsolva akkor sem okoz gondot, csak az okozza a gondot ha O0-ban akarok always_inline függvényt meghívni.
(#) don_peter válasza csatti2 hozzászólására (») Júl 21, 2019 /
 
Csatti2: volt pár pillanatod rá pillantani a 24MHz-es mintavételű jelsorozatra?
Lehet neked többet mond mind nekem, talán egy kicsit szebb a struktúrája, de nekem nem sokat mond így sem.. Köszi..
A hozzászólás módosítva: Júl 21, 2019
(#) csatti2 válasza don_peter hozzászólására (») Júl 21, 2019 /
 
Bocs, nem is néztem. Pill, ránézek.
(#) csatti2 válasza don_peter hozzászólására (») Júl 21, 2019 /
 
Hát ez elég furcsa. Szemmel látható, hogy jóval sűrűbb középen, gondolom ott gyorsítottál rá.

Milyen motort használsz? Pontosan mit is mérsz és hogyan?
(#) csatti2 válasza cross51 hozzászólására (») Júl 21, 2019 /
 
Nézd meg a generált assembly kódot. Valami furcsaság lesz ott.
(#) don_peter válasza csatti2 hozzászólására (») Júl 21, 2019 /
 
Mxus 3K turbo.
Az egyik fázisa közvetlen van kivezetve és az megy bele a kijelzővezérlőbe.
A kijelző vezérlőn full gáznál a teljes akkumulátor feszültségének 50%-a jelenik meg, a motor amúgy 84v-ról jár, tehát ha tele van az aksi, akkor full gázadásnál 42v jön be azon az egy fázison. Ezt műszerrel mértem.

Ez a benő jel egy egyenirányító diódával meg van fogva, és mögötte pedig egy tranzisztorral és néhány ellenállás segítségével minden impulzusnál 3.3v-ot enged a mikrokontroller lábára.
Kvázi egy szintillesztő. És az eredményt meg már te is láttad.

A felvett adatok a következőt mutatják: Az első 1/3 időben csak az álló motornál kapott jelek látszanak, majd a 2/3-nál húztam egy kis gázt, majd a 3/3-ban ismét az alap állapotot mutatja.
A hozzászólás módosítva: Júl 21, 2019
(#) csatti2 válasza don_peter hozzászólására (») Júl 21, 2019 /
 
Szóval egy BLDC motor egyik fázisát figyeled. Álló helyzetben rögzíti a kereket a motorvezérlő? Tud fékezéskor visszatölteni?

Megtaláltam aliexpress-en ezt a motort. Két szett Hall szenzor kimenete is van ha jól értettem. Miért nem használod egyszerűen az egyik Hall kimenetet inkább.
Következő: »»   140 / 177
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem