• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

выравнивание памяти ;-)

doleynikov

New member
Привет. Я играюсь: пытаюсь запустить BASIC на ESP8266. Проект ESP8266BASIC меня не устраивает - я хочу сделать самодостаточную конструкцию типа ретроминикомпьютера, а его можно и к умному дому приспособить.
Успешно запускаются эмулятор C64 комодор и tiny basic (MySketchbook/ttbasic_ESP8266 at master · doleynikov/MySketchbook · GitHub). Нашел один интересный проект: GitHub - robinhedwards/ArduinoBASIC: A BASIC interpreter & environment for the Arduino . На Arduino Nano работает отлично! полноценный BASIC практически, пробую перенести на ESP8266 - облом! Я убрал вообще работу с клавиатурой и дисплеем, а также работу с PROGMEM. Валится на работе с указателями. Ексепшен вот какой: Exception 9: LoadStoreAlignmentCause: Load or store to an unaligned address
как раз, идет токенизация ввода и заполнение, например , описания переменных, или заполнение программы в виде токенов.
Я не понимаю работу с указателями, к сожалению. Ну, то есть в теории - спедставляю себе, что это, а вот когда вижу
Код:
 unsigned char *p = &mem[sysVARSTART];
        *(uint16_t *)p = bytesNeeded;
        p += 2;
        *p++ = VAR_TYPE_NUM;
        strcpy((char*)p, name);
        p += nameLen + 1;
        *(float *)p = val;
или
Код:
               *tokenOut++ = TOKEN_INTEGER;
                *(long*)tokenOut = (long)val;
                tokenOut += sizeof(long);
, как тот слон из мультика - теряю волю.
Помогите разобраться с этим выравниванием!
 

doleynikov

New member
а вот может быть. надо посмотреть.
А где об этом можно почитать?

PS: не, я вывел длину long - это , как и должно быть, 4 байта. Так что long одинаковый.
 
Последнее редактирование:

Юрий Ботов

Moderator
Команда форума
Первая мысль: немедленно избавиться от всех uint16_t (0...0xFFFF) в указателях на память в пользу uint32_t. Гляньте на карту памяти и поймете почему: Memory Map · esp8266/esp8266-wiki Wiki · GitHub
...

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

doleynikov

New member
Первая мысль: немедленно избавиться от всех uint16_t (0...0xFFFF) в указателях на память в пользу uint32_t. Гляньте на карту памяти и поймете почему: Memory Map · esp8266/esp8266-wiki Wiki · GitHub
Юрий, я во всяких сях не силен, к сожалению. подскажите ответ, почему лучше заменить типы? потому, что памяти больше чем в atmega?
Спасибо за понимание и сочувствие :)
 

Юрий Ботов

Moderator
Команда форума
Вроде не надо менять... Это у меня привычка к PC заговорила. Просто на PC (xxx*) - двухбайтный а если нужен четырехбайтный указатель пишут (xxx far*). А на 32 разрядном контроллере (xxx*) уже 4х байтный. Я бегло просмотрел код, вроде бы нигде не видно чтобы мешали 16 и 32 разрядные числа как это обычно бывает.
 

doleynikov

New member
@doleynikov
выложите свой скетч, попробую посмотреть. Самому выпиливать всё неохота.
MySketchbook/arduino_BASIC/arduino_BASIC at master · doleynikov/MySketchbook · GitHub - это мои потуги адаптировать
вот этот проект https://github.com/robinhedwards/ArduinoBASIC
для esp8266 и под нокиевский дисплей
 

doleynikov

New member
а это что?
Код:
basic.cpp
#include <pgmspace.h>
у меня и UNO и Nano на это ругается

