<?xml version="1.0"?>
<rss version="2.0"><channel><title>&#x41F;&#x440;&#x43E;&#x433;&#x440;&#x430;&#x43C;&#x43C;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x435; Latest Topics</title><link>https://electronix.ru/forum/forum/154-programmirovanie/</link><description>&#x41F;&#x440;&#x43E;&#x433;&#x440;&#x430;&#x43C;&#x43C;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x435; Latest Topics</description><language>en</language><item><title>&#x432;&#x43E;&#x43F;&#x440;&#x43E;&#x441; &#x43F;&#x43E; lwIP</title><link>https://electronix.ru/forum/topic/95218-vopros-po-lwip/</link><description><![CDATA[
<p>Больше не знаю, где задать этот вопрос...</p>
<p>
Заметил у lwIP такую проблему, что если при пропадании линка закрывать сокет, а при восстановлении линка создавать его заново, валятся ошибки выделения памяти MEMP_TCP_PCB. Проблема, судя по всему, в том, что при пропадании линка сокет остаётся активным и не может корректно закрыться. При последуюшем создании сокета обнаруживается, что больше свободных сокетов нет и после принудительного удаления активного соединения всё создается как надо.</p>
<p>
Проблема не очень серьёзная, но хотелось бы выяснить, как её обойти, и у всех ли она проявляется. </p>
<p>
Для проверки попробуйте создавать сокет после появления линка, закрывать через close после исчезновения линка. Ограничьте память до одного сокета: MEMP_NUM_TCP_PCB = 1.</p>
]]></description><guid isPermaLink="false">95218</guid><pubDate>Thu, 06 Oct 2011 10:15:45 +0000</pubDate></item><item><title>&#x421;&#x438;++ 17, &#x432;&#x43E;&#x437;&#x432;&#x440;&#x430;&#x449;&#x430;&#x435;&#x43C;&#x44B;&#x439; &#x442;&#x438;&#x43F; &#x444;&#x443;&#x43D;&#x43A;&#x446;&#x438;&#x438; &#x434;&#x43E;&#x43B;&#x436;&#x435;&#x43D; &#x437;&#x430;&#x432;&#x438;&#x441;&#x435;&#x442;&#x44C; &#x43E;&#x442; &#x437;&#x43D;&#x430;&#x447;&#x435;&#x43D;&#x438;&#x44F; &#x430;&#x440;&#x433;&#x443;&#x43C;&#x435;&#x43D;&#x442;&#x430;</title><link>https://electronix.ru/forum/topic/217753-si-17-vozvraschaemyy-tip-funktsii-dolzhen-zaviset-ot-znacheniya-argumenta/</link><description><![CDATA[<p>
	Добрый день!
</p>

<p>
	Не могу решить задачу, если она решаемая. Chat GPT и Stack Overflow опрошены, но результаты мне не понравились.
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">// Настроечная структура содержит настройки для вольтметра и амперметра
struct Settings {
        VSettings voltmeter;
        ASettings ampermeter; // Типы VSettings и ASettings разные, не имеют ничего общего, но имеют одинаковые названия полей

        auto &amp; get( int ch ) { // Хочу, чтобы этот метод возвращал разные структуры настройки в зависимости от величины аргумента
            if (ch &lt; 3)
                return voltmeter;
            else
                return ampermeter;
        }
};

                       
// Использовать хочу так
Settings s;
s.get(chvalue).поле_структуры = некое_значение;</span></pre>

<p>
	Это возможно на Си++ 17?)
</p>
]]></description><guid isPermaLink="false">217753</guid><pubDate>Wed, 04 Mar 2026 03:39:54 +0000</pubDate></item><item><title>&#x41C;&#x43E;&#x43D;&#x438;&#x442;&#x43E;&#x440;&#x438;&#x43D;&#x433; &#x430;&#x43A;&#x442;&#x438;&#x432;&#x43D;&#x43E;&#x441;&#x442;&#x438; &#x431;&#x440;&#x430;&#x443;&#x437;&#x435;&#x440;&#x430;</title><link>https://electronix.ru/forum/topic/218902-monitoring-aktivnosti-brauzera/</link><description><![CDATA[<p>
	Некоторые браузеры отправляют телеметирию и собирают данные модель материнки или версия ос. Какие варианты отключения доступа к реестру или всяким функциям WIN API
</p>
]]></description><guid isPermaLink="false">218902</guid><pubDate>Sun, 15 Mar 2026 10:59:43 +0000</pubDate></item><item><title>&#x420;&#x430;&#x431;&#x43E;&#x442;&#x430; &#x441; &#x421;&#x41E;&#x41C; &#x43F;&#x43E;&#x440;&#x442;&#x43E;&#x43C;</title><link>https://electronix.ru/forum/topic/2699-rabota-s-som-portom/</link><description><![CDATA[
<p>Здравствуйте, уважаемые!</p>
<p>
Если кто сталкивался, помогите плизз. Долбаюсь уже 2 недели, и ничего не получается. Ситуация следующая: Есть некий контроллер и общается он с компьютером через RS232, в Win98 все работает, а вот Операционка Win2000</p>
<p>
блокирует прямое обращение к портам. Мне подсказали прогу WinDriver для обхода этой проблемы... но опять-же, для LPT порта там есть стандартная заготовка, которая прекрасно работает... а о СОМ порте ни слова. Сразу оговорюсь, я не являюсь системным программистом и с железом дел никогда не имел... а тут пришлось ;) Искренне надеюсь на Вашу помощь. Заранее спасибо.</p>
<p>
З.Ы.</p>
<p>
Я впервые на этом форуме, и вполне возможно что запостил тему не совсем в тот раздел куда следовало бы.</p>
<p>
ЗЗ.ЫЫ</p>
<p>
Работать с этой штукой через CreateFile/ReadFile/WriteFile тоже не получается,</p>
<p>
в ReadFile постоянно нули возвращаются, хотя команда сформирована верно и контроллером принята...</p>
]]></description><guid isPermaLink="false">2699</guid><pubDate>Thu, 03 Feb 2005 09:12:34 +0000</pubDate></item><item><title>&#x428;&#x438;&#x444;&#x440;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x435; &#x434;&#x430;&#x43D;&#x43D;&#x44B;&#x445; HTTP</title><link>https://electronix.ru/forum/topic/210329-shifrovanie-dannyh-http/</link><description><![CDATA[<p>
	Необходимо зашифровать передаваемые по HTTP данные, но шифровать весь поток нет необходимости, вполне достаточно сделать это для передаваемых логин/пароль и двоичного файла прошивки (разбитого на более мелкие файлы). Добавлять для этого TLS думаю как-то излишне. <br />
	Помимо TLS какие еще могут быть механизмы шифрования передаваемых данных?
</p>
]]></description><guid isPermaLink="false">210329</guid><pubDate>Sun, 09 Nov 2025 12:55:07 +0000</pubDate></item><item><title>CreateFile &#x438; &#x432;&#x438;&#x440;&#x442;&#x443;&#x430;&#x43B;&#x44C;&#x43D;&#x44B;&#x439; COM &#x43F;&#x43E;&#x440;&#x442; FT232</title><link>https://electronix.ru/forum/topic/208760-createfile-i-virtualnyy-com-port-ft232/</link><description><![CDATA[<p>
	Физические порты открываются - оба виртуальных FT232 нет. Подскажите, так должно быть или я где - то ступил? 
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">   HANDLE hComm;
   hComm = CreateFileA("\\\\.\\COM2",                 //port name
                        GENERIC_READ | GENERIC_WRITE, //Read/Write
                        0,                            // No Sharing
                        NULL,                         // No Security
                        OPEN_EXISTING,                // Open existing port only
                        0,                            // Non Overlapped I/O
                        NULL);                        // Null for Comm Devices
   if (hComm == INVALID_HANDLE_VALUE)
       printf("Error in opening serial port\n\n");
   else
       printf("Opening serial port successful\n\n");
   CloseHandle(hComm);//Closing the Serial Port</span></pre>

<p>
	Если нет, пойду курить FT2xx
</p>
]]></description><guid isPermaLink="false">208760</guid><pubDate>Fri, 03 Oct 2025 07:45:55 +0000</pubDate></item><item><title>lwip NETCONN_TCP, netconn_new</title><link>https://electronix.ru/forum/topic/207712-lwip-netconn_tcp-netconn_new/</link><description><![CDATA[<p>
	Здравствуйте!
</p>

<p>
	Подскажите пожалуйста, кто знает, где определен параметр NETCONN_TCP?
</p>

<p>
	 
</p>

<p>
	Я пытаюсь сделать соединение lwip TCP clien-server  используя netconn
</p>

<p>
	Соответственно с такими дефайнами 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "lwip.h"
#include "lwip/init.h"
#include "lwip/netif.h"
#include "lwip/timeouts.h"
#include "netif/etharp.h"
#include "ethernetif.h"
#include "app_ethernet.h"
#include "tcp_echoclient.h"
#include "lwip/sys.h"
#include "lwip/api.h"</span></pre>

<p>
	делаю соединение
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted"><span class="pln">struct netconn *client_conn;
client_conn = netconn_new(NETCONN_TCP);


</span></pre>

<p>
	и получаю при сборке ошибки
</p>

<p>
	 
</p>

<blockquote class="ipsQuote" data-ipsquote="">
	<div class="ipsQuote_citation">
		Quote
	</div>

	<div class="ipsQuote_contents">
		<p>
			../Core/Src/main.c:134:20: warning: implicit declaration of function 'netconn_new' [-Wimplicit-function-declaration]<br />
			  134 |      client_conn = netconn_new(NETCONN_TCP);<br />
			      |                    ^~~~~~~~~~~<br />
			../Core/Src/main.c:134:32: error: 'NETCONN_TCP' undeclared (first use in this function)
		</p>
	</div>
</blockquote>

<p>
	Поискал в библиотеках STM и примерах, также не нашел определение NETCONN_TCP
</p>

<p>
	И также не понятно почему с такими дефайнами также ругаются на netconn_new
</p>
]]></description><guid isPermaLink="false">207712</guid><pubDate>Sun, 07 Sep 2025 16:03:49 +0000</pubDate></item><item><title>&#x41E;&#x441;&#x440;&#x435;&#x434;&#x43D;&#x435;&#x43D;&#x438;&#x435;</title><link>https://electronix.ru/forum/topic/162081-osrednenie/</link><description><![CDATA[
<p>
	Всем привет, 
</p>

<p>
	приходят данные одномерный массив на 1600 байт, его надо налету осреднить самым простым способом 
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted">
<span class="kwd">for</span><span class="pun">(</span><span class="pln">z</span><span class="pun">=</span><span class="lit">2</span><span class="pun">;</span><span class="pln">z</span><span class="pun">!=</span><span class="lit">1600</span><span class="pun">-</span><span class="lit">3</span><span class="pun">;</span><span class="pln">z</span><span class="pun">+=</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
  </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">if</span><span class="pun">(</span><span class="typ">Flag_3x3</span><span class="pun">)</span><span class="pln"> data_main</span><span class="pun">[</span><span class="pln">z</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">  data_main</span><span class="pun">[</span><span class="pln">z</span><span class="pun">-</span><span class="lit">1</span><span class="pun">]+</span><span class="pln">                              </span><span class="com">// осреднение по 3</span><span class="pln">
                                   data_main</span><span class="pun">[</span><span class="pln">z</span><span class="pun">+</span><span class="lit">1</span><span class="pun">]+</span><span class="pln">
                                   data_main</span><span class="pun">[</span><span class="pln">z</span><span class="pun">+</span><span class="lit">0</span><span class="pun">])/</span><span class="lit">3</span><span class="pun">;</span><span class="pln">
 </span><span class="pun">}</span></pre>

<p>
	при осреднении обработка данных заметно тормозится, 
</p>

<p>
	можно как то ускорить осреднение и вообще непонятно откуда такие тормоза, вроде простые операции.
</p>

<p>
	Массив приходит с частотой 70 гц
</p>
]]></description><guid isPermaLink="false">162081</guid><pubDate>Thu, 10 Jun 2021 22:24:20 +0000</pubDate></item><item><title>&#x41A;&#x430;&#x43A; &#x437;&#x430;&#x43F;&#x438;&#x441;&#x430;&#x442;&#x44C; &#x432; &#x444;&#x430;&#x439;&#x43B; &#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x443;&#x44F; &#x43F;&#x43E; &#x43C;&#x438;&#x43D;&#x438;&#x43C;&#x443;&#x43C;&#x443; &#x41E;&#x417;&#x423;  ?</title><link>https://electronix.ru/forum/topic/205520-kak-zapisat-v-fayl-ispolzuya-po-minimumu-ozu/</link><description><![CDATA[<p>
	Здравствуйте! Работаем с устройством на котором заведен linux 5.9 . На борту свободно 25 мегабайт. Из них наша программа отъедает еще 4 мб. <br />
	При попытке записать на SD карту файл более 7мб , ядро пытается высободить память и ломает либо wpa_supplicant , либо выдает ошибку segmentation fault, либо kernel panic возникает. <br />
	Всё перепробовал. Скачивание файла происходят по частям через RLDP. Уже дошло дело до того, что после получения каждой части скачиваемого файла я выполняю fopen, fseek, fwrite, fclose. И как только файл превысит размер 7413221 байт сразу возникают ошибки. <br />
	Я подозреваю , что когда выполняешь fopen система все таки кэширует весь файл, и свободная оперативка заканчивается. <br />
	Можно как-то иначе работать с файлами , чтобы кэш по меньше затрачивался ? 
</p>

<p>
	Через wget проблем со скачиванием нету вовсе, где-то что-то я делаю не так.
</p>
]]></description><guid isPermaLink="false">205520</guid><pubDate>Sun, 20 Jul 2025 15:01:45 +0000</pubDate></item><item><title>&#x41E;&#x431;&#x43D;&#x430;&#x440;&#x443;&#x436;&#x435;&#x43D;&#x438;&#x435; &#x43F;&#x440;&#x43E;&#x43F;&#x430;&#x434;&#x430;&#x43D;&#x438;&#x44F; COM-&#x43F;&#x43E;&#x440;&#x442;&#x430; &#x438;&#x437; &#x441;&#x438;&#x441;&#x442;&#x435;&#x43C;&#x44B;.</title><link>https://electronix.ru/forum/topic/203095-obnaruzhenie-propadaniya-com-porta-iz-sistemy/</link><description><![CDATA[<p>
	Вопрос касается виртуальных COM-портов разного рода: как USB CDC, так и разного рода виртуальных COM-портов образованных различными драйверами (bluetooth, виртуальных портов образованных из TCP-сокетов и т.п.).
</p>

<p>
	<strong><em>Дано</em>:</strong> Приложение (WinXP...Win11) открыло COM-порт и держит его открытым. Обмен данными по порту предположим - отсутствует. Или приложение ожидает входящих данных, не начиная передачу в порт по своей инициативе. Порт открыт и используется в overlapped-режиме. Работа с портом производится напрямую - через WinAPI, без каких-либо прослоек/либ.
</p>

<p>
	<strong><em>Вопрос</em>:</strong> Как в данном случае приложению быстро и достоверно обнаружить факт пропадания COM-порта из системы? (при отключении USB-устройства например) Каким методом отслеживать факт пропадания порта?Передавать данные в порт по инициативе приложения или менять состояние сигналов (RTS, DTR, etc.) - нельзя (по условию задачи). Периодически закрывать и переоткрывать дескриптор - тоже нельзя.
</p>

<p>
	 
</p>

<p>
	Если продолжать держать COM-порт открытым, то после пропадания COM-порта, его дескриптор остаётся валидным и активным. С ним продолжают корректно работать операции WinAPI чтения данных (возвращают 0 байт) и операции запроса статуса. По результату их выполнения судить о пропадании порта не получается. Если порт был удалён из системы, а потом заново появился, то пока старый дескриптор остаётся открытым, программа не видит данных, идущих из вновь появившегося порта. И не увидит, пока не закроет/переоткроет порт заново. Но как ей узнать, что необходимо произвести такое действие? Имхо - любому, кто работал с виртуальными COM-портами должна быть известна такая проблема.
</p>

<p>
	Создание дубликата дескриптора открытого порта и операции с ним проходят аналогично успешно - так не получается детектировать факт пропадания. Использовать WM_DEVICECHANGE - тоже не хочется (так как типы виртуальных портов могут быть разными; хочется универсального метода). Также не хочется использовать детектирование через SetupAPI (по пропаданию порта из реестра Windows). Ведь порт может пропасть на короткий интервал времени. И заново появиться. И насколько тогда часто нужно сканировать реестр через SetupAPI чтобы поймать этот момент?
</p>

<p>
	Желателен какой-то метод определения, что текущий открытый дескриптор COM-порта <s>протух</s> более не связан с существующим в данный момент COM-портом. Метод работающий без закрытия дескриптора и без отправки каких-либо данных в порт. Пробовал разные функции WinAPI, но не нашёл такой, по выполнению которой можно было бы обнаружить эту ситуацию.
</p>

<p>
	 
</p>

