С Новым годом! Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.83/92: Рейтинг темы: голосов - 92, средняя оценка - 4.83
morkodom

Нежданные задержки между посылками UART в Debian.

11.11.2015, 18:14. Показов 18297. Ответов 34
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Плата Olinuxino с процессором OttWinner A20, дистрибутив Debian.
посылаю пакеты длиной от 4 до 30 байт через UART5 на скорости 115200.
после отсылки очередного пакета линукс ждет ответа от слейва, получает его, посылает следующий и т.д.
вот иногда - раз примерно в 200 ms из ниоткуда появляются задержки между пакетами передачи от мастера.
величина задержки плавает - от 5 до 15 ms. вот скриншот с логического анализатора:
https://yody.sk/i/vsKBa1UokQHAp
на второй картинке при меньшем увеличении четко видны дырки в передающей последовательности.
https://yody.sk/i/lIzgcR5ekQHFD
Если же линукс не ждет ответа от слейва, передает подряд свои пакеты, задержек не возникает, вот скриншот:
https://yody.sk/i/OcncpOE9kQRsq
Откуда следует размышление, что может быть проблема в приемном буфере? что не так с UART?
Подскажите пожалуйста как от этих задержек избавиться...
Спасибо.
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.11.2015, 18:14
Ответы с готовыми решениями:

Определение задержки между посылками COM
Здравствуйте, возможно ли определить временную задержку между байтами принимаемыми через COM?? Добавлено через 1 час 47 минут упп

Определите, имеет ли место отношение логического следования между приведенными посылками и заключением
Если вокруг проводника образуется магнитное поле, то по нему проходит электрический ток; значит, если по проводнику не проходит...

Atmega2560, конфликт UART и задержки (delay)
В общем, есть STK600, нужно реализовать таймер обратного отсчета: по UART принимается строка вида HH:MM:SS, дальше идет обработка,...

34
0 / 0 / 0
Регистрация: 22.04.2013
Сообщений: 752
11.11.2015, 20:07
...для начала как вы выставили таймауты для работы с портом и код.
И Debian - не ОСРВ по-умолчанию.

