2015-08-11 2 views
-1

Я пытался печатать переменные через UART с помощью следующего кода в C.Доступа к глобальным переменному дает значение нежелательной

Процессор - Intel 80486

Compiler - компилятор IC (от Intel, выпущенный в 1990 году)

uint32_t unGlobal = 0xABCDEF90; 

void main (void) 
{ 
    uint32_t unLocal = 0x12345678; 

    UartWrite (unLocal); 
    UartWrite (unGlobal); 
} 

UartWrite() - это драйвер последовательного порта. Аргумент UartWrite 32 бит, и внутри он печатает каждый символ.

Здесь локальная переменная напечатана правильно, но глобальная глобальная переменная дает значения нежелательной почты! Что может быть причиной не получения значения глобальной переменной. Может кто-нибудь мне помочь?

+0

Вы попробовали другие ценные бумаги? Если вы переключите значения глобальной и локальной переменных, измените ли они поведение? – mch

+0

Что происходит, если вы меняете строки записи и сначала печатаете глобальные? Whart происходит, если вы перебираете значения так, чтобы глобальное значение 0x12345678? –

+0

Давай - сделаем некоторые отладки. Попробуйте что-нибудь, посмотрите, что произойдет, вместо того, чтобы бесцельно выставить две строки в SO: (( –

ответ

0

Проблема была в статической инициализации. Поскольку повторная инициализация глобальной переменной во время выполнения дает правильное значение. Спасибо ryyker, @Lundin и все

1

Аргумент type в прототипе для UartWrite не может быть достаточного размера, чтобы содержать значение для вашего глобального. У меня нет прототипа, но для similar функции (разные библиотеки, без сомнения), тип аргумента char. Если в вашем прототипе также есть char, то, скорее всего, источником вашей проблемы станет передача значения unsigned int.

Ниже показан сценарий, в котором функция принимает переменную размер слишком большой для прототипа без ошибок, но может привести к неожиданным результатам:

int func(char a) 
{ 
    a = 10000; 
    return a; 
} 

int main(void) 
{ 
    int a = 10000; 
    int b; 
    b = func(a);// note int type, or 10000 does not fit into a char type 
       // b is returned, but not with the expected value. 
    printf("%d" b); 
    return 0; 
} 

Результаты: б = -24

Опубликовать прототип для UartWrite (???);

EDIT (новая информация)

Я нашел this Intel document on a compiler released in 1990, которые могут быть кузеном компилятор вы используете. Посмотрите на разделах, начиная со стр 68:

Каждое глобальное определение символа или ссылки в модуле компиляции имеет атрибут в видимость, которая контролирует, как (или если) оно может ссылаться извне компонента, в котором он определен , Есть пять значений: Возможные значения:
• EXTERNAL - компилятор должен обрабатывать символ , как если бы он был определен в другом компоненте. Для определения это означает, что компилятор должен предположить, что символ будет переопределен (вытеснен) с помощью определения с тем же именем в другим компонентом. См. «Предотвращение символа». Если символ функции 69 имеет внешнюю видимость, то компилятор знает, что он должен называться косвенно и может содержать косвенный вызов.
• ПО УМОЛЧАНИЮ - Другие компоненты могут ссылаться на символ .Кроме того, определение символа может быть переопределено (вытеснено) с помощью определения с тем же именем в другом компоненте.
• PROTECTED - Другие компоненты могут ссылаться на символ, но не могут быть выгружены одним и тем же именем в другом компоненте.
• HIDDEN - Другие компоненты не могут напрямую ссылаться на символ. Однако его адрес может быть передан другим компонентам косвенно (например, в качестве аргумента для вызова функции в другом компоненте или путем сохранения его адреса в позиции элемента данных с помощью функции в другом компоненте) ,
• ВНУТРЕННИЙ - символ не может быть указанным вне его определяющего компонента, либо напрямую, либо косвенно.

Чуть дальше Например:

int i __attribute__ ((visibility("default"))); 
void __attribute__ ((visibility("hidden"))) x() {...} 
extern void y() __attribute__ ((visibilty("protected"); 

Существует гораздо больше там. Надеюсь это поможет.

+0

void UartWrite (uint32_t) – Anantha

+0

@ Аннанта - Ну, с этим я озадачен. К сожалению, я недостаточно разбираюсь в компиляторе _IC, и я ничего не знаю о реализации 'UartWrite()'.Ясно, что только переменный размер не влияет на проблему, так как 'uint32_t' должен обрабатывать значение до *** 4,294,967,295 ***, тогда как ваш глобальный (большее из двух значений в вашем сообщении) в десятичной форме равен до чуть более половины этого значения (*** 2882400144 ***). Надеюсь, вы опубликуете решение, когда узнаете об этом. – ryyker

+0

UartWrite() использует функцию записи символов для печати каждого байта. IC-компилятор очень старый, может быть до C90 std. Может ли проблема быть связана с сегментацией x486 или локальной в стеке и глобально в сегменте данных или в некотором роде? – Anantha

0

C ключевое слово volatile указывает, что «значение может меняться между различными режимами доступа, даже если оно не изменяется». Попробуйте это и посмотрите, работает ли это для вас.

+1

*** [volitile] (http://tigcc.ticalc.org/doc/keywords.html#volatile) *** *** OP не использовал это ключевое слово *** в сообщении, так что маловероятно, чтобы значения объявленных переменных были бы изменены другим процессом. Если бы это было использовано, это (ваш ответ) было бы вероятным сценарием, так как значения каждой ссылки на переменную будут перезагружать содержимое из памяти, а не из реестра. – ryyker

+0

Привет rykker. Я имею в виду, что он должен добавить этот модификатор. В случае, если он не используется, компилятор может оптимизировать использование этой переменной и, следовательно, может дать неожиданные значения. –

+0

Да, я это понял. Но действительно ли это решило бы проблему? Есть неизвестные OP, которые не были предоставлены, например, какой размер (тип) является аргументом _UartWrite (?) _ Если это 'char', передача' uint' будет проблемой. – ryyker

Смежные вопросы