1 Ответы
Цитата:Стало известно, что энтузиастам ретросистем удалось урегулировать вопрос с лицензией на исходные тексты операционной системы CP/M, которая в 70-е годы прошлого века доминировала на компьютерах с 8-битными процессорами i8080 и Z80. Компания Lineo Inc, которой перешла интеллектуальная собственность разработчика CP/M в лице Digital Research, передала код ОС в руки сообщества cpm.z80.de в 2001 году.

Лицензия на переданный код допускала его использование, распространение и изменение, но с пометкой, что эти права распространяются на участников упомянутого сообщества. Из-за этого разработчики связанных с CP/M проектов, таких как CP/Mish, не использовали оригинальный код ОС, поскольку это могло привести к нарушению лицензии. Один из энтузиастов связался с президентом компаний Lineo и DRDOS Брайаном Спарксом и попросил его уточнить, что конкретно имелось ввиду при упоминании отдельного сайта в лицензии.

В ответ на это Спаркс сообщил, что изначально он не планировал передавать код ОС только одному сайту, и упоминание конкретной площадки является лишь отдельным частным случаем. Он также дал официальные разъяснения по данному вопросу, в которых от имени компании, владеющей интеллектуальными правами на CP/M, указал, что определённые в лицензии условия применимы ко всем желающим. Это означает, что текст лицензии по своей сути аналогичен лицензии MIT.

Напомним, исходные тексты CP/M написаны на языке PL/M и ассемблере. Ознакомиться с этой операционной системой можно с помощью эмулятора, работающего в веб-браузере.

Источник
10 Ответы
   
Nokia представила три фичерфона.

Первый - Nokia 5710 XpressAudio. Он поддерживает 4G, в комплект входят беспроводные наушники. Их можно заряжать из встроенного в телефон кейса. Их хватает на 4 часа музыки или 2.5 часа разговора. У телефона съёмная батарея на 1450 мАч.

Второй - Nokia 8210 4G. Он основан на дизайне Nokia 8210, вышедшей в 1999 году.

Третий - Nokia 2660 Flip.

Дополнительно Nokia представила планшет Nokia T10.

   
Nokia T10, Nokia 8210 4G, Nokia 2660 Flip и Nokia 5710 XpressAudio

https://www.theverge.com/2022/7/12/23199...rging-case
1 Ответы
В этой небольшой статье я решил написать про язык программирования D, что он из себя представляет, его плюсы и минусы, а также какие платформы им поддерживаются и т.п.

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

Некоторые маленькие куски были скопированы из других источников.

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

***

Кратко о том, что из себя представляет язык программирования D

Начать стоит с трёх данных вещей:
  1. D - очередной ужасно медленный убийца с крайне неэффективным оружием C и C++ (но заявляется только про C++). Эту задачу он благополучно провалил.
  2. Вакансий по нему почти нет. Т.е. если писать на нём - то разве что в качестве хобби. Язык используется в различных организациях, хоть и список известных достаточно мал. Несмотря на это, по нему проводятся конференции и различные митапы.
  3. Язык, вроде бы, считается мёртвым. Тем не менее, хоть на нём и не выходит каких-то крупных проектов и не случается громких анонсов, его используют довольно много небольших и средних проектов. Некоторые из них можно увидеть здесь.

D - мультипарадигменный (императивное, объектно-ориентированное, функциональное, контрактное, обобщённое программирование) статически типизированный компилируемый язык программирования с Си-подобным синтаксисом и довольно богатой стандартной библиотекой. Изначально создавался как улучшенный C++. Компилятор изначально был закрытым и платным, потом (в 2007 году) стандартная библиотека была полностью переписана. В итоге хоть язык и стабилизировался и обзавёлся аж тремя компиляторами (о них ниже), но огромной популярности не набрал. 

Версионирование отличается от C и C++. В C и C++ версии привязаны к стандартам (т.е. это и есть версии), в то время как в D это что-то вроде роллинг релиза (т.е. новые версии появляются довольно часто). При этом, legacy и deprecated за 15 лет появилось очень мало, а крупных изменений синтаксиса и вовсе не было (тут я, конечно, могу ошибаться, но код десятилетней давности у меня заводился с минимальными правками). 

