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

задержка в отправке пакета из буфера uart

странная картина наблюдается - из уарта делаем RS485, соответственно при посылке пакета в порт на конвертер 485го на одной ноге выставляю строб начала передачи

stat = write( ttyfd, query, length );

setP01(0,24, 1);

delay(20);

но посмотрев по осцилографу вижу что delay отрабатывается ровно, а посылка гуляет на протяжении 200милисекунд от начала строба, но не случайно, а по какой то линейной зависимости. пробовал следить за U3LSR, но толи что не так делал, толи этот регистр тут не помошник

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

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


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

Линукс не является системой реального времени и вы наблюдаете его штатное поведение.

Для синхронизации в вашем случае надо править функцию putchar(), которая физически выдаёт байт в uart, и перекомпилировать ядро.

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


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

Для синхронизации в вашем случае надо править функцию putchar(), которая физически выдаёт байт в uart, и перекомпилировать ядро.

 

putchar все еще в userspace к тому же понятия не имеет - сколько байт в посылке, смысла править ее честно говоря не вижу. Нужно править драйвер uart - после передачи байта смотреть в прерывании есть ли новые данные в буфере для передачи и если нет переключаться на прием аналогично если там используется dma (я не знаком с этим soc) тогда все еще проще - там и так ясно сколько байт передается.

 

PS "putchar все еще в userspace" - это я к тому что задержки в linux гарантируют что время выдержки будет не меньше того что запрошено, поэтому никто не гарантирует что задержка может оказаться раз в 5 больше что может привести к потере данных которые подчиненное устройство за это время уже может начать передавать а мы все еще не переключились на прием.

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

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


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

Нужно править драйвер uart - после передачи байта
понятно, носом не ткнёте где найти уарт драйвер? конечно предполагаю что в директории drivers

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


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

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

 

 

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


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

интересно, а флаг O_DIRECT для записи в порт в uClinux работает? компилятор ругается на него, хотя <fcntl.h> прописан

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

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


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

проблему не решил, но обуздал фронт посылки. сначала, посмотрел в сторону регистра 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 );

 

завтра наверное надо будет добавить таймаутов, а в целом код рабочий, правда по большому счёту не устраивает и надо будет искать другое решение

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


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

Есть очевидное решение: запретить прерывания и работать напрямую с регистрами UARTa и регистрами ножки ввода-вывода.

Как уже говорилось, uCLinux это позволяет.

Тут уж либо реальное время, либо многозадачность.

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


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

лучше время :) будем копать

 

Если что откопаете, пожалуйста сообщите, галерка тоже интересуется...

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


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

ооооо ееее нииигааа ... нашёл регистр для отправки посылки путём прямого доступа в память

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);

и получаем посылку почти чётко вписанную в строб, за качество кода прошу не ругать, ибо делал енто на коленях, по наитию и не успел ещё отредактировать, опять же почему то не получаю ответа от дочернего устройства где то есть косяк, вобщем объективная критика принимается

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


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

насчёт дочернего устройства я ошибся - оно мою посылку принимает и отвечает, это я где то при приёме дал косяка, короче код рабочий, его только надо оптимизировать и сделать красивым

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


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

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

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

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

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

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

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

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

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

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