Forum : ST7/STM8
Post Information | Post |
---|---|
April 18, 2012 - 2:34pm
|
Hello Forum: I have come across something unexpected when working with enumerated values with the Raisonance compiler. Long story short, I was wondering if there was a way to tell the compiler to treat enumerations as unsigned rather than signed values? I had expected using the ET(CHAR) and UNSIGNEDCHAR directives together would have this effect, but it does not. The code snippet below shows the issue I have been seeing. This code is in a packet handler in a link that has fixed packet type priorities. When my current state is idle and I receive a command packet (and I expect 0x80 to be greater than 0x01), I do not do any processing on the packet. typedef enum { IdleEvent = 0x01, AcknowledgementEvent = 0x40, CommandEvent = 0x80, MaxEventType = 0x81 } EventType; typedef struct { EventType LinkState; /* ... */ } LinkEventParameters; typedef struct { EventType PacketType; uint8_t* PacketBuffer; /* ... */ } ReceivedPacketInfo; static LinkEventParameters DataLinkEventParams; static void doPacketProcessing(const ReceivedPacketInfo * const packetInfo) { if (DataLinkEventParams.LinkState < packetInfo->PacketType) { /* Do work */ } else if (DataLinkEventParams.LinkState == packetInfo->PacketType) { /* Do different work */ } /* else, do no work */ } Here is the assembly generated by the compiler: ; FUNCTION ?doPacketProcessing?MY_MODULE?S (BEGIN) ; Register XW is assigned to parameter packetInfo 0000 88 PUSH A 0001 B600 F LD A,DataLinkEventParams 0003 F1 CP A,(X) 0004 2E03 JRSGE ?ELSE_0036 ; Doing a signed compare! ; SOURCE LINE # 609 ; Do Work 0009 ?ELSE_0036: ; SOURCE LINE # 611 0009 B600 F LD A,DataLinkEventParams 000B F1 CP A,(X) 000C 265E JRNE ?NXT_0039 ;... Note that I have been able to workaround this problem by casting EventType to a uint8_t before doing the compare, but I would rather not have to do this. Any help would be appreciated. |
Hi,
There are several ways to answer your question:
- The C standard mandates that enumerations are integers. So no, you cannot have unsigned values.
- Our compiler can reduce the enumeration type size to a char, which is a Raisonance extension to the C standard (as we are on a 8-bit architecture). This is what you played with with the ET(CHAR) directive. If you use ET(INT), your code should be OK, as the enumerations will then be handled as 16-bit signed integers.
However, the main answer I would give would be more like a coding advice. We are on very limited systems (STM8) and you have to adapt you C programming style for these deeply embedded architectures. For this reason, you should use enumerations only for identifiers that have interchangeable values.
What I mean is that enumerations should be used as placeholders only, NOT TO HOLD ACTUAL VALUES.
This is because enumerations load the compiler with a lot of extra burden; using macros will let the compiler optimize in a much nicer way.
In your case, the best compiler code will be generated by something like:
Lots of users are rewriting the ST firmware libraries this way, as it provides much better code performance.
Best Regards,