Přetypování ukazatele na strukturu? – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Přetypování ukazatele na strukturu? – C / C++ – Fórum – Programujte.comPřetypování ukazatele na strukturu? – C / C++ – Fórum – Programujte.com

 

Maly10
Duch
10. 2. 2023   #1
-
0
-

Mějme strukturu reg, která  obsahuje 5 prvků typu unsigned char a jeden prvek signed short.

Tdy vlastně se na ni jde koukat jako na 7 bytů.

Ja bych potřeboval v nějakém cyklu těchto 7 bytů byt po  bytu nějak zpracovat,

Teoreticky reg je ukazatel na strukturu tak by měl jít přetypovat na ukrazatel na uchar a takto by mělo jít projít všechny byty v struktuře.

Otázkou je jak to udělat správně , jak zajistit, aby překladač ukladat členy struktury za sebe atd,

Poradíte?

Nahlásit jako SPAM
IP: 2602:fc24:11:dbe8::1...–
10. 2. 2023   #2
-
0
-

Jestli je to 7 Bytů záleží na zarovnávání. To je závislé na platformě.

Ukazatel jde přetypovat nebo použít union, ve kterém bude struktura a pole bytů. Pořád je to závislé na platformě, u vícebytových proměnných bude Byty číst v pořadí závislém na endianitě, v případě jednobytové proměnné se může vlivem zarovnávání vyskytnout prázdný Byt.

Raději bych si napsal funkci, která bude číst strukturu a zapisovat jednotlivé Byty do pole. V takovém případě bude pořadí položek a jejich Bytů v poli dáno tím, co naprogramuješ. Odpadnou potíže s endianitou a prázdnými Byty vlivem zarovnávání.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Maly10
Duch
10. 2. 2023   #3
-
0
-

#2 hlucheucho
Použitím takové funkce to celé ztrácí poezii. Pro upřesnění řeším to pro ARM MCU s tím, že jednotlivé byty jsou odesílany na HW sběrnici bud procesorem nebo klidně pomocí DMA.

Ano muzu misto struktury pouzit pole bytu, ale jednak budu muset short rozsekat do dvou bytů pole a především to poněkud znepřelednuje program. Ve struktuře se jednotlivé proměné mohou jmenovat stejně jako registry externího hw v kterém  daný byt skončí, kdežto u pole  se to nedá poznat, respektive musel bych použit něco jako #define REG_CR0 pole[3];

Struktura je elegantnější , existuji direktivy jako #pragma packt u MS překladače, respektive __attribute__((packed)) u GNU ale nejsem si uplně jist zda zajistí vždy to co potřebuji.

Nahlásit jako SPAM
IP: 2620:18c:0:192::214...–
10. 2. 2023   #4
-
0
-

Tím spíš bych si dal pozor na endianitu a zarovnávání. Bylo to myšleno takto:

1. alokuji buffer (pole Bytů)
2. naplním ho obsahem struktury (pomocí funkce)
3. s polem pak dělám, co potřebuji (předám DMA controléru)
4. nakonec pole uvolním

Body 2 a 3. vlastně řeší synchronizaci.

Při odesílání samotné struktury pomocí DMA bys narazil na problémy:
1. endianita: u vícebytových proměnných  mohou být Byty v paměti uloženy v různém pořadí. To nemusí souhlasit s pořadím ve kterém je přijímá hardware.
2. zarovnávání: 1-Bytová proměnná může být doplněna prázdným Bytem. Tady musíš vyřešit odeslání jen datového Byte
3. synchronizace: práce DMA je asynchronní, po dobu vysílání by ke struktuře nebyl přístup. Kopírování dat (a jejich převod na pole) budou blokovat přístup ke struktuře podstatně kratší dobu.

Navíc pak máš možnost požadavky na vysílání skládat do fronty.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
JerryM0
Věrný člen
10. 2. 2023   #5
-
0
-

vubec nechapame co chceš ... to je zas nějakem školní maglajs ... přetypovat ukazatel na strukturu na uchar je samozřejmě nesmysl sám o sobě :) ukazatel ukazuje na nějakou konkrétní část paměťi a v případě ARM procesoru to bude 32bitová nebo 64bitová  paměťová adresa a protože 32 bit ARM procesory nižší řady mají zvlášť segment a offset jako 8086ka tak se asi něco posere :)

k prvkům pole se normálně přistupuje přes těčkovou notaci takže takhle

https://www.programiz.com/cpp-programming/structure-pointer

a celý tečkový výraz se pak dá přetypovat na .. třeba unsigned char. Samozřejmě mužeš použít i operátor -> pro přístup k prvkům pole máísto tečkový notace.

Nahlásit jako SPAM
IP: 2a00:1028:83bc:e52a:8922:37eb:11c8:b1b3...–
10. 2. 2023   #6
-
0
-

#5 JerryM
on chce odeslat obsah struktury po sběrnici (SPI, IIC ...) nějakému hardware. Komunikace po sběrnici je "Byte oriented". Líbí se mu, že struktura "esteticky" napodobuje organizaci registrů. Chce přetypovat ukazatel aby se ze struktury stala sekvence Bytů (což se pravděpodobně stane). Jenže přináší to řadu úskalí spojených s uspořádáním struktury v paměti.

Jednou větou: Jak serializovat strukturu abych ji mohl poslat nějaké periferii a bylo to pro periferii "stravitelné"?

hu

Nahlásit jako SPAM
IP: 195.178.67.–
10. 2. 2023   #7
-
0
-

#4 hlucheucho
Dá se to vylepšit pomocí OOP. Na místo struktury použít třídu. Atributy stejně jako ve struktuře a metoda, která vrátí data v "odesílatelné" podobě.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
10. 2. 2023   #8
-
0
-

