[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: openssl und kein Ende



On 09/24/2016 11:59 AM, Sascha Reißner wrote:
> Am Samstag, den 24.09.2016, 10:09 +0200 schrieb Uwe Kleine-König:
> …
>> Ich kenne mich mit dem openssl-Krams auch nicht so aus, aber ich bin
>> neulich einem anderen Problem begegnet, das durchaus komplexer ist, als
>> ursprünglich vermutet. Wenn Du Dich daran versuchen willst:
>>
>> Es geht darum ein Rechteck-Signal mit x HZ abzutasten. Die
>> Abtasthardware hat eine Eingangsclock von y Hz und einen Divider um eine
>> Frequenz einzustellen, mit der man möglichst gut das gegebene Signal
>> abtasten kann. Dieser Divider wird über zwei Bitfelder eingestellt: A
>> ist 16 Bit breit und B ist 3 Bit breit.
>> Die Frequenz, die die Hardware verwendet ist:
>>
>> 	y / (16 * (A + B / 8))
>>
>> . Aufgabe ist, ein C-Programm ohne Gleitkomma-Arithmetik zu schreiben,
>> das für gegebenes x und y die idealen A und B ermittelt.
>>
>> Wenn Du (oder auch wer anders) einen Lösungsvorschlag hast: schickt ihn
>> gerne an die Liste, ich suche dann Fehler :-)
>> Selbst, wenn Du es auf Anhieb richtig hinbekommst, stelle ich mir vor,
>> dass Du nachher verstehst, wie solche Fehler zustande kommen.
> 
> Wenn wir nur A betrachten, wird es mit 16 multipliziert.
> B wird zuerst mit 8 dividiert und dann mit 16 multipliziert.
> Ergibt das selbe wie gleich mit 2 mutiplizieren.
> So betrachtet ist der Teiler 20 Bit breit wobei nur gerade Zahlen
> zulässig sind.
> 
>     Teiler = (A << 4) + (B << 1)
> 
> Ergibt: AAAA AAAA AAAA AAAA BBB0
>               16 Bit       | 3 Bit + 1 Füllbit
> 
> 
> C-Code:
>     uint32_t divisor = ((A << 4) | ((B << 1) & 0x0f) & 0x000fffff);
> 
> Ich vermute dieses Beispiel basiert auf einen Microcontroller der nur 16
> Bit breit arbeiten kann. Das bedeutet, du berechnest den Teiler und
> musst deisen dann als 16 Bit und 8 Bit zurück schreiben.
> Nach dem berechnen des Teilers bekommst du die 2 Teile mit:
> 
>     if (divisor & 0x000fffff) {
>         fprintf(stderr, "divisor too big!\n");
>         return 1;
>     }
>     A = ((divisor >> 4) & 0xffff);
>     B = ((divisor >> 1) & 0x07);
> 
> Nun kannst du A und B in die zugehörigen Register schreiben.

Und die verbleibende Preisfrage ist nun noch: Wie berechnet man divisor,
wenn x und y gegeben sind?

Liebe Grüße
Uwe

Attachment: signature.asc
Description: OpenPGP digital signature


Reply to: