Глобальная переменная разбита - PullRequest
0 голосов
/ 09 октября 2019

У меня есть следующий код:

#include <math.h>

int x;
float Temp = 0;

void main(){

x = 2;

for(;;){
   Temp=log(20);
}
}

Я сократил свой код до важной строки. У меня проблема в том, что когда x объявлен как 2, а затем я выполняю функцию log (), в этом вычислении переменная изменяется на x и превращается в огромную доблесть.

Codewarrior (IDE, для которой я использую), говорит, что переменная Temp находится в расположении 0x0102, а переменная x находится в 0x0108.

Мне нужен x для функции в "MCUinit.h", поэтому важно, чтобы переменная x не превышала 5, и codewarriorдать как 5000 или даже больше после выполнения журнала (что угодно)

Как я могу сделать так, чтобы log () не изменял другие переменные?

спасибо

Перед выполнением журнала() функция. https://ibb.co/6ZHh6D0

После выполнения функции log (). https://ibb.co/Np99Sz4

Ответы [ 2 ]

2 голосов
/ 09 октября 2019

Это очевидное переполнение стека. S08 - невероятно ограниченный по ресурсам 8-битный MCU. Это не ПК. У него нет FPU. Это означает, что вы не можете и не должны использовать арифметику с плавающей запятой, когда-либо . Период. И вообще избегайте использования 32-битной арифметики.

Что происходит, когда вы запускаете math.h, так это то, что Codewarrior внедряет бесполезную программную библиотеку с плавающей запятой, полностью убивая всю доступную память и ресурсы ЦП во всем MCU, поворачиваяваша программа в бесполезном беспорядке. Одного log вызова было достаточно для уничтожения стека. Я не удивлен, у вас есть 100-200 байтов стека на дефолт. И когда это происходит, стек переполняется в области памяти .data / .bss, в которых хранятся переменные x и Temp, уничтожая их во время записи бессмысленных в этих областях.

Если вы на самом деле нужно , чтобы использовать вычисления с плавающей запятой, тогда вам не повезло, вы выбрали неправильный MCU. Нужно было выбрать Cortex M4.

Кроме того, вы всегда должны размещать стек так, чтобы он рос (это SP с понижающим счетом) в безопасных областях памяти, а не в разделах .data / .bss. ,Почему Codewarrior не делает этого по умолчанию, очень странно. Превращение стека в карту регистров также не является идеальным, но в случае, если вы не используете все периферийные устройства таймера около 0x70, это, по крайней мере, менее плохой сценарий, чем повреждение всех переменных в программе.

0 голосов
/ 10 октября 2019

Как-то я придумал возможное решение. Я полагаю, что это не лучшее решение из-за моего уровня программирования, но оно работает.

Поскольку моя программа выполнила строку Temp=log(20), ее результат был немного беспорядочным, потому что он изменял слишком много значений в ОЗУ с некоторымипеременные внутри, а затем log () давал мне собственную доблесть и хлам, разбиваясь с его позиции 0x0100 и далее. Поэтому я изменил «float Temp» на «float Temp» [10], и я собрал настоящую доблесть и мусор в этом массиве. Поэтому мне просто нужно было проявить заинтересованность в доблести.

Спасибо за eveyone. Я все еще здесь, чтобы услышать новое предложение.

...