C/C++

Android OS fejlesztés, packages fordítása emulált környezetbe

Fórumok

Sziasztok, Android source build-hez ért valaki?

 

Emulátor környezetben szeretnék tesztelni egy EVS_APP nevű programot, ami egy native app és az Android source code-jának a része a packages folderben:

https://cs.android.com/android/plat...r:packages/services/Car/cpp/evs/apps/default/

Sajnos rengeteg belső libet használ, ezért csak a teljes forrás részeként fordítható.

Ez egy automotive alkalmazás. Nagy nehezen találtam egy lunch target-et, amivel elindult egy Automotive emulátor: sdk_car_x86_64

 

Viszont fogalmam sincs, hogyan lehetne ezt (és dependenciáit) hozzáadni a buildhez. 

Ha valakinek van ötlete, szívesen fogadom. 

C++, kapcsos zárójeles inicializálás és template argument deduction

Fórumok

Üdv!

 

Miért van az, hogy az alábbi kódban a T template paramétert nem bírja kitalálni a compiler (g++):

#include<iostream>
#include<iomanip>

#include<boost/numeric/ublas/vector.hpp>
#include<boost/numeric/ublas/io.hpp>

template<typename T, size_t n> boost::numeric::ublas::vector<T> vecFromArray(const std::array<T, n> x){
  boost::numeric::ublas::vector<T> retVal(n);
  std::copy(x.begin(), x.end(), retVal.begin());
  return retVal;
}

int main(){
  boost::numeric::ublas::vector a = vecFromArray({0.0, 1.0, 2.0});
  std::cout << a << std::endl;
  return 0;
}

és szájba kell rágni neki úgy, hogy

  boost::numeric::ublas::vector a = vecFromArray<double, 3>({0.0, 1.0, 2.0});

ami persze nem jó, mert neked kell odafigyelned, hogy a szám és a lista hossza stimmeljen. (Nyilván meg lehet oldani, ha az ember ír egy ilyen függvényt külön, ami eleve egy std::initializer_list-et kap, de most nem ez a kérdés. Meg akkor, ha mind a kettő kell, akkor duplikálva van egy kis kód.)

 

 

Szerk.: kódismétlés nélkül megoldható, de azért érdekelne a válasz az előzőre:

#include<iostream>
#include<iomanip>
#include<initializer_list>

#include<boost/numeric/ublas/vector.hpp>
#include<boost/numeric/ublas/io.hpp>

template<class T1, class T2> T2 vectorConvert(const T1 &x){
  T2 convertedVector(x.size());
  std::copy(x.begin(), x.end(), convertedVector.begin());
  return convertedVector;
}


int main(){
  auto a = vectorConvert<std::initializer_list<double>, boost::numeric::ublas::vector<double> >({0.0, 1.0, 2.0});
  std::cout << a << std::endl;
  return 0;
}

arm gcc, stack reuse

Fórumok

Sziasztok!

Egy erdekes problema jott szembe most. Van egy ARMv6 Cortex-M0 mikrokontrollerre szant program, ami kb ezt csinalja tobbek kozott:

main()
{
// ...
 while ( 1 )
  {  // ... 
     if ( whatever )
      {    call_something_that_prints_the_stack_pointer();
      }
     // ...
     if ( something_totally_unrelated )
      {    uint8_t array[256];
           do_something_with_array(array);
      }
     // ...
  };
}

Namost, azt tapasztaltam hogy a call_something_that_prints_the_stack_pointer() altal kiirt ertek, meg ugy altalaban a stack fogyasztasa (itt ebben a peldaban) hatarozottan fugg az array[] meretetol. Ha azt kisebbre veszem, pl 128-ra, akkor a stack pointer kiirt erteke 128-cal nagyobb lesz. Most gondolnank hogy "igen, ez logikus". Dehat ugye nem az. Kis utanajarassal eljutottam ide, es ezalapjan... hat, igen, ezalapjan is nagyon ugy nez ki hogy nem kene fuggnie mert az array[] az elegge local, es ezt a fordito szereti romma optimalizani (es aki dangling pointereket csinal, az nyilvan igy jart es jarjon is igy). 

Kiprobaltam mas reszleteiben is a programot, valahol azert jol mukodik ez, szoval abszolut nem altalanos. Node mivel mikrokontroller, ezert minden RAM szamit, plane igy, hogy egy ilyen nagyon local scope local scopejaban levo valami miert is fogyasszon barmit... Es hat ugy is tunt fel hogy 1-2 plusz featura hozzaadasa utan osszeert a statikus terulet (data, bss) a stack-kel, es akkor jott a karorakutya, stb :) Raadasul libc-heap nincs is, csak egyedi allokatorok. 

