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,