📄 cmd_load.c.l
字号:
811 static int k_recv (void)812 {813 char new_char;814 char k_state, k_state_saved;815 int sum;816 int done;817 int length;818 int n, last_n;819 int z = 0;820 int len_lo, len_hi;821 822 /* initialize some protocol parameters */823 his_eol = END_CHAR; /* default end of line character */824 his_pad_count = 0;825 his_pad_char = '\0';826 his_quote = K_ESCAPE;827 828 /* initialize the k_recv and k_data state machine */829 done = 0;830 k_state = 0;831 k_data_init ();832 k_state_saved = k_state;833 k_data_save ();834 n = 0; /* just to get rid of a warning */835 last_n = -1;836 837 /* expect this "type" sequence (but don't check):838 S: send initiate839 F: file header840 D: data (multiple)841 Z: end of file842 B: break transmission843 */844 845 /* enter main loop */846 while (!done) {847 /* set the send packet pointer to begining of send packet parms */848 send_ptr = send_parms;849 850 /* With each packet, start summing the bytes starting with the length.851 Save the current sequence number.852 Note the type of the packet.853 If a character less than SPACE (0x20) is received - error.854 */855 856 #if 0857 /* OLD CODE, Prior to checking sequence numbers */858 /* first have all state machines save current states */859 k_state_saved = k_state;860 k_data_save ();861 #endif862 863 /* get a packet */864 /* wait for the starting character or ^C */865 for (;;) {866 switch (getc ()) {867 case START_CHAR: /* start packet */868 goto START;869 case ETX_CHAR: /* ^C waiting for packet */870 return (0);871 default:872 ;873 }874 }875 START:876 /* get length of packet */877 sum = 0;878 new_char = getc ();879 if ((new_char & 0xE0) == 0)880 goto packet_error;881 sum += new_char & 0xff;882 length = untochar (new_char);883 /* get sequence number */884 new_char = getc ();885 if ((new_char & 0xE0) == 0)886 goto packet_error;887 sum += new_char & 0xff;888 n = untochar (new_char);889 --length;890 891 /* NEW CODE - check sequence numbers for retried packets */892 /* Note - this new code assumes that the sequence number is correctly893 * received. Handling an invalid sequence number adds another layer894 * of complexity that may not be needed - yet! At this time, I'm hoping895 * that I don't need to buffer the incoming data packets and can write896 * the data into memory in real time.897 */898 if (n == last_n) {899 /* same sequence number, restore the previous state */900 k_state = k_state_saved;901 k_data_restore ();902 } else {903 /* new sequence number, checkpoint the download */904 last_n = n;905 k_state_saved = k_state;906 k_data_save ();907 }908 /* END NEW CODE */909 910 /* get packet type */911 new_char = getc ();912 if ((new_char & 0xE0) == 0)913 goto packet_error;914 sum += new_char & 0xff;915 k_state = new_char;916 --length;917 /* check for extended length */918 if (length == -2) {919 /* (length byte was 0, decremented twice) */920 /* get the two length bytes */921 new_char = getc ();922 if ((new_char & 0xE0) == 0)923 goto packet_error;924 sum += new_char & 0xff;925 len_hi = untochar (new_char);926 new_char = getc ();927 if ((new_char & 0xE0) == 0)928 goto packet_error;929 sum += new_char & 0xff;930 len_lo = untochar (new_char);931 length = len_hi * 95 + len_lo;932 /* check header checksum */933 new_char = getc ();934 if ((new_char & 0xE0) == 0)935 goto packet_error;936 if (new_char != tochar ((sum + ((sum >> 6) & 0x03)) & 0x3f))937 goto packet_error;938 sum += new_char & 0xff;939 /* --length; */ /* new length includes only data and block check to come */940 }941 /* bring in rest of packet */942 while (length > 1) {943 new_char = getc ();944 if ((new_char & 0xE0) == 0)945 goto packet_error;946 sum += new_char & 0xff;947 --length;948 if (k_state == DATA_TYPE) {949 /* pass on the data if this is a data packet */950 k_data_char (new_char);951 } else if (k_state == SEND_TYPE) {952 /* save send pack in buffer as is */953 *send_ptr++ = new_char;954 /* if too much data, back off the pointer */955 if (send_ptr >= &send_parms[SEND_DATA_SIZE])956 --send_ptr;957 }958 }959 /* get and validate checksum character */960 new_char = getc ();961 if ((new_char & 0xE0) == 0)962 goto packet_error;963 if (new_char != tochar ((sum + ((sum >> 6) & 0x03)) & 0x3f))964 goto packet_error;965 /* get END_CHAR */966 new_char = getc ();967 if (new_char != END_CHAR) {968 packet_error:969 /* restore state machines */970 k_state = k_state_saved;971 k_data_restore ();972 /* send a negative acknowledge packet in */973 send_nack (n);974 } else if (k_state == SEND_TYPE) {975 /* crack the protocol parms, build an appropriate ack packet */976 handle_send_packet (n);977 } else {978 /* send simple acknowledge packet in */979 send_ack (n);980 /* quit if end of transmission */981 if (k_state == BREAK_TYPE)982 done = 1;983 }984 ++z;985 }986 return ((ulong) os_data_addr - (ulong) bin_start_address);987 }988 989 static int getcxmodem(void) {990 if (tstc())991 return (getc());992 return -1;993 }994 995 /* support xmodem, www.arm9.net */996 static ulong load_serial_xmodem (ulong offset)997 {998 int size;999 char buf[32];1000 int err;1001 int res;1002 connection_info_t info;1003 char xmodemBuf[1024];1004 ulong store_addr = ~0;1005 ulong addr = 0;1006 1007 size = 0;1008 info.mode = xyzModem_xmodem;1009 res = xyzModem_stream_open (&info, &err);1010 if (!res) {1011 1012 while ((res =1013 xyzModem_stream_read (xmodemBuf, 1024, &err)) > 0) {1014 store_addr = addr + offset;1015 size += res;1016 addr += res;1017 #ifndef CFG_NO_FLASH1018 if (addr2info (store_addr)) {1019 int rc;1020 1021 rc = flash_write ((char *) xmodemBuf,1022 store_addr, res);1023 if (rc != 0) {1024 flash_perror (rc);1025 return (~0);1026 }1027 } else1028 #endif1029 {1030 memcpy ((char *) (store_addr), xmodemBuf,1031 res);1032 }1033 1034 }1035 } else {1036 printf ("%s\n", xyzModem_error (err));1037 }1038 1039 xyzModem_stream_close (&err);1040 xyzModem_stream_terminate (false, &getcxmodem);1041 1042 1043 flush_cache (offset, size);1044 1045 printf ("## Total Size = 0x%08x = %d Bytes\n", size, size);1046 sprintf (buf, "%X", size);1047 setenv ("filesize", buf);1048 1049 return offset;1050 }1051 1052 static ulong load_serial_ymodem (ulong offset)1053 {1054 int size;1055 char buf[32];1056 int err;1057 int res;1058 connection_info_t info;1059 char ymodemBuf[1024];1060 ulong store_addr = ~0;1061 ulong addr = 0;1062 1063 size = 0;1064 info.mode = xyzModem_ymodem;1065 res = xyzModem_stream_open (&info, &err);1066 if (!res) {1067 1068 while ((res =1069 xyzModem_stream_read (ymodemBuf, 1024, &err)) > 0) {1070 store_addr = addr + offset;1071 size += res;1072 addr += res;1073 #ifndef CFG_NO_FLASH1074 if (addr2info (store_addr)) {1075 int rc;1076 1077 rc = flash_write ((char *) ymodemBuf,1078 store_addr, res);1079 if (rc != 0) {1080 flash_perror (rc);1081 return (~0);1082 }1083 } else1084 #endif1085 {1086 memcpy ((char *) (store_addr), ymodemBuf,1087 res);1088 }1089 1090 }1091 } else {1092 printf ("%s\n", xyzModem_error (err));1093 }1094 1095 xyzModem_stream_close (&err);1096 xyzModem_stream_terminate (false, &getcxmodem);1097 1098 1099 flush_cache (offset, size);1100 1101 printf ("## Total Size = 0x%08x = %d Bytes\n", size, size);1102 sprintf (buf, "%X", size);1103 setenv ("filesize", buf);1104 1105 return offset;1106 }1107 1108 #endif /* CFG_CMD_LOADB */1109 1110 /* -------------------------------------------------------------------- */1111 1112 #if (CONFIG_COMMANDS & CFG_CMD_LOADS)1113 1114 #ifdef CFG_LOADS_BAUD_CHANGE1115 U_BOOT_CMD(1116 loads, 3, 0, do_load_serial,1117 "loads - load S-Record file over serial line\n",1118 "[ off ] [ baud ]\n"1119 " - load S-Record file over serial line"1120 " with offset 'off' and baudrate 'baud'\n"1121 );1122 1123 #else /* ! CFG_LOADS_BAUD_CHANGE */1124 U_BOOT_CMD(1125 loads, 2, 0, do_load_serial,1126 "loads - load S-Record file over serial line\n",1127 "[ off ]\n"1128 " - load S-Record file over serial line with offset 'off'\n"1129 );1130 #endif /* CFG_LOADS_BAUD_CHANGE */1131 1132 /*1133 * SAVES always requires LOADS support, but not vice versa1134 */1135 1136 1137 #if (CONFIG_COMMANDS & CFG_CMD_SAVES)1138 #ifdef CFG_LOADS_BAUD_CHANGE1139 U_BOOT_CMD(1140 saves, 4, 0, do_save_serial,1141 "saves - save S-Record file over serial line\n",1142 "[ off ] [size] [ baud ]\n"1143 " - save S-Record file over serial line"1144 " with offset 'off', size 'size' and baudrate 'baud'\n"1145 );1146 #else /* ! CFG_LOADS_BAUD_CHANGE */1147 U_BOOT_CMD(1148 saves, 3, 0, do_save_serial,1149 "saves - save S-Record file over serial line\n",1150 "[ off ] [size]\n"1151 " - save S-Record file over serial line with offset 'off' and size 'size'\n"1152 );1153 #endif /* CFG_LOADS_BAUD_CHANGE */1154 #endif /* CFG_CMD_SAVES */1155 #endif /* CFG_CMD_LOADS */1156 1157 1158 #if (CONFIG_COMMANDS & CFG_CMD_LOADB)1159 U_BOOT_CMD(1160 loadb, 3, 0, do_load_serial_bin,1161 "loadb - load binary file over serial line (kermit mode)\n",1162 "[ off ] [ baud ]\n"1163 " - load binary file over serial line"1164 " with offset 'off' and baudrate 'baud'\n"1165 );1166 1167 /* support xmodem, www.arm9.net */1168 U_BOOT_CMD(1169 loadx, 3, 0, do_load_serial_bin,1170 "loadx - load binary file over serial line (xmodem mode)\n",1171 "[ off ] [ baud ]\n"1172 " - load binary file over serial line"1173 " with offset 'off' and baudrate 'baud'\n"1174 );1175 1176 U_BOOT_CMD(1177 loady, 3, 0, do_load_serial_bin,1178 "loady - load binary file over serial line (ymodem mode)\n",1179 "[ off ] [ baud ]\n"1180 " - load binary file over serial line"1181 " with offset 'off' and baudrate 'baud'\n"1182 );1183 1184 #endif /* CFG_CMD_LOADB */1185 1186 /* -------------------------------------------------------------------- */1187 1188 #if (CONFIG_COMMANDS & CFG_CMD_HWFLOW)1189 int do_hwflow (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])1190 {1191 extern int hwflow_onoff(int);1192 1193 if (argc == 2) {1194 if (strcmp(argv[1], "off") == 0)1195 hwflow_onoff(-1);1196 else1197 if (strcmp(argv[1], "on") == 0)1198 hwflow_onoff(1);1199 else1200 printf("Usage: %s\n", cmdtp->usage);1201 }1202 printf("RTS/CTS hardware flow control: %s\n", hwflow_onoff(0) ? "on" : "off");1203 return 0;1204 }1205 1206 /* -------------------------------------------------------------------- */1207 1208 U_BOOT_CMD(1209 hwflow, 2, 0, do_hwflow,1210 "hwflow - turn the harwdare flow control on/off\n",1211 "[on|off]\n - change RTS/CTS hardware flow control over serial line\n"1212 );1213 1214 #endif /* CFG_CMD_HWFLOW */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -