andybeg 0 1 июля, 2010 Опубликовано 1 июля, 2010 (изменено) · Жалоба странная картина наблюдается - из уарта делаем RS485, соответственно при посылке пакета в порт на конвертер 485го на одной ноге выставляю строб начала передачи stat = write( ttyfd, query, length ); setP01(0,24, 1); delay(20); но посмотрев по осцилографу вижу что delay отрабатывается ровно, а посылка гуляет на протяжении 200милисекунд от начала строба, но не случайно, а по какой то линейной зависимости. пробовал следить за U3LSR, но толи что не так делал, толи этот регистр тут не помошник Изменено 1 июля, 2010 пользователем andybeg Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
etoja 0 1 июля, 2010 Опубликовано 1 июля, 2010 · Жалоба Линукс не является системой реального времени и вы наблюдаете его штатное поведение. Для синхронизации в вашем случае надо править функцию putchar(), которая физически выдаёт байт в uart, и перекомпилировать ядро. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sasamy 9 1 июля, 2010 Опубликовано 1 июля, 2010 (изменено) · Жалоба Для синхронизации в вашем случае надо править функцию putchar(), которая физически выдаёт байт в uart, и перекомпилировать ядро. putchar все еще в userspace к тому же понятия не имеет - сколько байт в посылке, смысла править ее честно говоря не вижу. Нужно править драйвер uart - после передачи байта смотреть в прерывании есть ли новые данные в буфере для передачи и если нет переключаться на прием аналогично если там используется dma (я не знаком с этим soc) тогда все еще проще - там и так ясно сколько байт передается. PS "putchar все еще в userspace" - это я к тому что задержки в linux гарантируют что время выдержки будет не меньше того что запрошено, поэтому никто не гарантирует что задержка может оказаться раз в 5 больше что может привести к потере данных которые подчиненное устройство за это время уже может начать передавать а мы все еще не переключились на прием. Изменено 1 июля, 2010 пользователем sasamy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
etoja 0 1 июля, 2010 Опубликовано 1 июля, 2010 · Жалоба согласен Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andybeg 0 1 июля, 2010 Опубликовано 1 июля, 2010 · Жалоба Нужно править драйвер uart - после передачи байта понятно, носом не ткнёте где найти уарт драйвер? конечно предполагаю что в директории drivers Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
etoja 0 1 июля, 2010 Опубликовано 1 июля, 2010 · Жалоба A driver for 8250/16550 compatible serial ports are integrated in the kernel source tree. That driver is possible to use without modification for the LPC24xx. The source code is available in the uClinux-dist/linux-2.6.x/drivers/serial/8250.c file. Документ "Getting_started_with_uClinux_A.pdf" (4Мбайта) находится здесь: http://slil.ru/29418617 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andybeg 0 1 июля, 2010 Опубликовано 1 июля, 2010 · Жалоба спасибо, ценный документ :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andybeg 0 5 июля, 2010 Опубликовано 5 июля, 2010 (изменено) · Жалоба интересно, а флаг O_DIRECT для записи в порт в uClinux работает? компилятор ругается на него, хотя <fcntl.h> прописан Изменено 5 июля, 2010 пользователем andybeg Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andybeg 0 7 июля, 2010 Опубликовано 7 июля, 2010 · Жалоба проблему не решил, но обуздал фронт посылки. сначала, посмотрел в сторону регистра U3LSR в итоге имеем - ставим строб отправки пакета, отправляем пакет данных и ждём пока этот регистр сообщит нам , что данные сначала поступили на отправку, а затем , что они ушли из буфера , затем ставим строб на приём ответа и слушаем ... int write_stat,fd; unsigned char *U3LSR,data,res; fd = open("/dev/mem", O_RDWR); U3LSR = mmap(0, 0x100, PROT_READ, MAP_SHARED, fd, 0xE007C000); if (U3LSR == MAP_FAILED) { printf("Error mmapping the file"); return 0; } #ifdef DEBUG int i; #endif modbus_query( query, string_length ); string_length += 2; #ifdef DEBUG fprintf( stderr, "\n" ); for( i = 0; i < string_length; i++ ) { fprintf( stderr, "[%0.2X]", query[ i ] ); } fprintf( stderr, "\n" ); #endif tcflush( ttyfd, TCIOFLUSH ); setP01(1,13, 1); write_stat = write( ttyfd, query, string_length ); data = 1; //ждём захода данных в буфер отправки while(data) { data = *(U3LSR+0x14)&(1<<6); res = *(U3LSR+0x14); printf("\ndata =%x",res); } printf("\n"); //ждём когда они покинут буфер while(!data) { data = *(U3LSR+0x14)&(1<<6); res = *(U3LSR+0x14); printf("\nres =%x",res); } printf("\n"); //delay(220); setP01(1,13, 0); if (munmap(U3LSR, 0x100) == -1) { perror("Error un-mmapping the file"); } close(fd); return( write_stat ); завтра наверное надо будет добавить таймаутов, а в целом код рабочий, правда по большому счёту не устраивает и надо будет искать другое решение Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
etoja 0 8 июля, 2010 Опубликовано 8 июля, 2010 · Жалоба Есть очевидное решение: запретить прерывания и работать напрямую с регистрами UARTa и регистрами ножки ввода-вывода. Как уже говорилось, uCLinux это позволяет. Тут уж либо реальное время, либо многозадачность. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andybeg 0 8 июля, 2010 Опубликовано 8 июля, 2010 · Жалоба лучше время :) будем копать Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexeyVL 1 8 июля, 2010 Опубликовано 8 июля, 2010 · Жалоба лучше время :) будем копать Если что откопаете, пожалуйста сообщите, галерка тоже интересуется... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andybeg 0 8 июля, 2010 Опубликовано 8 июля, 2010 · Жалоба откопаю, ибо деваться некуда, с понедельнка начну Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andybeg 0 9 июля, 2010 Опубликовано 9 июля, 2010 · Жалоба ооооо ееее нииигааа ... нашёл регистр для отправки посылки путём прямого доступа в память 4.2 UARTn Transmit Holding Register (U0THR - 0xE000 C000, U2THR - 0xE007 8000, U3THR - 0xE007 C000 when DLAB = 0, Write Only) The UnTHR is the top byte of the UARTn TX FIFO. The top byte is the newest character in the TX FIFO and can be written via the bus interface. The LSB represents the first bit to transmit. The Divisor Latch Access Bit (DLAB) in UnLCR must be zero in order to access the UnTHR. The UnTHR is always Write Only. Table 379. UART0 Transmit Holding Register (U0THR - address 0xE000 C000, U2THR - 0xE007 8000, U3THR - 0xE007 C000 when DLAB = 0, Write Only) bit description Bit Symbol Description Reset Value 7:0 THR Writing to the UARTn Transmit Holding Register causes the data NA to be stored in the UARTn transmit FIFO. The byte will be sent when it reaches the bottom of the FIFO and the transmitter is available. пишем функцию отсылки чара int putC(unsigned char ch) { int write_stat,fd; unsigned char *map,data,res; fd = open("/dev/mem", O_RDWR); map = mmap(0, 0x100, PROT_READ, MAP_SHARED, fd, UnLCR_BASE_ADDR); if (map == MAP_FAILED) { printf("Error mmapping the file"); return 0; } while(!(U0LCR && 0x20)); if (munmap(map, 0x100) == -1) { perror("Error un-mmapping the file"); } close(fd); fd = open("/dev/mem", O_RDWR); map = mmap(0, 0x100, PROT_READ, MAP_SHARED, fd, UnTHR_BASE_ADDR); if (map == MAP_FAILED) { printf("Error mmapping the file"); return 0; } U3THR = ch; if (munmap(map, 0x100) == -1) { perror("Error un-mmapping the file"); } close(fd); return 0; } модернизируем отправку tcflush( ttyfd, TCIOFLUSH ); /* flush the input & output streams */ setP01(1,13, 1); //write_stat = write( ttyfd, query, string_length ); for( i = 0; i < string_length; i++ ) putC(query); fd = open("/dev/mem", O_RDWR); map = mmap(0, 0x100, PROT_READ, MAP_SHARED, fd, UnLCR_BASE_ADDR); if (map == MAP_FAILED) { printf("Error mmapping the file"); return 0; } while(!(U0LCR && 0x20)); if (munmap(map, 0x100) == -1) { perror("Error un-mmapping the file"); } close(fd); printf("\n"); setP01(1,13, 0); и получаем посылку почти чётко вписанную в строб, за качество кода прошу не ругать, ибо делал енто на коленях, по наитию и не успел ещё отредактировать, опять же почему то не получаю ответа от дочернего устройства где то есть косяк, вобщем объективная критика принимается Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andybeg 0 9 июля, 2010 Опубликовано 9 июля, 2010 · Жалоба насчёт дочернего устройства я ошибся - оно мою посылку принимает и отвечает, это я где то при приёме дал косяка, короче код рабочий, его только надо оптимизировать и сделать красивым Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться