Блоґ одного кібера

Історія хвороби контуженого інформаційним вибухом

Posts Tagged ‘C++

Stm32 Nucleo – вхідні сигнали і комунікація з компю’тером

with 10 comments

Сьогодні продовжимо розбиратись з нашою платою, і почнемо з того, як отримати натиснення кнопки. Якщо вас цікавить початок – переходьте сюди.

Якихось чітких інструкцій в інтернеті я не знайшов, зате в IDE було аж два демо проекти про кнопку:

  • “Read the user button state on the Nucleo board.”
  • “Read the user button using external interrupt.”

Код там досить простий, але я його ще спростив ось так:

#include "mbed.h"
 
DigitalIn mybutton(USER_BUTTON);
DigitalOut myled(LED1);
 
int main() {
  while(1) {
    myled = mybutton;
  }
}

Прочитати решту цього запису »

Written by bunyk

21 Лютого, 2015 at 15:04

Опубліковано в Інструменти, Кодерство, Конспекти

Tagged with ,

Привіт “ядерному мікроконтролеру” ;)

with 3 comments

Вкотре переконуюсь що якщо чогось дуже хочеш – то отримаєш. Так от я хотів якось спробувати скласти гірлянду якою можна буде керувати з комп’ютера, трохи думав про Arduino, і недавно мені в руки для тестування потрапила плата NUCLEO-F411RE від компанії STMicroelectronics. Все завдяки автору сайту embedded.co.ua, Василю Йосипенку, якому за це величезне дякую.

nucleo

Почну з того що на платі надруковане посилання: www.st.com/stm32nucleo. І наклеєна наклейка NUCLEO-F411RE. З діаграми на сайті видно що F411 це найшвидша плата, яка має найбільший розмір флеш-пам’яті – 512K. Аж пів метра!

Далі я звісно перейшов на сторінку плати і почав RTFM. Ось інструкція.
Прочитати решту цього запису »

Written by bunyk

18 Лютого, 2015 at 00:39

Перший український технотриллер

with 15 comments


Технотриллер – це гібрид наукової фантастики і шпигунсько-військового роману а-ля Віктор Суворов. Це не кіберпанк. Кіберпанк – це фантастика на тему суспільства в якому маємо не одного кібера, і вони там всім заправляють. 🙂

Я почну з мінусів, але ви не переживайте, книжка – те що треба. Може бути й краще, але й так непогано.

В мене цієї неділі відбувся приблизно такий діалог з філологом:

– Добре що хоч програмісти не пишуть книжки.
– Пишуть, в мене зараз в рюкзаку якраз є одна. Хочеш покажу?
– Правда? Давай.
– Дивись, тут є код на C++, формула Мандельброта і 3d-моделі на ілюстраціях.
– Пахне третьосортною літературою… О, я вже знайшла три помилки!

Так, книжку писав не філолог. А редактори напевне побоялись чіпати, бо там своєрідна термінологія і лексика.

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

Written by bunyk

6 Жовтня, 2012 at 01:57

Опубліковано в Нещоденник

Tagged with ,

Прочитати матрицю з файлу

with 22 comments

Думаєте просто? І я так думав.

Таки зробив, не знаю чи найкращим чином, але добре що добрі люди допомогли.

С++ STL

#include <vector> //for datatypes
#include <sstream> //for istringstream 
#include <fstream> // for ifstream
#include <iostream> // for cerr, cout
#include <string> // for string type
using namespace std;

vector<int> readRow(string row)
{
	vector<int> retval;
	istringstream is;
	is.str(row);
	int num;
	while (is >> num) retval.push_back(num);
	return retval;
}

vector< vector<int> > readVector(istream &is) 
{
	string line;
	vector<vector<int> > retval;
	while (getline(is, line))
		retval.push_back(readRow(line));
	return retval;
}

int main()
{
	ifstream infile("test.txt");
	if(!infile){
		cerr << "Error! Cant open file test.txt";
		return -1;
	}
	vector< vector<int> > data = readVector(infile);
	int rows = data.size();
	int cols = data[0].size();
	int i,j;
	for(i=0;i<rows;i++)
	{
		for(j=0;j<cols;j++)
		{
			cout << data[i][j] << " ";
		}
		cout << endl;
	}
}

Так це я такий, чи це C++ такий?

C++ без STL, масив має максимальний розмір

#include <sstream> //for istringstream 
#include <fstream> // for ifstream
#include <iostream> // for cerr, cout
#include <string> // for string type
using namespace std;

const int maxwidth=1000;
const int maxheight=100;
int x=0,y=0;
int width,height;
int array[maxwidth][maxheight];

void readRow(string row)
{
	istringstream is;
	is.str(row);
	x = 0;
	int num;
	while (is >> num) {
		array[x][y] = num;
		x++;}
	width=x;
}

void readVector(istream &is) 
{
	string line;
	y=0;
	while (getline(is, line)){
		readRow(line);
		y++;
		}
	height = y;
}