Вот несколько интересных штук, которые есть из коробки: неизменяемые (immutable) переменные, инструменты для гарантии безопасной работы с памятью, полная поддержка юникода и инструменты для работы с ним, юнит-тесты, модули вместо заголовочных файлов (о них ниже), ассоциативные массивы, CTFE (Compile Time Function Execution - выполнение функций во время компиляции), лямбда-функции.

Что вы получите, выбрав D:
  • Своевременное получение современных возможностей
  • Unicode из коробки и инструменты для работы с ним
  • Знакомый и интуитивный синтаксис
  • Богатую стандартную библиотеку, в которой есть очень много часто используемых вещей, чтобы не пришлось велосипедить. Плюс различные функции алгоритмов (сортировки, итераторы, сравнения, поиск и т.д.), поддержка регулярных выражений, лямбда-функции,
  • Исправленные недочёты касаемо других, более старых языков. Например, единица кода в D - модуль. Модуль может быть как одним файлом .d, так и набором таких файлов (для комплексных модулей). Нет разделения на заголовочный файл и файл исходного кода. Компилятор D куда более продуман и подогнан под современные реалии, так что функции можно размещать в любом порядке, не требуется жонглирование с #pragma once и extern - в общем, те вещи, которые объективно устарели, в D отсутствуют.
  • Возможность связывания (binding) с кодом на языке C. Создание биндингов для готовых библиотек очень простое, при наличии списка известных функций и переменных, не в последнюю очередь из-за совместимости некоторых типов.
  • Фичи, которые добавят в грядущем стандарте C++, но которые в D были уже 10 лет назад.

Компиляторы

Тут всё просто. Есть DMD, существующий ради эталонной реализации, и поддерживающий всего две платформы. Есть LDC, который поддерживает огромное количество платформ, имеет хорошую оптимизацию и рекомендуется к использованию. Есть GDC, который существует ради лицензии. Список поддерживаемых платформ находится здесь: https://dlang.org/spec/version.html#predefined-versions (пример будет ниже).

В отличие от компиляторов C/C++, компиляторы D при ошибке компиляции выдают только важную информацию, не замусоривая вывод.

Сборка даже крупных проектов проходит очень быстро. Итоговое приложение очень хорошо оптимизировано.

Стандартная библиотека

В D есть стандартная библиотека, которая называется Phobos. Она довольно богатая и содержит много полезных функций, позволяя не велосипедить и увеличить продуктивность написания кода. Например: алгоритмы, правильная конвертация переменных, работа с чексуммами, математические функции, регулярные выражения, поддержка JSON.

Есть три минуса:
  1. Стандартную библиотеку надо всегда таскать с бинарником. Т.к. в системе она обычно не установлена (это ж не libc какая-нибудь), то при сборке она встраивается в бинарник. Возможность сборки без вкомпилирования стандартной библиотеки присутствует.
  2. У каждого компилятора своя реализация стандартной библиотеки.
  3. Отдельно библиотеку установить можно не во всех дистрибутивах. Она есть в Ubuntu, Debian, Fedora, Arch. В других я не проверял.

Стандартная библиотека занимает около 300 КБ в итоговом бинарнике.

Не все функции из стандартной библиотеки могут быть всегда доступны, об этом ниже.

Поддерживается кросскомпиляция (код может быть собран для другой платформы).

Области применения

