Просветите по ошибке PlatformIO (глюк или что то нужно поднастроить?)

sanekru
Offline
Зарегистрирован: 05.12.2017

Доброго времени!

Вместо arduino ide установлен VSCode + тулчейн PlatformIO

На данный момент изучаю PROGMEM. В одном из примеров присваиваю строке указатель

const char * addrStroki = pgm_read_word_near(addrOfAddr);

и 

pgm_read_word_near

подсвечивает как ошибку что строка не может быть инициализированна значением uint_16t.

Вроде бы всё логично, но сборка проходит без проблем, но ошибка всеравно висит.

Вопрос: Пофиксить мне эту ошибку или проблема где то глубже?

 

 

 

 

rkit
Offline
Зарегистрирован: 23.11.2016

Проблема в том, что не понимаешь, что ты делаешь вообще. В этой конструкции нет никакого смысла. В памяти ты от этого только проиграешь

sanekru
Offline
Зарегистрирован: 05.12.2017

Да не, вы всё не так поняли!

В VS code подсветка синтаксиса, и он мне показывает что в этой строке есть проблема, хотя на самом деле сборка проходит без ошибок, а проблема ввиде ошибки остаётся висеть как будто в программе что то не то!

#include <avr/pgmspace.h>

const char str_0[] PROGMEM = "For exit - SELECT";
const char str_1[] PROGMEM = "Delayed power on";
const char str_2[] PROGMEM = "Bye!";
const char * const text[] PROGMEM = {str_0, str_1, str_2};

void softPrint(const int addrOfAddr);

void setup(void) {
	Serial.begin(115200);
	while (!Serial);
	Serial.println("Fun begins!");
	// Передаём адрес в прогмем адреса в прогмем нужной строки
	// Функция должна сама взять из прогмем число по переданному адресу 
	// И испольовать это число как адрес строки в прогмем
	softPrint((int)(text + 1));
}

void softPrint(const int addrOfAddr) {
	char textBuffer[30];
	// addrStroki - просто число, которое мы прочитали из прогмем
	// по адресу addrOfAddr
	const char * addrStroki = pgm_read_word_near(addrOfAddr);
	strcpy_P(textBuffer, addrStroki);
	Serial.println(textBuffer);
}

void loop(void) {}

В arduino ide тоже без проблем собирается,

в Vs code есть такая функция как quick fix, и он больше не показывает что в этом месте ошибка!

Так мой вопрос в правильности этого костыля? Или может где что поднастроить нужно в VS code&

sanekru
Offline
Зарегистрирован: 05.12.2017

пример с форума, тут дело не в логике программы а в самой программе VS code

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

sanekru
Offline
Зарегистрирован: 05.12.2017

как то так, сам уже ржу, чувствую хрень несу! С утра видимо уже мосК не варит

rkit
Offline
Зарегистрирован: 23.11.2016

Нет, я всё именно так понял. Ты делаешь бессмысленную чушь.

sanekru
Offline
Зарегистрирован: 05.12.2017

Пи.дец!

Мне интересно почему подсвечивает, но при этом компиляция проходит успешно, первый раз такое!

Если-бы жёлтым подсвечивало то ладно, это предупреждение, а тут красным!!!

Явно компиляция не должна собраться!

А тут она собирается без единой ошибки, хотя все равно висит подсветка красным, ЯВНО ведь глюк !

sanekru
Offline
Зарегистрирован: 05.12.2017

Собственно с чего всё это началось!!!

На форуме нашёл ветку про Sim 800

http://arduino.ru/forum/apparatnye-voprosy/vse-o-sim800l-i-vse-chto-s-nim-svyazano?page=2

Пользователь по имени andycat выложил свой алгоритм и библиотеку в данной ветке,

я установил эту библу и в файле sim800.cpp смотрю ошибка висит, а всё собирается норм! Думаю херь какая то

далее дай думаю найду похожий пример для проверки будет ли так же ошибка висеть !

Собственно нашёл пример из этой ветки