Latott barki mar barmi hasonlo ilyesmit? Nyilvan ez inkabb beagyazott tema, nem klasszik C, de akkoris erdekes... van-e valami mod pl az arm-none-eabi-gcc hasznalataban ahol ezt le tudom debuggolni? Nyilvan automatikus valtozoknak nincsen memoriaterkepe, max frame pointer-hez viszonyitott, de ARM-nel meg kulon frame pointer se nagyon kell mert sp-relativ cimzesu az utasitaskeszlet (LDR*, STR*). Ami meg meginkabb erdekesse teszi ezt a kerdest szerintem...

Thx, A.

Openssl session átadása process-ek közt

Fórumok

Sziasztok,

Adott 2 process (a,b) akik egy siman tcp socketen tartják a kapcsolatot. B processnek van egy openssl/boost::asio listen portja, ahol varja a bejovo kapcsolatokat majd megcsinalja a tls handshaket. Ha ez meg van, szeretnem atadni az A process-nek az ssl sessiont. Maga a tcp layeren levo socket file descriptor atadasa mar megoldott, az mukodik, de a session atadassal gondjaim vannak. Elvileg a i2d_ssl_session/d2i_ssl_session-al serializalhato a teljes session context, de  egyelore hibat dob ha az atadott ssl socketen megprobalom folytatni a kommunikaciot.

Foglalkozott mar valaki hasonloval?

Amikor az optimalizáló teszi futtathatóvá a hibás kódot

Fórumok

Valami ehhez hasonlót írtam:

*(uint16_t *) (buff + 241) = get_crc(buff, 241);

buff 4-re align-olt uint8_t buffer, illetve get_crc() uint16_t-vel tér vissza. -O1-gyel fordítva a kód hibátlanul fut, míg -O0-val lefordul, de futásidőben exception-t dob. Ami persze érthető. Nyilván -O0 esetén a fordító bután lefordította a páratlan címre történő egy gépi ciklussal történő 16 bites írást. Csak ugye itt meglehet, hogy két gépi ciklus kell, először egy 32 bites duplaszónak a felső byte-jába kell írni a 16 bites számunk alsó byte-ját, majd utána a következő 32 bites duplaszó alsó byte-jába írjuk a 16 bites számunk felső byte-ját. Little endian MIPS architektúra. Az optimalizáló érti, mire gondoltam, de ha csak bután lefordítjuk, akkor bizony ez nyilván exception. A programozónak látnia kell a hardware-t, annak működését is, nem elég az, hogy amit leírtunk, az elméletileg jó. Azt valódi hardware hajtja végre.

Egy kis DSP x86-on...

Fórumok

Sziasztok!

Egy kis digital signal processinghez kapcsolodo optimalizacios kerdes. Van egy effele programtoredek, amiben egesz aritmetikaval, mindenfele lookup-tablak hasznalataval es bufferek kezelesevel egy multiply-and-accumulate  jellegu belso ciklusmag futkoraszik:

 for ( i=0; i<nsample; i++ )
  {     [...]
        int     si,sq; 
 
        si=sq=0;

        for ( k=0,b_offset=2*i,sip=sip0; k<nnode; k++,b_offset+=2*nsample,sip++ )
         {      int     ci,cq,rot_cos,rot_sin;
       
                ci=2*(int)sib->sib_buffer[b_offset+0]-255;      /* 2*(k*nsample+i)+0 */
                cq=2*(int)sib->sib_buffer[b_offset+1]-255;      /* 2*(k*nsample+i)+1 */

                rot_cos=sif->sif_phase_shift_array[sip->sip_offset].re;
                rot_sin=sif->sif_phase_shift_array[sip->sip_offset].im;

                si += +rot_cos*ci-rot_sin*cq;
                sq += +rot_sin*ci+rot_cos*cq;
 
                sip->sip_offset = (sip->sip_offset+sip->sip_step)%sif->sif_phase_shift_length;
 
         }

        sif_out_buffer[0] = (si+255*PHASE_SHIFT_AMPLITUDE)/(2*PHASE_SHIFT_AMPLITUDE);
        sif_out_buffer[1] = (sq+255*PHASE_SHIFT_AMPLITUDE)/(2*PHASE_SHIFT_AMPLITUDE);
        sif_out_buffer += 2;
        [...]
  }

Itt a belso ciklusmag az erdekes, az `nnode` erteke a gyakoratban 8 lesz. A kerdes az az hogy vannak-e olyan SIMD utasitasok x86_64 alatt, amivel ez a ciklusmag jol kioptimalizalhato es/vagy a forditot ra tudjuk venni hogy hasznalja? Most nezem a objdump/disasm-ot, gcc-10.2.1 alatt, -O3-as optimalizacioval, es kb olyan mintha en irtam volna minimalis assembly rutinnal (oke, a LEA-s trukkok erdekesek). Ugy latom elsore hogy mar SSE2 alatt vannak pl 4x32 bites integer regiszterek, amikkel mar egy kis unroll felhasznalasaval eleg jol lehetne optimalizalni a fenti ciklust... de meg az is lehet hogy a ket ciklus felcserelesevel (nnode fut kivul, az nsamples pedig belul) megjobban kihasznalhatoak bizonyos SIMD/MAC utasitasok. 