int main()
{
	ifstream infile("test.txt");
	if(!infile){
		cerr << "Error! Cant open file test.txt";
		return -1;
	}
	readVector(infile);
	int i,j;
	for(i=0;i<height;i++)
	{
		for(j=0;j<width;j++)
		{
			cout << array[j][i] << " ";
		}
		cout << endl;
	}
}

Python

f = open("test.txt")
lns = f.readlines()
nums = map(lambda x: x[:-1].split(" "),lns)
for i in nums:
    for j in i:
        print float(j)+0.1,
    print

# OUT: 1.1 2.1 3.1 4.1 5.1
# OUT: 6.1 7.1 8.1 9.1 0.1
# OUT: 9.1 8.1 7.1 6.1 5.1

Порівняйте розміри коду, враховуючи те, що в C++ використовується той же stl, і я не забув using namespace std; , як дехто робить щоб загадити код префіксами.

Знаєте як краще, чи маєте питання – пишіть нижче.

Written by bunyk

22 Лютого, 2011 at 00:17

Опубліковано в Кодерство, Конспекти

Tagged with ,

Лінкер для чайників

with 4 comments

50 хвилинна лекція через jabber

pidginЗазвичай хороші лекції виходять при вузькій цільовій аудиторії. Якщо ця аудиторія – одна людина – то лекція стає майже ідеальна. Цікаво перевірити, чи ще хтось крім зможе розібратись з принципами компіляції багатомодульних програм на C++ за допомогою пояснення Улідтки? Тоді його витрачена година буде витрачена з більшою користю. Хоча текст концентрований. Якщо справитесь менш ніж за 5 хв, розкажіть, як враження.