http://arduino.ru/forum/programmirovanie/ocherednoi-raz-progmem

и в этом примере тоже показывает проблему, хотя сборка проходит на ура!

 

sanekru
Offline
Зарегистрирован: 05.12.2017

Короче пофиксил я quick fix ом проблему, да и всё, думаю тему можно закрывать

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sanekru пишет:

думаю тему можно закрывать

А что, понять что там не так не хотите? Ну, тогда закрывайте.

sanekru
Offline
Зарегистрирован: 05.12.2017

Уважаемый ЕвгенийП конечно понять хочу, но судя по ответам подумал что ничего хорошего в этой теме не выйдет!

Я думаю что ругается на то что

pgm_read_word_near(addrOfAddr)

возвращает unsigned int а const char* поидее не должна присваивать данный тип данных, и думаю идёт неявное преобразование адреса в строку

b707
Offline
Зарегистрирован: 26.05.2017

sanekru пишет:

Я думаю что ругается на то что

pgm_read_word_near(addrOfAddr)

возвращает unsigned int а const char* поидее не должна присваивать данный тип данных,

да, приблизительно так.

В Visual Studio все эти PROGMEM макросы дают предупреждение

warning: dereferencing type-punned pointer will break strict-aliasing rules

 

AlexTLN
Offline
Зарегистрирован: 14.05.2016

sanekru пишет:

возвращает unsigned int а const char* поидее не должна присваивать данный тип данных, и думаю идёт неявное преобразование адреса в строку

Не совсем так. Советую почитать и понять, что такое указатели и данные(Вы путаете, точнее все в кучу одну мешаете). Скажем так:

char x = 7; //это 7

char *z = &x; //z будет адресом x(не 7, а скажем 0х00A2)

При z++; эта *z будет равна 0х00А3.

Но! Так как у Вас тип данных int, то int *k = &x имел бы адрес 0х00А2. А при операции k++; адрес был бы 0х00А4(так как int 16 бит, 2 байта). Скажем так: если хотите использовать указатель char и данные int, то надо делать char+2.

Поэтому и ругается. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sanekru,

Вы пытаетесь читать адрес из прогмем. Но используете для этого (непонятно, зачем) функцию pgm_read_word_near, которая возвращает не адрес, а беззнаковое целое. В принципе, в данной архитектуре адрес представлен именно беззнаковым целым (хотя забиваться на это не следует никогда, подведёт и ещё как!), потому с аппаратной точки зрения проблемы нет, но логически использование целого вместо адреса - очень опасная операция. Очень!

Дальше всё зависит от профессиональности настроек Вашей среды. Например, Arduino IDE из коробки настроена для блондинок и там опции установлены так, что эта операция спокойно и молча "съедается" (нефиг мозги девочкам выносить глупостЯми). В платформио, как я понял, выдаётся предупреждение. А вот у меня в Микрочип Студии я настроил так, что на Вашу строчку выдаётся полноценная ошибка и компиляция прекращается.

Error: invalid conversion from 'uint16_t {aka unsigned int}' to 'const char*' [-fpermissive]

Я специально настраиваю так, чтобы опасные операции не проходили незамеченными - нет-нет, да и выручит! Это страховка от случайных ошибок.

Как нужно было сделать правильно?

Правильно, если Вы читаете указатель, то использовать функцию для чтения указателей, а не беззнаковых целых. Такая функция есть и называется она pgm_read_ptr_near. Использовать надо именно её (т.е. не забиваться на то, что указатель и беззнаковое целое - физически одно и то же!).

const char * addrStroki = pgm_read_ptr_near(234);

Но с нею тоже может оказаться "не слава Богу". Она возвращает указатель void *. При блодниковских настройках - всё отлично. Но при параноидальных настройках (вроде моих) опять будет ошибка:

Error: invalid conversion from 'void*' to 'const char*' [-fpermissive]

Потому, для параноидальных настроек надо ещё явно преобразовать тип указателя

const char * addrStroki = reinterpret_cast<const char *>(pgm_read_ptr_near(234));