Co se týče "poezie": párkrát jsem měl chuť takovému "básníku" dát tečku doprostřed ciferníku (ne proti covidu), když jsem zjistil, že jeho kód mi nefunguje jen proto, že si libuje v implementačně závislých věcech a on měl překladač s big endian a já měl překladač s litle endian.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
JerryM0
Věrný člen
10. 2. 2023   #9
-
-1
-
Mimo téma

ano ano život je krutý :)

přiznám se, že nechápu co na toom řeší, jestli se na sběrnici posílají data po 1 bytu tak prostě at tam napíše

(unsigned char)reg.R1;

(unsigned char)reg.R2;

...

...

(unsigned char)reg.R7;

Nahlásit jako SPAM
IP: 2a00:1028:83bc:e52a:8922:37eb:11c8:b1b3...–
10. 2. 2023   #10
-
0
-

#9 JerryM
takhle to vypadá, že jsi nikdy:
1. nevysílal po sběrnici vícebytovou proměnnou jako např. unsigned int o velikosti 16 bitů
2. neobsluhoval přerušení
3. nepoužíval DMA

hu

Nahlásit jako SPAM
IP: 195.178.67.–
10. 2. 2023   #11
-
0
-

   

uint8_t communication_reg;
uint8_t destiny_reg;

uint8_t send_buffer[3];

void FillSendBuffer(uint8_t* buffer){
buffer[0] = communication_reg;
buffer[1] = destiny_reg >> 8;
buffer[2] = destiny_reg & 0x00FF;
}

//function use
FillSendBuffer(send_buffer)

Nakonec odvysílat obsah send_buffer. Takto se dá udělat např. komunikace po SPI  s AD7792

hu

Nahlásit jako SPAM
IP: 195.178.67.–
JerryM0
Věrný člen
10. 2. 2023   #12
-
-1
-
Mimo téma

#11 hlucheucho
pokud je ta sběrnice 16ti bitová tak se asi bude muset udělat aj ty proměnný ve struktuře REG 16ti bitový .. to je logický ... však on tam nepíše jakou šířku má ta sběrnice

Nahlásit jako SPAM
IP: 2a00:1028:83bc:e52a:8922:37eb:11c8:b1b3...–
10. 2. 2023   #13
-
0
-

#12 JerryM
sběrnice je obvykle "Byte oriented", vysílá se tedy po Bytech.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
JerryM0
Věrný člen
10. 2. 2023   #14
-
0
-

když se vysílá po bytech tak nechápu o co mu de ???? další dotaz co sem nepochopil :) :) :) :) :) :) :) :) :) :)

Nahlásit jako SPAM
IP: 2a00:1028:83bc:e52a:8922:37eb:11c8:b1b3...–
Staon0
Návštěvník
27. 6. 2023   #15
-
0
-

Z tohoto fóra se už opravdu stala žumpa. Někdo napíše nějaký dotaz, a jediné odpovědi, které dostane, jsou "seš úplně blbý, když něco takového děláš."

Přetypování struktury na binární reprezentaci je něco, co se samozřejmě v C/C++ často dělá, typicky v ovladačích nebo jako hlavičky souborů či paketů. Není to ovšem úplně přímočaré, je potřeba splnit 4 podmínky:

  1. struktura musí mít definovanou paměťovou podobu. V C++ se tomu dříve říkalo POD (Plain Old Data), od C++11 je to komplikovanější. V principu to znamená, že struktura obsahuje pouze základní typy nebo jiné POD struktury (pravidla jsou složitější, ale takhle by to mělo stačit). Potom je struktura skutečně v paměti organizovaná položku za položkou a překladač si tam nemůže přidat žadný další balast.
  2. Položky musí mít definovanou velikost. C/C++ nezaručuje jak je velký int či další standardní typy, proto je potřeba používat standardní typy uint_8, uint_16 atd.
  3. Vypnout zarovnávání položek struktury, které způsobuje, že překladač kolem menších položek vkládá prázdné místo. Na to má každý překladač jinou pragmu, kterou je potřeba si najít. A je silně vhodné pragmu obalit #ifdefem, který překladač detekuje a do else větve přidat #error, který varuje na kód závislý na platformě.
  4. A popasovat se s endianitou. Lze použít klasická síťová makra ntoh a hton. Anebo lepší, podle mne, je Boost.Endian knihovna.

Pokud tyto podmínky jsou splněné, pak přetypování už je hračka:

MojeHlavicka header;
const uint_8* buffer = reinterpret_cast<uint_8*>(&header);

Vzhledem k tomu, jak je tohle řešení křehké, tak ideální C++ řešení je si naprogramovat nějaké streamy (tzn. objekty, které budou mít něco jako writeInt, writeByte atd.), které budou binární podobu vytvářet/číst. Ale uvnitř nich stejně nakonec budeš potřebovat řešit alespoň endianitu.

Rozhodně ale nikdy nemíchej objekt a binární reprezentaci, jak tu někdo napovídal - porušíš první podmínku a můžeš se se zlou potázat.

Nahlásit jako SPAM
IP: 94.113.119.–
Jerry
~ Anonymní uživatel
512 příspěvků
27. 6. 2023   #16
-
0
-

z fora se nestala žumpa, zkus si počkat co ti odpoví tazatel :) 

Nahlásit jako SPAM
IP: 195.250.132.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 13 hostů

Podobná vlákna

Ukazatele — založil Šimon

Ukazatele — založil IBTR

Ukazatele v C? — založil Zakruta

C++ Ukazatele — založil pointer

C# ukazatelé — založil Kubas129

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý