Skip to content

Commit 7ae5adc

Browse files
committed
detect bootloader using version command instead
1 parent f7991c7 commit 7ae5adc

File tree

1 file changed

+41
-23
lines changed

1 file changed

+41
-23
lines changed

src/uart.c

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ unsigned char imagebuf[IMAGEBUFSIZE + 1];
6262
#define MODE " M"
6363
#define FORMAT " format "
6464
#define VERSION "Firmware version: "
65+
#define BOOTVERSION "BuildHAT bootloader"
6566
#define DONEINIT "Done initialising ports"
6667

6768
#define BASE_DIRECTORY "/sys/class/gpio"
@@ -745,9 +746,9 @@ int load_firmware(char *firmware_path, char *signature_path)
745746
return -1;
746747
}
747748

748-
749-
long checkversion(){
750-
char vbuf[100];
749+
char * checkmessage(char *message, char *send){
750+
int buffsize = 100;
751+
char *vbuf = malloc(buffsize);
751752
char *vbuf_t = vbuf;
752753
int nfds;
753754
struct epoll_event ev1, events[1];
@@ -766,6 +767,13 @@ long checkversion(){
766767
exit(EXIT_FAILURE);
767768
}
768769

770+
if(write(uart_fd, send, strlen(send)) != strlen(send)){
771+
// Failed to write data
772+
goto cleanup;
773+
}
774+
775+
int diffcount = 0;
776+
769777
while(1){
770778
nfds = epoll_wait(epollfd, events, MAX_EVENTS, 2000);
771779
if (nfds == -1) {
@@ -774,39 +782,49 @@ long checkversion(){
774782
}
775783
if(nfds == 0){
776784
// No data
777-
return 0;
785+
goto cleanup;
778786
}
779787
for (int n = 0; n < nfds; ++n) {
780788
if ( events[n].data.fd == uart_fd){
781789
int rcount = read(events[n].data.fd, vbuf_t, 1);
782790
if(rcount == 1){
783791
if(vbuf_t[0] == '\n'){
784-
if (strncmp(VERSION, vbuf, strlen(VERSION)) == 0) {
785-
return strtol(vbuf+strlen(VERSION), NULL, 10);
792+
vbuf_t[0] = 0;
793+
if (strncmp(message, vbuf, strlen(message)) == 0) {
794+
return vbuf;
795+
} else {
796+
// Different message than expected
797+
diffcount++;
798+
if(diffcount >= 2)
799+
goto cleanup;
786800
}
787801
vbuf_t = vbuf;
788802
break;
789803
}
790804
vbuf_t++;
791-
if((vbuf_t-vbuf) >= sizeof vbuf)
792-
vbuf_t = 0;
805+
if((vbuf_t-vbuf) >= buffsize){
806+
vbuf_t = vbuf;
807+
}
793808
} else {
794809
// No data
795-
return 0;
810+
goto cleanup;
796811
}
797812
}
798813
}
799814
}
800-
return 0;
815+
816+
cleanup:
817+
epoll_ctl(epollfd, EPOLL_CTL_DEL, uart_fd, &ev1);
818+
return NULL;
801819
}
802820

821+
803822
/* Open the UART bus, select the Hat as the device to communicate with,
804823
* and return the file descriptor. You must close the file descriptor
805824
* when you are done with it.
806825
*/
807826
int uart_open_hat(char *firmware_path, char *signature_path, long version)
808827
{
809-
char *buffer = "version\r";
810828
enum hatstate state = other;
811829
int rv;
812830
struct termios ttyopt;
@@ -833,34 +851,31 @@ int uart_open_hat(char *firmware_path, char *signature_path, long version)
833851
tcsetattr(uart_fd, TCSANOW, &ttyopt);
834852
tcflush(uart_fd, TCIOFLUSH);
835853

836-
if(getprompt()){
854+
if(checkmessage(BOOTVERSION,"version\r") != NULL){
837855
state = bootloader;
838856
if (load_firmware(firmware_path, signature_path) < 0){
839857
PyErr_SetString(PyExc_IOError, "Failed to load firmware");
840858
close(uart_fd);
841859
return -1;
842860
}
843861
} else {
844-
long ver = 0;
845862

846-
if (write(uart_fd, buffer, strlen((char*)buffer)) < 0){
847-
PyErr_SetString(PyExc_IOError, "Failed to send command");
848-
close(uart_fd);
849-
return -1;
863+
long ver = 0;
864+
char *vers = checkmessage(VERSION,"version\r");
865+
if(vers != NULL){
866+
ver = strtol(vers+strlen(VERSION), NULL, 10);
867+
if(ver > 0)
868+
state = firmware;
850869
}
851870

852-
ver = checkversion();
853-
if(ver > 0)
854-
state = firmware;
855-
856871
if(state == firmware){
857872
if(ver != version){
858873
if (uart_reset_hat() < 0){
859874
PyErr_SetString(PyExc_IOError, "Failed to reset hat for new firmware");
860875
close(uart_fd);
861876
return -1;
862877
}
863-
if(getprompt()){
878+
if(checkmessage(BOOTVERSION,"version\r") != NULL){
864879
state = bootloader;
865880
if (load_firmware(firmware_path, signature_path) < 0){
866881
PyErr_SetString(PyExc_IOError, "Failed to load new firmware");
@@ -934,8 +949,11 @@ int uart_open_hat(char *firmware_path, char *signature_path, long version)
934949
sleep(7);
935950
} else if(state == firmware){
936951
// Already in current firmware, so just list devices that are connected
937-
char *buffer = "list\r";
952+
char *buffer = "echo 0; list\r";
938953
if (write(uart_fd, buffer, strlen((char*)buffer)) < 0){
954+
PyErr_SetString(PyExc_IOError, "Failed to list devices");
955+
close(uart_fd);
956+
return -1;
939957
}
940958
}
941959

0 commit comments

Comments
 (0)