8 bit datentyp erzeugen wenn der kleinste datentyp automatisch 16 bit gross ist.
-
Hallo, bei dem TI DSP 320f2812 ist ein char Datentyp automatisch 16 bits
groß.Das Datenblatt schreibt hierzu:
By ANSI/ISO C definition, the sizeof operator yields the number of bytes
required
to store an object. ANSI/ISO further stipulates that when sizeof is
applied to char,
the result is 1. Since the TMS320C28x char is 16 bits (to make it
separately
addressable), a byte is also 16 bits. This yields results you may not
expect; for
example, size of (int) = = 1 (not 2). TMS320C28x bytes and words are
equivalent
(16 bits).Jetzt möchte ich aber ASCII Zeichen über die Serielle Schnittstelle
einlesen und zwischenspeichern. Um Speicherplatz zu sparen wäre es
praktisch ich könnte mir ein Datentyp erzeugen der wirklich nur 8 Bit
groß ist.
Ich habe hierbei an eine Lösung über Bitfelder gedacht wie.Struct test { Unsigned datentyp8a :8 Unsigned datentyp8b :8 }structur;
Jetzt schaffe ich es nur nicht mit typedef ein 8 bit datentyp erzeugen. Also aus den 8 einzelnen bits vom Bitfeld.
Bin ich nur zu doof dafür oder gibts da keine möglichkeit?
Wäre echt klasse falls jemand eine idee oder vorschlag hat wie ich das machen kann...
gruss Tobe
-
Du brauchst nicht unbeding einen 8-bittigen Datentyp:
unsigned char read_lower_byte( const unsigned char * const source ) { return *source & 0x00ff; } unsgined char read_upper_byte( const unsigned char * const source ) { return *source >> 8; } void write_lower_byte( unsigned char * const dest, unsigned char value ) { *dest = ( *dest & 0xff00 ) | ( value & 0x00ff ); } unsigned char write_upper_byte( unsigned char * const dest, unsigned char value ) { return ( *dest = ( *dest & 0x00ff ) | ( value << 8 ) ); }
greetz, Swordfish
-
@Swordfish: diese Funktionalität hat er schon durch sein Bitfield.
@tobe1980: mit Compilermitteln geht das nicht (genausowenig wie etwa ein 4bittiger Datentyp auf einem x86). Wie stellst du dir z.B. die Adressierung vor? Die Adresse müsste der Compiler dann einen Bit länger machen (weil er dann zusätzlich das Halbbyte adressieren müsste) und sie bei deinen Datentypen besonders behandeln. Sowas wird er nicht können.
-
tobe1980 schrieb:
Jetzt möchte ich aber ASCII Zeichen über die Serielle Schnittstelle
einlesen und zwischenspeichern. Um Speicherplatz zu sparen wäre es
praktisch ich könnte mir ein Datentyp erzeugen der wirklich nur 8 Bit
groß ist.mit einem bitfield, das nur einen 8-bit member hat, kannst dann zwar nur 8 bits nutzen, aber es wird wohl trotzdem 16 bits verbraten. wahrscheinlich ist dein RAM auch 16-bittig organisiert, so dass kürzere zugriffe gar nicht erst möglich sind. musste wohl alles zusammenshiften und dazuodern.
-
Superlexx schrieb:
@Swordfish: diese Funktionalität hat er schon durch sein Bitfield.
Ah, da hab' ich die Hälfte überlesen.
greetz, Swordfish
-
mit einem bitfield, das nur einen 8-bit member hat, kannst dann zwar nur 8 bits nutzen, aber es wird wohl trotzdem 16 bits verbraten. wahrscheinlich ist dein RAM auch 16-bittig organisiert, so dass kürzere zugriffe gar nicht erst möglich sind. musste wohl alles zusammenshiften und dazuodern.
Genau so habe ich auch gedacht...
Das heisst wenn ich kein Speicher verbraten will muss ich einfach 2 ascii zeichen in ein 16 bit speicher verbraten. Da jedes ascii Zeichen ja genau 8 bit benötigt. Dann ist es eben wesentlich komplizierter so z.b. 200 ascii zeichen zu speichern.wie wenn es einen schönen 8 bit datentyp geben würde. Aber das geht ja wohl nicht.
Ich danke aber euch allen für die schnelle Hilfe.
Gruß tobe
-
naja, das ist ja nicht so schlimm. in 50% aller fälle verschwendest du ein octett (8bits), wenn du eine ungerade anzahl an zeichen in einen char-buffer einliesst.
btw, such' mal in der doku des compilers, ob es nicht doch einen 8-bit datentyp gibt (z.b. int8_t aus stdint.h). eventuell nach einem anderen (c99 kompatiblen) compiler unschauen, der das kann.
btw#2: bei so einem controller/compiler wirst du dich übrigens wundern wie viele, angeblich standard-kompatible codes, nicht mehr funzen, weil sie davon ausgehen, dass 'char' 8 bits hat.
-
speicherspar-freak schrieb:
btw, such' mal in der doku des compilers, ob es nicht doch einen 8-bit datentyp gibt (z.b. int8_t aus stdint.h). eventuell nach einem anderen (c99 kompatiblen) compiler unschauen, der das kann.
Die Hoffnung würde ich mir nicht machen. Eben wegen solcher Hardware sind die "exact width integer types" wie int8_t in C99 auch optional.
-
Tim schrieb:
Die Hoffnung würde ich mir nicht machen. Eben wegen solcher Hardware sind die "exact width integer types" wie int8_t in C99 auch optional.
naja, wenn ich 'nen compiler für so'ne CPU basteln würde, dann würde ich meinen kunden einen 8-bit datentyp anbieten und ihn als typedef in <stdint.h> eintragen. dessen benutztung wäre zwar langsam, weil ja oft code zum shiften und maskieren eingefügt werden muss, aber dafür könnte man frickelfrei quelltexte portieren, die 'nen 8-bit datentyp brauchen.
-
8bit-freak schrieb:
aber dafür könnte man frickelfrei quelltexte portieren, die 'nen 8-bit datentyp brauchen.
Was machst dann z.B. damit?
int main(void) { uint8_t array[4]; for ( size_t i=0; i<sizeof(array)/sizeof(*array); i++ ) { // mache was mit array } }
Oder willst du das ganze so umbiegen, dass CHAR_BIT wieder 8 ergibt?
-
Tim schrieb:
Oder willst du das ganze so umbiegen, dass CHAR_BIT wieder 8 ergibt?
wahrscheinlich ja. ich würde den compiler so machen, dass man sich aussuchen kann, ob man 8 oder 16 bittige 'chars' verwenden will. als globale einstellung die dann noch pro-funktion mit #pragma änderbar wäre.
// globales setting ist 16-bit chars ... #pragma charbits=8 // in dieser funktion sind chars 8-bittig void mach_was (void) { uint8_t array[4]; for ( size_t i=0; i<sizeof(array)/sizeof(*array); i++ ) { // mache was mit array } } ... // nächste funktion würde wieder mit 16-bit chars arbeiten ... void mach_was_anderes (void) { uint8_t a; // <--- compilerfehler 'not allowed in native mode' ... }
...oder so ähnlich
-
tobe1980 schrieb:
Jetzt schaffe ich es nur nicht mit typedef ein 8 bit datentyp erzeugen. Also aus den 8 einzelnen bits vom Bitfeld.
gruss TobeGeht leider nicht direkt, vielleicht kann man auf Macroebene was zusammenschnitzen.
Aber soweit ich weiß, muß sich ein Bitfield nur wie ein Bitfield verhalten, nicht als Zugriff auf Bits implementiert sein. Mitstruct bytes { char byte0:8; char byte1:8; };
kann es sogar sein, daß der Compiler zweimal zwei Bytes belegt, also nix gespart, sondern genauso mit schwierigerem Zugang verbraten. Also leg' doch einfach mal so eine struct an und überprüf' das mit sizeof(), erst dann würde ich mir überlegen, ob's das wert ist, ggf. schwer portablen Frickelcode zu basteln.