Ещё и #include <PCD85448266.h> присутствует в host.cpp
не, для arduino не мой проект, а мистера Эдвардса (https://github.com/robinhedwards/ArduinoBASIC )
мой - попытка запуститься на esp8266.
PCD85448266.h - это некоторая адаптация библиотечки для вывода на нокиевский дисплей.

я не всю работу с PROGMEM попытался удалить, а только часть с таблицей токенов. Таблица сообщений об ошибках - осталась пока в PROGMEM
 

Сергей_Ф

Moderator
Команда форума
@doleynikov я же Вас попросил выложить Ваш проект, а Вы мне весь свой репозиторий качать предлагаете и искать там библиотеки. Эх...
 

doleynikov

New member
@doleynikov я же Вас попросил выложить Ваш проект, а Вы мне весь свой репозиторий качать предлагаете и искать там библиотеки. Эх...
Извините, пожалуйста.
arduino_BASIC.ino basic.cpp basic.h host.cpp host.h README.md - файлы проекта
MySketchbook/libraries/pcd8544-master at master · doleynikov/MySketchbook · GitHub - библиотека из проекта
остальные вроде стандартные

Компилируется оно без ошибок, а при выполнении возникают ексепшены
 

doleynikov

New member
ага. начинаем вводить команды. например скажите :
?
должно вернуться количество свободных байтов. Потом :
10 print 10
Вот тут должно вывалиться исключение
10 10 и 4 - это отладочная печать, показывающая, что проблема при обработке первого токена "10" как номера строки.
Код:
1024 bytes free
*******************
10
10
4
*******************
Fatal exception 9(LoadStoreAlignmentCause):
epc1=0x40202f77, epc2=0x00000000, epc3=0x00000000, excvaddr=0x3ffee9a1, depc=0x00000000

Exception (9):
epc1=0x40202f77 epc2=0x00000000 epc3=0x00000000 excvaddr=0x3ffee9a1 depc=0x00000000

ctx: cont
sp: 3ffefe40 end: 3fff0060 offset: 01a0

>>>stack>>>
3ffeffe0:  3ffe8e38 3ffeee18 00000000 40202f75 
3ffefff0:  40003031 00000001 00000001 402012d7 
3fff0000:  00000031 00000001 00000000 40204eca 
3fff0010:  3fffdad0 00000000 0000000a 3ffef02c 
3fff0020:  3fffdad0 3ffee9a0 3ffef024 402031c3 
3fff0030:  3fffdad0 00000000 3ffef024 4020222c 
3fff0040:  3fffdad0 00000000 3ffef024 40205398 
3fff0050:  feefeffe feefeffe 3ffef040 40100970 
<<<stack<<<
расшифровка дает:
Код:
Exception 9: LoadStoreAlignmentCause: Load or store to an unaligned address
Decoding 10 results
0x40202f77: nextToken() at /home/dimao/MySketchbook/build/sketch/basic.cpp line 819
0x40202f77: nextToken() at /home/dimao/MySketchbook/build/sketch/basic.cpp line 819
0x40202f75: nextToken() at /home/dimao/MySketchbook/build/sketch/basic.cpp line 819
0x402012d7: delay at /home/dimao/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/core_esp8266_wiring.c line 50
0x40204eca: HardwareSerial::available() at /home/dimao/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/HardwareSerial.cpp line 193
0x402031c3: tokenize(unsigned char*, unsigned char*, int) at /home/dimao/MySketchbook/build/sketch/basic.cpp line 923
0x4020222c: loop at /home/dimao/MySketchbook/arduino_BASIC/arduino_BASIC/arduino_BASIC.ino line 39
0x40205398: loop_wrapper at /home/dimao/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/core_esp8266_main.cpp line 56
0x40100970: cont_norm at /home/dimao/.arduino15/packages/esp8266/hardware/esp8266/2.3.0/cores/esp8266/cont.S line 109
 
Последнее редактирование:

Юрий Ботов

Moderator
Команда форума
Сразу бы показали...
Вот строки кандидаты на ошибку:
...
*(long*)tokenOut = (long)val;
...
*(float*)tokenOut = (float)strtod(numStr, 0);
...
И наверное есть и другие такие - когда в массив char пишутся вперемешку символы разной длины.

Но из этих строк следует что интерпретатор принципиально заточен под 8 битную архитектуру...
Не факт что не переписав все заново удастся оживить его на 32 битной архитектуре. Впрочем есть способ... хотя и кривоватый: длинные слова (16,32 бит) сначала засовывать через union во внешний массив char, потом эти char по одному засовывать в массив tokenOut и при доставании из tokenOut тоже но наоборот - по одному байту копировать из массива в union а потом уже длинное из union куда надо.
 

Сергей_Ф

Moderator
Команда форума
@doleynikov в коде активно фигурирует int в работе с токенами. А уж его размер точно у AVR=2, а у ESP=4. Не знаю тут ли собака порылась, но попробуйте заменить на int16_t, может поможет.

есть такие куски *tokenOut++ = TOKEN_INTEGER;
где TOKEN_INTEGER = 2
а по факту на esp 4

это не совсем то
 
Последнее редактирование:

doleynikov

New member
Спаасибо. буду пробовать. Если получится - напишу.

ЗЫ: если нет - тоже напишу.
 

Сергей_Ф

Moderator
Команда форума
@doleynikov c PROGMEM вы точно не разобрались
host_outputProgMemString((char *)(&(errorTable[ret])));
выводит совсем не то что надо
а вот

host_outputProgMemString(errorTable[ret]);
работает правильно
во всяком случае host_outputProgMemString(errorTable[0]); выводит Ok, как положено
 
Последнее редактирование:

doleynikov

New member
сорри, я тот еще программист ;-)
Изменил все int на 16 разрядный -не помогло. Возможно это исправит потенциальные ошибки с записью int в структуры программы.
Но вот, чего я не понимаю вообще: Юрий писал:
в массив char пишутся вперемешку символы разной длины.
про вот такой кусок:
Код:
        *tokenOut++ = TOKEN_INTEGER;
        *(long*)tokenOut = (long)val;
         tokenOut += sizeof(long);
где тут символы разной длины? (!!! проклятые указатели !!!)
 
Сверху Снизу