Valamelyik internetekben azt olvastam hogy a forditok mar eleg okosak hogy felismerjek hogyha SIMD-del jol kioptimalizalhatoak az effele ciklusok, de ottan a peldak valos arithmetikara vannak kihegyezve. Itt meg integer aritmetika van.... opcionalisan annyi lehet a konnyites hogy a rot_cos, rot_sin ertekek valojaban i16-osak es a ci/cq ertekek pedig i8-asok, szoval akar valami PMADDWD is lehetne. 

Alapjaraton a fenti implementacio sem rossz a gyakorlatban, de hamar annyira nagy az arconporges az effele utasitaskeszletek irant, akkor kezdjuk el ertelmesen is hasznalni ;) 

[Ugy tunik megoldva] Valtozo elhelyezese abszolut cimre - GCC

Fórumok

Hali,

 

Szeretnek egy valtozot egy fix abszolut cimre tenni, a nehezites, hogy kizarolag a linker filebol, tehat a forrast (.c) nem akarom modositani (szoval pont a

int myvar __attribute__((section(".mySection")))

jellegu, a forrashoz hozzaadott dolgokat szertnem kikuszobolni).

Az architekture Cortex M4, de felteszem ez nagyjabol lenyegtelen.

A dolog hattererol: van egy (konstans) tomboket, stukturakat, ezek egymasbaagyazasat tartalmazo kod es a forras generalva van, kulso eszkozzel  - ezek a valtozok alapbol az applikacioba fordulnak (linkelodnek) bele, de ki kellene szervezni egy masik memoriacimre (egy file-ban van minden, amit az applikaciotol fuggetlenul kellene kezelni).

Az a resze mar megvan, hogy az egesz file egy megadott cimre kerul, viszont van egy "fo" valtozo (minden mas onnan indul). Viszont most az, hogy ez a valtozo hova kerul a szekcion belul, az a tobbi valtozo meretetol fugg (tehat kb. random). Ennek kellene fixhelyre kerulni, hogy az applikaco akkor is elerje, ha ez ezek a tombok, strukturak, etc. valtoznak.

Ezek a tombok, egyebek konstansok, szoval mindenkepp a flashbe kerulnek, csak ha nem specifikalom kulon, akkor egybe lesznek linkelve az alkalmazassal, nekem viszont egy kijelolt regioban kellene, hogy legyenek.

Nem tudom mennyire sikerult erthetoen fogalmaznom, ha kell, szivesen pontositok rajta.

Koszi

Vegulis csinaltam meg egy szekciot es a "fo" tombot attettem ebbe masik szekcioba, ahol csak az van, igy a cime fixalodott - meg nem probaltam ki, de eddig hasznalhatonak tunik.

Koszi mindenkinek az otleteket!

C String láma

Fórumok

Ritkán kell C-ben dolgoznom, leginkább mikrokontrollerek esetén, és akkor is zömében Arduino környezetben, ahol elég kényelmes String osztály érhető el.

Most azonban ESPIDF alapon kellene SVG-t generálnom, sok mérési adat megjelenítéséhez. Ehhez sok stringet kellene összefűznöm, és sprintf műveletekkel kitöltenem. Kerestem valami kényelmesebben kezelhető String osztályt, amit használhatnék, de nem találtam. Nekiállhatnék megírni, de olyan nehezen hiszem el, hogy ezt ne csinálták volna már meg ezren.

Tudtok valami kényelmesen használható C String osztályt, amit egyszerűen használhatnék? Fontos az append és az sprintf szerű formátumkezelés.

Pre- és post increment, decrement kifejezésekben

Fórumok

Nézzük az alábbi C kifejezést:

unsigned int *ptr;

if (ptr && *ptr && --*ptr == 0) timeout();

Egyfelől logikus, amit csinál. Megnézi, a pointer nem NULL-e, utána megvizsgálja, a ptr által mutatott unsigned int változó nagyobb-e nullánál, ha ez is igaz, csökkenti azt, majd megnézi, nullává vált-e. Ha igen, hívja a timeout() függvényt. Ha a ptr == NULL, vagy érvényes, de az általa mutatott változó nulla, akkor nem nyúl semmihez. Ha a ptr által mutatott érték nem nulla, csökkenti azt, de csak akkor hívja timeout() függvényt, ha elérte a nullát.

Ilyesmit szoktam írni, de egy pillanatra megrémültem. A -- precedenciája nagyobb, mint az && operátoré, így akár az is lehetne, hogy előbb minden vizsgálat nélkül csökkent, s csak utána értékeli ki az &&-ek által határolt tagokat. Bár, ha így lenne, szinte semmire sem lenne jó az, hogy amint a logikai kifejezésről tudható annak értéke, nem értékeli ki azt tovább, hanem kilép.

Gyakorlatiasan, az elvárt módon csinálja, de ha szigorúan nézem a precedenciát, akkor szerintem nem működne ez jól.