2015-02-02 8 views
1

Следующий фрагмент кода, который представляет собой двумерный массив, вызывает ошибку # 29, ожидающую выражения.ошибка # 29 ожидаемое выражение

typedef enum 
{ 
    BATTERY_POW = 0, 
    USB_POW = 1, 
    END_STATE = 2 
} BMTState_e; 

typedef enum //event enums 
{ 
    NO_EVENT = 0, 
    BOOT_EVENT =1, 
    //I/O events 
    POW_GOOD_LOW =2, 
    POW_GOOD_HIGH = 3, 
    VBUS_POW_LOW = 4, 
    VBUS_POW_HIGH =5 
}BMTEvent_e; 

Структура определяется как

typedef struct //state machine definition 
{ 
    void (*funcPtr)(); 
    BMTState_e nextState; 
}BMTAction_t; 
BMTState_e BMTGlobal_State ; //global state 

Функция определяется как

void BMTTest() 
{ 
//do nothing for time being 
} 
BMTAction_t action[END_STATE][END_EVENT]={ 
    [BATTERY_POW][NO_EVENT] = {BMTTest,BATTERY_POW} 
    [BATTERY_POW][BOOT_EVENT] = {BMTTest,BATTERY_POW}, 
    [BATTERY_POW][POW_GOOD_LOW] = {BMTTest,USB_POW}, 
    [BATTERY_POW][POW_GOOD_HIGH] = {BMTTest,BATTERY_POW} 
    [BATTERY_POW][VBUS_POW_LOW] = {BMTTest,BATTERY_POW}, 
    [BATTERY_POW][VBUS_POW_HIGH] = {BMTTest,USB_POW}, 
    [USB_POW][BOOT_EVENT] = {BMTTest,USB_POW_} 
    [USB_POW][BOOT_EVENT] = {BMTTest,USB_POW}, 
    [USB_POW][POW_GOOD_LOW] = {BMTTest,USB_POW}, 
    [USB_POW][POW_GOOD_HIGH] = {BMTTest,BATTERY_POW} 
    [USB_POW][VBUS_POW_LOW] = {BMTTest,BATTERY_POW}, 
    [USB_POW][VBUS_POW_HIGH] = {BMTTest,USB_POW} 
}; 

void BMT_HandleEvent(BMTEvent_e event) 
{ 
    BMTAction_t stAction; 


    if(event != NO_EVENT) 
    { 
     stAction.funcPtr = action[BMTGlobal_State][event].funcPtr; 
     stAction.nextState = action[BMTGlobal_State][event].nextState; 
     printf("current State =%d, event = %d, nextState = %d",BMTGlobal_State, event,stAction.nextState); 

     if(NULL!= stAction.funcPtr) 
     stAction.funcPtr(); 
     BMTGlobal_State = stAction.nextState; 
    } 

} 

int main() 
{ 
BMTEvent_e = BOOT_EVENT; 
if(retVal) 
    { 
    BMTGlobal_State = BATTERY_POW; 
    } 
else // PG is low so check VBUS signal 
    { 
retVal = GPIO_Read_Pin(USB_VBUS_PWR_PIN); 
if(retVal) 
     { 
     BMTGlobal_State = USB_POW; 
     } 
else 
     { 
     BMTGlobal_State = CRADLE_POW; 
     } 
    } 
event = BOOT_EVENT; 
while (1) 
    { 
    BMT_HandleEvent(event); 
    } 
} 

Идея выполнить государственную машину, основанную на событиях получил. 2D-массив отображает текущее состояние и все возможные события для состояния, как только событие будет получено, будет вызываться указатель на функцию, и состояние перейдет в следующее состояние.

Я использую MicroC/OS2 с компилятором/инструментами GreenHills. Буду признателен за ваш ответ.

Я последовал за рекомендацию Кит

BMTAction_t action[END_STATE][END_EVENT] = { 
        {{NULL,BATTERY_POW}}, //0 
        {{BMTProcess_BatteryPowBoot,BATTERY_POW}},// 1 
        {{BMTProcess_PowGoodLow,BATTERY_POW}},//2 
        {{BMTProcess_PowGoodHigh,BATTERY_POW}}, //3 
        {{BMTProcess_VBUSPowerLow,BATTERY_POW}}, //4 
        {{BMTProcess_VBUSPowerHigh,BATTERY_POW}},//5 
}; 

компилятор дает ошибку в строке

"{{BMTProcess_PowGoodHigh,BATTERY_POW}}, //3" 
"error # 146 too many initializer values" 
+0

попробуйте написать '(BMTAction_t)' перед '{BMTTest' –

+0