(17:59:55) bunyk: А я от не знаю що прочитати, щоб зрозуміти що таке лінкер.
(18:00:31) Улідтко: дивись
(18:00:38) Улідтко: у тебе є main.c
(18:00:52) Улідтко: який робить #include "foo.h"
(18:01:11) Улідтко: відповідно, є окремі foo.c і foo.h
(18:01:56) Улідтко: в foo.h визначені деякі інтерфейсні типи даних та функція func, що працює з ними
(18:02:29) Улідтко: (як ми знаємо, в .h заголовках функції лише декларуються, коду там немає)
(18:02:45) Улідтко: власне код функції описується в foo.c
(18:02:58) bunyk: ну…
(18:03:11) Улідтко: Подумаєм, як проходить процес компіляції
(18:04:17) Улідтко: gcc foo.c -o foo.o дасть нам "об’єктний файл" foo.o
(18:04:32) Улідтко: що таке об’єктний файл?
(18:04:49) Улідтко: це файл, в якому зберігається машинний код функції func
(18:05:11) Улідтко: все, лише самі інструкції
(18:05:21) Улідтко: платформно-залежні і все таке
(18:05:56) Улідтко: для його генерації компілятор використовував метадані із foo.h і код із foo.c
(18:06:22) Улідтко: далі — як компілюється main.c?
(18:06:40) bunyk: gcc main.c main -lfoo
(18:06:43) bunyk: ?
(18:06:50) Улідтко: %)
(18:06:51) Улідтко: ні
(18:07:16) Улідтко: отримаєш якийсь різновид file not found
(18:07:45) Улідтко: зрозуміло, що gcc main.c -o main не піде
(18:07:47) Улідтко: чому?
(18:08:11) bunyk: бо нема коду func
(18:08:38) Улідтко: правильно, хоча власне компілятору це не заважає
(18:09:00) Улідтко: він знає, які у func аргументи і тип результату
(18:09:10) Улідтко: (із foo.h)
(18:09:49) Улідтко: і вільно перетворює виклики func у машинний код
(18:10:51) Улідтко: він може це робити, бо у .o файлах конкретні адреси (функцій, змінних) не використовуються
(18:11:10) Улідтко: використовуються символічні імена, references
(18:11:41) Улідтко: таким чином ми можемо скомпілювати_ main.c в main.o
(18:12:12) Улідтко: але воно не є придатним для виконання
(18:12:23) Улідтко: бо нема конкретних адрес, які потрібні процесору
(18:12:35) Улідтко: от в цьому і полягає задача лінкера
(18:13:43) Улідтко: він повинен сумістити main.o і foo.o в один виконуваний файл, склавши все це в купу і назначивши усім символічним іменам конкретні адреси
(18:14:20) Улідтко: і позамінявши усі звернення до цих символічних імен на їх конкретні адреси
(18:15:28) Улідтко: тобто, в коді функції main виклики call func будуть перетворені в call 0x04053a8, наприклад
(18:15:37) Улідтко: (в машинному коді)
(18:16:04) Улідтко: це все уже буде придатним до виконання на процесорі
(18:16:41) Улідтко: Прикол в тому, що gcc насправді для полегшення нашого життя викликає лінкера самотужки
(18:17:11) Улідтко: (а також препроцесора, асемблера та інші штуки)
(18:17:35) Улідтко: від чого, власне, і вийде помилка при спробі gcc main.c -o main
(18:17:47) Улідтко: воно скаже undefined reference
(18:18:18) Улідтко: бо ніякої конкретної адреси для func не знайдеться
(18:18:43) Улідтко: От це все називається статичним лінкуванням.
(18:19:13) Улідтко: весь код включається в результатуючий виконуваний файл
(18:20:31) bunyk: так, як таки його відкомпілювати
(18:20:49) Улідтко: gcc main.c foo.c -o main 🙂
(18:21:08) bunyk: ага. 🙂
(18:21:11) Улідтко: це найзручніший і найнеочевидніший спосіб, коротше 🙂
(18:21:38) Улідтко: якщо змусити gcc бути лише компілятором, то сценарій був би приблизно таким:
(18:21:50) Улідтко: gcc foo.c -o foo.o
(18:21:56) Улідтко: gcc main.c -o main.o
(18:22:16) Улідтко: ld foo.o main.o
(18:22:37) Улідтко: ну, і перейменувати готовий a.out
(18:23:40) bunyk: а -lGL що значить? Шукати об’єктний код десь в /usr/lib ?
(18:23:59) Улідтко: так, чекай
(18:24:05) Улідтко: це лише одна модель лінкування
(18:24:08) Улідтко: статичне
(18:24:45) Улідтко: Припустимо далі, шо ти використовуєш якусь велику класну бібліотеку, типу OpenGL
(18:25:31) Улідтко: якшо ти будеш лінкувати статично
(18:25:44) Улідтко: то весь код цієї бібліотеки потрабить до твого бінарника
(18:26:14) Улідтко: далі, хтось інший пише іншу прожку, яка теж використовує OpenGL
(18:26:32) Улідтко: або ти пишеш другу прожку, яка теж використовує OpenGL
(18:26:56) Улідтко: і, якщо лінкувати далі статично, то код бібліотеки потрапляє і туди, і туди, і туди.
(18:27:09) Улідтко: це викликає тучу проблем
(18:27:20) Улідтко: очевидно, що бінарний код бібліотеки дублюється
(18:27:24) bunyk: а це щось типу dll?
(18:27:34) Улідтко: витрачаючи різні види ресурсів
(18:28:40) Улідтко: … і ускладнюючи підтримку софта (обновлення бібліотеки не будуть використовуватися прожками, поки вони не будуть перекомпільовані)
(18:29:04) Улідтко: от для цього і є динамічне лінкування
(18:29:23) Улідтко: так, dll — це dynamic linking library
(18:31:09) Улідтко: воно заключається в тому, що твоя прожка має в бінарному вигляді має так звану таблицю імпорту
(18:31:33) Улідтко: це куча змінних
(18:31:38) Улідтко: вказівників
(18:31:55) Улідтко: а саме, вказівників на функції
(18:32:18) Улідтко: на функції з тих самих dll’ок
(18:33:44) Улідтко: при запуску такої прожки операційна система знаходить і завантажує усі потрібні dll’ки, а потім заносить у цю саму таблицю імпорту всі вказівники на реальні функції з бібліотек
(18:35:33) Улідтко: знову ж таки, власне компілятора не хвилює де саме будуть розміщені коди функцій
(18:35:50) Улідтко: хоча, насправді, ні, хвилює 🙂
(18:36:16) Улідтко: синтаксично функції позначаються як імпортовані із dll
(18:36:49) Улідтко: а компілятор замість call func генерує інструкціє вигляду call [_import_table_entry_for_func]
(18:37:33) Улідтко: тобто, адреса для call витягується із пам’яті за адресою _import_table_entry_for_func
(18:38:00) Улідтко: _import_table_entry_for_func — це, ефективно, змінна-вказівник
(18:38:35) Улідтко: знову ж таки, компілятор не знає (і не має знати) точної, конкретної адреси цього вказівника
(18:38:57) Улідтко: він звертається до нього символічно
(18:39:32) Улідтко: а задача лінкера в цьому випадку — окрім іншого, сформувати таблицю імпорту
(18:40:59) Улідтко: розмістити, як і раніше, змінні-вказівники, і на додаток до цього, надати інформацію, потрібну для операційної системи для заватнаження dll’ок
(18:41:50) Улідтко: *.dll під юніксами мають імена lib*.so
(18:42:15) bunyk: я знав! /usr/lib/ 🙂
(18:42:22) Улідтко: угу
(18:43:11) Улідтко: але в /usr/lib є два набори файлів: lib*.so та lib*.a
(18:44:18) Улідтко: .a — це просто архіви .o, тобто це static link library
(18:45:49) Улідтко: max@ulidtko:~$ ls /usr/lib/libGL.so
(18:46:19) Улідтко: відповідно, щоб скомпілювати прожку із використанням OpenGL, ти маєш сказати
(18:46:30) Улідтко: gcc main.c -lGL
(18:47:26) Улідтко: щоб лінкер, викликаний gcc, прикрутив усі gl* функції до динамічної бібліотеки libGL.so
(18:47:38) bunyk: Ооо! Тепер ясно.
(18:48:31) bunyk: Дякую.

Written by bunyk

14 Вересня, 2009 at 15:31

Опубліковано в Інструменти, Кодерство

Tagged with ,