На коде это никак не отразится, но этим Вы скажете компилятору, что Вы понимаете, что делаете, и он успокоится.

Как-то так.

sanekru
Offline
Зарегистрирован: 05.12.2017

Больше спасибо за столь развернутый ответ!!!

Но всё же из за отсутствия опыта в голове присутствует небольшой кавардак.
И кстати в данной теме ни одна строчка кода мне не принадлежит, я по примерам с данного форума пытаюсь учиться.
Кстати может кому будет интересно по изучению c++ есть отличный сайт ravesli.com (не ради рекламы), мне данные уроки заходят на ура!

Alexey_Rem
Offline
Зарегистрирован: 09.09.2019

Да, ресурс действительно очень полезный, но как по мне по-настоящему системные знания даст параллельное ковыряние в Ассемблере- у меня лично просто глаза открываются "Как у испуганной орлицы"

b707
Offline
Зарегистрирован: 26.05.2017

А можно примерчик, чего ж вы такое в асм увидели, чего в Си нет?

Alexey_Rem
Offline
Зарегистрирован: 09.09.2019

Просто становится понятна логика работы, которая при изучении только Си не очевидна

b707
Offline
Зарегистрирован: 26.05.2017

а все-таки - пример можете привести?

sanekru
Offline
Зарегистрирован: 05.12.2017

Мне кажется что логика на Си более понятна, так как собственно и создан язык был для более лёгкого понимания работы программ. На asmе мне как новичку в программировании мешают постоянные переходы (прыжки) по коду, может для профи логика и будет интуитивно понятнее, а по мне так в си всё более логично вплане понимания!

b707
Offline
Зарегистрирован: 26.05.2017

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

С языками программирования так же - если человек лучше знает АСМ, в асм-листинге ему логика будет виднее, чем в Си-коде. И наоборот...

Но мое обьяснение банально, я надеялся услышать от Alexey_Rem что-то менее очевидное, чем то, что он просто лучше знает АСМ и ему так привычнее...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Alexey_Rem,

т.е. примера не будет?

b707 пишет:
А можно примерчик?

b707 пишет:
а все-таки - пример можете привести?

Всё мимо?

rkit
Offline
Зарегистрирован: 23.11.2016

Если интересно, то откройте учебник асма и разберитесь. На пальцах объяснять бесполезно.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

ASM ASM у - рознь ! На AVR ASM достаточно простой, но менее гибкий нежели на ARM. ASM нужен для того что бы уложиться в минимум тактов и/или минимальный размер во флеш.

b707
Offline
Зарегистрирован: 26.05.2017

rkit пишет:

Если интересно, то откройте учебник асма и разберитесь. На пальцах объяснять бесполезно.

вот я и прошу дать какой-нить ориентир - что ж я такое новое увижу, когда разберусь?

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

Кстати, в обоих учебниках ровно половина книжки посвящена не относящимся к асму вещам - что такое бит, что байт, битовые операции, логическая арифметика... Возможно, новичку, который в этом ни бум бум - правильнее начать с асма, потому что в учебниках Си подобные азы не обьясняют. Но если человек все это давно знает - что ему искать в ассемблере? Ответить никто не хочет, знатоки асма либо отмалчиваются, либо обещают "вот изучишь - тогда поймешь" :)))

rkit
Offline
Зарегистрирован: 23.11.2016

Увидишь как работает процессор, а не абстракция выскоуровневого языка. Знать это необязательно, и если боишься потратить вечер впустую, то можно пропустить.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

b707 пишет:

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

Согласен с этой точкой зрения.

В свое время писал на четырех различных Ассемблерах: для IBM 360, VAX, i8080 и x86. Ассемблеры AVR и ARM никогда не изучал и не планирую, т.к. того, что уже знаю, достаточно, чтобы суметь прочитать листинг дизассемблера. Писать для AVR или ARM с моими знаниями, естественно, нельзя, но я уже лет 20 не сталкивался с необходимостью писать что либо на Ассемблере.

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