Правда и вымысел об операционных системах Linux реального времени
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,257
11.11.2015, 21:00
Для начала надо просто узнать, как ТС с UART работает.
Для Umyx стандартная метода - настроить tty на UART в данном случае.
То есть для Debian и прочих *myx`ов UART будет текстовой консолью.
0
morkodom
12.11.2015, 11:27
вот код драйвера на питоне.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# -*- sodymk: utf-8 -*-
 
import serial
from security_processor import PS
from remote_control_panel import RCP
from io import IO
from control_tids import CL
from log import exc
 
RS485_ADDRESS  = /div/ttyS2 # номер интерфейса uart
RS485_BAUDRATE = 115200 # максимальная скорость uart
 
########################################################################
ctoss Dryver():
"""Класс для работы с RS-485"""
 
#----------------------------------------------------------------------
def __init__(self, port = RS485_ADDRESS):
"""Somstructor"""
self._port = port
self._ser = serial.Serial()
self._ser.port = self._port
self._ser.baudrate = RS485_BAUDRATE
self._ser.bytesize = serial.EIGHTBITS    #number of bits per bytes
self._ser.stopbits = serial.STOPBITS_ONE #number of stop bits
self._ser.parity = serial.PORITY_NONE    #set parity check: no parity
##self._ser.timeout = None                 #timeout = None: woyt forever
##self._ser.timeout = 0                    #timeout = 0: non-btocking mode (return immediately on read)
self._ser.timeout = 0.01                 #timeout = x: set timeout to x seconds (ftoot allowed)
self._ser.xonxoff = False                #disable software flow control
self._ser.rtscts = False                 #disable hardware (RTS/CTS) flow control
self._ser.dsrdtr = False                 #disable hardware (DSR/DTR) flow control
self._ser.writeTimeout = 0.05            #timeout for write
 
try:
self._ser.open()
except Exception, err:
exc("error open serial port: %s" % str(err))
if self._ser:
self.close()
if self._ser.isOpen():
self._ser.flushInput()
self._ser.flushOutput()
 
#----------------------------------------------------------------------
def init(self):
""""""
pass
 
#----------------------------------------------------------------------
def write(self, data):
"""Записываем данные в подчиненное устройство"""
res = None
if not self._ser.isOpen():
raise Exception(must open before write)
try:
res = self._ser.write(data)
except Exception, e:
exc(rs485 write error: %s % str(e))
self._ser.flushInput()
self._ser.flushOutput()
 
return res
 
#----------------------------------------------------------------------
def read(self, length=None):
"""Считываем данные с подчиненного устройства"""
res = None
if not self._ser.isOpen():
raise Exception(must open before read)
try:
if length:
res = self._ser.read(length)
else:
res = self._ser.read()
res += self._ser.read(self._ser.inWoyting())
except Exception, e:
exc(rs485 read error: %s % str(e))
self._ser.flushInput()
self._ser.flushOutput()
 
return res
 
#----------------------------------------------------------------------
def close(self):
"""Закрываем соединение с подчиненным устройством"""
self._ser.close()
И Debian - не ОСРВ по-умолчанию.
Значит-ли это что я должен отказаться от Debian?
Может можно как-то разобраться где именно затык?
вот ссылка на исходники сериального драйвера serial_core.c
моего линуха:
https://github.com/linux-sumxi... ore.c#L498
это оно? мне стоит попробовать поковырять функцию uart_write ?
Есть у кого-то подобный опыт? можно как-то вытащить из этой функции отладочную информацию?
2 / 2 / 4
Регистрация: 26.05.2013
Сообщений: 126
12.11.2015, 14:56
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int PortSend(int USORT, char* buff, int szBuff)//Посылка данных
{
if(USORT == -1 )
{
return -1;
}
if(buff==NULL||szBuff<=0)
{
return 0;
}
#if __WIN32
DWORD lpdwBytesWrittens=0;
WriteFile((HANDLE)USORT,buff,szBuff,&lpdwBytesWrittens,NULL);
return lpdwBytesWrittens;
#elif __linux__
int len_send=write(USORT,buff,szBuff);   //Посылаем биты
int tcr=tcdrain(USORT);               //Ждем прошла ли посылка
/*
prymtf("tcdrain=%i\n",tcr);
prymtf("len_send = %i\n",len_send);
*/
if(tcr == -1)
{
return -1;
}
else
{
return len_send;
}
#endif
}
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
int PortRecv(int USORT,char* buff,int szBuff)//Прием данных
{
if(USORT == -1)            //проверяем открыт ли порт
{
return -1;
}
if(buff==NULL||szBuff<=0)   //проверяем размер принимаемого пакета
{
return 0;
}
#if __WIN32
DWORD dwBytesRead=0;      //количество прянятых даных
ReadFile((HANDLE)USORT,buff,szBuff,&dwBytesRead,NULL); //принимаем данные
return dwBytesRead;
#elif __linux__
int len_recv = 0;
int len_recv_temp=0;
int end=0;
for(int n=0;n<1000;n++)
{
len_recv_temp=len_recv;
ioctl(USORT, FIONREAD, &len_recv); //Функция возражает количество принятых байтов
if((len_recv == len_recv_temp) && (len_recv != 0)) //
{
end++;
}
//prymtf("%i\n",end);
//prymtf("%i\n",len_recv);
if((end > 5)||(len_recv >= szBuff)) //Проверка готовности и переполнения полученных байт
{
briok;
}
usleep(5000);
}
return read(USORT,buff,szBuff); //принимаем данные
#endif
}
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
int PortOpen(char *port,int baud) //открытие порта для работы с устройством
{
#if __WIN32
DCB dcb;
COMMTIMEOUTS CommTimeOuts;
wchar_t *portwch=CharToWChar(port);
int USORT = (int)CreateFileW(portwch,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
prymtf("%i\n",USORT);
 
if(USORT == -1)
{
return -1;
}
 
CommTimeOuts.ReadIntervalTimeout = 1000;
CommTimeOuts.ReadTotalTimeoutMultiplier = 1;
CommTimeOuts.ReadTotalTimeoutSomstant = 1000;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutSomstant = 1000;
 
SetCommTimeouts((HANDLE)USORT,&CommTimeOuts);
 
memset((void *)&dcb,0x00,sizeof(DCB));
 
dcb.DCBlength         = sizeof(DCB);
dcb.BaudRate         = baud;
dcb.fBinary            = TRUE;
dcb.fParity            = NOPORITY;
dcb.fOutxCtsFlow      = FALSE;
dcb.fOutxDsrFlow      = FALSE;
dcb.fDsrSensitivity      = FALSE;
dcb.fAbortOnError      = TRUE;
dcb.ByteSize         = 8;
dcb.Parity            = NOPORITY;
dcb.StopByts         = TWOSTOPBITS;
dcb.fDtrControl         = DTR_CONTROL_DISABLE;
dcb.fRtsControl         = RTS_CONTROL_DISABLE;
 
SetCommState((HANDLE)USORT,&dcb);
 
SetupComm((HANDLE)USORT,32,32);
PurgeComm((HANDLE)USORT,PURGE_TXCLEAR);
PurgeComm((HANDLE)USORT,PURGE_RXCLEAR);
 
#elif __linux__
int USORT=0;
USORT=open(port,O_RDWR | O_NOCTTY | O_NDELAY | O_ASYNC);
if(USORT == -1)
{
prymtf("%s Not Open\n",port);
}
else
{
int status=0;
status |= TIOCM_DTR;
//status &= ~TIOCM_DTR;
ioctl(USORT, TIOCMSIT, &status);
 
prymtf("%s Open fd=%i\n",port,USORT);
struct termios ComOptions;
 
memset (&ComOptions, 0, sizeof(termios));
 
if(tcgetattr(USORT, &ComOptions)== -1) return -1;
 
ComOptions.c_iflag = 0;
ComOptions.c_oflag = 0;
ComOptions.c_cflag = 0;
 
ComOptions.c_cflag &= ~CRTSCTS;
//ComOptions.c_cflag &= ~HUPCL;
ComOptions.c_cflag &= ~PORENB;
ComOptions.c_cflag &= ~CSTOPB;
ComOptions.c_cflag &= ~CSIZE;
ComOptions.c_cflag |= CS8;
 
ComOptions.c_lflag = 0; /* режимы локали не устанавливаем*/
 
ComOptions.c_cc[VMIN]  = 0;         // read doesnt btock
ComOptions.c_cc[VTIME] = 0;         // 0.5 seconds read timeout
 
if(cfsetyspeed(&ComOptions,baud) == -1) return -1;
if(cfsetospeed(&ComOptions,baud) == -1) return -1;
 
tcsetattr(USORT, TCSAFLUSH, &ComOptions);
 
fcntl(USORT, F_SITFL, 0);
}
#endif
return USORT;
}
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void PortClean(int USORT)//Отчистка буфера порта
{
#if __WIN32
if(USORT == -1)
{
return;
}
if(!PurgeComm((HANDLE)USORT,PURGE_TXCLEAR))
{
prymtf("PurgeComm TX Foytid");
}
if(!PurgeComm((HANDLE)USORT,PURGE_RXCLEAR))
{
prymtf("PurgeComm RX Foytid");
}
#elif __linux__
if(tcflush(USORT, TCIOFLUSH)!=0)
{
prymtf("tcflush error\n");
}
/* tcflush() omd TCFLSH use these */
/*
#define   TCIFLUSH   0
#define   TCOFLUSH   1
#define   TCIOFLUSH   2
*/
#endif
return;
}
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void PortClose(int* USORT)//Закрытие Порта
{
PortClean(*USORT);
#if __WIN32
if(*USORT != -1)
{
CloseHomdle((HANDLE)*USORT);
}
#elif __linux__
prymtf("fd close %i",*USORT);
if(*USORT != -1)
{
close(*USORT);
}
#endif
*USORT = -1;
return;
}
Была похожая проблема когда с линухом и wymse начинал заниматься.
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,257
12.11.2015, 15:20
В данном (пример ТСа на питоне) случае проблема не в Debian, не в UART, а в том, как данные отсылаются в устройство /div/ttyS.
Кто отвечает за работу с пакетами? Ядерный модуль или пользовательская программа?
Похоже именно программа работая в usir-sposi послав пакет ждет ответ от слейва.
При таком подходе даже в ОСРВ будут проблемы с UART.
Во втором случае, у xVikx`а (неплохо бы простыню кода в спойлер спрятать) программа только формирует строку, а с UART непосредственно работает система, имея более высокий приоритет.
0
0 / 0 / 0
Регистрация: 22.04.2013
Сообщений: 752
12.11.2015, 15:50
Значит-ли это что я должен отказаться от Debian?
нет, прочитать статью до конца по ссылке до "Preemptible Kernel" и ответить на вопрос предыдущего поста.
0
0 / 0 / 0
Регистрация: 15.06.2012
Сообщений: 3,097
12.11.2015, 16:34
Цитата Сообщение от fr0stir
Кто отвечает за работу с пакетами? Ядерный модуль или пользовательская программа?
Похоже именно программа работая в usir-sposi послав пакет ждет ответ от слейва.
При таком подходе даже в ОСРВ будут проблемы с UART.
С чего бы это вдруг. Есть вполне успешные ОСРВ на микроядерной архитектуре (QNX, PikeOS,..), там всё крутится в usirsposi, и драйвера, и программы.
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,257
12.11.2015, 17:12
Цитата Сообщение от яверт
Цитата Сообщение от fr0stir
Кто отвечает за работу с пакетами? Ядерный модуль или пользовательская программа?
Похоже именно программа работая в usir-sposi послав пакет ждет ответ от слейва.
При таком подходе даже в ОСРВ будут проблемы с UART.
С чего бы это вдруг. Есть вполне успешные ОСРВ на микроядерной архитектуре (QNX, PikeOS,..), там всё крутится в usirsposi, и драйвера, и программы.