@MattMcNabb: Я не думаю, что это поможет. Это сделает его составным литералом, но это не обязательно для инициализатора. –

+1

Содержит ли компилятор Greenhills MicroC C99 назначенные инициализаторы? Сообщение об ошибке предполагает, что это не так. –

ответ

4

Это не правильный синтаксис для назначенного инициализаторе. Вы можете указывать только один индекс за раз.

Я был некорректным; несколько указателей : разрешено. На самом деле, ваш код компилируется без ошибок с помощью gcc -std=c99 -pedantic -Wall -Wextra после добавления нескольких объявлений.

typedef enum { BATTERY_POW, END_STATE } BMTState_e; 
typedef enum { BOOT_EVENT, POW_GOOD_LOW, POW_GOOD_HIGH, END_EVENT } BMTEvent_e; 

void BMTTest(void); 

typedef struct //state machine definition 
{ 
    void (*funcPtr)(); 
    BMTState_e nextState; 
}BMTAction_t; 

BMTAction_t action[END_STATE][END_EVENT]={ 
    [BATTERY_POW][BOOT_EVENT] = {BMTTest,BATTERY_POW}, 
    [BATTERY_POW][POW_GOOD_LOW] = {BMTTest,BATTERY_POW}, 
    [BATTERY_POW][POW_GOOD_HIGH] = {BMTTest,BATTERY_POW} 
}; 

Скорее всего, ваш компилятор не понимает назначенные инициализаторы. (Они были добавлены к языку по стандарту 1999 года, и даже сегодня не все их компиляторы поддерживают их.)

Если это не так, вам нужно удалить выражения в квадратных скобках (и убедитесь, что у вас есть элементы в правильный порядок). Возможно, что-то вроде:

BMTAction_t action0[END_STATE][END_EVENT] = { 
    {{ BMTTest, BATTERY_POW }}, 
    {{ BMTTest, BATTERY_POW }}, 
    {{ BMTTest, BATTERY_POW }} 
}; 
+0

Привет, Кен, спасибо за ответ, я обнаружил, что код скомпилирован после выполнения вашей инструкции, но как это происходит после конечного автомата при изменении события. – user1867459

+0

Hi Ken, код, скомпилированный после выполнения вашей инструкции с удалением скобочной части ([BATTERY_POW] [BOOT_EVENT]), но как это происходит после конечного автомата при изменении события. т. е. для всех трех событий в состоянии BATTERY_POW установлена ​​одна и та же функция «BMTest» и одно и то же конечное состояние «BATTERY_POW». Если это так, первая функция BMTest соответствует BOOT_EVENT в состоянии BATTERY_POW, а вторая функция BMTest соответствует состоянию BATTERY_POW и POW_GOOD_LOW и т. Д.? Так что я должен делать это для всех состояний и событий, связанных с состоянием? – user1867459

+0

@ user1867459: (Это Кейт, а не Кен). Я не уверен, что понимаю этот вопрос. Вам просто нужно переписать инициализацию, чтобы она присваивала одни и те же значения тем же элементам. –

0

Ответ Keith помог мне разобраться в правильной инициализации. Я должен был перечислять все возможные события и связанный указатель функции для данного состояния внутри {{}}.

Это походит на инициализацию элементов строки [0] [0] и ряд [0] [1] я должен был перечислить все элементы внутри верхнего уровня двойных фигурных скобок что-то вроде

