EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

bootloader in C

Started by Thomas Baier August 16, 2004
Hi there,

I've got a little problem while working on a bootloader for a C164
microcontroller. The microcontroller gets the data over the serial port.
I've already implemented some functions that transmit some vmc and hex
files to the controller while there is a OS running on it. But now I'd like
to transmit my one bootstrap loader and I've got some problems with the
serial communication in C. 

Here's my code to configure the serial port under linux (I'm working on Suse
Linux prof. 9.0):

int openport(char* device)
{
��������int�fd;
��������struct�termios�*current;����������������//IO-Settings
��������struct�termios�options;

��������fd�=�open(device,�O_RDWR�|�O_NOCTTY);

��������if�(fd�==�-1)
����������������return�-1;

��������bzero(&options,�sizeof(options));


��������tcgetattr(fd,�&options);

��������cfsetispeed(&options,�B19200);
��������cfsetospeed(&options,�B19200);

��������
��������options.c_cflag�=�B19200�|�CRTSCTS�|�CSTOPB�|�CLOCAL�|�CREAD;
��������//8�databits,�no�paritybit,�1�stopbit
��������options.c_cflag�&=�~PARENB;
��������options.c_cflag�&=�~CSTOPB;
��������options.c_cflag�&=�~CSIZE;
��������options.c_cflag�|=�CS8;
��������options.c_iflag�=�IGNPAR;
��������options.c_oflag�=�0;
��������options.c_lflag�=�0;

��������tcflush(fd,�TCIFLUSH);
��������tcsetattr(fd,�TCSANOW,�&options);

��������return�(fd);
}

And now I simply want to transmit a zero byte (say 1 startbit, 8 zero bits
and 1 stopbit):

int comport = openport("/dev/ttyS0");
write(comport,0,1);
usleep(250);
unsigned char cbuf = 0;
while(read(sfd, &cbuf, 1)>0) {
��������printf("%i\t",(int)�cbuf);
}


but the microcontroller doesn't answer. It should return an identification
byte, but I do not receive anything at all. I've got some software for
windows that works fine (but only under windows) and I spied on its
communication between itself and the comport and got this as the first two
lines:

#00�������������//out���-�zero�byte
#F8#D5����������//in����-�identification�byte

So there can't be a failure at the microcontroller.


Thanks for any help.

Thomas
>write(comport,0,1); >
This looks suspicious.
> int comport = openport("/dev/ttyS0");
Aside from Gary's comment, do you mean "/dev/ttys0" (no DTR)? Or does your microcontroller have a full set of control lines? Andrew
Andrew Jackson wrote:

