Re: Problém s C kompilátorem nebo mezi klávesnicí a židlí?

Milan B. milan na bastl.sk
Neděle Červenec 7 20:34:52 CEST 2019


ioctl FIONREAD ocakava aku velkost premennej pre vratenu hodnotu?

Ak - tak ako byva zvykom - 32 bitov (a premenna ktora sa mu podstrkuje 
je 16-bitova), tak potom ioctl zrejme prepisuje aj to co je za nou/nad 
nou v zasobniku...

Skuste zmenit bytes_avail na 32 bitovu premennu, co to spravi.

-m-


On 07.07.2019 19:57, Jakub Ladman wrote:
> Ahoj
>
> Moc často sem dotazy nekladu, ale teď si oravdu nevím rady a jsou tu 
> odborníci, z nichž někteří znají normu téměř z paměti :-)
>
> Mějme funkci, která předává příkazy hardwaru přes sériový port a za 
> odměnu od něj dostane 1-256 bytů dat.
>
> Nadřazený kus sw ale požaduje 0-65535 bytů (ano jeden chybí, ale to 
> není část aktuálního problému)
>
> Problém je proměnná "biboch", která se jmenuje tak blbě jen proto, že 
> už jsem měl podezření, že původní název "actual_len" s něčím koliduje. 
> Ovšem asi ne, ani prohledání celého kódu neodhalí žádnou takovou 
> proměnnou a už vůbec ne globální.
>
> Proměnná může nabývat jen zmíněných 1-256
>
> Ale její obsah nepřežije vstup do while smyčky.
>
> Uvnitř proměnná existuje, ale její obsah je vynulován.
>
> Absolutně nechápu co je to za ptákovinu.
>
> Když si to v debuggeru krokuju a tu původní hodnotu si ručně obnovím, 
> tak to funguje jak má.
>
> Díky za tip.
>
>
> Jakub Ladman
>
> static uint8_t membuf[0xffff];    //whole 64kB memory image
> static uint8_t page = 0;
> uint8_t *doMemRead(uint16_t addr, uint16_t length)
> {
>     uint8_t data[4];
>     uint8_t *output = membuf+addr;
>     uint16_t biboch;
>     uint16_t bytes_avail;
>     uint8_t *temp;
>     uint8_t len;
>
>     while(length > 0)
>     {    // set address
>         data[0] = (addr >> 8) & 0xff;
>         data[1] = addr & 0xff;
>         data[2] = page;
>
>         if(length/0x100)
>             biboch = 0x100;
>         else
>             biboch = length%0x100;
>
>         data[3] = (biboch & 0xff);
>
>         if(ADR != send_hw_command(ADR, data, 4))
>             return NULL;
>         // read the data
>         if(RDM != send_hw_command(RDM, data, 1)) // data byte is 
> necessary but unread by hw
>             return NULL;
>
>         usleep(1000);
>
>         printf("actual len %d\n", biboch);
>         ioctl(sfd, FIONREAD, &bytes_avail);
>
>         while(bytes_avail && !global_server_quit)
>         {
>             printf("actual len %d\n", biboch);
>             if(bytes_avail>=(biboch+4))
>             {
>                 if((biboch+4)==read(sfd,inbuf,(biboch+4)))
>                 {
>                     if(biboch == 
> packet_decode(&len,&temp,inbuf,(biboch+4)))
>                     {
>                         memcpy(membuf+addr,temp,biboch);
>                         length -= biboch;
>                         addr   += biboch;
>                     }
>                     else return NULL;
>                 }
>             }
>             ioctl(sfd, FIONREAD, &bytes_avail);
>         }
>     }
>     return output;
> }
>
>
> Target: x86_64-linux-gnu
>
> gcc version 8.3.0 (Ubuntu 8.3.0-6ubuntu1)
>
> defaultně -std=gnu18, ale zkoušel jsem i 17 a 99
>
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list




Další informace o konferenci Hw-list