<p>
	В результате размышлений придумал следующий способ: Не закрывая текущий дескриптор, периодически пробовать открывать ещё один дескриптор этого же порта. Тогда:
</p>

<ul>
	<li>
		если порт ещё жив и не пропадал из системы: при попытке параллельного открытия возвращается код ошибки "ERROR_ACCESS_DENIED" (так как порт открывался не в shared-режиме);
	</li>
	<li>
		если порт пропал из системы и в данный момент отсутствует: при попытке параллельного открытия возвращается код ошибки "ERROR_FILE_NOT_FOUND" (такого порта нет);
	</li>
	<li>
		если порт пропал из системы и появился заново: его параллельное открытие проходит успешно, без ошибки.
	</li>
</ul>

<p>
	Проверил этот метод на Win7 с USB CDC COM-портом - работает стабильно. Но насколько он надёжен? Нет ли каких-то подводных камней? Будет ли он также надёжно работать в других версия Win? И насколько надёжно полагаться на коды ошибок, возвращаемых функциями WinAPI? Не станут ли в других версиях Win возвращаться другие коды ошибок для описанных состояний? Может лучше комбинировать данный метод со сканированием реестра через SetupAPI?
</p>

<p>
	Кто что думает?
</p>

<p>
	Может кто-то решал подобную задачу, успешно её решил и поделится своим методом? 
</p>
]]></description><guid isPermaLink="false">203095</guid><pubDate>Sun, 04 May 2025 12:36:41 +0000</pubDate></item><item><title>&#x41C;&#x43E;&#x436;&#x43D;&#x43E; &#x43B;&#x438; &#x437;&#x430;&#x441;&#x442;&#x430;&#x432;&#x438;&#x442;&#x44C; &#x43D;&#x435;&#x441;&#x43A;&#x43E;&#x43B;&#x44C;&#x43A;&#x43E; &#x441;&#x43E;&#x441;&#x442;&#x430;&#x432;&#x43D;&#x44B;&#x445; &#x43B;&#x438;&#x442;&#x435;&#x440;&#x430;&#x43B;&#x43E;&#x432; &#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x43E;&#x434;&#x43D;&#x443; &#x438; &#x442;&#x443; &#x436;&#x435; &#x43F;&#x430;&#x43C;&#x44F;&#x442;&#x44C; &#x441;&#x442;&#x435;&#x43A;&#x430;?</title><link>https://electronix.ru/forum/topic/202499-mozhno-li-zastavit-neskolko-sostavnyh-literalov-ispolzovat-odnu-i-tu-zhe-pamyat-steka/</link><description><![CDATA[<p style="text-align:justify;">
	Имеем следующее
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted"><span class="kwd">typedef</span><span class="pln"> </span><span class="kwd">struct</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  u32 id  </span><span class="pun">:</span><span class="pln"> </span><span class="lit">29</span><span class="pun">,</span><span class="pln">
      ext </span><span class="pun">:</span><span class="pln">  </span><span class="lit">1</span><span class="pun">,</span><span class="pln">
      rtr </span><span class="pun">:</span><span class="pln">  </span><span class="lit">1</span><span class="pun">,</span><span class="pln">
      dlc</span><span class="pun">;</span><span class="pln">
  
  </span><span class="kwd">union</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    u8  byte</span><span class="pun">[</span><span class="lit">8</span><span class="pun">];</span><span class="pln">
    u16 half</span><span class="pun">[</span><span class="lit">4</span><span class="pun">];</span><span class="pln">
    u32 word</span><span class="pun">[</span><span class="lit">2</span><span class="pun">];</span><span class="pln">
  </span><span class="pun">};</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> sCANFrame</span><span class="pun">;</span><span class="pln">

s32 can_Send</span><span class="pun">(</span><span class="pln">eCANBus canBus</span><span class="pun">,</span><span class="pln"> sCANFrame </span><span class="kwd">const</span><span class="pln"> </span><span class="pun">*</span><span class="pln">frame</span><span class="pun">);</span></pre>

<p style="text-align:justify;">
	<br />
	Частенько вместо прямого создания объекта <strong>sCANFrame</strong>, заполнения его, и вызова <strong>can_Send()</strong>, я прибегаю к использованию составных литералов
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted"><span class="pln">can_Send</span><span class="pun">(</span><span class="pln">CAN_BUS_1</span><span class="pun">,</span><span class="pln"> </span><span class="pun">&amp;(</span><span class="pln">sCANFrame</span><span class="pun">){</span><span class="pln">
  </span><span class="pun">.</span><span class="pln">id      </span><span class="pun">=</span><span class="pln"> DEV_CAN_TX_ID</span><span class="pun">,</span><span class="pln">
  </span><span class="pun">.</span><span class="pln">ext     </span><span class="pun">=</span><span class="pln"> CAN_ID_EXT</span><span class="pun">,</span><span class="pln">
  </span><span class="pun">.</span><span class="pln">rtr     </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln">
  </span><span class="pun">.</span><span class="pln">dlc     </span><span class="pun">=</span><span class="pln"> </span><span class="lit">8</span><span class="pun">,</span><span class="pln">
  </span><span class="pun">.</span><span class="pln">word</span><span class="pun">[</span><span class="lit">0</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0xA</span><span class="pun">,</span><span class="pln">
  </span><span class="pun">.</span><span class="pln">word</span><span class="pun">[</span><span class="lit">1</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0xB</span><span class="pln">
</span><span class="pun">});</span></pre>

<p style="text-align:justify;">
	<br />
	Т.е. здесь в стеке создается анонимный объект типа <strong>sCANFrame</strong> и передается функции отправки.
</p>

<p style="text-align:justify;">
	Однако, если я в ряд расположу множество (&gt;1) таких конструкций, листинг показывает, что начальная резервация стека увеличивается как раз на N * sizeof (sCANFrame) + конечное выравнивание. Т.е. ничего не мешает компилятору использовать ту же память стека под составные литералы последующих вызовов, однако компилятор так не делает.
</p>

<p style="text-align:justify;">
	Может, есть какой-то ключик в CLang/GCC?
</p>
]]></description><guid isPermaLink="false">202499</guid><pubDate>Thu, 10 Apr 2025 19:03:08 +0000</pubDate></item><item><title>&#x421;&#x442;&#x440;&#x430;&#x442;&#x435;&#x433;&#x438;&#x44F; &#x43F;&#x440;&#x438;&#x441;&#x432;&#x43E;&#x435;&#x43D;&#x438;&#x44F; &#x432;&#x435;&#x440;&#x441;&#x438;&#x439; &#x41F;&#x41E; &#x438; &#x430;&#x43F;&#x43F;&#x430;&#x440;&#x430;&#x442;&#x443;&#x440;&#x44B;</title><link>https://electronix.ru/forum/topic/202475-strategiya-prisvoeniya-versiy-po-i-apparatury/</link><description><![CDATA[<p>
	Какую стратегию вы используете?
</p>

<p>
	Казалось бы, простой вопрос, но в реальности не совсем простой.
</p>

<p>
	У меня любой девайс имеет зашитую HW-версию и FW-версию в виде MAJOR.MINOR.PATCH. Например, 1.0.0.
</p>

<p>
	С FW обычно все просто: мажорная версия отражает глобальные изменения прошивки - т.е. функциональное наполнение проекта в целом. Например, прошивка версии 1.x.y не задействовала обмены по какой-то линии связи. В версии 2.x.y она задействуется, и по ней осуществляется обмен с какими-то внешними девайсами. Минорная циферка показывает номер стабильной версии ПО, т.е. она чуть детализирует мажорную цифру. Циферка патча наращивается при любом изменении текущего образа ПО, например, в процессе отлова багов - глобальный функционал не меняется, но для различения версий как раз служит патч-цифра.
</p>

<p>
	То же самое с HW.
</p>

<p>
	И вот тут появляется проблема. Например, разводится плата на другом МК. Версия HW меняется, но версия функционала ПО может не меняться: "извне" для разработчика функционал остается прежним. Т.е. циферки версии FW не должны меняться. Например, такое бывает, когда плата с одной и той же электрической схемой разводится по-разному конструктивно (поэтому версия HW меняется, чтобы удаленно можно было мониторить, что это за девайс). Но бывает и так, что плата меняется незначительно, но требует программных изменений (дергать лишнюю ножку, например). При этом фукцнионал девайса для стороннего наблюдателя не изменяется никак. В общем случае, рано или поздно, появляется зоопарк прошивок, на которых, вроде, и пишется версия ПО, но из них не понятно, с кем и чем она совместима<span class="ipsEmoji">🙂</span>
</p>

<p>
	А еще все сильно усугубляется различной применимостью одних и тех же девайсов: например, какая-нибудь CAN-клавиатура может отличаться только измененным битрейтом и набором рабочих CAN-ID. Т.е. появляется некое техлицо/исполнение.
