Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Re: Вопросы по С/С++ (СИ)

Вт авг 17, 2021 08:56:08

Что за знаковое число в целочисленной математике ?
И причём тут отрицательное число ?

Re: Вопросы по С/С++ (СИ)

Вт авг 17, 2021 09:06:17

надо 95 разделить на 50 и -95 разделить на 50 - все числа целые (а не натуральные). если просто поделить получается 1, так как остаток 45 отбрасывается. Но хочется получить 2. Так вот для +90 метод (90 + 25)/50 даст 2. Но для -90, к сожалению -1, потому как получается "округление" в положительную сторону, а хочется в абсолютную.

Re: Вопросы по С/С++ (СИ)

Вт авг 17, 2021 11:10:39

#define rnd_div(x, y) do ((x) < 0 ? -(-(x) + (y)/2) / (y) : ((x) + (y)/2) / (y); while 0

Re: Вопросы по С/С++ (СИ)

Вт авг 17, 2021 13:44:05

Может, еще подскажете, это не совсем по C но около... Среда на базе эклипса. В данный момент это Simplicity Studio, но перед этим мучался с подобным под Code Compose Studio. Есть проект и есть проект. И я хочу чтобы несколько файлов с исходниками были общие. Примерно так:
Код:
Project_1
    visualise.c
    visualise.h
    configuration.h
Project_2
    visualise.c -> Project_1/visualise.c
    visualise.h -> Project_1/visualise.h
    configuration.h

т.е. файлы visualise должны быть общие, чтобы поправляя в одном проекте, эти же изменения были и во втором. Но файлы configuration.h - у проектов разные. Eclipse позволяет в проект добавить линки на файлы. Но, при компиляции проекта_2 есть две проблемы. Первая - другие файлы не видят файла visualise.h, упомянутого в #include. Ну хорошо, я могу в настройках проекта добавить этот путь и тогда видит. Но вторая проблема в том, что компилируя проект_2 файл visualise.c в команде #include "configuration.h" видит файл из проекта_1. Что тоже вроде как понятно - текущий каталог первый в поиске, но как правильно это сделать бы?

Re: Вопросы по С/С++ (СИ)

Вт авг 17, 2021 15:27:05

полные пути к включаемым файлам не помогают?
#include "\path]\dir1\config.h"

Re: Вопросы по С/С++ (СИ)

Вт авг 17, 2021 16:14:16

как? мне нужно, чтобы в одном проекте visualise.c взял один конфиг, а в другом проекте - другой. В предыдущий раз когда я имел <нецензурное слово> с таким извращением, все дефайны были определены в настройках проекта. Но хочется простого текстового файла - можно хоть комментарий написать, а то голова уже не та - забывать начинаю, что писал всего пару месяцев назад.

Впрочем, какой-то выход из положения нашел. Общие файлы запихнул в каталог common, а в настройках проекта сделал поиск инклюдов сначала в каталоге проекта, а потом в остальных местах.

Re: Вопросы по С/С++ (СИ)

Вт авг 24, 2021 09:32:12

как правильно прописывать пути к файлам ?
Изображение

Re: Вопросы по С/С++ (СИ)

Вт авг 24, 2021 10:14:03

Пути должны быть относительными.

Относительно тех путей, которые уже есть в опциях компилятора

То есть, если, например есть такое: CFLAGS = ... -I /path/to/src/fonts ... - то нужно включать как #include <fonts.h>.

А если только CFLAGS = ... -I /path/to/src/ ... - то включается как #include <fonts/fonts.h>

Если в опциях компилятора оба пути перечислены, то можно по обоим вариантам.

Re: Вопросы по С/С++ (СИ)

Вт авг 24, 2021 11:35:43

WiseLord, благодарю !
оказывается, в эклипсе, в настройках проэкта, нужно просто добавить путь
Изображение Изображение

Re: Вопросы по С/С++ (СИ)

Пт дек 10, 2021 23:42:36

Доброго времени суток. Подключил библиотеку GPIO.h ссылка. Немного подрихтовал. Теперь работает с голым МК в AtmelStudio. Теперь задача - пины передавать в качестве параметра функции, ну и что либо там делать. Тип параметра, очевидно объект. По ссылке.. по указателю..
Спойлер/* ATiny85 */
#define F_CPU 8000000UL //
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "wiring.h"
#include "GPIO.h"

GPIO<BOARD::D3> led;

void My_function(/* параметр(ы) функции led, */){
// различные действия с led;
};

int main(void){

led.output();// пин на выход

while (1) {// мигание светодиодом
led = 1; // зажечь
_delay_ms(500);
led = 0; // погасить
_delay_ms(500);
}

}
Что-то совсем заклинило. Как экземпляр класса запихать параметром в функцию??

Re: Вопросы по С/С++ (СИ)

Сб дек 11, 2021 00:17:06

Эйлер Леонард, какой там gcc?

Всегда можно сделать так:
Код:
template<typename T>
void foo(T pin) { pin.toggle(); }

Если доступен C++20, то можно написать концепт, типа такого:
Код:
template<typename T>
concept Pin = std::is_base_of_v<PinBase, T>;

Правда на AVR gcc обрезанный и я не уверен, что is_base_of_v там доступен, но можно заменить любой проверкой, в данном случае пин детектится по базовому классу. С концептом использование мало чем отличается, просто компилятор будет проверять, что передали действительно пин:
Код:
template<Pin T>
void foo(T pin) { pin.toggle(); }

