2012-03-13 3 views
1

Это мой код:летучий uint32_t на Cortex-M3

volatile uint32_t value = *((volatile uint32_t *) 0xA0000000); // here `value` is 12498 
value *= 2; // here `value` is still 12498 
value |= 0x0000001; // still 12498 

При анализе в моем отладчике переменную value, она имеет то же значение на всех линиях. Что я делаю не так?

+0

Возможно, ваш отладчик правильно справляется с летучами? –

+0

Почему бы просто не использовать некоторую трассировку и проверить поведение реальной программы, не полагаясь на отладчик для проверки. –

+0

Какой процессор вы используете? – DipSwitch

ответ

5

Возможно, ваш отладчик на самом деле не так хорош. Когда один из моих инструментов не работает, я всегда проверяю его на другой инструмент.

Попробуйте отладить старинке, с:

volatile uint32_t value = *((volatile uint32_t *) 0xA0000000); 
printf ("A:%d\n", value); 

value *= 2; 
printf ("B:%d\n", value); 

value |= 0x0000001; 
printf ("C:%d\n", value); 

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

Посмотрите, что вы получите с этим - я был бы более склонен доверять printf -debugging, чем отладчики.


Если ваша проблема не связана с value, но вместо того, чтобы с памятью на месте 0xA0000000, то он работает, как ожидалось.

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

*((volatile uint32_t *) 0xA0000000) = value; 

Однако, учитывая ваше использование изменчиво, это вполне возможно, вы просто хотели переменную указателя к этому месту, так что изменения будут отражать немедленно ,

Если это так, то вам нужно будет что-то вдоль линий:

volatile uint32_t *pValue = (volatile uint32_t *) 0xA0000000; 
*pValue *= 2; 
*pValue |= 0x00000001; 

В этом случае ячейка памяти будет изменена в каждой инструкции без, имеющих явно записать значение.

+0

У меня нет 'printf' в данный момент, потому что я разрабатываю для встроенной системы. – Randomblue

+0

Затем вы должны найти другой способ, например http://stackoverflow.com/questions/5165654/cost-of-fprintf/5165813#5165813, и в конечном итоге сделать что-то с символьным буфером ('puts' или выводить на последовательный порт и т. Д.). – paxdiablo

+0

http://github.com/dwelch67, ищите hexstring, я использую его везде или создаю свой собственный, восьмеричный еще проще, но большинство из нас все еще работает в hex, но не восьмеричном. не требует делений, масок сдвига и добавления/или для восьмеричного, условного, требуемого для hex, выталкивает его из uart или если у вас есть область или логический анализатор, выталкивайте его параллельно или другому последовательному интерфейсу (намного быстрее, чем скорость uart). –

1
  1. Это может быть, что ваш оптимизатор заметил, что value является автоматическим переменным, адрес которого никогда не принимается, и так фактически игнорируется тот факт, что его неустойчивым, так как это происходит что-то узнать об архитектуре он работает на , и пришел к выводу, что соответствующая программа не может наблюдать, какая последовательность чтения и записи на нее происходит, хотя стандарт говорит, что это наблюдаемо. Очевидно, что это не очень удобно для отладчика, но я не удивлюсь, если это произойдет. Фактически, компилятор предположил бы, что вы не можете «видеть» стек, что является ложным, если вы используете отладчик, исследуете дамп ядра, отмечаете стек только для чтения и обрабатываете результирующие сигналы и т. Д. Проверьте разборку, посмотрите, действительно ли отображаются множители/сдвиг и бит.
  2. Возможно, ваш отладчик неправильно отслеживает значение, либо из-за (1), либо иным образом.
+0

0xA0000000 - это что-то важное в карте памяти платы, над которой я работаю. – Randomblue

+0

@ Randomblue: отредактировано для удаления ложных обвинений :-) –

+0

На самом деле это не определено, иначе встраиваемые системы никогда не смогут требовать соответствия памяти ввода-вывода. Стандарт утверждает, что он не определен, только если «недопустимое значение было присвоено указателю» - недопустимые значения включают нулевое, неправильное выравнивание и объект после его жизненного цикла, но это все, что он должен сказать. Недействителен ли 0xa0000000, это вопрос для реализации. – paxdiablo

0

попробуйте записать значение в другую временную переменную и изучить это значение. Иногда это позволяет компилятору/отладчику делать то, что вы хотите. AFAIK, volatile сообщает компилятору всегда читать значение, не обязательно держать его вокруг для записи, если его никогда не читать.

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