</p>

<p>
	Может, есть весьма строгий и проверенный временем метод контроля и присвоения версий?
</p>

<p>
	P.S. Мда. Стоило ведь отправить пост, как через пять минут поисков наткнулся на замечательный сайт: <a href="https://semver.org/" rel="external nofollow">https://semver.org/</a>. 100% попадание.
</p>
]]></description><guid isPermaLink="false">202475</guid><pubDate>Wed, 09 Apr 2025 16:37:58 +0000</pubDate></item><item><title>&#x41C;&#x430;&#x43A;&#x441;&#x438;&#x43C;&#x430;&#x43B;&#x44C;&#x43D;&#x430;&#x44F; &#x432;&#x43E;&#x437;&#x43C;&#x43E;&#x436;&#x43D;&#x430;&#x44F; &#x440;&#x435;&#x430;&#x43B;&#x442;&#x430;&#x439;&#x43C;&#x43E;&#x432;&#x43E;&#x441;&#x442;&#x44C; &#x43F;&#x43E;&#x434; Win.</title><link>https://electronix.ru/forum/topic/191160-maksimalnaya-vozmozhnaya-realtaymovost-pod-win/</link><description><![CDATA[<p>
	Вопрос несколько не по теме форума, но наверняка актуальный для многих при работе с железом из win-приложения.
</p>

<p>
	<em><strong>Какова максимальная возможная реалтаймовость не-GUI потока win-приложения на уровне пользователя (без разработки драйвера уровня ядра)?</strong></em>
</p>

<p>
	Допустим: Имеем отдельный поток (для работы с железом). Без GUI-вызовов из него. И без блокировок потока при доступе к разделяемым ресурсам (предположим - вся межпоточная синхронизация выполняется неблокирующими методами: Interlocked...()-функциями, межпоточными асинхронными сообщениями, сигналами и т.п.). Поток работает только со своими данными и своими же (выделенными только ему) ресурсами.
</p>

<p>
	Так вот - как обеспечить максимально возможную реалтаймовость этого потока? Т.е. - чтобы все события в нём происходили максимально точно по заданными времянкам. Если скажем нужно, чтобы поток получал управление каждые 20 мсек, с минимальным отклонением от этого интервала вне зависимости от прочих событий в системе? Какими средствами этого достичь? На обычном ПК, без каких-то аппаратных добавлений к нему и без доп.драйверов на уровне ядра. На виндах от XP до последних.
</p>

<p>
	 
</p>

<p>
	Рабочему потоку (о котором и идёт речь) выставлен высокий приоритет = THREAD_PRIORITY_TIME_CRITICAL. Временные интервалы пробую создавать двумя методами:
</p>

<p>
	1. Мультимедиа-таймером: timeBeginPeriod(1)/timeEndPeriod(1). Разрешение (запрошенное и выданное) = 1ms. Из callback-функции ММ-таймера пинаю рабочий поток посылкой ему сигналов (SetEvent()).
</p>

<p>
	2. Созданием отдельного высокоприоритетного потока (также THREAD_PRIORITY_TIME_CRITICAL). Который занимается только тем, что ложится спать на 20 ms, просыпаясь посылает сигнал (SetEvent()) рабочему потоку и снова ложится спать. Больше ничего не делает.
</p>

<p>
	Но оба этих метода работают не очень хорошо. <img alt=":sad:" data-emoticon="" src="https://electronix.ru/forum/storage/emoticons/sad.gif" title=":sad:" /> Потестил программу в течение некоторого времени параллельно с обычной работой на двух разных ПК (ничего особенного - обычный набор программ: браузеры, компиляторы и т.п.) с разными win (Win7, Win11). Сделал сбор статистики периодичности вызовов функций пинания рабочего потока. Получаю такую картину:
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="166586" href="https://electronix.ru/forum/uploads/monthly_2024_08/image.png.a659406bf95073b61d0024ac33b32566.png" rel=""><img alt="image.thumb.png.6db9724d6f0aae878959411ffecdb874.png" class="ipsImage ipsImage_thumbnailed" data-fileid="166586" data-ratio="40.16" width="640" src="https://electronix.ru/forum/uploads/monthly_2024_08/image.thumb.png.6db9724d6f0aae878959411ffecdb874.png" /></a>
</p>

<p>
	С префикса "mmTimer" - статистика по вызовам мультимедиа-таймера. "Thread" - по вызовам из спец.потока. Статистика накоплена за время работы - немногим более часа.
</p>

<p>
	3 столбца = минимальное/среднее/максимальное время между вызовами.
</p>

<p>
	Как видно - разброс получился довольно значительный. Хоть ПК, на котором это работало - современный AMD Ryzen (6 ядер / 12 потоков) и не загружен особо. Почему так?  <img alt=":umnik2:" data-emoticon="" src="https://electronix.ru/forum/storage/emoticons/umnik2.gif" title=":umnik2:" />
</p>

<p>
	Причём (как видно) - "Thread"-метод довольно хорошо держит нижнюю границу (отклонение менее 1 ms). Но зато - плохо держит верхнюю границу. Иногда возникают какие-то задержки аж на почти 70ms сверх положенного! Да и в среднем - отклонение больше, чем у ММ-таймера.
</p>

<p>
	А мультимедиа-таймер лучше держит средний интервал, но очень плохо - нижний интервал (а это самый критичный для меня параметр). Причём - это в данном запуске теста нижний интервал упал всего до ~8.2 ms. В другом запуске на другом ПК он падал ещё ниже.
</p>

<p>
	 
</p>

<p>
	Так вот: Может кто подсказать ещё другие способы получения событий потоку (пинания потока) в Win с более высокой точностью/стабильностью? <strong>Пинания с обычного уровня пользовательского приложения</strong>. Кроме двух вышеприведённых испытываемых.
</p>

<p>
	 
</p>

<p>
	PS: Все данные измерений времени получены от службы аппаратного таймера - QueryPerformanceFrequency()/QueryPerformanceCounter(). Поэтому думаю - достоверны.
</p>
]]></description><guid isPermaLink="false">191160</guid><pubDate>Thu, 08 Aug 2024 09:36:39 +0000</pubDate></item><item><title>&#x414;&#x440;&#x430;&#x439;&#x432;&#x435;&#x440; &#x441;&#x435;&#x442;&#x435;&#x432;&#x43E;&#x433;&#x43E; &#x443;&#x441;&#x442;&#x440;&#x43E;&#x439;&#x441;&#x442;&#x432;&#x430; linux.</title><link>https://electronix.ru/forum/topic/189162-drayver-setevogo-ustroystva-linux/</link><description><![CDATA[<p>
	Всем привет! Пришлось писать драйвер сетевого устройства. Тк, в драйверах я новичок, то встал в тупик. Может кто подскажет? В чем суть: в каком-то объеме драйвер написан. Он принимает пакеты от железяки и кладет их в skb. В wireshark-е я эти пакеты вижу, однако, никакая софтина кроме wireshark-а и ostinsto эти пакеты принять не может. Те, как я понимаю, дальше вврерх по сетевому стеку они не идут. Я не понимаю - почему? В чем может быть причина? В какую сторону копать?