{ **{{**values/function/events associated with row [0][0],{values/function/events associated with row [0][1] }}, 
//now do the same for row 1. 
**{{**values/function/events associated with row [1][0],{values/function/events associated with row [1][1] **}}** }; //end of the array 

BMTAction_t action[END_STATE][END_EVENT] = { 
       //STATE = BATTERY_POW 
        {{NULL,BATTERY_POW}, //0 
        {BMTProcess_BatteryPowBoot,BATTERY_POW},// 1 
        {BMTProcess_PowGoodLow,BATTERY_POW},//2 
        {BMTProcess_PowGoodHigh,BATTERY_POW}, //3 
        {BMTProcess_VBUSPowerLow,BATTERY_POW}, //4 
        {BMTProcess_VBUSPowerHigh,BATTERY_POW}},//5 
        //STATE = USB_POW 
        {{NULL,USB_POW}, //0 
        {BMTProcess_BatteryPowBoot,USB_POW},// 1 
        {BMTProcess_PowGoodLow,USB_POW},//2 
        {BMTProcess_PowGoodHigh,USB_POW}, //3 
        {BMTProcess_VBUSPowerLow,USB_POW}, //4 
        {BMTProcess_VBUSPowerHigh,USB_POW}}//5 
       }; 
0

инициализация, которую вы использовали, будет работать с компилятором greenhills, если вы используете опцию -c99.

я должен был сделать несколько незначительных изменений в коде, чтобы получить его скомпилировать:

  • Добавить END_EVENT перечисление
  • Добавьте некоторые запятые между пунктами в action декларации.
  • Исправлена ​​опечатка USB_POW_ в USB_POW

Вот измененный код:

#include <stdio.h> 
typedef enum { 
    BATTERY_POW = 0, 
    USB_POW = 1, 
    END_STATE = 2 
} BMTState_e; 

typedef enum { 
    NO_EVENT = 0, 
    BOOT_EVENT =1, 
    //I/O events 
    POW_GOOD_LOW =2, 
    POW_GOOD_HIGH = 3, 
    VBUS_POW_LOW = 4, 
    VBUS_POW_HIGH =5, 
    END_EVENT = 6 

} BMTEvent_e; 

typedef struct { 
    void (*funcPtr)(); 
    BMTState_e nextState; 
} BMTAction_t; 

void BMTTest() 
{ 
//do nothing for time being 
} 
BMTAction_t action[END_STATE][END_EVENT]={ 
[BATTERY_POW][NO_EVENT] = {BMTTest,BATTERY_POW}, 
[BATTERY_POW][BOOT_EVENT] = {BMTTest,BATTERY_POW}, 
[BATTERY_POW][POW_GOOD_LOW] = {BMTTest,USB_POW}, 
[BATTERY_POW][POW_GOOD_HIGH] = {BMTTest,BATTERY_POW}, 
[BATTERY_POW][VBUS_POW_LOW] = {BMTTest,BATTERY_POW}, 
[BATTERY_POW][VBUS_POW_HIGH] = {BMTTest,USB_POW}, 
[USB_POW][BOOT_EVENT] = {BMTTest,USB_POW}, 
[USB_POW][BOOT_EVENT] = {BMTTest,USB_POW}, 
[USB_POW][POW_GOOD_LOW] = {BMTTest,USB_POW}, 
[USB_POW][POW_GOOD_HIGH] = {BMTTest,BATTERY_POW}, 
[USB_POW][VBUS_POW_LOW] = {BMTTest,BATTERY_POW}, 
[USB_POW][VBUS_POW_HIGH] = {BMTTest,USB_POW} 
}; 
int main() 
{ 
    return 1; 
} 

Вот вывод компилятора без -c99:

$ ccppc test.c 
"test.c", line 30: error #29: expected an expression 
    [BATTERY_POW][NO_EVENT] = {BMTTest,BATTERY_POW}, 
^

"test.c", line 31: error #29: expected an expression 
    [BATTERY_POW][BOOT_EVENT] = {BMTTest,BATTERY_POW}, 
^

"test.c", line 32: error #29: expected an expression 
    [BATTERY_POW][POW_GOOD_LOW] = {BMTTest,USB_POW}, 
^

"test.c", line 33: error #29: expected an expression 
    [BATTERY_POW][POW_GOOD_HIGH] = {BMTTest,BATTERY_POW}, 
^

"test.c", line 34: error #29: expected an expression 
    [BATTERY_POW][VBUS_POW_LOW] = {BMTTest,BATTERY_POW}, 
^

"test.c", line 35: error #29: expected an expression 
    [BATTERY_POW][VBUS_POW_HIGH] = {BMTTest,USB_POW}, 
^

"test.c", line 36: error #29: expected an expression 
    [USB_POW][BOOT_EVENT] = {BMTTest,USB_POW}, 
^

"test.c", line 37: error #29: expected an expression 
    [USB_POW][BOOT_EVENT] = {BMTTest,USB_POW}, 
^

"test.c", line 38: error #29: expected an expression 
    [USB_POW][POW_GOOD_LOW] = {BMTTest,USB_POW}, 
^

"test.c", line 39: error #29: expected an expression 
    [USB_POW][POW_GOOD_HIGH] = {BMTTest,BATTERY_POW}, 
^

"test.c", line 40: error #29: expected an expression 
    [USB_POW][VBUS_POW_LOW] = {BMTTest,BATTERY_POW}, 
^

"test.c", line 41: error #29: expected an expression 
    [USB_POW][VBUS_POW_HIGH] = {BMTTest,USB_POW} 
^

И с -c99:

$ ccppc -c99 test.c 
0

Вы понимаете, что ваш код включает следующее:

[USB_POW][BOOT_EVENT] = {BMTTest,USB_POW_} 
    [USB_POW][BOOT_EVENT] = {BMTTest,USB_POW}, 

Даже я бы смущен этим. Возможно, вы имели в виду первый, кто будет NO_EVENT?