Перейти к содержанию
    

Большое число программных прерываний в ОС Linux при приеме информации по интерфейсу CAN на AM3517

Упс..., промашку давал... Утячья скорость получается - в полёте... :)

 

Интересно. Т.е. 1 интеррапт на каждые 64 байта? Это облегчает задачу. EDMA же привязана к ивенту, она и сложит эти 64 байта в угол, т.е. в буфер...

 

5 микросек это 3000 клоков процессора. На вход многовато, вход прост (разумно предположить такое?), а вот выход сложнее из-за перепланировки (знать бы алгоритм...). Ну условно можно считать, что 5 на вход и выход - разумное число. Хотя, это же Ослинукс, кто его разберёт... При 0.8 загрузке 5,900*64 клоков на 64 байта это 377К, от коего числа 3К на оверхед интеррапта составляет 0.0079 - т.е. 8 промилле. Меньше, чем процент.

 

1 message 64 бита.

Значит я ошибся в 8 раз, что уже приближается к порядку величины, полученной экспериментально.

Еще надо на обработку прерывания сколько-то дать. Потом апликация начинает обрабатывать. Выходим на порядок десятков процентов.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Интересно. Т.е. 1 интеррапт на каждые 64 байта? Это облегчает задачу. EDMA же привязана к ивенту, она и сложит эти 64 байта в угол, т.е. в буфер...

DMA слабо помогает в случае приема кан пакетов. Пакеты короткие и их из-за специфики применений шины кан приходится обрабатывать все программно.

 

5 микросек это 3000 клоков процессора. На вход многовато, вход прост (разумно предположить такое?), а вот выход сложнее из-за перепланировки (знать бы алгоритм...). Ну условно можно считать, что 5 на вход и выход - разумное число. Хотя, это же Ослинукс, кто его разберёт... При 0.8 загрузке 5,900*64 клоков на 64 байта это 377К, от коего числа 3К на оверхед интеррапта составляет 0.0079 - т.е. 8 промилле. Меньше, чем процент.

Такты считать бессмысленно потому что нужно плюсовать: промах I-cache с загрузкой строки с кодом обработчика прерывания (в это время цпу стоит), промах D-cache с загрузкой строки стека прерываний (в это время цпу стоит), плюсуйте латентность DDR2/3, плюсуйте задержки шинных коммутаторов. Прерывания каждые 50мкс для процессора это существенная нагрузка, причем чем больше гигагерц и ядер тем тяжелее

 

Также смотрим исходник драйвера кан (любого) и видим что на каждый пакет вызываются такие интересные функции как:

alloc_can_skb()

netif_receive_skb() которая в свою очередь вызывает совсем забавную функцию __netif_receive_skb()

 

Удивляет что оно вообще успевает принимать пакеты без потерь.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Такты считать бессмысленно потому что нужно плюсовать: промах I-cache с загрузкой строки с кодом обработчика прерывания (в это время цпу стоит), промах D-cache с загрузкой строки стека прерываний (в это время цпу стоит), плюсуйте латентность DDR2/3, плюсуйте задержки шинных коммутаторов. Прерывания каждые 50мкс для процессора это существенная нагрузка, причем чем больше гигагерц и ядер тем тяжелее
Они (ЦПУ столлы) с необходимостью входят в итоговый счёт. Но, всё-таки полагаем, что кеши увеличивают производительность, а не уменьшают :)

 

Поток с интервалом 50мкс, т.е. 20KHz, это даже меньше чем хай-фай аудио 2Х4 байта @96KHz, а ведь и стереозвук обрабатывают.

 

У меня получилось чуть больше, 65мкс на 8 байт. Предположим, что 5мкс оверхед прерывания, остаётся 60мкс или 36К клоков на расфасовку 8 байт. На первый взгляд - выполнимо...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поток с интервалом 50мкс, т.е. 20KHz, это даже меньше чем хай-фай аудио 2Х4 байта @96KHz, а ведь и стереозвук обрабатывают.

 

У меня получилось чуть больше, 65мкс на 8 байт. Предположим, что 5мкс оверхед прерывания, остаётся 60мкс или 36К клоков на расфасовку 8 байт. На первый взгляд - выполнимо...

 

Стерео звук обрабатывает дополнительное ядро DSP или специальный хардвер. Да и обработать большой буфер без метаний в прерывание легче если он уже принять при помощи ПДП.

5 мкс это вход в прерывание, потом еще обработка и вызов тасклета или work, что возьмет дополнительное время. Некоторые сообщения вызовут действия в пользовательском пространстве. Получится значительно больше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я не знаком с NAPI и CAN драйверы на Линуксе я тоже не делал. Полагаю, что CAN драйвер надо настроить (или дописать), чтобы использовал механизм NAPI. Если вы не работали с кернелом, то вам будет непросто выполнить эту задачу.

 

Прежде чем начинать надо оценить насколько оно вам поможет.

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

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

 

Решение задачи я вижу только в одном из направлений:

1. Снижение интенсивности сообщений

2. Использование более мощного процессора.

3. Установка дополнительного устройства, ответственного за обработку (хотя бы частичную) сообщений.

 

В третьем случае может понадобится написать драйвер.

 

Приношу извинения за задержку немного погрузился в проблему загрузки ОС. Ситуацию удалось изменить, сейчас загрузка ОС Linux составляет примерно 10-11% при той же ~80% загрузке шины CAN (при компиляции не обратил внимание, что в ядро включено много не нужного). Данная загрузка приемлемая, но возникла другая проблема.

 

Mem: 52544K used, 191492K free, 0K shrd, 1796K buff, 43212K cached
CPU:   0% usr   5% sys   0% nic  78% idle   0% io   0% irq  14% sirq
Load average: 0.11 0.06 0.03 1/54 832
 PID    PPID        USER     STAT      VSZ    %MEM    %CPU    COMMAND
 831    828         root         R        1472          1%      10%    ./a.out 
 355        2         root       SW             0          0%        1%    [kworker/0:1]
 832    828         root         R        2844          1%        0%    top 
 507        2         root       SW             0          0%        0%   [ksdioirqd/mmc1]
 828    801         root         S         2844          1%       0%    -sh 
 768        1         root         S         2732          1%       0%    /sbin/syslogd -n -C64 -m 20 
 770        1         root         S         2668          1%       0%    /sbin/klogd -n 
 518        1         root         S         2668          1%       0%    /bin/sh /etc/rcS.d/S01psplash start 
 761        1         root         S         2668          1%       0%    /usr/sbin/telnetd 
 521    518         root         S         2536          1%       0%     sleep 120 
 756        1    messageb     S         2436          1%       0%    /usr/bin/dbus-daemon --system 
 801        1         root         S         2400          1%       0%     login -- root      
 539        1         root         S <      2188          1%       0%    /sbin/udevd -d 
 557    539         root         S <      2184          1%       0%    /sbin/udevd -d 
 567    539         root         S <      2184          1%       0%    /sbin/udevd -d 
     1        0         root         S         1628           1%       0%    init [5]   
     5        2         root       SW              0           0%       0%    [kworker/u:0]
 495        2         root       SW              0           0%       0%    [mmcqd/0]
     3        2         root       SW              0           0%       0%    [ksoftirqd/0]
    45       2         root       SW              0           0%       0%    [irq/74-serial i]

 

root@am3517-evm:~# cat /proc/interrupts 
            CPU0
11:               0        INTC  prcm
12:         2658        INTC  DMA
20:               0        INTC  gpmc
24:     999278        INTC  can0
25:               4        INTC  OMAP DSS
37:     177708        INTC  gp timer
56:     921263        INTC  omap_i2c
57:               0        INTC  omap_i2c
58:       33368        INTC  omap_hdq
61:               0        INTC  omap_i2c
71:               1        INTC  musb-hdrc.0
72:               0        INTC  serial idle
73:               0        INTC  serial idle
74:       30619        INTC  serial idle, OMAP UART2
77:               0        INTC  ehci_hcd:usb2
83:         4935        INTC  mmc0
86:      178303        INTC  mmc1
160:              0        GPIO  tps6507x
162:              1        GPIO  mmc1
184:              0        GPIO  ds1374
186:              0        GPIO  tca8418-keypad
224:              0        GPIO  mmc0
Err:               0

 

root@am3517-evm:~# ifconfig 
can0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
         UP RUNNING NOARP  MTU:16  Metric:1
         RX packets:1000000 errors:0 dropped:0 overruns:0 frame:0
         TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:10 
         RX bytes:8000000 (7.6 MiB)  TX bytes:0 (0.0 B)
         Interrupt:24 

lo        Link encap:Local Loopback  
         inet addr:127.0.0.1  Mask:255.0.0.0
         UP LOOPBACK RUNNING  MTU:16436  Metric:1
         RX packets:0 errors:0 dropped:0 overruns:0 frame:0
         TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:0 
         RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

 

DMA слабо помогает в случае приема кан пакетов. Пакеты короткие и их из-за специфики применений шины кан приходится обрабатывать все программно.

 

 

Такты считать бессмысленно потому что нужно плюсовать: промах I-cache с загрузкой строки с кодом обработчика прерывания (в это время цпу стоит), промах D-cache с загрузкой строки стека прерываний (в это время цпу стоит), плюсуйте латентность DDR2/3, плюсуйте задержки шинных коммутаторов. Прерывания каждые 50мкс для процессора это существенная нагрузка, причем чем больше гигагерц и ядер тем тяжелее

 

Также смотрим исходник драйвера кан (любого) и видим что на каждый пакет вызываются такие интересные функции как:

alloc_can_skb()

netif_receive_skb() которая в свою очередь вызывает совсем забавную функцию __netif_receive_skb()

 

Удивляет что оно вообще успевает принимать пакеты без потерь.

 

Действительно при превышении 15% загрузки шины CAN при скорости 1МБит/с начинаются потери пакетов (потери наблюдались при загрузки шины CAN ~20%). Максимально замеченные потери составили 0.03% на 1000000 пакетов. Как побороть эту проблему пока не понимаю. Если у кого то есть идеи или вариант решения буду благодарен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Действительно при превышении 15% загрузки шины CAN при скорости 1МБит/с начинаются потери пакетов (потери наблюдались при загрузки шины CAN ~20%). Максимально замеченные потери составили 0.03% на 1000000 пакетов. Как побороть эту проблему пока не понимаю. Если у кого то есть идеи или вариант решения буду благодарен.

 

Вы пользуетесь поллингом или интерраптом?

Не исключено, что возникают ошибки. Посмотрите как обрабатываются ошибки.

 

Поставить счетчик обработаных сообщений интерраптом и проверить равно ли количество интерраптов этому значению. Если они не равны то:

Заведите на каждую ошибку по переменной, инициализируйте их нулем, вставьте инкрементировани этих переменных в обработчики ошибок. После эксперимента проверьте переменные, так можно будет узнать о характере проблемы.

 

Если используете поллинг, то он может пропустить пакет, а если ошибка -- выбросить испорченый.

Если interrupt, то неплохо бы время реакции померять. Самый простой способ -- дернуть пин в обработчике прерывания и двухлучевым осциллографом посмотреть на шину CAN и этот пин. Посмотреть сколько времени занимает от конца сообщения до дергания пина.

 

Попробовать слать сообщения с интервалом между сообщениями и без интервала. Сравнить статистику.

 

Изменено пользователем Tarbal

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы пользуетесь поллингом или интерраптом?

Не исключено, что возникают ошибки. Посмотрите как обрабатываются ошибки.

 

Поставить счетчик обработаных сообщений интерраптом и проверить равно ли количество интерраптов этому значению. Если они не равны то:

Заведите на каждую ошибку по переменной, инициализируйте их нулем, вставьте инкрементировани этих переменных в обработчики ошибок. После эксперимента проверьте переменные, так можно будет узнать о характере проблемы.

 

Если используете поллинг, то он может пропустить пакет, а если ошибка -- выбросить испорченый.

Если interrupt, то неплохо бы время реакции померять. Самый простой способ -- дернуть пин в обработчике прерывания и двухлучевым осциллографом посмотреть на шину CAN и этот пин. Посмотреть сколько времени занимает от конца сообщения до дергания пина.

 

Попробовать слать сообщения с интервалом между сообщениями и без интервала. Сравнить статистику.

 

Экспериментируя с приемом по CAN заметил такую закономерность: если во время приема вылетело сообщение omap_device: omap_i2c.1: new worst case deactivate latency 0: 518798 или omap_device: omap_i2c.1: new worst case activate latency 0: 183105, то происходит потеря пакетов, если таких сообщений нет, то прием проходит без потерь. Что это за задержки и как они могут влиять на CAN?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Экспериментируя с приемом по CAN заметил такую закономерность: если во время приема вылетело сообщение omap_device: omap_i2c.1: new worst case deactivate latency 0: 518798 или omap_device: omap_i2c.1: new worst case activate latency 0: 183105, то происходит потеря пакетов, если таких сообщений нет, то прием проходит без потерь. Что это за задержки и как они могут влиять на CAN?

 

latency имеет немного не такой смысл как задержка. Это скорее интервал временной недоступности рессурса. Вот например имеем мы обработчик прерывания на 10 микросекунд и в это время менее приоритетные прерывания не могут быть обработаны, значит имеем latency 10 мкс. Другой пример видео устройство обрабатывает видеопоток, но между входным и выходным кадром четыре находятся внутри видео устройства. Имеем latency 4 кадра.

 

Полагаю, что если где-то запрещены прерывания, то это тоже вызывает latency.

 

Я бы поискал кто пишет сообщения и выяснил бы сценарий. Каким боком к вашему CAN относится i2c? Возможно они борятся за какой-то общий рессурс или их обоих кто-то третий тормозит.

строка 231:

http://lxr.free-electrons.com/source/arch/..._device.c?v=3.6

 

 

Про сообщение:

http://git.igep.es/?p=pub/scm/linux-omap-2...1a6f2cb4f79b6c0

Изменено пользователем Tarbal

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

latency имеет немного не такой смысл как задержка. Это скорее интервал временной недоступности рессурса. Вот например имеем мы обработчик прерывания на 10 микросекунд и в это время менее приоритетные прерывания не могут быть обработаны, значит имеем latency 10 мкс. Другой пример видео устройство обрабатывает видеопоток, но между входным и выходным кадром четыре находятся внутри видео устройства. Имеем latency 4 кадра.

 

Полагаю, что если где-то запрещены прерывания, то это тоже вызывает latency.

 

Я бы поискал кто пишет сообщения и выяснил бы сценарий. Каким боком к вашему CAN относится i2c? Возможно они борятся за какой-то общий рессурс или их обоих кто-то третий тормозит.

строка 231:

http://lxr.free-electrons.com/source/arch/..._device.c?v=3.6

 

 

Про сообщение:

http://git.igep.es/?p=pub/scm/linux-omap-2...1a6f2cb4f79b6c0

 

Сделал следующим образом, в файле omap_device.c поправил функцию _omap_device_activate

было

124         odpl = od->pm_lats + od->pm_lat_level;
125 
126         if (!ignore_lat &&
127             (od->dev_wakeup_lat <= od->_dev_wakeup_lat_limit))
128             break;
129 
130         read_persistent_clock(&a);

сделал

124         odpl = od->pm_lats + od->pm_lat_level;
125 
126         if (!ignore_lat)
127             break;
128 
129         read_persistent_clock(&a);

Так же поправил функцию _omap_device_deactivate

было

191         odpl = od->pm_lats + od->pm_lat_level;
192 
193         if (!ignore_lat &&
194             ((od->dev_wakeup_lat + odpl->activate_lat) >
195              od->_dev_wakeup_lat_limit))
196             break;
197 
198         read_persistent_clock(&a);

сделал

190         odpl = od->pm_lats + od->pm_lat_level;
191 
192         if (!ignore_lat)
193             break;
194 
195         read_persistent_clock(&a);

При таком раскладе работает. Сейчас буду стучать в поддержку TI, чтоб нормально все поправили.

Изменено пользователем Таратухин Сергей

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы уверены, что вы починили функциональность, а не только предотватили печатание сообщения?

Я бы разобрался что происходит для начала.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы уверены, что вы починили функциональность, а не только предотватили печатание сообщения?

Я бы разобрался что происходит для начала.

 

После правки, проверил работоспособность периферии сидящей на i2c, а так же проверил прием по CAN интерфейсу, потери пакетов не наблюдалось. Проверки продолжу, потому что действительно пока сам не уверен, что все работает должным образом. Параллельно буду донимать поддержку TI, чтоб они подтвердили, наличие ошибки и сделали корректный патч, не как я поступил, просто обрезал латентности.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

И не рассчитывайте :(

У них (как и у Фрискейла) сейчас кампания за Андроид. Все что напрямую не связано с Андроидом ими игнорируется. Однако в e2e написать стоит.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И не рассчитывайте :(

У них (как и у Фрискейла) сейчас кампания за Андроид. Все что напрямую не связано с Андроидом ими игнорируется. Однако в e2e написать стоит.

 

Вот ответ из TI:

If you make some search on the src code you will fond out that the fct the print this messages are  _omap_device_activate and _omap_device_deactivate from arch/arm/plat-omap/omap_device.c.

Seems to be called from I2c driver context in this case. You will need to investigate when this code is called and why it would prevent the CAN driver to capture packets.

 

Нашел, более правильное решение, в файле omap_device.c для функции _omap_device_activate внес немного другое изменение.

было:

144         if (act_lat > odpl->activate_lat) {
145             odpl->activate_lat_worst = act_lat;
146             if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
147                 odpl->activate_lat = act_lat;
148                 pr_warning("omap_device: %s.%d: new worst case "
149                        "activate latency %d: %llu\n",
150                        od->pdev.name, od->pdev.id,
151                        od->pm_lat_level, act_lat);
152             } else
153                 pr_warning("omap_device: %s.%d: activate "
154                        "latency %d higher than exptected. "
155                        "(%llu > %d)\n",
156                        od->pdev.name, od->pdev.id,
157                        od->pm_lat_level, act_lat,
158                        odpl->activate_lat);
159         }

сделал

144         if (act_lat > odpl->activate_lat) {
145             odpl->activate_lat_worst = act_lat;
146             if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
147                 odpl->activate_lat = act_lat;
148             } else
149                 pr_warning("omap_device: %s.%d: activate "
150                        "latency %d higher than exptected. "
151                        "(%llu > %d)\n",
152                        od->pdev.name, od->pdev.id,
153                        od->pm_lat_level, act_lat,
154                        odpl->activate_lat);
155         }

 

И для функции _omap_device_deactivate

было

212         if (deact_lat > odpl->deactivate_lat) {
213             odpl->deactivate_lat_worst = deact_lat;
214             if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
215                 odpl->deactivate_lat = deact_lat;
216                 pr_warning("omap_device: %s.%d: new worst case "
217                        "deactivate latency %d: %llu\n",
218                        od->pdev.name, od->pdev.id,
219                        od->pm_lat_level, deact_lat);
220             } else
221                 pr_warning("omap_device: %s.%d: deactivate "
222                        "latency %d higher than exptected. "
223                        "(%llu > %d)\n",
224                        od->pdev.name, od->pdev.id,
225                        od->pm_lat_level, deact_lat,
226                        odpl->deactivate_lat);
227         }

сделал

208         if (deact_lat > odpl->deactivate_lat) {
209             odpl->deactivate_lat_worst = deact_lat;
210             if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
211                 odpl->deactivate_lat = deact_lat;
212             } else
213                 pr_warning("omap_device: %s.%d: deactivate "
214                        "latency %d higher than exptected. "
215                        "(%llu > %d)\n",
216                        od->pdev.name, od->pdev.id,
217                        od->pm_lat_level, deact_lat,
218                        odpl->deactivate_lat);
219         }

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте. Уже месяц бьюсь над такой-же проблемой.

Контроллер Freescale на плате iMX6 Marsboard.

При скорости 1Mbit и 18% загрузке шины (~2.3к сообщений в секунду) потери пакетов составляют стабильно 2,83-2,87%.

Попробовал изменить can_bittiming_const в драйвере, потери уменьшились до 0,03% но все еще присутствуют.

static struct can_bittiming_const flexcan_bittiming_const = {
    .name = DRV_NAME,
-    .tseg1_min = 4,
+      .tseg1_min = 2,
-    .tseg1_max = 16,
+    .tseg1_max = 8,
    .tseg2_min = 2,
    .tseg2_max = 8,
    .sjw_max = 4,
    .brp_min = 1,
    .brp_max = 256,
    .brp_inc = 1,
};

Попытался изменить настройки ядра, но ничего путного не вышло т.к. я с Linux до этого никогда так плотно не работал. Только параметр Preemption Model существенно изменил результаты. По умолчанию стоит "Preemptible Kernel (Low-Latensy Desktop)" и приходит огромное множество прерываний. При установке значения в "No Forsed Preemption (Server)" количество прерываний резко падает (по ощущениям именно в этот момент начинает нормально работать NAPI), но потери достигают 97%.

 

Пробовал добавлять в драйвер информационные сообщения что бы увидеть порядок вызова функций. Получилось приблизительно следующее:

Call flexcan_irq
Call flexcan_poll
Call flexcan_poll_state, quota = 8
Call flexcan_read_frame
Call flexcan_read_fifo
Call flexcan_read_frame
Call flexcan_read_fifo
Call flexcan_read_frame
Call flexcan_read_fifo
Call flexcan_read_frame
Call flexcan_read_fifo
Call flexcan_read_frame
Call flexcan_read_fifo
Call flexcan_read_frame
Call flexcan_read_fifo
Call flexcan_read_frame
Call flexcan_read_fifo
Call flexcan_read_frame
Call flexcan_read_fifo
Call flexcan_irq
Call flexcan_poll
Call flexcan_poll_state, quota = 8
Call flexcan_read_frame
Call flexcan_read_fifo
И так далее...

В общем буфер заполняется и получается Rx_Overflow.

 

Программа, которая считает пакеты получилась как тут, даже проще: просто инкремент по принятию и раз в 10 секунд выдача в консоль.

#include "main.h"
#include "types.h"

#define SAVE_TIMER_TIME 10

static void Save_Timer(void);

unsigned int TransMessageCount = 0;

int main(int argc, char **argv)
{
const char* INTERFACE = NAME_CAN;

signal(SIGALRM, (void (*)(int)) Save_Timer);

signed int CanSocket = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (CanSocket < 0)	{
	perror("READ: Can't open CAN socket");
}
alarm(SAVE_TIMER_TIME);	

ifreq Ifr;
strncpy(Ifr.ifr_name, INTERFACE, sizeof(Ifr.ifr_name));
if (ioctl(CanSocket, SIOCGIFINDEX, &Ifr))	{
	perror("READ: Error in IOCTL func");
}

sockaddr_can Addr;
Addr.can_family = PF_CAN;
Addr.can_ifindex = Ifr.ifr_ifindex;
if (bind(CanSocket, (struct sockaddr*)&Addr, sizeof(Addr)) < 0)	{
	perror("READ: Error in BIND func");
}

static unsigned int TransMessBufLength = 0;
static int ReadBytes;
static can_frame Frame;

while(1)	{
	ReadBytes = recv(CanSocket, &Frame, sizeof(struct can_frame), 0);
	if(ReadBytes > 0)	{
		TransMessageCount++;
	}
}
close(CanSocket);
return 0;
}

static void Save_Timer(void)
{
cout <<"Read "<< TransMessageCount <<" messages\n";
alarm(SAVE_TIMER_TIME);	
return;
}

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

 

В общем я застрял на потерях и не знаю в каком направлении мне двигаться дальше. Прошу у вас помощи или совета.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...