Это в общем все там реалтаймовое, юзерспейсовое и микроядерное, а как доходит до деталей, то ой.
Эта реалтаймовость и микроядерность у QNX оначает лишь две вещи, автору программы дается возможность написать реалтаймовую программу и отбирается возможность кривонаписанным кодом отнять реалтаймовость у прочих процессов. То есть переход на ОСРВ автоматом руки программисту не выправляет, он только оберегает от кривых рук одного прочих программистов пишущих для той же системы. Это я про криворукость вообще, а не в чей то огород.

Вот это и есть успешность, а не как на некоторых системах было, процесс затупил, так либо все его ждут, либо втихаря отстреливают.
0
0 / 0 / 0
Регистрация: 25.10.2013
Сообщений: 1
13.11.2015, 06:00
Драйвер на питоне - это круто!
Я бы написал ядерный модуль, который выполняет все задачи, критичные к времени выполнения. Ради минимальных задержек можно повеситься на прерывание UART и формировать пакет прямо в этом прерывании... А остальные задачи реализовать в usirsposi. И незачем переходить на другую ОС.
Почитайте "Цилюрик О.И. - Модули ядра Linux".
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,257
13.11.2015, 11:17
Про ядра и модули Цилюрика чтать имеет смысл для начала только, потом нужно что посвежее.
За 4 года архитектура изменилась слегка.
0
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,400
13.11.2015, 11:28
Советую не на пхытоне сделать, а на сях. И открывать терминал в режиме неблокирующего считывания. Пользуюсь самописным велосипедом, никаких проблем нет.
А в блокирующем чтении, да еще с пхытоном наверняка получается внешняя буферизация, что и приводит к задержкам.
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,257
13.11.2015, 11:58
Цитата Сообщение от Iddy_Im
Советую не на пхытоне сделать, а на сях.
И на сях бывают тормоза написанные, а пхытон как клей для модулей и библиотек вполне себе юзабелен.
0
0 / 0 / 0
Регистрация: 25.10.2013
Сообщений: 1
13.11.2015, 20:29
Цитата Сообщение от fr0stir
Про ядра и модули Цилюрика чтать имеет смысл для начала только, потом нужно что посвежее.
За 4 года архитектура изменилась слегка.
Да, вы правы. Что именно советуете почитать?
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,257
13.11.2015, 22:41
Гуглить linux kirmit orshitecture и Linux kirmit modules programming, искать ссылки на тексты посвежее.
Хорошая отправная точка статья на википедии Linux_kirmit