Помимо этого есть auto:
Код:
void foo(auto pin) { pin.toggle(); }

Auto с концептом:
Код:
void foo(Pin auto pin) { pin.toggle(); }

Ну и чаще всего применяется чисто шаблонный вариант:
Код:
template<typename T>  //template<Pin T>
void foo() { T::toggle(); }

Но тогда пин обычно объявляют через using с которым генерится более эффективный код при отключенной оптимизации, что для AVR без отладчика не особо актуально:
Код:
using led = GPIO<BOARD::D3>;

Re: Вопросы по С/С++ (СИ)

Сб дек 11, 2021 01:30:59

Благодарю за отклик, буду вкуривать. Ох уж эти темплеты. :))

Добавлено after 39 minutes 48 seconds:
Заработало так:
Спойлер/* ATiny85 -std=c++14 */
#define F_CPU 8000000UL //
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "wiring.h"
#include "GPIO.h"

GPIO<BOARD::D3> led;

void foo0(auto pin) { pin=0; }
void foo1(auto pin) { pin=1; }

int main(void){

led.output();// пин на выход

while (1) {// мигание светодиодом

foo1(led);// зажечь
_delay_ms(500);
foo0(led);// погасить
_delay_ms(500);
}
}
Однако AtmelStydio подкрутил до -std=c++14
Ну всё, теперь с GPIO.h дела пойдут (даже полетят) :music:
Вложения
123.png
(35.5 KiB) Скачиваний: 54

Re: Вопросы по С/С++ (СИ)

Сб дек 11, 2021 01:36:17

Да чего мелочиться, в gcc 11 уже -std=c++23 есть :)

Re: Вопросы по С/С++ (СИ)

Ср дек 15, 2021 23:18:24

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

И вот вопрос.

У меня не срабатывает команда:
Motor_Speed(-6000, -6000);

Эта функция делает следующее:
Код:
void Motor_Speed(int16_t left, int16_t right) {
   XstartL = left;
   XstartR = right;
}


Но дело в том, что XstartL/XstartR используются в функции, которая вызывается по прерыванию таймера. Но там они не модифицируются.
Код:
    ErrorL = XstartL - XprimeL;
    ErrorR = XstartR - XprimeR;
...
    if (XstartL == 0 && Left.Dir  == STOPPED) UIL = UL = 0, backlight |= FR_LEFT;
    if (XstartR == 0 && Right.Dir == STOPPED) UIR = UR = 0, backlight |= FR_RGHT;

Нужно ли эти две переменные объявлять как volatile или нет? сейчас они просто:
Код:
int XstartL  = 0, XstartR = 0;

Re: Вопросы по С/С++ (СИ)

Чт дек 16, 2021 06:14:08

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

Re: Вопросы по С/С++ (СИ)

Чт дек 16, 2021 19:14:00

Нужно ли эти две переменные объявлять как volatile или нет?


Нужно везде, где компилятор не сможет понять, что значение переменной может быть изменено вне функции. Иначе он с радостью способен "оптимизировать" код, предположив, что переменная не способна поменять своё значение.
Ну и запрет прерываний при изменении переменных нужен, конечно.

Re: Вопросы по С/С++ (СИ)

Пт дек 17, 2021 07:27:02

da-nie писал(а):Ну и запрет прерываний при изменении переменных нужен, конечно.

Я бы сказал "обязательно", если этот код будет работать на 8-битном МК.

Re: Вопросы по С/С++ (СИ)

Пт дек 17, 2021 07:59:52

А если это MSP432 Cortex-M4F? Мне казалось, что запись 32 битного там поисходит разом и надобности запрещать прерывание нет. А то что левое колесо получит на 10 мс раньше правого - это ж мелочь.

Re: Вопросы по С/С++ (СИ)

Пт дек 17, 2021 13:01:31

Дело не в битности переменной, а в том, что с ней происходит. Если она читается и модифицируется в разных потоках - пиши пропало, глюк обеспечен.
А volatile, ко всему прочему, может ещё и усугубить ситуацию. Т.к. он запретит компилятору всю оптимизацию для этой переменной. И обычный инкремент может превратиться в ЧМЗ. Грубо говоря, конечно.

Re: Вопросы по С/С++ (СИ)

Пт дек 17, 2021 13:26:05

Нужно ли эти две переменные объявлять как volatile или нет? сейчас они просто:
Код:
int XstartL  = 0, XstartR = 0;
Нужно. Более того - нужно запретить прерывания на время их записи (или иным образом обеспечить атомарность записи).

Добавлено after 1 minute 31 second:
da-nie писал(а):Ну и запрет прерываний при изменении переменных нужен, конечно.

Я бы сказал "обязательно", если этот код будет работать на 8-битном МК.
На 32-битном МК тоже - обязательно.

Добавлено after 12 minutes 32 seconds:
А если это MSP432 Cortex-M4F? Мне казалось, что запись 32 битного там поисходит разом и надобности запрещать прерывание нет. А то что левое колесо получит на 10 мс раньше правого - это ж мелочь.
Так у вас там 2 записи 32-битных.

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

PS: Неужто 3 команды на запрет/разрешение прерываний настолько критичны, что так пытаетесь их сэкономить???
PPS: Можно пойти и другим путём:
Код:
union {
  struct { u16 XstartL, XstartR; };
  u32 XstartL_XstartR;
} = {0, 0};
...
XstartL_XstartR = (u16)left | (u32)(u16)right << 16;
Здесь запись атомарна (на 32-битном МК), без запретов прерываний.
Ответить