На D возможны такие вещи, как:
  • Пользовательские и системные приложения
  • Динамические и статические библиотеки
  • Ядра и операционные системы (PowerNex, XOmB, Trinix, https://wiki.osdev.org/D_Bare_Bones)
  • Прошивки для микроконтроллеров и одноплатных ПК (пока только на ARM, с использованием LWDR) (пример)
  • Браузерные приложения (WebAssembly или с помощью Emscripten, хоть и неофициально)
  • С помощью rdmd можно использовать .d-файлы как скрипты, и запускать их напрямую из терминала
  • Веб-сайты и веб-приложения с помощью фреймворков Vibe.d, Hunt и других.


Поддерживаемые платформы

Помимо основных платформ (Windows, Linux, macOS, FreeBSD, Android (но только в виде библиотеки)) поддерживается создание "сырых" бинарных файлов для "железа". Поддерживаются X86, ARM, MIPS, SPARC, PowerPC и множество других платформ. Это позволяет создавать SDK под платформы вроде Nintendo 3DS, PSP, Playdate и других игровых консолей.

Модули

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

Модуль - обычный файл .d. В нём можно явно задать имя модуля (тогда название файла может быть любым), или импортировать по имени файла.

Код:
// module_test_blah_blah_1.d
module my_awesome_module;
import std.format;

string TestFunction(int a, int b)
{
    return (format("The sum is %d", a + b));
}

// main.d
import std.stdio;

import my_awesome_module;

void main()
{
    writeln(TestFunction(2, 4)); // The sum is 6
}

Можно импортировать модули и давать им другие названия:
Код:
import io_1 = std.stdio;

void main()
{
    io_1.writeln("Hello, World!");
}

Можно импортировать только определённый список функций из модуля:
Код:
import io_1 = std.stdio : writeln; // Будет доступна только функция writeln

void main()
{
    io_1.writeln("Hello, World!");
}

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

Для D существует каталог сторонних модулей. Как pip для Python или npm для NodeJS. Модули устанавливаются через DUB.

GUI

На D можно писать приложения с:
  • GTK (пока только 3)
  • Qt5 (с некоторыми ограничениями)
  • Tk
  • Нативный интерфейс в Windows (через WinAPI) и macOS (через сторонний модуль)
  • SDL2 (но это уже больше для игр, тем не менее возможность есть)

Честно скажу, что насчёт других тулкитов и платформ я пока не интересовался.

Структура проекта

Можно как вручную компилировать отдельные файлы, так и создать проект с полноценной структурой.

Для управления проектом существует DUB. Среди его функций:
  • Инициализация проекта
  • Управление сторонними модулями (поиск, установка и удаление)
  • Сборка проекта
  • Запуск приложения
  • Тестирование приложения

Для указания свойств проекта используется файл dub.json (или dub.sdl, кому как удобнее). В нём указываются такие свойства, как:
  • Тип проекта (приложение, библиотека и т.д.)
  • Название проекта
  • Параметры компилятора
  • Параметры линкера
  • Список требуемых модулей
  • Список требуемых версий компиляторов
  • Лицензия (для публикации проекта)
  • Команды до и после сборки проекта
  • Список конфигураций сборки

Про последнее напишу подробнее.

Конфигурации позволяют собирать проект с разными параметрами и под разные платформы. Вот пример:
Код:
{
"authors": [
"user"
],
"copyright": "Copyright © 2022, user",
"description": "A minimal D application.",
"license": "proprietary",
"name": "dub_test",
"configurations": [
{
"name": "config_1",
"targetType": "executable",
"platforms": ["linux"],
"buildTypes":
{
"debug":
{
"buildOptions": ["debugMode"]
},
"release":
{
"buildOptions": ["releaseMode", "optimize"]
}
}
},
{
"name": "config_2",
"targetType": "executable",
"platforms": ["linux"],
"dflags-ldc": ["-release", "-Oz"],
"postBuildCommands": ["strip -S dub_test"]
}
]
}

Здесь присутствуют две конфигурации. Первая собирает проект, и в зависимости от типа сборки (отладочная или релизная) устанавливает разные опции компилятора. По сути, buildOptions - это другие названия уже существующих опций компилятора, чтобы избавить от необходимости задавать опции для каждого отдельного компилятора (у которых могут быть свои названия опций).

dflags-ldc - пример передачи опций напрямую компилятору, в данном случае LDC. Данная опция ещё может называться dflags-dmd, dflags-gdc или просо dflags (тогда не будет учтён компилятор). -Oz - оптимизация по размеру. Использование передачи опций напрямую компилятору не рекомендуется, но такая возможность есть.

В config_2 после сборки вызывается strip.

Проект можно собрать так:
Код:
dub build -c config_1 -b=debug
dub build -c config_1 -b=release
dub build -c config_2

Где -c - название конфигурации, -b (или --build) - тип сборки.

В качестве альтернативы существует сборочная система Reggae. Но лично я про неё ничего рассказать не могу, т.к. ещё не пользовался.

Помимо этого можно использовать Make. Лично для меня этот способ неудобен.

Типы переменных

Поддерживаются как стандартные для C типы переменных (int, char, float, short, long, double, void), так и другие: string, byte, bool, real, cent (пока не реализован, в будущем это будет 128-битный тип). Целочисленные переменные поддерживают беззнаковость (например, uint, ubyte, ulong, ushort). Полный список типов находится здесь: https://dlang.org/spec/type.html

Поддерживается работа с указателями.

Синтаксис

Синтаксис очень сильно похож на C/C++/C#/Java. В D он интуитивно понятен и имеет различные улучшения. Условия, циклы - всё почти то же самое, что и в C/C++/etc. Если вы уже знаете какой-нибудь из этих языков или пробовали на них писать - для вас порог вхождения ещё ниже.

Пример Hello World:
Код:
import std.stdio;

void main()
{
    writeln("Hello, World");
}

Отсутствуют области видимости - можно размещать функции в любом порядке:
Код:
import std.stdio;

void main()
{
    TestFunction();
}

void TestFunction()
{
    writeln("Hello World!");
}

Массивы, звёздочки в указателях перемещены к типу переменной, что, как мне кажется, визуально удобнее.
Код:
int[] a;
char* b;

Многие вещи, которые являются макросами в C/C++, в D присутстувют из коробки:
Код:
int.min
int.max
float.max
char.max
char.min
ulong.max
double.min_normal

double.nan
double.infinity
double.dig
double.epsilon
double.mant_dig
double.max_10_exp
double.max_exp
double.min_10_exp
double.min_exp

Из коробки присутствует цикл foreach:
Код:
import std.stdio;

void main()
{
    int[5] intArray = [1, 2, 3, 4, 5];
   
    foreach (i; intArray)
    {
        writef("%d ", i);
    }
}

У массивов есть свойство length:
Код:
import std.stdio;

void main()
{
    string str = "Hello, World!";
    int[] a = new int[](10);
   
    writefln("str's length is: %d\na's length is: %d", str.length, a.length);
    //str's length is: 13
//a's length is: 10
}

В D очень простое соединение массивов:
Код:
import std.stdio;

void main()
{

    int[] arr1 = [1, 2, 3];
    int[] arr2 = [4, 5];
    int[] arr3 = arr1 ~ arr2; //[1, 2, 3, 4, 5]

    string str1 = "Hello";
    string str2 = "World";
    string str_result = str1 ~ ", " ~ str2 ~ "!";
   
    writeln(str_result); // Hello, World!
}

Оператор ~ отвечает за конкатенацию. Для неё не требуется выделение дополнительной памяти. Также возможно использование ~=, что будет равносильно += для чисел. Эти операторы работают со всеми массивами (строки тоже являются массивами - dchar[]).
Код:
import std.stdio;

void main()
{
    int[] a;
   
    for (int i = 0; i < 10; i++)
    {
        a ~= i;
    }
   
    writeln(a); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
}

Работа с массивами в циклах сделана удобнее:
Код:
import std.stdio;

void main()
{
    int[5] intArray = [1, 2, 3, 4, 5];

foreach (i; intArray[2..$])
    {
        writef("%d ", i); // 3 4 5
    }
   
    writeln();
   
    foreach (i; 0..10)
    {
        writef("%d ", i); // 0 1 2 3 4 5 6 7 8 9
    }
}

$ означает конец массива.

Таким образом можно сравнить кусок строки:

Код:
import std.stdio;

void main()
{
    string testString = "Hello, World!";
   
    for (int i = 0; i < testString.length; i++)
    {
        if (testString[0..5] == "Hello")
        {
            writeln("World");
            break;
        }
    }
}

Функции могут вызываться и так:
Код:
import std.stdio;

void main()
{
    "Hello, World".writeln();
}

Это - универсальный синтаксис вызова функций. Благодаря этому цепочки функций могут выглядеть так:
Код:
import std.stdio;
import std.string;

void main()
{
    string hw = "Hello, World!";
   
    writeln(replace(toUpper(hw), ", ", "_")); // HELLO_WORLD!
    writeln(toUpper(hw).replace(", ", "_"));
}

Оператор switch тоже имеет некоторые улучшения:
Код:
import std.stdio;

void main()
{
    string testStr = "Test";
   
    switch (testStr)
    {
        case ">_<":
        case "X_X":
        writeln("testStr is >_< or X_X");
        break;
        case "Test":
        writeln("testStr is Test");
        break;
        default:
        writeln("well...");
        break;
    }
}

Во-первых, из коробки в языке присутствует сравнение строк. Во-вторых, можно указать несколько case. Также существует final switch на случай, если все возможные варианты учтены:
Код:
import std.stdio;

void main()
{
    string testStr = "Test";
   
    final switch (testStr)
    {
        case ">_<":
        case "X_X":
        writeln("testStr is >_< or X_X");
        break;
        case "Test":
        writeln("testStr is Test");
        break;
    }
}

Благодаря тому, что в стандартной библиотеке есть реализации различных итераторов и поддержка лямбда-функций, вместо написания нескольких (десятков) строк кода возможны такие вполне лаконичные конструкции:
Код:
import std.stdio;
import std.algorithm;

void main()
{
    int[] arr = [2, 4, 6, 8];
   
    // Проведение операции над каждым элементом массива
    writeln(arr.map!((a) => a + a)); // [4, 8, 12, 16]
   
    // Проведение операции над каждым элементом массива
    writeln(arr.map!((a) => a * a)); // [4, 16, 36, 64]
   
    // Сложение всех элементов массива
    writeln(arr.fold!((a, b) => a + b)); // 20
   
    //Сортировка
    writeln(arr.sort!((a, b) => b < a)); // [8, 6, 4, 2]
}

Возможно указать код для определённой платформы:
Код:
import std.stdio;

void main()
{
    version(linux)
    {
        writeln("Hello, Linux!");
    }
    version(Windows)
    {
        writeln("Hello, Windows!");
    }
}

В D есть обработка исключений.
Код:
import std.stdio;
import std.file;

void main()
{
    try
    {
        File someFile = File("/tmp/blahblahblah", "r"); // Попытка открыть несуществующий файл
        someFile.close();
    }
    catch (FileException ex)
    {
        writeln(ex); // std.exception.ErrnoException@std/stdio.d(636): Cannot open file `/tmp/blahblahblah' in mode `r' (No such file or directory)
    }
}

Блоков catch может быть несколько, и они могут быть разными.

В D из коробки присутствуют юнит-тесты. Есть два варианта их использования.

Первый:
Код:
import std.stdio;

void main()
{
    writeln("Hello, World!");

    assert(2 + 2 == 5); // core.exception.AssertError@onlineapp.d(7): Assertion failure
}

Второй - прописать в отдельном блоке. Тогда при сборке можно будет указать опцию -unittest, чтобы компилятор провёл юнит-тестирование.
Код:
import std.stdio;

class TestClass
{

    int sum(int a, int b)
    {
        return a + b;
    }
}

void main()
{
    writeln("Hello, World!");
}

unittest
{
    TestClass testClass = new TestClass();
    assert(testClass.sum(2, 2) == 4);
    assert(testClass.sum(3, 3) == 6);
    // 1 modules passed unittests
}
Код:
import std.stdio;

class TestClass
{
    int a;
    this()
    {
        a = 5;
    }
}

void main()
{
    writeln("Hello, World!");
}

unittest
{
    TestClass testClass = new TestClass();
    assert(testClass.a < 5);
    // [unittest] Assertion failure
    // 1/1 modules FAILED unittests
}

Блоков unittest может быть много, и они могут присутствовать в разных файлах.

Для управления памятью, инициализации массивов и классов используются new и destroy.
Код:
import std.stdio;

struct TestStruct
{
    int a;
    string str;
    long c;
}

void main()
{   
    TestStruct[] a = new TestStruct[](4);
   
    for (int i = 0; i < a.length; i++)
    {
        a[i] = TestStruct(i, "Hello, World!", i * 2);
    }
   
    writeln(a); // [TestStruct(0, "Hello, World!", 0), TestStruct(1, "Hello, World!", 2), TestStruct(2, "Hello, World!", 4), TestStruct(3, "Hello, World!", 6)]
    destroy(a);
}

В D можно распараллелить многое. Например:
Код:
import std.stdio;
import std.parallelism;

void main()
{
string[] testStr = new string[](5);
testStr = [
"Line 1",
"Line 2",
"Line 3",
"Line 4",
"Line 5",
];

foreach (key; testStr)
{
writeln(key);
}

writeln();

foreach (key; testStr.parallel)
{
writeln(key);
}
}

Это возможно благодаря функции parallel из модуля std.parallelism.

Результат:
Код:
Line 1
Line 2
Line 3
Line 4
Line 5

Line 1
Line 3
Line 4
Line 5
Line 2

Т.к. элементы обрабатываются параллельно, то это во многих случаях ускорит работу.

Допустим, нам нужно 100 тысяч раз посчитать квадратный корень для 100 тысяч чисел. Нет, ну вдруг. Пример слишком надуманный, но в реальной разработке могут попадаться подобные вещи.

В D есть инструменты для бенчмаркинга.
Код:
import std.datetime.stopwatch;
import std.math;
import std.parallelism;
import std.stdio;
import std.conv;

void main()
{
float[] sq = new float[](100_000);

Duration[2] bm = benchmark!({
foreach(i, ref x; sq)
{
x = sqrt(to!float(i));
}
}, {
foreach(i, ref x; sq.parallel)
{
x = sqrt(to!float(i));
}
})(100_000);

writefln("Linear sqrt test: %s msecs\nParallel sqrt test: %s msecs", bm[0].total!"msecs", bm[1].total!"msecs");
}

Результат на AMD Ryzen 5 1500X:
Код:
Linear sqrt test: 13874 msecs
Parallel sqrt test: 7998 msecs

Символ подчёркивания необязателен, он просто визуально улучшает разборчивость. to!float - конвертирование переменной из int в float.

Безопасность и стабильность

Пока вы используете инструменты и функции языка D, не обращаясь к функциям из C - вероятность сегфолтов и падений при использовании отлова исключений стремится к нулю. Исключения обработать можно для почти всех инструментов в D, даже у простых вещей, вроде выхода из границ массива. Для выделения и освобождения памяти используются new и destroy. И хоть десять раз вы решите освободить одну и ту же область памяти - приложение не упадёт, т.к. всегда происходит проверка.

Вероятность UB (undefined behavior, неопределённое поведение) сведена к минимуму. Нет "особенностей" вроде вывода мусора как в printf("%d\n"). Проверки есть везде.

Подробнее про безопасную работу с памятью можно почитать здесь.
1 Ответы
Компилятор D позволяет линковать итоговый бинарник с практически любым .o файлом. Таким образом, можно написать часть приложения на C (например, если не нашлось подходящего модуля для D). По сути, получается что-то вроде написания заголовочного файла, но без необходимости компилировать отдельно в .a/so/dll/etc.

Данный пример - всего лишь Hello World, но его вполне достаточно, чтобы продемонстрировать эту возможность. Работоспособность проверена в Linux, в других системах я не проверял.

Файл source/test_c.c:
Код:
#include <stdio.h>

void CTestFunction(char* charvar)
{
    printf("%s\n", charvar);
}

Файл source/app.d:
Код:
import std.stdio;

extern (C) void CTestFunction(char* charvar);

void main()
{
    CTestFunction(cast(char*)("Hello, World!"));
}

Через extern © объявлена функция из файла test_c.c.

Теперь dub.json. То, благодаря чему это работает.
Код:
"preBuildCommands": ["cc -c $PACKAGE_DIR/source/test_c.c -o $PACKAGE_DIR/source/test_c.o"],
"lflags": ["$PACKAGE_DIR/source/test_c.o"]

Первая опция компилирует test_c без вызова линкера. Вторая опция линкует файл с итоговым бинарником.

Проверяем:
Код:
(ldc2-1.29.0-linux-x86_64)user@desktop ~/d/c_linker_test> ./c_linker_test
Hello, World!

Таким образом можно взаимодействовать с различными штуками через C.
6 Ответы
Курсы станут дополнительными к основному образованию и продлятся два года.
Ученики 8-11 классов смогут пройти бесплатные двухлетние курсы и освоить современные языки программирования. Соответствующие правила подписал премьер-министр РФ Михаил Мишустин.
  • Программа будет состоять из четырех модулей по 36 академических часов;
  • Продолжительность обучения — два года;
  • Форматы обучения: онлайн и офлайн — на базе региональных образовательных площадок;
  • На портале «Госуслуги» можно будет пройти тестирование, по итогам которого определять уровень знаний, и помогут записаться на соответствующий курс;
  • Курсы станут дополнением к базовой школьной программе по математике и информатике.

http://static.government.ru/media/files/...ZErALe.pdf
5 Ответы
Цитата:Ростех освоил технологию собственного производства из российских материалов монокристаллического кремния с удельным электрическим сопротивлением более 1000 Ом-сантиметров.

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

https://rostec.ru/news/rostekh-sozdal-kr...opriborov/
17 Ответы
Цитата:«Вымпелком» (бренд «Билайн») первым из крупных операторов фактически откажется от стандарта связи 3G в Москве и Подмосковье. К сентябрю оператор завершит перевод сетей стандарта 3G в диапазоне 2,1 ГГц на технологию LTE (4G) в Москве и Московской области.

В компании заявили, что трафик 3G стабильно падает (в 2022 году в столице и Подмосковье у оператора на него пришлось лишь 4%), а потребление LTE растет. Эти изменения должны позволить увеличить емкость сети передачи данных на 50%. В Московском регионе для 3G оператор оставит самую низкую и короткую полосу — 900 МГц (только для голосовых звонков). До конца 2023 года «Вымпелком» планирует отказаться от 3G в более чем 25 регионах России.

Гендиректор «ТМТ Консалтинга» Константин Анкилов заявил, что сети 3G — первый кандидат на отключение в условиях дефицита емкости сетей. Операторы оставляют GSM-сети для того, чтобы в самых удаленных местах абоненты имели доступ к голосовой связи, а доступ в интернет обеспечивается уже по LTE-сетям.

В Московском регионе меньше 3% смартфонов, поддерживающих только сети 3G, в регионах таких устройств осталось до 5%. Постоянно используют подобные смартфоны не более 1% абонентов мобильной связи. Если они используют мобильный интернет, придётся менять смартфон.

Те, кто пользуется простыми кнопочными телефонами для звонков, не пострадают, частоты 2G продолжают работать. Аналитики полагают, что ускорять переход на современные стандарты будут все операторы.

Источник.

Ну и традиционно к новости мое мнение: сам 3G уже давно не видел на смартфоне, но периодически в разных дребеденях телефон на него переходит. И скорости там... нет. 

Был модем от мегафона, старенький, пользовал его почти 10 лет, пока не заметил, что скорость на нем какая-то слишком уж маленькая. Оказалось, что тоже дело в 3G, и хотя Мегафон на вопрос «Режете или нет?» ответил «Найн!», мне казалось, что они специально глушат скорость «старых» форматов. 

В догонку к последнему абзацу — когда-то с этого модема в интернете сидел весь наш отдел, то есть около 15 человек, и всем хватало Smile
Нет ответов
Иногда решение (.sln) может не загрузиться, в консоли появится ошибка, что открыть получилось не все файлы.

Чинится это так: в $HOME/.config/Code/User/settings.json добавьте (или поправьте, если уже есть) следующую строку:
Код:
"omnisharp.useGlobalMono": "never"
Перезапустите VS Code. Теперь решение проекта должно загружаться (в т.ч. если открывать его не напрямую, а только какой-нибудь скрипт в проекте).

Возможно, это относится и к другим проектам на C#.
2 Ответы
В Armbian OTG включается в armbian-config, и обычно включён по умолчанию. Нужно только модифицировать boot.cmd.

Управление будет доступно через Serial Port.

В /etc/rc.local добавьте следующую строку перед exit 0:
Код:
echo -n 2 > /sys/bus/platform/devices/sunxi_usb_udc/otg_role
Эта команда включает OTG и передаёт управление USB одноплатнику, а не ПК.

В /boot/boot.cmd добавьте в конце строки, которая начинается с setenv bootargs, в кавычки:
Код:
console=ttyS0,115200 console=ttyGS0,115200
Это перенаправит вывод из TTY в Serial Port. Через запятую задаётся скорость в битах.

Пересоберите boot.scr:
Код:
mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr
Готово. Подключите одноплатник к компьютеру через USB (лучше подключать через 3.0, ибо на 2.0 при нагрузке одноплатник может отключиться). В dmesg должно появиться что-то подобное:
Код:
[54836.584466] usb 1-8: new high-speed USB device number 21 using xhci_hcd
[54836.795864] usb 1-8: New USB device found, idVendor=0525, idProduct=a4a7, bcdDevice= 5.15
[54836.795875] usb 1-8: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[54836.795879] usb 1-8: Product: Gadget Serial v2.4
[54836.795881] usb 1-8: Manufacturer: Armbian Linux 5.15.48-sunxi with musb-hdrc
[54836.819015] cdc_acm 1-8:2.0: ttyACM0: USB ACM device
Где ttyACM0 - интерфейс, по которому нужно подключаться.