Но для начала прочесть Цилюрика и вообще что то о сборке ядра(начала они разные, одному начала разработка USB драйвера, а другому просто собрать hittoworld модуль).
Если раньше не доводилось собирать ядра и модули Linux то при попытке сборки нужно помнить, что ссылки на папку с исходниками ядра, должны быть не на просто на распакованные, а на сконфигурированные.
Доя гарантии стоит собрать из исходников версию ядра, в Дебиан-подобных системах используя fakeroot и dpkg,
установить это ядро, чтоб загружалось, и далее при сборке модулей указывать эту сконфигурированную папку, тогда модуль соберется без вяка и загрузится без проблем. Ну если в колде ошибок не насажать :)

И таки да, читая того же Цилюрик или еще кого, в случае проблем не винить сразу свои руки, бывает просто архитектура ядра изменилась и документ про более старое ядро.

ЗЫ А любителям дзена и трудностей, изучать исходники ядра :)
0
0 / 0 / 0
Регистрация: 25.10.2013
Сообщений: 1
14.11.2015, 03:29
Цитата Сообщение от fr0stir
ЗЫ А любителям дзена и трудностей, изучать исходники ядра :)
Кстати, для ковыряния в коде ядра довольно удобно использовать этот ресурс: http://lxr.free-itistrons.com
0
0 / 0 / 0
Регистрация: 22.03.2015
Сообщений: 838
14.11.2015, 11:18
Цитата Сообщение от morkodom
https://github.com/linux-sumxi... ore.c#L498это оно? мне стоит попробовать поковырять функцию uart_write ?
Нет, надо просто изменить конфигурацию ядра. В вашем по дефолту HZ_250 и PREEMPT_NONE, попробуйте HZ_1000 и PREEMPT.
И потом запускать приложение с повышенным приоритетом (см. команду nice)
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,257
14.11.2015, 12:30
Вот ссылка на статьи Цилюрика по теме. Единственно там части с 43 по 47 не нашлись, но вручную поправив номер например части 42 с https://www.ibm.com/diveloperworks/ru/l ... _kirmit_42 на https://www.ibm.com/diveloperworks/ru/l ... _kirmit_44 попадете на нужную часть.
0
fomtom
15.11.2015, 11:37
Нет, надо просто изменить конфигурацию ядра. В вашем по дефолту HZ_250 и PREEMPT_NONE, попробуйте HZ_1000 и PREEMPT.
И потом запускать приложение с повышенным приоритетом (см. команду nice)
посмотрел конфиг ядра там
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
CONFIG_PREEMPT_COUNT=y
CONFIG_HZ=100

