Exakt kontroll av serieport i gcc?

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 6953
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Exakt kontroll av serieport i gcc?

Inlägg av Marta »

När något skrivs med write(serieport, &data, #bytes); så antar jag att data först läggs i en buffer, innan den sänds och att write() återvänder i princip omedelbart.

Finns det något sätt att få sändningen att starta direkt, utan att vänta på mer data, samt att veta när allt är sänt? Programmet körs på en RPi 0W. När allt är sänt skall porten switchas via GPIO och en extern grind. Det blir segt av att vänta så sändningen säkert har skett.
Användarvisningsbild
AndLi
Inlägg: 17156
Blev medlem: 11 februari 2004, 18:17:59
Ort: Knivsta
Kontakt:

Re: Exakt kontroll av serieport i gcc?

Inlägg av AndLi »

Det låter som du vill göra ungefär det som en del RS485 implementationer gör för att switcha riktning på drivaren. Implementeras ofta i kärndrivrutinen för serieporten.
Skulle inte bli förvånad om det finns någon som patchat in ett sådant stöd för RPi 0W
Användarvisningsbild
hawkan
Inlägg: 2636
Blev medlem: 14 augusti 2011, 10:27:40

Re: Exakt kontroll av serieport i gcc?

Inlägg av hawkan »

Något i stil med att sätta porten i raw mode och läsa/skriva byte efter byte?

Edit
Annars är det vanligt att ställa in porten i rätt mode, och ha en select() som lyssnar på fil-numret om det finns data färdigt eller om det är möjligt att skicka.
MiaM
Inlägg: 9990
Blev medlem: 6 maj 2009, 22:19:19

Re: Exakt kontroll av serieport i gcc?

Inlägg av MiaM »

Det kanske vore bra att lägga till vilket OS du eventuellt kör, eller om du kör direkt på hårdvaran? (Det kanske är underförstått av funktionsnamnet att det är Linux, eller?)

Tänker att det här är väl ett typiskt fall där man antagligen helt enkelt vill göra något som slår av multitaskingen och sen gå direkt på hårdvaran från userapplikationen ifall man inte är sugen på att ev peta på kärnan (förutsatt att kärnan inte redan fixar detta). Vet inte i vilken mån det ens går i Linux. (Som jämförelse så på en Amiga så finns paren Disable()/Enable() och Forbid()/Permit(), där ena varianten enbart slår av task schedulern och den andra slår av alla hårdvaruinterrupter.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 6953
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Exakt kontroll av serieport i gcc?

Inlägg av Marta »

Det är givetvis Linux och jag vill inte rota med hårdvaran direct. Det är för övrigt Broadcom, så dokumentation är förmodligen obefintlig för vanligt folk.

Hade hoppats där skulle finnas en eller flera i kombination IOCTL e.dyl. som kan användas för att antingen direkt skicka tecken för tecken, eller ännu hellre starta sändning och blocka tills sändning är klar.

Det är seriell ut som skall kunna växlas att antingen sända till en PIC på samma kort, eller en utgång till något vid sidan av kortet.
Användarvisningsbild
rvl
Inlägg: 5815
Blev medlem: 5 april 2016, 14:58:53
Ort: Helsingfors

Re: Exakt kontroll av serieport i gcc?

Inlägg av rvl »

Går det att sparka igång omedelbar buffertömning med flush? Allt är ju filer i unix...
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 6953
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Exakt kontroll av serieport i gcc?

Inlägg av Marta »

Den enda flush jag hittat innebär att droppa buffrarna. tcflush med olika parametrar, dock ingen för omedelbar sändning.
Fast det kanske bara är vid USB som den väntar? inns ju ingen anledning till det när det är en vanlig serieport.
I å fall återstår "bara" att veta när den sänt färdigt.
ie
EF Sponsor
Inlägg: 1276
Blev medlem: 23 oktober 2006, 13:12:57
Ort: Tyresö

Re: Exakt kontroll av serieport i gcc?

Inlägg av ie »

Nu var det länge sen jag skrev den här koden, men jag tror att det gör det du vill. Körs på RPI. Inte så väl dokumenterat, men kan kanske ge dig tips på vad du ska leta efter.

Kod: Markera allt

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>

FILE *uart_linux_str;

/* Use this variable to remember original terminal attributes. */
struct termios saved_attributes;

/* Set the O_NONBLOCK flag of desc if value is nonzero,
or clear the flag if value is 0.
Return 0 on success, or -1 on error with errno set. */
int set_nonblock_flag (int desc, int value)
{
	int oldflags = fcntl(desc, F_GETFL, 0);

	/* If reading the flags failed, return error indication now. */
	if (oldflags == -1)
		return -1;

	/* Set just the flag we want to set. */
	if (value != 0)
		oldflags |= O_NONBLOCK;
	else
		oldflags &= ~O_NONBLOCK;

	/* Store modified flag word in the descriptor. */
	return fcntl (desc, F_SETFL, oldflags);
}

int uart_linux_init(void)
{
	int uart_linux_str_fd;
	struct termios tattr;
	
	if (!(uart_linux_str = fopen("/dev/ttyAMA0","w+b")))
	{
		fputs("Error can't create uart_linux stream\n",stderr);
		return -1;
	}	

	uart_linux_str_fd = fileno(uart_linux_str);
	set_nonblock_flag (uart_linux_str_fd,1);
	tcgetattr(uart_linux_str_fd, &tattr);
	cfmakeraw(&tattr);
	cfsetospeed(&tattr,B9600);
	tcsetattr(uart_linux_str_fd, TCSAFLUSH, &tattr);
	
	return 0;
}
MiaM
Inlägg: 9990
Blev medlem: 6 maj 2009, 22:19:19

Re: Exakt kontroll av serieport i gcc?

Inlägg av MiaM »

Den här frågan verkar ta upp delvis samma sak. Ett av svaren länkar vidare till vad som antagligen är en bra guide också.

https://stackoverflow.com/questions/322 ... -is-called
Skriv svar