在不同级别使用不同的枚举类型

时间:2017-07-23 11:11:45

标签: c gcc enumerated-types

虽然枚举是整数常量,但我在使用/组织方面存在问题。 我已将串行数据接收分为三个级别。最低级别0是一个中断服务程序,上面我在级别1及以上有一个名为receiveData()的函数,我在level2中写了processReceivedFrame()。我有两个枚举类型,一个用于级别0和级别1,另一个用于级别2.类似地,一个用于传输的枚举类型。

   enum FRAME_RECEIVE_STATUS
    {
        FR_STS_FRAME_NOT_RECEIVED=0,            // Initial state by default
        FRAME_RECEIVED,                 // Indicates that frame is received by interrupt vector

        FIRST_START_BYTE_RECVD,        // Set as soon as first start byte is received in case of multiple start bytes
        RECV_PROGRESS,                 //Indicates that the receiving is in progress
        INVALID_DATA_LENGTH,        // This status is updated if length byte is invalid. We are verifying only against minimum possible length.
        RX_BUFFER_FULL,             // ISR will update this status in case buffer is full
        INVALID_START_BYTE,         // This will be set when first start byte is received, but second byte is incorrect.
        FIRST_END_BYTE_RECEIVED,    // Set as soon as first end byte is received.
       };

    enum FRAME_PROCESS_STATUS
    {
        FRAME_VALID=100,
        FP_STS_FRAME_NOT_RECEIVED,
        CHECKSUM_SUCCESS,               //
        CHECKSUM_ERROR,
    };
enum TRANSMIT_STATES
{
    FRAME_SEND_SUCCESS=0,
    FRAME_SEND_RESPONSE_TIMEOUT,
    FRAME_SEND_RESP_WAITING,
    INVALID_RESPONSE_BYTE,
    EXCEEDED_MAX_ATTEMPTS,
    TRANSMIT_BUFFER_FULL,
};

但是现在我觉得如果我选择不同的枚举类型会有困难。特别是在level1中,我最终会根据一定的条件返回二级枚举类型。如果使用不同的类型,我会在某些地方收到警告。

通常,使用枚举类型进行错误处理的最佳方法是什么?可以是相关功能的单个枚举类型,例如一个用于接收(RECEIVE_STATES),一个用于传输(TRANSMIT_STATES)?但即使在这种情况下,我们最终可能会混合不同类型。例如,假设我正在传输一些数据然后等待响应。响应可以是enum RECEIVE_STATES类型的RECEIVE_BUFFER_FULL。如果函数返回类型是枚举TRANSMIT_STATES,但在过程中得到RECEIVE_STATES的枚举,我们可能会再次遇到问题并通过替换适当类型的枚举元素来处理代码。例如: -

enum TRANSMIT_STATES sendDataByte(char );     // Forward declaration.
enum RECEIVE_STATES receiveData(char *);  // Forward declaration.
enum TRANSMIT_STATES transmitData(char *data)
{
     for(.....)
     {
     enum TRANSMIT_STATES t_Status = sendDataByte(*(data+i));   // Transmit the data
      if(t_Status==TRANSMIT_BUFFER_FULL)
       return(t_Status);
     }
     // Wait for the response
     enum RECEIVE_STATES r_Status = receiveData(data);
     // Alternatively, t_Status = receiveData(data);
     if(rStatus==RX_BUFFER_FULL)
     t_Status=RX_BUFFER_FULL;  // Assigning different type
     return(t_Status);
}

在上面的代码中,如果我选择: -

t_Status = receiveData(); 

我有分配不同类型的问题。即使在以下情况下: -

r_Status = receiveData(data);

我必须检查状态并从TRANSMIT_STATES返回适当的代码。我不能在两种不同的类型中使用相同的枚举元素。所以用不同的名字维护也是一个问题。 那么在这种情况下,建议为所有类型的错误组合一个枚举?但是如果我们使用一些标准库用于较低级别,那些库可能使用不同类型的枚举或普通int值。在这里我也不确定推荐的做法是什么。

1 个答案:

答案 0 :(得分:3)

最简单的方法是将所有枚举合并为一个。稍微复杂一点的方法是使用“tagged union”aka变体:

enum ERROR_TYPE {
    SUCCESS = 0,
    TRANSMIT,
    RECEIVE
};
struct result_t {
    enum ERROR_TYPE err; // 0 means no error, i.e. success
    union {
        enum TRANSMIT_STATES err_send; // err 1
        enum RECEIVE_STATES err_recv; // err 2
    };
};

然后您的代码如下所示:

struct result_t transmitData(char *data)
{
    struct result_t result = {SUCCESS};
    for(...)
    {
        result.err_send = sendDataByte(*(data+i));   // Transmit the data
        if(result.err_send==TRANSMIT_BUFFER_FULL) {
            result.err = TRANSMIT;
            return(result);
        }
    }
    // Wait for the response
    result.err_recv = receiveData(data);
    if(result.err_recv==RX_BUFFER_FULL) {
        result.err = RECEIVE;
    }
    return(result);
}