</p>
]]></description><guid isPermaLink="false">189162</guid><pubDate>Sun, 14 Jul 2024 21:16:06 +0000</pubDate></item><item><title><![CDATA[Интересный способ преобразования Unix TimeStamp -> Date/Time]]></title><link>https://electronix.ru/forum/topic/195832-interesnyy-sposob-preobrazovaniya-unix-timestamp-datetime/</link><description><![CDATA[<pre class="ipsCode prettyprint lang-c prettyprinted"><span class="pln"> </span><span class="com">/**
  * @brief Convert Unix timestamp to date
  * @param[in] t Unix timestamp
  * @param[out] date Pointer to a structure representing the date and time
  **/</span><span class="pln">
  
 </span><span class="kwd">void</span><span class="pln"> convertUnixTimeToDate</span><span class="pun">(</span><span class="typ">time_t</span><span class="pln"> t</span><span class="pun">,</span><span class="pln"> </span><span class="typ">DateTime</span><span class="pln"> </span><span class="pun">*</span><span class="pln">date</span><span class="pun">)</span><span class="pln">
 </span><span class="pun">{</span><span class="pln">
    </span><span class="typ">uint32_t</span><span class="pln"> a</span><span class="pun">;</span><span class="pln">
    </span><span class="typ">uint32_t</span><span class="pln"> b</span><span class="pun">;</span><span class="pln">
    </span><span class="typ">uint32_t</span><span class="pln"> c</span><span class="pun">;</span><span class="pln">
    </span><span class="typ">uint32_t</span><span class="pln"> d</span><span class="pun">;</span><span class="pln">
    </span><span class="typ">uint32_t</span><span class="pln"> e</span><span class="pun">;</span><span class="pln">
    </span><span class="typ">uint32_t</span><span class="pln"> f</span><span class="pun">;</span><span class="pln">
  
    </span><span class="com">//Negative Unix time values are not supported</span><span class="pln">
    </span><span class="kwd">if</span><span class="pun">(</span><span class="pln">t </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">1</span><span class="pun">)</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
       t </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
  
    </span><span class="com">//Clear milliseconds</span><span class="pln">
    date</span><span class="pun">-&gt;</span><span class="pln">milliseconds </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
  
    </span><span class="com">//Retrieve hours, minutes and seconds</span><span class="pln">
    date</span><span class="pun">-&gt;</span><span class="pln">seconds </span><span class="pun">=</span><span class="pln"> t </span><span class="pun">%</span><span class="pln"> </span><span class="lit">60</span><span class="pun">;</span><span class="pln">
    t </span><span class="pun">/=</span><span class="pln"> </span><span class="lit">60</span><span class="pun">;</span><span class="pln">
    date</span><span class="pun">-&gt;</span><span class="pln">minutes </span><span class="pun">=</span><span class="pln"> t </span><span class="pun">%</span><span class="pln"> </span><span class="lit">60</span><span class="pun">;</span><span class="pln">
    t </span><span class="pun">/=</span><span class="pln"> </span><span class="lit">60</span><span class="pun">;</span><span class="pln">
    date</span><span class="pun">-&gt;</span><span class="pln">hours </span><span class="pun">=</span><span class="pln"> t </span><span class="pun">%</span><span class="pln"> </span><span class="lit">24</span><span class="pun">;</span><span class="pln">
    t </span><span class="pun">/=</span><span class="pln"> </span><span class="lit">24</span><span class="pun">;</span><span class="pln">
  
    </span><span class="com">//Convert Unix time to date</span><span class="pln">
    a </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">uint32_t</span><span class="pun">)</span><span class="pln"> </span><span class="pun">((</span><span class="lit">4</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> t </span><span class="pun">+</span><span class="pln"> </span><span class="lit">102032</span><span class="pun">)</span><span class="pln"> </span><span class="pun">/</span><span class="pln"> </span><span class="lit">146097</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="lit">15</span><span class="pun">);</span><span class="pln">
    b </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">uint32_t</span><span class="pun">)</span><span class="pln"> </span><span class="pun">(</span><span class="pln">t </span><span class="pun">+</span><span class="pln"> </span><span class="lit">2442113</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> a </span><span class="pun">-</span><span class="pln"> </span><span class="pun">(</span><span class="pln">a </span><span class="pun">/</span><span class="pln"> </span><span class="lit">4</span><span class="pun">));</span><span class="pln">
    c </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">20</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> b </span><span class="pun">-</span><span class="pln"> </span><span class="lit">2442</span><span class="pun">)</span><span class="pln"> </span><span class="pun">/</span><span class="pln"> </span><span class="lit">7305</span><span class="pun">;</span><span class="pln">
    d </span><span class="pun">=</span><span class="pln"> b </span><span class="pun">-</span><span class="pln"> </span><span class="lit">365</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> c </span><span class="pun">-</span><span class="pln"> </span><span class="pun">(</span><span class="pln">c </span><span class="pun">/</span><span class="pln"> </span><span class="lit">4</span><span class="pun">);</span><span class="pln">
    e </span><span class="pun">=</span><span class="pln"> d </span><span class="pun">*</span><span class="pln"> </span><span class="lit">1000</span><span class="pln"> </span><span class="pun">/</span><span class="pln"> </span><span class="lit">30601</span><span class="pun">;</span><span class="pln">
    f </span><span class="pun">=</span><span class="pln"> d </span><span class="pun">-</span><span class="pln"> e </span><span class="pun">*</span><span class="pln"> </span><span class="lit">30</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> e </span><span class="pun">*</span><span class="pln"> </span><span class="lit">601</span><span class="pln"> </span><span class="pun">/</span><span class="pln"> </span><span class="lit">1000</span><span class="pun">;</span><span class="pln">
  
    </span><span class="com">//January and February are counted as months 13 and 14 of the previous year</span><span class="pln">
    </span><span class="kwd">if</span><span class="pun">(</span><span class="pln">e </span><span class="pun">&lt;=</span><span class="pln"> </span><span class="lit">13</span><span class="pun">)</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
       c </span><span class="pun">-=</span><span class="pln"> </span><span class="lit">4716</span><span class="pun">;</span><span class="pln">
       e </span><span class="pun">-=</span><span class="pln"> </span><span class="lit">1</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
    </span><span class="kwd">else</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
       c </span><span class="pun">-=</span><span class="pln"> </span><span class="lit">4715</span><span class="pun">;</span><span class="pln">
       e </span><span class="pun">-=</span><span class="pln"> </span><span class="lit">13</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
  
    </span><span class="com">//Retrieve year, month and day</span><span class="pln">
    date</span><span class="pun">-&gt;</span><span class="pln">year </span><span class="pun">=</span><span class="pln"> c</span><span class="pun">;</span><span class="pln">
    date</span><span class="pun">-&gt;</span><span class="pln">month </span><span class="pun">=</span><span class="pln"> e</span><span class="pun">;</span><span class="pln">
    date</span><span class="pun">-&gt;</span><span class="pln">day </span><span class="pun">=</span><span class="pln"> f</span><span class="pun">;</span><span class="pln">
  
    </span><span class="com">//Calculate day of week</span><span class="pln">
    date</span><span class="pun">-&gt;</span><span class="pln">dayOfWeek </span><span class="pun">=</span><span class="pln"> computeDayOfWeek</span><span class="pun">(</span><span class="pln">c</span><span class="pun">,</span><span class="pln"> e</span><span class="pun">,</span><span class="pln"> f</span><span class="pun">);</span><span class="pln">
 </span><span class="pun">}</span></pre>

<p>
	<br />
	Вообще, конечно, интересна математика происходящего. Как я понимаю, авторы каким-то образом считают в "14-месяцовых годах". В чем тут "фокус"? Откуда именно такие магические числа в преобразованиях?<span class="ipsEmoji">🙂</span>
</p>
]]></description><guid isPermaLink="false">195832</guid><pubDate>Sat, 02 Nov 2024 18:58:05 +0000</pubDate></item><item><title>&#x420;&#x435;&#x434;&#x430;&#x43A;&#x442;&#x43E;&#x440; &#x438;&#x43D;&#x442;&#x435;&#x440;&#x444;&#x435;&#x439;&#x441;&#x430; &#x444;&#x43E;&#x440;&#x43C; &#x434;&#x43B;&#x44F; GUI/HMI &#x43F;&#x43E;&#x434; &#x432;&#x438;&#x43D;&#x434;&#x443;, &#x432; &#x438;&#x441;&#x445;&#x43E;&#x434;&#x43D;&#x438;&#x43A;&#x430;&#x445;</title><link>https://electronix.ru/forum/topic/172314-redaktor-interfeysa-form-dlya-guihmi-pod-vindu-v-ishodnikah/</link><description><![CDATA[<p>
	Приветствую.
</p>

<p>
	Вопросик такой, не встречались-ли никому редакторы форм для графических приложений, виджетов и пр. а-ля винда и подобные, EMWIN- подобные и пр, но в исходниках на Си (С++), язык принципиально, т.е. всякие шарпы, qt и пр. не интересно. Под винду, любую версию)))
</p>

<p>
	Наверняка есть что-то подобное, чтоб с нуля не ваять все это хозяйство)))
</p>
]]></description><guid isPermaLink="false">172314</guid><pubDate>Fri, 08 Sep 2023 09:12:51 +0000</pubDate></item><item><title>&#x412;&#x437;&#x430;&#x438;&#x43C;&#x43E;&#x43F;&#x440;&#x435;&#x43E;&#x431;&#x440;&#x430;&#x437;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x435; &#x443;&#x43A;&#x430;&#x437;&#x430;&#x442;&#x435;&#x43B;&#x44F; &#x43D;&#x430; &#x441;&#x442;&#x440;&#x443;&#x43A;&#x442;&#x443;&#x440;&#x443; &#x438; &#x43D;&#x430; &#x435;&#x435; &#x43F;&#x435;&#x440;&#x432;&#x44B;&#x439; &#x447;&#x43B;&#x435;&#x43D; &#x438; strict aliasing &#x432; &#x421;&#x438;</title><link>https://electronix.ru/forum/topic/189344-vzaimopreobrazovanie-ukazatelya-na-strukturu-i-na-ee-pervyy-chlen-i-strict-aliasing-v-si/</link><description><![CDATA[<p style="text-align:justify;">
	Полистал я стандарт, как-то мутновато описано. В упрощенном виде опишу затею.