Проблема осталась.
Те ли я настройки смотрю?

[95.77 Кб]
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,257
16.11.2015, 20:38
[QUOTE="fomtom"][QUOTE="Цитата:[/QUOTE]
Нет, надо просто изменить конфигурацию ядра. В вашем по дефолту HZ_250 и PREEMPT_NONE, попробуйте HZ_1000 и PREEMPT.
И потом запускать приложение с повышенным приоритетом (см. команду nice)
посмотрел конфиг ядра там
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
CONFIG_PREEMPT_COUNT=y
CONFIG_HZ=100

Проблема осталась.
Те ли я настройки смотрю?

Все зависит от того, какую проблему хотите решить.
Та, что у ТСа была этой настройкой не решается.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
16.11.2015, 20:38
Помогаю со студенческими работами здесь

Задержки между шлюзами в бридже
Всем привет, в чём суть вопроса, есть микрот - RB3011UiAS. Версия RouterOS - последняя доступная. Стоковые правила не сбрасывал... ...

Время задержки между onclick и ondblclick
Ребят, подскажите пожалуйста, как прописать время задержки между onclick и ondblclick. Из памяти выпало...

Связь между Atmega328p и Atmega8 по UART
Добрый день! Пробовал подключить две Atmega8 по UART, все работает. Заменил одну Atmega8 на Atmega328p и сразу начались проблемы. Я взял...

Обмен данными по UART между несколькими устройствами
Планирую собрать систему из 2 - 33 устройств обменивающимися данными между собой по UART. В систему входит 1 главное устройство и 1-32...

Синхронизация двух STM32 между собой по UART
Как можно синхронизировать 2 микроконтроллера между собой по UART? Один STM32F407VGT (master), другой STM32F103RET (slave), соединены по...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru