Меню

+7 (495) 785-95-25
sale@lcard.ru
sale@lcard.ru
Страницы 1
Пошел смотреть на всякий случай dmesg и увидел там ошибки:
[ 408.554192] workqueue: vmstat_update hogged CPU for >10000us 32 times, consider switching to WQ_UNBOUND
[ 411.179146] workqueue: psi_avgs_work hogged CPU for >10000us 4 times, consider switching to WQ_UNBOUND
[ 419.804140] lpcie: Cannot stop dma channel 0!!
[ 419.814709] workqueue: sync_rcu_exp_select_node_cpus hogged CPU for >10000us 4 times, consider switching to WQ_UNBOUND
[ 427.689782] workqueue: sync_rcu_exp_select_node_cpus hogged CPU for >10000us 8 times, consider switching to WQ_UNBOUND
[ 432.929163] lpcie: Cannot stop dma channel 1!!
[ 438.179160] sched: RT throttling activated
[ 438.179161] workqueue: psi_avgs_work hogged CPU for >10000us 8 times, consider switching to WQ_UNBOUND
[ 443.439924] workqueue: sync_rcu_exp_select_node_cpus hogged CPU for >10000us 16 times, consider switching to WQ_UNBOUND
[ 446.054176] lpcie: Cannot stop dma channel 0!!
[ 457.866670] watchdog: BUG: soft lockup - CPU#2 stuck for 27s! [l502:6680]
[ 457.866677] Modules linked in: intel_rapl_msr intel_rapl_common intel_uncore_frequency intel_uncore_frequency_common isst_if_common skx_edac skx_edac_common nfit x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel snd_hda_codec_realtek kvm snd_hda_codec_generic irqbypass crct10dif_pclmul polyval_clmulni polyval_generic ghash_clmulni_intel sha256_ssse3 snd_hda_intel sha1_ssse3 snd_intel_dspcfg aesni_intel snd_intel_sdw_acpi crypto_simd snd_hda_codec binfmt_misc cryptd snd_hda_core snd_hwdep snd_pcm rapl snd_seq_midi snd_seq_midi_event ipmi_ssif nls_iso8859_1 intel_cstate snd_rawmidi lpcie(OE) snd_seq snd_seq_device snd_timer intel_wmi_thunderbolt altera_cvp fpga_mgr joydev input_leds plx_pci cmdlinepart snd sja1000 ast peak_pciefd spi_nor can_dev i2c_algo_bit soundcore mei_me mtd ioatdma mei intel_pch_thermal acpi_power_meter ipmi_si acpi_ipmi ipmi_devintf ipmi_msghandler acpi_pad mac_hid sch_fq_codel msr parport_pc ppdev lp parport efi_pstore ip_tables x_tables autofs4 hid_generic usbhid hid crc32_pclmul ixgbe
[ 457.866793] spi_intel_pci i2c_i801 xfrm_algo ahci spi_intel dca i2c_smbus lpc_ich xhci_pci mdio libahci xhci_pci_renesas wmi
[ 457.866810] CPU: 2 PID: 6680 Comm: l502 Tainted: G OEL 6.8.0-60-generic #63~22.04.1-Ubuntu
[ 457.866814] Hardware name: Supermicro Super Server/X11DPG-QT, BIOS 3.3 02/21/2020
[ 457.866816] RIP: 0010:ioread32+0x3c/0x80
[ 457.866824] Code: 89 fa ed 31 d2 31 f6 31 ff c3 cc cc cc cc 8b 05 ba 2e e6 01 85 c0 75 1d b8 ff ff ff ff 31 d2 31 f6 31 ff c3 cc cc cc cc 8b 07 <31> d2 31 f6 31 ff c3 cc cc cc cc 55 83 e8 01 48 89 fe 48 c7 c2 a5
[ 457.866828] RSP: 0018:ffffb10228bd3a58 EFLAGS: 00000296
[ 457.866831] RAX: 00000000ffffffff RBX: ffffb10228bd3ac4 RCX: 0000000000000001
[ 457.866833] RDX: ffffb10228bd3ac4 RSI: 0000000000000701 RDI: ffffb10220325c04
[ 457.866835] RBP: ffffb10228bd3a68 R08: 0000000000000000 R09: 0000000000000000
[ 457.866837] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000002
[ 457.866838] R13: 0000000000000001 R14: 0000000000000002 R15: ffff9f49c05e9680
[ 457.866840] FS: 0000745b2f85f740(0000) GS:ffff9f60cf300000(0000) knlGS:0000000000000000
[ 457.866842] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 457.866844] CR2: 000073b1cc01d898 CR3: 000000012fad8001 CR4: 00000000007706f0
[ 457.866845] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 457.866846] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[ 457.866848] PKRU: 55555554
[ 457.866849] Call Trace:
[ 457.866851] <IRQ>
[ 457.866855] ? show_regs+0x6d/0x80
[ 457.866862] ? watchdog_timer_fn+0x206/0x290
[ 457.866867] ? __pfx_watchdog_timer_fn+0x10/0x10
[ 457.866869] ? __hrtimer_run_queues+0x10f/0x2a0
[ 457.866874] ? rcu_core+0x1d2/0x390
[ 457.866878] ? hrtimer_interrupt+0xf6/0x250
[ 457.866881] ? __sysvec_apic_timer_interrupt+0x4e/0x120
[ 457.866887] ? sysvec_apic_timer_interrupt+0x8d/0xd0
[ 457.866893] </IRQ>
[ 457.866894] <TASK>
[ 457.866895] ? asm_sysvec_apic_timer_interrupt+0x1b/0x20
[ 457.866900] ? ioread32+0x3c/0x80
[ 457.866905] ? lpcie_fpga_reg_read+0x31/0x60 [lpcie]
[ 457.866910] f_dma_stop+0x80/0x560 [lpcie]
[ 457.866916] lpcie_stream_free+0x28/0x140 [lpcie]
[ 457.866921] lpcie_streams_dev_release+0x28/0x50 [lpcie]
[ 457.866925] lpcie_release+0x2e/0x40 [lpcie]
[ 457.866930] __fput+0xa0/0x2e0
[ 457.866937] __fput_sync+0x1c/0x30
[ 457.866940] __x64_sys_close+0x3e/0x90
[ 457.866945] x64_sys_call+0x19ad/0x2480
[ 457.866949] do_syscall_64+0x81/0x170
[ 457.866964] ? iterate_tty_write+0x1a1/0x260
[ 457.866971] ? tty_ldisc_deref+0x16/0x20
[ 457.866976] ? file_tty_write.constprop.0+0x9b/0x110
[ 457.866980] ? tty_write+0x11/0x20
[ 457.866983] ? vfs_write+0x2a5/0x480
[ 457.866988] ? ksys_write+0x73/0x100
[ 457.866992] ? syscall_exit_to_user_mode+0x83/0x260
[ 457.866995] ? do_syscall_64+0x8d/0x170
[ 457.866998] ? restore_fpregs_from_fpstate+0x3d/0xd0
[ 457.867002] ? switch_fpu_return+0x55/0xf0
[ 457.867005] ? syscall_exit_to_user_mode+0x83/0x260
[ 457.867009] ? _copy_from_user+0x2f/0x80
[ 457.867015] ? lpcie_fpga_reg_write+0x32/0x50 [lpcie]
[ 457.867018] ? lpcie_ioctl_unlock+0x53a/0x580 [lpcie]
[ 457.867023] ? __x64_sys_ioctl+0xa0/0xf0
[ 457.867030] ? syscall_exit_to_user_mode+0x83/0x260
[ 457.867034] ? do_syscall_64+0x8d/0x170
[ 457.867037] ? do_syscall_64+0x8d/0x170
[ 457.867040] ? do_syscall_64+0x8d/0x170
[ 457.867044] ? irqentry_exit+0x43/0x50
[ 457.867047] ? clear_bhb_loop+0x15/0x70
[ 457.867051] ? clear_bhb_loop+0x15/0x70
[ 457.867061] ? clear_bhb_loop+0x15/0x70
[ 457.867064] entry_SYSCALL_64_after_hwframe+0x78/0x80
[ 457.867070] RIP: 0033:0x745b2f714f67
[ 457.867093] Code: ff e8 0d 16 02 00 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 03 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 41 c3 48 83 ec 18 89 7c 24 0c e8 73 ba f7 ff
[ 457.867095] RSP: 002b:00007fff21ca20e8 EFLAGS: 00000246 ORIG_RAX: 0000000000000003
[ 457.867098] RAX: ffffffffffffffda RBX: 00005e6929ccb880 RCX: 0000745b2f714f67
[ 457.867100] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000003
[ 457.867101] RBP: 00007fff21ca2140 R08: 0000000000000000 R09: 00007fff21ca1fea
[ 457.867103] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
[ 457.867104] R13: 00007fff21ca2130 R14: 00007fff21ca2124 R15: 00005e69198c609b
[ 457.867107] </TASK>
Происходит ошибка "Cannot stop dma channel" уже после вызовов X502_GetRecvReadyCount. Может быть, что проблемы связаны?
Приветствую!
Разрабатываю модуль на C для получения измерений с аналоговых входов L-502. Столкнулся со следующей проблемой: метод X502_Recv всегда выполняется около 4х секунд, вне зависимости от частоты АЦП и количества запрашиваемых отсчетов. Если передать таймаут меньше 4х секунд, то стабильно ничего не возвращается.
В целях дебага написал простой код, который с интервалом в 1 секунду вызывает X502_GetRecvReadyCount, и также получил весьма странные результаты.
Код:
#include <locale.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <x502api.h>
#include <l502api.h>
uint32_t calc_delay(struct timeval *start, struct timeval *stop) {
return (stop->tv_sec - start->tv_sec) * 1000000 + stop->tv_usec - start->tv_usec;
}
int main(int argc, char** argv) {
setlocale(LC_NUMERIC, "");
struct timeval start, stop;
uint64_t delta_us;
int32_t err;
// Получаем версию библиотеки
uint32_t ver = X502_GetLibraryVersion();
printf("Library version: %d.%d.%d\n", (ver >> 24)&0xFF, (ver>>16)&0xFF, (ver>>8)&0xFF);
// Получаем количество подключенных устройств по интерфейсу PCI
uint32_t devcnt = 0;
L502_GetDevRecordsList(NULL, 0, 0, &devcnt);
printf("Found %d PCI device(s)\n", devcnt);
// Выводим список найденных устройств
if (devcnt == 0) {
return 0;
}
// Выделяем память для массива для сохранения найденного количества записей
t_x502_devrec *devices = NULL;
devices = malloc(devcnt * sizeof(t_x502_devrec));
// Получаем записи о модулях L502
L502_GetDevRecordsList(&devices[0], devcnt, 0, NULL);
for (int i=0; i<devcnt; ++i) {
printf("Device %d: %s (SN: %s, Flags: %x)\n", i, devices[i].devname, devices[i].serial, devices[i].flags);
}
// Устанавливаем соединение
t_x502_hnd dev_hnd = X502_Create();
gettimeofday(&start, NULL);
err = X502_OpenByDevRecord(dev_hnd, &devices[0]);
gettimeofday(&stop, NULL);
printf("X502_OpenByDevRecord took %'d us\n", calc_delay(&start, &stop));
if (err != X502_ERR_OK) {
fprintf(stderr, "Error connecting to device: %s\n", X502_GetErrorString(err));
return 1;
}
printf("Successfully connected to device!\n");
// Освобождение ресурсов действительных записей из списка
X502_FreeDevRecordList(devices, devcnt);
// Очистка памяти самого массива
free(devices);
// Устанавливаем параметры логической таблицы АЦП
err = X502_SetLChannelCount(dev_hnd, 1);
if (err != X502_ERR_OK) {
fprintf(stderr, "Error configuring ADC inputs: %s\n", X502_GetErrorString(err));
return 1;
}
err = X502_SetLChannel(dev_hnd, 0, 0, X502_LCH_MODE_COMM, X502_ADC_RANGE_10, 0);
if (err != X502_ERR_OK) {
fprintf(stderr, "Error configuring ADC inputs: %s\n", X502_GetErrorString(err));
return 1;
}
err = X502_SetMode(dev_hnd, X502_MODE_FPGA);
if (err != X502_ERR_OK) {
fprintf(stderr, "Error setting mode: %s\n", X502_GetErrorString(err));
return 1;
}
// Устанавливаем частоту АЦП
double f_adc = 2000.0;
err = X502_SetAdcFreq(dev_hnd, &f_adc, NULL);
if (err != X502_ERR_OK) {
fprintf(stderr, "Error setting ADC frequency: %s\n", X502_GetErrorString(err));
return 1;
}
// Записываем настройки
err = X502_Configure(dev_hnd, 0);
if (err != X502_ERR_OK) {
fprintf(stderr, "Error configuring device: %s\n", X502_GetErrorString(err));
return 1;
}
// Разрешаем синхронные потоки
int streams = X502_STREAM_ADC;
err = X502_StreamsEnable(dev_hnd, streams);
if (err != X502_ERR_OK) {
fprintf(stderr, "Error configuring input streams: %s\n", X502_GetErrorString(err));
return 1;
}
// Начинаем чтение данных
gettimeofday(&start, NULL);
err = X502_StreamsStart(dev_hnd);
gettimeofday(&stop, NULL);
printf("X502_StreamsStart took %'d us\n", calc_delay(&start, &stop));
if (err != X502_ERR_OK) {
fprintf(stderr, "Error during startup: %s\n", X502_GetErrorString(err));
return 1;
}
printf("Measurement started\n");
uint32_t rdy_cnt = 0;
for (int i=0; i < 10; ++i) {
err = X502_GetRecvReadyCount(dev_hnd, &rdy_cnt);
if (err != X502_ERR_OK) {
fprintf(stderr, "Error during GetRecvReadyCount: %s\n", X502_GetErrorString(err));
return 1;
}
printf("ReadyCount: %d\n", rdy_cnt);
sleep(1);
}
gettimeofday(&start, NULL);
err = X502_StreamsStop(dev_hnd);
gettimeofday(&stop, NULL);
printf("X502_StreamsStop took %'d us\n", calc_delay(&start, &stop));
if (err != X502_ERR_OK) {
fprintf(stderr, "Error stopping measurement: %s\n", X502_GetErrorString(err));
return 1;
}
gettimeofday(&start, NULL);
err = X502_Close(dev_hnd);
if (err != X502_ERR_OK) {
fprintf(stderr, "Error closing connection: %s\n", X502_GetErrorString(err));
}
gettimeofday(&stop, NULL);
printf("X502_Close took %'d us\n", calc_delay(&start, &stop));
X502_Free(dev_hnd);
return 0;
}
Возвращает этот код следующее:
Library version: 1.1.34
Found 1 PCI device(s)
Device 0: L502 (SN: , Flags: 800400)
X502_OpenByDevRecord took 5105046 us
Successfully connected to device!
X502_StreamsStart took 1332647 us
Measurement started
ReadyCount: 0
ReadyCount: 0
ReadyCount: 0
ReadyCount: 0
ReadyCount: 17408
ReadyCount: 17408
ReadyCount: 17408
ReadyCount: 17408
ReadyCount: 17408
ReadyCount: 17408
X502_StreamsStop took 26249431 us
X502_Close took 26250668 us
Значение 17408 понятно: столько измерений будет выполнено за примерно 4 секунды при 2000Гц. Тот факт, что количество отсчетов далее не меняется, можно объяснить переполнением буфера. Но почему в течение первых 4х секунд буфер пуст, я так и не смог понять.
Попытки установить вручную шаг генерации прерываний при помощи X502_SetStreamStep ни к чему позитивному не привели.
Подскажите пожалуйста, в чем может быть причина такого поведения и куда еще можно покопать?
Страницы 1