</p>

<p style="text-align:justify;">
	Допустим, у меня есть структуры разного формата, имеющие одинаковые начальные последовательности, для их динамической идентификации
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted"><span class="kwd">typedef</span><span class="pln"> </span><span class="kwd">struct</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  u32 type</span><span class="pun">;</span><span class="pln">
  
  </span><span class="typ">float</span><span class="pln"> f</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">int</span><span class="pln">   i</span><span class="pun">[</span><span class="lit">10</span><span class="pun">];</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> S0</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">typedef</span><span class="pln"> </span><span class="kwd">struct</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  u32 type</span><span class="pun">;</span><span class="pln">
  
  </span><span class="kwd">char</span><span class="pln"> </span><span class="kwd">const</span><span class="pln"> </span><span class="pun">*</span><span class="pln">name</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> S1</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">typedef</span><span class="pln"> </span><span class="kwd">struct</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  u32 type</span><span class="pun">;</span><span class="pln">
  
  </span><span class="kwd">double</span><span class="pln"> d</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">char</span><span class="pln"> </span><span class="kwd">const</span><span class="pln"> </span><span class="pun">*</span><span class="pln">name</span><span class="pun">;</span><span class="pln">
  u32    u</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> S2</span><span class="pun">;</span><span class="pln">

</span><span class="pun">...</span><span class="pln">

S0 s0 </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="pun">...};</span><span class="pln">
S1 s1 </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="pun">...};</span><span class="pln">
S2 s2 </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="pun">...};</span><span class="pln">
</span><span class="pun">...</span></pre>

<p style="text-align:justify;">
	<br />
	Как видно, у них у всех имеется в начале <strong>u32 type</strong>. Язык Си пишет вот что (6.7.2.1)
</p>

<blockquote class="ipsQuote" data-ipsquote="">
	<div class="ipsQuote_citation">
		Цитата
	</div>

	<div class="ipsQuote_contents">
		<p style="text-align:justify;">
			Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. <strong>A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), <u>and vice versa.</u></strong> There may be unnamed padding within a structure object, but not at its beginning.
		</p>
	</div>
</blockquote>

<p style="text-align:justify;">
	Соответственно, указатель на объект структуры можно явно преобразовать в указатель на первый член структуры <u>и наоборот.</u>
</p>

<p style="text-align:justify;">
	Теперь, я собираю в кучу-массив указатели на эти структуры: явно это сделать не получится, поэтому можно через тип первых членов
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted"><span class="pln">u32 </span><span class="pun">*</span><span class="typ">array</span><span class="pun">[]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="pun">&amp;</span><span class="pln">s2</span><span class="pun">.</span><span class="pln">type</span><span class="pun">,</span><span class="pln">
  </span><span class="pun">&amp;</span><span class="pln">s0</span><span class="pun">.</span><span class="pln">type</span><span class="pun">,</span><span class="pln">
  </span><span class="pun">&amp;</span><span class="pln">s1</span><span class="pun">.</span><span class="pln">type</span><span class="pun">,</span><span class="pln">
  </span><span class="pun">...</span><span class="pln">
</span><span class="pun">};</span></pre>

<p style="text-align:justify;">
	<br />
	Теперь мне из внешнего мира, в run-time прилетает "индекс", по которому я лезу в этот массив и должен обратиться к объемлющей структуре, к любым ее полям
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted"><span class="pln">u32 num </span><span class="pun">=</span><span class="pln"> get_num</span><span class="pun">();</span><span class="pln">
u32 </span><span class="pun">*</span><span class="pln">p </span><span class="pun">=</span><span class="pln"> </span><span class="typ">array</span><span class="pun">[</span><span class="pln">num</span><span class="pun">];</span><span class="pln"> </span><span class="com">// получили указатель на начало какой-то структуры в памяти, а дальше парсим ее</span><span class="pln">

</span><span class="kwd">switch</span><span class="pun">(*</span><span class="pln">p</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="pun">...</span><span class="pln">
    </span><span class="kwd">case</span><span class="pln"> </span><span class="lit">1</span><span class="pun">:</span><span class="pln">
      printf</span><span class="pun">(</span><span class="str">"%s"</span><span class="pun">,</span><span class="pln"> </span><span class="pun">((</span><span class="pln">S1 </span><span class="pun">*)</span><span class="pln">p</span><span class="pun">)-&gt;</span><span class="pln">name</span><span class="pun">);</span><span class="pln"> </span><span class="com">// вот - преобразую "обратно" - из указателя на u32 в указатель на структуру, чей первый член есть u32, все законно</span><span class="pln">
    </span><span class="pun">...</span><span class="pln">
</span><span class="pun">}</span></pre>

<p style="text-align:justify;">
	<br />
	Однако не совсем законно это с точки зрения правил псевдонимов, вроде как. Как тогда реализовать динамический парсинг структур, когда заранее не известен порядок указателей в массиве? Корректно с точки зрения правил Си.
</p>
]]></description><guid isPermaLink="false">189344</guid><pubDate>Tue, 16 Jul 2024 22:06:44 +0000</pubDate></item><item><title>&#x43F;&#x440;&#x438;&#x43E;&#x441;&#x442;&#x430;&#x43D;&#x43E;&#x432;&#x43A;&#x430; &#x43E;&#x441;&#x43D;&#x43E;&#x432;&#x43D;&#x43E;&#x433;&#x43E; &#x43F;&#x43E;&#x442;&#x43E;&#x43A;&#x430; pthread</title><link>https://electronix.ru/forum/topic/187276-priostanovka-osnovnogo-potoka-pthread/</link><description><![CDATA[<p>
	Система Linux + T113-s3
</p>

<p>
	сделан один поток , в котором постоянно ждем событие прерывания на ноге процессора
</p>

<p>
	после появления события вызываем коллбэк , в котором чтото делаем и отсылаем-принимаем по SPI
</p>

<p>
	кроме того сама главная программа постоянно работает со SPI
</p>

<p>
	Как сделать некий аналог IRQ callback  как в обычном контроллере 
</p>

<p>
	Т.е что бы при вызове коллбэка в потоке основная программа блокировалась , после завершения коллбэка , основная программа разблокировалась?
</p>

<p>
	например где то в потоке бесконечн бежит опрос  паралельно с основной програмой 
</p>

<p>
	wile(){
</p>

<p>
	    if(waiting_rise_gpio  ()){
</p>

<p>
	     my_IRQ_callback();
</p>

<p>
	   }
</p>

<p>
	 
</p>

<p>
	а в самом коллбэке
</p>

<p>
	void my_IRQ_callback(){
</p>

<p>
	// блокируем выполнение(переключение потока) основного кода в мэйн
</p>

<p>
	//здесь бежит только этот поток , один
</p>

<p>
	 
</p>

<p>
	// включаем разрешение на возврат к main
</p>

<p>
	//теперь потоки опять чередуются
</p>

<p>
	}
</p>
]]></description><guid isPermaLink="false">187276</guid><pubDate>Tue, 18 Jun 2024 09:59:48 +0000</pubDate></item><item><title>&#x412;&#x43E;&#x43F;&#x440;&#x43E;&#x441; &#x43F;&#x43E; poll &#x432; Linux</title><link>https://electronix.ru/forum/topic/178526-vopros-po-poll-v-linux/</link><description><![CDATA[<p>
	Добрый день
</p>

<p>
	Могли бы пояснить некоторые моменты касательно использования poll для случая GPIO в роли IRQ
</p>

<p>
	Сейчас есть такой прототитп
</p>

<p>
	1.  chip0_poll = open ("/dev/gpiochip0", O_RDONLY);
</p>

<p>
	2.rq_poll.lineoffset = PD14;  //<br />
	  rq_poll.eventflags = GPIOEVENT_EVENT_RISING_EDGE;<br />
	  rq_poll.handleflags = GPIOHANDLE_REQUEST_INPUT;<br />
	  ret = ioctl (chip0_poll, GPIO_GET_LINEEVENT_IOCTL, rq_poll);
</p>

<p>
	3.  pfd.fd =        rq_poll.fd;<br />
	     pfd.events = POLLIN | POLLPRI;
</p>

<p>
	<strong> //lseek(</strong> chip0_poll<strong>, 0, SEEK_SET);    /* consume any prior interrupt */  ??</strong>
</p>

<p>
	4.ret = poll(&amp;pfd, 1, time_out_ms);
</p>