>> int comport = openport("/dev/ttyS0"); > Aside from Gary's comment, do you mean "/dev/ttys0" (no DTR)? Or does your > microcontroller have a full set of control lines? > > Andrew
Hmmm, I tried /dev/ttys0 and got an error while writing, so I think I should use /dev/ttyS0 instead. I also tried /dev/cua0, but that doesn't work, too. What I expected as I found out that /dev/ttyS0 and /dev/cua0 should be the same device, aren't they? What exactly is DTR? I google a bit and found out that "the DTR signal is generated by your workstation and tells the computer or device on the other end that you are ready (a space voltage) or not-ready (a mark voltage). DTR is usually enabled automatically whenever you open the serial interface on the workstation." What does that mean for me? How can I find out if my microcontroller does have a full set of control lines? But wouldn't all the other thinks (like transferring hex and vm-codes to an existing OS) I'm already able to do work, if that is the problem? @Gary:
>>write(comport,0,1); >This looks suspicious.
What exactly looks suspicious at this line? How to do it in the correct way? I tried unsigned char handshake = 0; int ret = write(sfd,&handshake,1); but that doesn't work, too and as I think it is really the same, isn't it? Thanks for your help Thomas
> Hmmm, I tried /dev/ttys0 and got an error while writing, so I think I
should
> use /dev/ttyS0 instead. I also tried /dev/cua0, but that doesn't work,
too.
> What I expected as I found out that /dev/ttyS0 and /dev/cua0 should be the > same device, aren't they? > What exactly is DTR? I google a bit and found out that "the DTR signal is > generated by your workstation and tells the computer or device on the
other
> end that you are ready (a space voltage) or not-ready (a mark voltage).
DTR
> is usually enabled automatically whenever you open the serial interface on > the workstation." > What does that mean for me? How can I find out if my microcontroller does > have a full set of control lines? But wouldn't all the other thinks (like > transferring hex and vm-codes to an existing OS) I'm already able to do > work, if that is the problem?
Serial communications are always fun &-). DTR is "Data Terminal Ready". Devices like modems can be configured to assert DTR when they answer a call. On Linux systems, attempts to open /dev/ttyS? will only complete the open when DTR is asserted (they "hang" until then). Using /dev/cua0 allows a program to open a serial line without considering the state of DTR. Not sure what development board you are using but many microcontroller development systems only have three wires: Rx, Tx and ground. If this is the case then you don't want the CRTSCTS option set when you open the serial port either (make sure that you clear that option).
> @Gary: > >>write(comport,0,1); > >This looks suspicious. > > What exactly looks suspicious at this line? How to do it in the correct
way? The data buffer pointer is NULL, you are not sending a zero byte to your microcontroller. I don't know what is *at* location zero ('*0') in your (Linux) system but it may not be zero. You may even get an exception/signal.
> I tried > unsigned char handshake = 0; > int ret = write(sfd,&handshake,1); > but that doesn't work, too and as I think it is really the same, isn't it?
Not the same but correct. Andrew
Andrew Jackson wrote:
>>int comport = openport("/dev/ttyS0"); > > Aside from Gary's comment, do you mean "/dev/ttys0" (no DTR)? Or does your > microcontroller have a full set of control lines? > > Andrew > >
Whatever convention you're thinking of is not universal. -- ------------------------------------------------------------ Creepy, Soulless Gigolo for President ? NOT ! --------------------------------------------- THK is one weird, weird something.
Thomas Baier wrote:
> Hi there, > > I've got a little problem while working on a bootloader for a C164 > microcontroller. The microcontroller gets the data over the serial port. > I've already implemented some functions that transmit some vmc and hex > files to the controller while there is a OS running on it. But now I'd like > to transmit my one bootstrap loader and I've got some problems with the > serial communication in C. > > Here's my code to configure the serial port under linux (I'm working on Suse > Linux prof. 9.0): >
Look back in C.A.E a few months for my example on how to really set termios to raw. -- ------------------------------------------------------------ Creepy, Soulless Gigolo for President ? NOT ! --------------------------------------------- THK is one weird, weird something.
Thomas

http://www.easysw.com/~mike/serial/serial.html

may be helpful to you.

    Andrew



On 2004-08-17, Andrew Jackson <alj@nospam.com> wrote:

> Serial communications are always fun &-). DTR is "Data > Terminal Ready". Devices like modems can be configured to > assert DTR when they answer a call.
Nope. PC's are "data terminals": they control DTR and read DSR. Modems are "data sets": they control DSR (usually asserted on power-up) and read DTR.
> On Linux systems, attempts to open /dev/ttyS? will only > complete the open when DTR is asserted (they "hang" until > then).
[Again, assuming you mean DSR.] Not true. I just opened /dev/ttyS0 and it had DSR inactive: $ ./showmodem.py /dev/ttyS0 DTR:1 DSR:0 RTS:1 CTS:0 CD:0 RI:0 DTR is active, but that's because DTR is an _output_ and is asserted during the open().
> Using /dev/cua0 allows a program to open a serial line without > considering the state of DTR.
Use of the "cua" devices has been deprecated for many years, and they aren't even present on modern installations. If they're there, they're probably identical to the the ttyS devices. I'm not even sure there is a way to make an open() call block waiting for DSR. IIRC, if the CLOCAL flag is not set, read() and write() will block waiting for CD. IIRC, /dev/ttysN and /dev/ttycuN devices _used_ to block if the other one was in use, and an open() on /dev/ttys used to block waiting for CD. -- Grant Edwards grante Yow! I feel real at SOPHISTICATED being in visi.com FRANCE!
> [Again, assuming you mean DSR.]
Mea culpa: I was thinking of the system connected seeing DCD being asserted which is really DSR on the modem.
> IIRC, if the CLOCAL flag is not set, read() and write() will > block waiting for CD.
That's what I understand too. I have some code from '94 which fiddles with CLOCAL to open and write without waiting for CD.
> IIRC, /dev/ttysN and /dev/ttycuN devices _used_ to block if the > other one was in use, and an open() on /dev/ttys used to block > waiting for CD.
You also used to be able to take a lock on the port by creating a magic file but that maybe showing my age ( which is also why I referred to /dev/ttys0 and /dev/ttyS0 :-) ). Andrew

The 2024 Embedded Online Conference