<p>
	 
</p>

<p>
	5. if (pfd.revents &amp; POLLPRI)
</p>

<p>
	<strong>          rd = read(req.fd, &amp;event, sizeof(event));  ??</strong>
</p>

<p>
	 
</p>

<p>
	<strong>close (</strong> pfd.fd<strong>)  ??</strong>
</p>

<p>
	<strong>close(</strong>rq_poll.fd<strong>)  ??</strong>
</p>

<p>
	<strong>close (</strong>chip0_poll<strong>) ??</strong>
</p>

<p>
	 
</p>

<p>
	-Вопрос по черным строкам, как я понимаю надо прочитать файл после poll что бы исключить ошибочного повтора , какой  размер <strong>sizeof(event)  ?? </strong>     Гдето 1 байт а гдето в примерах 10
</p>

<p>
	   
</p>

<p>
	<strong>-lseek    </strong>надо добавлять  , если да  то куда?
</p>

<p>
	 
</p>

<p>
	-<strong>close (</strong> pfd.fd<strong>) close(</strong>rq_poll.fd<strong>)  close (</strong>chip0_poll<strong>)  </strong>это одно и тоже  и можно один оставить или они содержат разные значения?
</p>

<p>
	 
</p>

<p>
	 
</p>
]]></description><guid isPermaLink="false">178526</guid><pubDate>Thu, 08 Feb 2024 12:54:43 +0000</pubDate></item><item><title>API &#x434;&#x43B;&#x44F; &#x431;&#x44B;&#x441;&#x442;&#x440;&#x43E;&#x433;&#x43E; &#x43A;&#x43E;&#x43F;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x44F; &#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x438;&#x445; &#x43E;&#x431;&#x44A;&#x451;&#x43C;&#x43E;&#x432; &#x434;&#x430;&#x43D;&#x43D;&#x44B;&#x445; &#x432; &#x443;&#x441;&#x442;&#x440;&#x43E;&#x439;&#x441;&#x442;&#x432;&#x43E;, DMA</title><link>https://electronix.ru/forum/topic/174010-api-dlya-bystrogo-kopirovaniya-bolshih-obyomov-dannyh-v-ustroystvo-dma/</link><description><![CDATA[<p>
	Много лет проблема стоит для Windows. (И для Linux тоже.)<br />
	Запись в память устройства по PCI ещё как-то устраивает через оптимизированный код в memcpy(), где применяются команды по 8 и 16 байт за такт.<br />
	А вот читать уже на порядок медленнее, даже порциями по 16 байт, там хочется слепить соседние запросы в burst-транзакции, чтобы стало похоже по эффективности на запись.<br />
	В идеале -- надо запустить свободный системный канал DMA (их масса на материнке) "туда" или "обратно", самому заняться другими делами, а по готовности операции уже вернуться обратно на готовое.<br />
	Наверняка кто-то уже решал подобную задачу. Или MS где-то припрятала такой функционал ? Базовая вещь.<br />
	Физические адреса в устройстве есть, они непрерывные.<br />
	У нас в памяти виртуальные непрерывны, а физические попутаны, как ОС раздаст, но с этим ядро ОС разбирается хорошо.<br />
	К физическим и вообще аппаратуре не подпускают из верхнего уровня приложений, нужен драйвер.<br />
	Писал уже кто-то такое "на продажу" ? Чтобы не ходить по граблям в 1000...-й раз, вызвать функцию волшебного драйвера и забыть...
</p>
]]></description><guid isPermaLink="false">174010</guid><pubDate>Thu, 26 Oct 2023 14:59:52 +0000</pubDate></item><item><title>&#x41D;&#x435; &#x432;&#x438;&#x436;&#x443;, &#x433;&#x434;&#x435; &#x431;&#x435;&#x440;&#x443;&#x442;&#x441;&#x44F; &#x43E;&#x43F;&#x440;&#x435;&#x434;&#x435;&#x43B;&#x435;&#x43D;&#x438;&#x44F; __INT8_C_SUFFIX__ &#x438; &#x442;.&#x434;.</title><link>https://electronix.ru/forum/topic/173905-ne-vizhu-gde-berutsya-opredeleniya-__int8_c_suffix__-i-td/</link><description><![CDATA[<p style="text-align:justify;">
	Использовал раньше самописные лительные "хвосты"-суффиксы
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted"><span class="com">#define</span><span class="pln"> INT_LITERAL_SUFFIX_OCT_0
</span><span class="com">#define</span><span class="pln"> INT_LITERAL_SUFFIX_OCT_1
</span><span class="com">#define</span><span class="pln"> INT_LITERAL_SUFFIX_OCT_2
</span><span class="com">#define</span><span class="pln"> INT_LITERAL_SUFFIX_OCT_3
</span><span class="com">#define</span><span class="pln"> INT_LITERAL_SUFFIX_OCT_4 ll
</span><span class="com">#define</span><span class="pln"> INT_LITERAL_SUFFIX_OCT_5 ll
</span><span class="com">#define</span><span class="pln"> INT_LITERAL_SUFFIX_OCT_6 ll
</span><span class="com">#define</span><span class="pln"> INT_LITERAL_SUFFIX_OCT_7 ll</span></pre>

<p style="text-align:justify;">
	чтобы использовать в хитрых макросах для склейки с числами, получая правильный тип данных.
</p>

<p style="text-align:justify;">
	И вот относительно недавно обнаружил, что среди вороха всплывающих идентификаторов в IDE мелкнул __INT8_C_SUFFIX__, а за ним и __UINT8_C_SUFFIX__ и т.д. для всех целых типов.
</p>

<p style="text-align:justify;">
	Подумал, чего мне свои определения писать для каждой платформы, если они уже где-то определены. Очень надеялся, что эти определения будут где-нибудь в стандартном &lt;stdint.h&gt;, ан-нет.
</p>

<p style="text-align:justify;">
	Это чисто компиляторные предопределенные макросы, наряду со всякими __LINE__, __FILE__ и т.д.? На них можно полагаться для разных компиляторов? Или оно не стандартно и где-то может отсутствовать?
</p>
]]></description><guid isPermaLink="false">173905</guid><pubDate>Fri, 20 Oct 2023 12:18:53 +0000</pubDate></item><item><title>Profiler windows mingw</title><link>https://electronix.ru/forum/topic/173698-profiler-windows-mingw/</link><description><![CDATA[<p>
	Пишу разный софт для windows (cmake+mingw64), linux, часто возникает желание поковырять на предмет утечек и профилирования, но все никак не решусь.
</p>

<p>
	Знаю что для linux есть valgrind, тут хоть как-то понятно направление
</p>

<p>
	А вот для винды даже не знаю в какую сторону копать. Есть профилировщик в MSVS, но это вынуждает использовать их компилятор, чего я не хочу. Есть ли для связки Windosw+mingw+cmake решения, работающие из коробки? Или хотя бы с адекватным порогом вхождения.
</p>
]]></description><guid isPermaLink="false">173698</guid><pubDate>Fri, 13 Oct 2023 07:10:57 +0000</pubDate></item><item><title>&#x423;&#x43D;&#x438;&#x43A;&#x430;&#x43B;&#x44C;&#x43D;&#x43E;&#x441;&#x442;&#x44C; &#x438;&#x434;&#x435;&#x43D;&#x442;&#x438;&#x444;&#x438;&#x43A;&#x430;&#x442;&#x43E;&#x440;&#x43E;&#x432; include guards</title><link>https://electronix.ru/forum/topic/172918-unikalnost-identifikatorov-include-guards/</link><description><![CDATA[<p style="text-align:justify;">
	Я проект разбиваю по каталогам и бывает такое, что несколько файлов ну очень хочется сделать с одинаковыми именами.
</p>

<p style="text-align:justify;">
	И если проблему с выбором конкретного файла решить весьма просто - на уровне синтаксиса #include "" или &lt;&gt; (при необходимости еще и с указанием полного пути), то вот из-за одинаковых именований защитных макросов последующие по иерархии подключений файлы не включат свое содержимое. Понятно, что во всем проекте <strong>желательно</strong> не использовать одинаковые имена заголовков, но это "желательно" иногда не возможно не нарушить.
</p>

<p style="text-align:justify;">
	Подправлять имя файла или его защитные макросы "по случаю" не очень хочется, т.к. иногда у меня структура папок немного разъезжается, да и мало ли что...
</p>

<p style="text-align:justify;">
	Как пример - у FreeRTOS есть queue.h с его QUEUE_H, projdefs.h с его PROJDEFS_H. Я тоже люблю так кратко именовать файлы и их защитников.
</p>

<p style="text-align:justify;">
	Вот только разработчики RTOS пишут не сильно думая об остальном наборе исходников у юзера, а юзеру (мне) уже нужно думать об уникальности защитников.
</p>

<p style="text-align:justify;">
	Есть ли в препроцессоре C/C++ возможность клеить имя защитного макроса на основе <strong>текущей директории</strong> файла?
</p>

<p style="text-align:justify;">
	Конкатенация ## для #ifndef не работает, поэтому напрямую не получится.
</p>
]]></description><guid isPermaLink="false">172918</guid><pubDate>Fri, 22 Sep 2023 08:59:52 +0000</pubDate></item><item><title>Kotlin &#x43F;&#x435;&#x440;&#x432;&#x44B;&#x439; &#x448;&#x430;&#x433; &#x43A; &#x441;&#x43E;&#x437;&#x434;&#x430;&#x43D;&#x438;&#x44E; &#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x439; &#x432; &#x41E;&#x421; Android</title><link>https://electronix.ru/forum/topic/171363-kotlin-pervyy-shag-k-sozdaniyu-prilozheniy-v-os-android/</link><description><![CDATA[<p>
	Сразу скажу, что я не продвинутый программист. Есть небольшой опыт написания программ на объектно-ориентированных языках.
</p>

<p>
	Хотелось бы создавать не сложные приложения под Android исключительно взаимодействующие внешними электронными устройствами (через сеть Wi-Fi или Bluetooth соединение), т.е. создавать некие "тяжелые" приложения с воспроизведением увесистой графики, подключением к сети Интернет и прочими функциями НЕ требуется.
</p>

<p>
	После прочтения некоторого количества информации вариантов для начала работы у меня в голове три:
</p>

<p>
	1. Писать на ARM-ассемблере. Быстрое начало для новичка без опыта и понимания структуры простейшего приложения под Android, как я понял, в этом случае невозможно.
</p>

<p>
	2. Писать на Kotlin в среде разработки типа Android Studio. Вроде как это самый стандартный вариант для начинающих, но последняя версия данной IDE требует как минимум 8Гб оперативки, ну и прочие системные требования для более менее соверенных компьютеров. Это не мой случай, т.к. ноуты у меня слабенькие, самый лучший вариант с 4Гб оперативки, остальные системные возможности даже смотрел. Я так понял бОльшая часть ресурсов будет уходить на отладку в эмуляторе. Ради Hello world покупать свежий современный ноут я точно не буду, ибо на данном этапе да и вообще в будущем - у меня не стоит задачи стать супер-крутым разработчиком мобильных приложений с перерождением в профессию в качестве основного заработка. Пока просто для развития, для себя хочу попробовать, благо время есть.
</p>

<p>
	3. Писать на Kotlin, компилировать через stand alone compiler, отлаживать на реальном устройстве. Вот этот вариант мне больше всего пока что нравится. По нему и буду просить подсказки далее по этой теме.
</p>

<p>
	Наверняка найдется туча продвинутой молодежи с лакированным эракезом на голове со вмятиной под экспандер для наушников, обитающих исключительно на Бали и поддерживающих свое рабочее место в идеальном порядке непременно с чистой салфеточкой и чашечкой вкуснейшего кофейка на ней, которые скажут - "дядя, в сети и так сотни туториалов на тему hello, world - погугли и не отнимай у нормальных людей время".
</p>

<p>
	С какой-то стороны я, наверное, от части, соглашусь с таким мнением. Но в целом, более обширном понимании, я не соглашусь с этими "райскими птицами" - гражданами мира, взрощенными в безумном хаосе технологического прогресса, разговаривающими на полупонятном, ломанном русском языке, со вставками через слово англоязычных терминов и слэнговых "программистских" выражений из английского языка, после начала прослушивания которых хочется через минуту-другую хлопнуть крышкой ноутбука и пойти покосить траву, подвязать помидоры или сделать что-то аналогичное, чтобы почистить заср***ую голову и вернуться в реальную жизнь.
</p>

<p>
	Я создал эту тему пока только для того, чтобы СДЕЛАТЬ ПЕРВЫЙ ШАГ к описанной выше цели, а именно:
</p>

<p>
	- установить компилятор языка Kotlin в свою ОС Windows, который по моему текущему представлению будет формировать из текстового файла с кодом исполняемое приложение под ОС Android
</p>

<p>
	- с учетом решения изучать только Kotlin, исключив изучение Java, хотелось бы услышать советы по этому вопросу - реально ли это? (я так понял Java отторгается и становится неактуальным языком в области создания приложений под Android, поэтому я не хочу тратить на его изучения свое время)
</p>

<p>
	Что я сделал:
</p>

<p>
	- собрал ресурсы по Kotlin и планирую его изучать, минуя долгое штудирование теории, т.е. хочу изучать от части методом тыка с максимально быстрым стартом практики с отладкой на реальном устройстве
</p>

<p>
	- скачал на гитхабе компилятор котлин kotlin-compiler-1.8.21.zip (я так понял, что это кроссплатформенная версия) и еще скачал компилятор для windows kotlin-native-windows-x86_64-1.8.21.zip (я так понял, что это как раз то, что мне скорее всего нужно, т.к. я планирую начать практическое изучение из под ОС Windows).
</p>

<p>
	Что не получается на текущий момент:
</p>

<p>
	Я пока не понял как мне правильно установить компилятор и какой из них все таки нужен для моего случая. Вроде бы и в сети есть и на англиском и на русском языках разные туториалы на эту тему, но бОльша часть из них мне кажется не актуальной с давностью 3-5 лет, когда Java еще был очень значим. В части этих статей рекомендуется скачать и установить полную IDE или отдельно NDK/SDK, а затем пользоваться компилятором, который также будет установлен в процессе. Более "низкоуровневые" варианты установки stand alone компилятора встречаются значительно реже и не совсем понятны, т.к. они в основном на англиском языке. Как я понял для установки компилятора нужно создать некую переменную в среде Windows, но не совсем понятно как это сделать.
</p>

<p>
	В общем, помогите шагнуть по варианту № 3 (отдельный компилятор под Windows без использования IDE с "крутой" отладкой на виртуальном устройстве)
</p>

<p>
	Извиняюсь за примитивный подход и примитивную "терминологию", я уже не очень молодой, мозги не так шустры, да и на Бали я не хочу, мне в деревне хорошо.
</p>
]]></description><guid isPermaLink="false">171363</guid><pubDate>Mon, 05 Jun 2023 11:00:41 +0000</pubDate></item><item><title>Rust &#x432;&#x43C;&#x435;&#x441;&#x442;&#x43E; C</title><link>https://electronix.ru/forum/topic/155300-rust-vmesto-c/</link><description><![CDATA[
<p>
	Вводная для тех, кто не слышал о Rust. Программисты Mozilla пережив три пожара и два переименования решили собрать все самые лучшие практики программирования на С и поняли, что они во многом сводятся к формализуемым четким правилам, выполнение которых делает программу надежной.
</p>

<p>
	Этот набор правил решили формализовать в виде компилятора языка программирования, который дает совершенно удивительные гарантии: целостность памяти, проверяемая во время компиляции.
</p>

<p>
	Т.е. не memory safety of assembler and speed of ruby, а наоборот.
</p>

<p>
	 
</p>

<p>
	Вот свежий пример: в зависимости от уровня приоритета прерывания, компилятор может потребовать обернуть обращение к переменной из обработчика в мьютекс.
</p>

<p>
	 
</p>

<p>
	Rust стал первым языком за много десятилетий, на котором можно написать библиотеку, которая будет встроена в код на С.  В обратную сторону умеет каждый язык программирования, а вот стать базовым не удавалось фактически даже плюсам.
</p>

<p>
	 
</p>

<p>
	Но всё было бы слишком скучно, если бы Rust так и оставался языком в рамках традиционного юникса.
</p>

<p>
	 
</p>

<p>
	Всё пошло дальше: из раста получилось выкинуть привычный stdlib и компилировать его под микроконтроллеры.
</p>

<p>
	<a href="https://rust-embedded.github.io/book/" rel="external nofollow">https://rust-embedded.github.io/book/</a>
</p>

<p>
	 
</p>

<p>
	а на базе этого родилась целая микро-ос в стиле freertos.
</p>

<p>
	<a href="https://rtfm.rs/0.5/book/en/by-example/tasks.html" rel="external nofollow">https://rtfm.rs/</a>
</p>

<p>
	 
</p>

<p>
	Если интересно — могу поделиться опытом нашей разработки под stm32<br />
	 
</p>

<p>
	 
</p>
]]></description><guid isPermaLink="false">155300</guid><pubDate>Sat, 25 Jan 2020 13:20:51 +0000</pubDate></item></channel></rss>
