找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4234|回复: 10
收起左侧

仿STC-ISP写的Linux版编程烧录软件,附源代码

  [复制链接]
ID:479409 发表于 2019-3-24 10:45 | 显示全部楼层 |阅读模式
本帖最后由 mp3 于 2019-3-25 08:48 编辑

只在STC11F04E单片机上试用过,其它型号可能要修改通信协议,可通过串口监控工具分析。

单片机脱机烧录源程序如下:
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include <termios.h>
  8. #include <sys/ioctl.h>
  9. #include <string.h>
  10. #include <arpa/inet.h>
  11. #include <sys/time.h>
  12. #include <ctype.h>

  13. #pragma pack(1)

  14. // config MCU clock
  15. #define MCU_CONFIG
  16. //#define MCU_6TO6
  17. //#define MCU_6TO12
  18. //#define MCU_12TO12
  19. //#define MCU_12TO6
  20. #ifdef MCU_6TO6
  21. #define MCU_CLOCK
  22. #endif
  23. #ifdef MCU_6TO12
  24. #define MCU_CLOCK
  25. #endif
  26. #ifdef MCU_12TO12
  27. #define MCU_CLOCK
  28. #define MCU_CLOCK_12MHZ
  29. #undef MCU_CONFIG
  30. #endif
  31. #ifdef MCU_12TO6
  32. #define MCU_CLOCK
  33. #define MCU_CLOCK_12MHZ
  34. #endif
  35. #ifndef MCU_CLOCK
  36. #error "You must define MCU clock!"
  37. #endif

  38. #define VERSION "0.1"
  39. #define DEFAULT_PORT "/dev/ttyS1"
  40. #define LOW_BAUD B2400
  41. #ifdef MCU_CLOCK_12MHZ
  42. #define HIGH_BAUD B57600
  43. #define MSG_HIGH_BAUD "57600bps"
  44. #else
  45. #define HIGH_BAUD B38400
  46. #define MSG_HIGH_BAUD "38400bps"
  47. #endif
  48. #define BUFFSIZE 1024
  49. #define TIMEOUT 2
  50. #define BLOCK_SIZE 128

  51. #define PKG_MINIMAL_LEN 9
  52. #define PKG_SIGN1 '\x46'
  53. #define PKG_SIGN2 '\xb9'
  54. #define PKG_SIGN3 '\x16'
  55. #define PKG_SIGN  0x46b9

  56. enum pkg_type {
  57.         PKG_TYPE1=0x68,
  58.         PKG_TYPE2=0x6a,
  59. };

  60. enum pkg_code {
  61.         CODE_INFO=0x50,
  62.         CODE_MODI=0x8f,
  63.         CODE_NEWB=0x8e,
  64.         CODE_ERASE=0x84,
  65.         CODE_DATA=0x00,
  66.         CODE_END =0x69,
  67.         CODE_CONF=0x8d,
  68.         CODE_BYE =0x82,
  69. };

  70. int port_fd=-1;
  71. FILE *rom_file;
  72. int file_length;
  73. int debug=0;
  74. enum pkg_code step;
  75. int block_no;
  76. struct timeval start_tv;

  77. typedef unsigned int uint32;
  78. typedef unsigned short int uint16;
  79. typedef unsigned char uint8;

  80. // Package format: head + data + tail
  81. typedef struct _pkg_head {
  82.         uint16 sign;                // 0x46b9
  83.         uint8  type;                // 68: MCU to PC; 6a: PC to MCU
  84.         uint16 lenth;                // from 'type' to 'pkg_tail.sign'
  85.         uint8  code;
  86. } pkg_head, *ppkg_head;

  87. typedef struct _pkg_tail {
  88.         uint16 cksum;                // from 'pkg_head.type' to 'data'
  89.         uint8  sign;                // 0x16
  90. } pkg_tail, *ppkg_tail;

  91. typedef struct _pkg_data_head {
  92.         uint16 dummy;                // always 0x0000
  93.         uint16 addr;                // start addr
  94.         uint16 lenth;                // 0x0080
  95. } pkg_data_head, *ppkg_data_head;

  96. void print_data(char *data, int len)
  97. {
  98.         unsigned char ch;
  99.         int i, j;
  100.         printf("Length: %x\n", len);
  101.         for(i=0; i<len; i++) {
  102.                 ch=data[i];
  103.                 if((i&0x0f)==0)
  104.                         printf("%04x: ", i);
  105.                 if((i&0x07)!=0x07)
  106.                         printf("%02x ", ch);
  107.                 else
  108.                         if((i&0x0f)!=0x0f)
  109.                                 printf("%02x-", ch);
  110.                         else {
  111.                                 printf("%02x  ", ch);
  112.                                 for(j=0x0f; j>=0; j--) {
  113.                                         ch=data[i-j];
  114.                                         if(!isascii(ch) || iscntrl(ch))
  115.                                                 ch='.';
  116.                                         putchar(ch);
  117.                                 }
  118.                                 putchar('\n');
  119.                         }
  120.         }
  121.         if(len&0x0f) {
  122.                 for(; i<(len&~0x0f)+0x10; i++)
  123.                         printf("   ");
  124.                 putchar(' ');
  125.                 for(j=len&~0x0f; j<len; j++) {
  126.                         ch=data[j];
  127.                         if(!isascii(ch) || iscntrl(ch))
  128.                                 ch='.';
  129.                         putchar(ch);
  130.                 }
  131.                 putchar('\n');
  132.         }
  133. }

  134. enum dbg_type {RECV, SEND};
  135. void print_dbg(int type, char *buf, int buf_len)
  136. {
  137.         struct timeval tv;
  138.         unsigned int sec, usec;
  139.         if(debug) {
  140.                 if(type==SEND)
  141.                         printf("\n[Send]\t\t");
  142.                 else
  143.                         printf("\n[Received]\t");
  144.                 gettimeofday(&tv, NULL);
  145.                 if(start_tv.tv_usec>tv.tv_usec) {
  146.                         usec=tv.tv_usec-start_tv.tv_usec+1000000;
  147.                         sec=tv.tv_sec-start_tv.tv_sec-1;
  148.                 } else {
  149.                         usec=tv.tv_usec-start_tv.tv_usec;
  150.                         sec=tv.tv_sec-start_tv.tv_sec;
  151.                 }
  152.                 printf("[%d.%06d]\n", sec, usec);
  153.                 printf("Step: %02x\t", step);
  154.                 print_data(buf, buf_len);
  155.         }
  156. }

  157. int checksum(char *buf, int buf_len)
  158. {
  159.         int i, sum=0;
  160.         for(i=0; i<buf_len; i++)
  161.                 sum+=(unsigned char)buf[i];
  162.         return sum;
  163. }

  164. // return: -1: bad pkg; >=0: pkg start position
  165. int check_pkg(int code, char *buf, int buf_len)
  166. {
  167.         int i, len;
  168.         ppkg_head ph=NULL;
  169.         ppkg_tail pt=NULL;
  170.         for(i=0; i<buf_len; i++) {
  171.                 if(buf[i]==PKG_SIGN1 && buf[i+1]==PKG_SIGN2 && i+PKG_MINIMAL_LEN<=buf_len) {
  172.                         ph=(ppkg_head)buf+i;
  173.                         if(ph->type==PKG_TYPE1 && ph->code==code) {
  174.                                 len=ntohs(ph->lenth);
  175.                                 pt=(ppkg_tail)((char *)ph+len-1);
  176.                                 if(pt->sign==PKG_SIGN3 && ntohs(pt->cksum)==checksum((char *)ph+2, len-3)) break;
  177.                                 pt=NULL;
  178.                                 break;
  179.                         }
  180.                 }
  181.         }
  182.         if(ph==NULL || pt==NULL)
  183.                 i=-1;
  184.         return i;
  185. }

  186. typedef struct port_info {
  187.         int port_fd;
  188.         int baud_rate;
  189.         char parity;
  190.         char stop_bit;
  191.         char flow_ctrl;
  192.         char data_bits;
  193. } *pport_info;

  194. int set_port(pport_info p_info)
  195. {
  196.         struct termios old_opt,new_opt;
  197.         memset(&old_opt,0,sizeof(old_opt));
  198.         memset(&new_opt,0,sizeof(new_opt));

  199.         cfmakeraw(&new_opt);
  200.         tcgetattr(p_info->port_fd,&old_opt);
  201.         
  202.         //修改new_opt结构中的串口输入/输出波特率参数
  203.         cfsetispeed(&new_opt,p_info->baud_rate);
  204.         cfsetospeed(&new_opt,p_info->baud_rate);
  205.         
  206.         //修改控制模式,保证程序不会占用串口
  207.         new_opt.c_cflag |=CLOCAL;
  208.         //修改控制模式,使得能够从串口中读取输入数据
  209.          new_opt.c_cflag |=CREAD;

  210.         /*===========设置数据流控制==========*/
  211.         switch(p_info->flow_ctrl){
  212.                 case '0':
  213.                         //不使用流控制
  214.                         new_opt.c_cflag &=~CRTSCTS;
  215.                         break;
  216.                 case '1':
  217.                         //使用硬件进行流控制
  218.                         new_opt.c_cflag |=CRTSCTS;
  219.                         break;
  220.                 case '2':
  221.                         new_opt.c_cflag |= IXON | IXOFF | IXANY;
  222.                         break;
  223.         }
  224.         
  225.         /*===========设置数据位============*/
  226.         new_opt.c_cflag &=~CSIZE;
  227.         switch(p_info->data_bits){
  228.                 case '5':
  229.                         new_opt.c_cflag |=CS5;
  230.                         break;
  231.                 case '6':
  232.                         new_opt.c_cflag |=CS6;
  233.                         break;
  234.                 case '7':
  235.                         new_opt.c_cflag |=CS7;
  236.                         break;
  237.                 case '8':
  238.                         new_opt.c_cflag |=CS8;
  239.                         break;
  240.                 default:
  241.                         new_opt.c_cflag |=CS8;
  242.                 }

  243.         /*===========设置奇偶效验位==========*/
  244.         switch(p_info->parity){
  245.                 case '0':        //不使用奇偶效验
  246.                         new_opt.c_cflag &=~PARENB;
  247.                         break;
  248.                 case '1':        //使用偶效验
  249.                         new_opt.c_cflag |=PARENB;
  250.                         new_opt.c_cflag &=~PARODD;
  251.                         break;
  252.                 case '2':        //使用奇效验
  253.                         new_opt.c_cflag |=PARENB;
  254.                         new_opt.c_cflag |=PARODD;
  255.                         break;
  256.         }

  257.         /*============设置停止位===========*/
  258.         if(p_info->stop_bit=='2')
  259.                 new_opt.c_cflag |=CSTOPB;
  260.         else
  261.                 new_opt.c_cflag &=~CSTOPB;

  262.         //修改输出模式,原始数据输出
  263.         new_opt.c_oflag &=~OPOST;
  264.         //修改控制字符,读取字符的最少个数为1
  265.         new_opt.c_cc[VMIN]=1;
  266.         //修改控制字符,读取第一个字符等待1*(1/10)s
  267.         new_opt.c_cc[VTIME]=1;

  268.         //如果发生数据溢出,接收数据,但是不再读取
  269.         tcflush(p_info->port_fd,TCIFLUSH);
  270.         
  271.         int result=tcsetattr(p_info->port_fd,TCSANOW,&new_opt);
  272.         if(result==-1){
  273.                 perror("Cannot set the serial port parameters");
  274.                 return -1;
  275.         }

  276.         tcgetattr(p_info->port_fd,&old_opt);
  277.         return result;
  278. }

  279. int open_port(char *port_name, int baud_rate)
  280. {
  281.         int port_fd;

  282.         if((port_fd=open(port_name, O_RDWR | O_NOCTTY | O_NONBLOCK))==-1){
  283.                 fprintf(stderr, "Failed to open serial port: %s\n", port_name);
  284.                 return -1;
  285.         }

  286.         //设置串口通信参数
  287.         struct port_info info;
  288.         info.port_fd=port_fd;
  289.         info.baud_rate=baud_rate;
  290.         info.data_bits='8';
  291.          info.flow_ctrl='0';
  292.         info.stop_bit='1';
  293.         info.parity='1';
  294.         if(set_port(&info)==-1) {
  295.                 fprintf(stderr, "Failed to setup serial port: %s\n", port_name);
  296.                 close(port_fd);
  297.                 return -1;
  298.         }
  299.         return port_fd;
  300. }

  301. void close_port()
  302. {
  303.         if(rom_file!=NULL) {
  304.                 fclose(rom_file);
  305.                 rom_file=NULL;
  306.         }
  307.         if(port_fd!=-1) {
  308.                 close(port_fd);
  309.                 port_fd=-1;
  310.         }
  311. }

  312. void reopen_port(char *port_name, int baud_rate)
  313. {
  314.         if(port_fd!=-1)
  315.                 close(port_fd);
  316.         if((port_fd=open_port(port_name, baud_rate))==-1)
  317.         {
  318.                 close_port();
  319.                 exit(1);
  320.         }
  321. }

  322. int send_data(int fd, char *data, int data_len)
  323. {
  324.         int len=write(fd, data, data_len);
  325.         //如果出现溢出的情况
  326.         if(len!=data_len)
  327.                 tcflush(fd, TCOFLUSH);
  328.         return len;
  329. }

  330. int send_mcu(int fd, char *data, int data_len)
  331. {
  332.         int i, len=0, total=0;
  333.         for(i=0; i<data_len; i++) {
  334.                 usleep(150);
  335.                 len=send_data(fd,data+i,1);
  336.                 if(len>0)
  337.                         total+=len;
  338.         }
  339.         print_dbg(SEND, data, total);
  340.         return total;
  341. }

  342. int recv_data(int fd, char *data, int data_len)
  343. {
  344.         static int timeout=0;
  345.         int len=0, fs_sel;
  346.         fd_set fs_read;
  347.         struct timeval time;

  348.         FD_ZERO(&fs_read);
  349.         FD_SET(fd, &fs_read);
  350.         if(step==CODE_MODI)
  351.                 timeout=TIMEOUT;
  352.         time.tv_sec=timeout;
  353.         time.tv_usec=10000;

  354.         //使用select实现串口的多路通信
  355.         fs_sel=select(fd+1, &fs_read, NULL, NULL, &time);
  356.         if(fs_sel)
  357.                 len=read(fd, data, data_len);
  358.         return len;
  359. }

  360. int recv_mcu(int fd, char *buf, int buf_len)
  361. {
  362.         int i, len=0;
  363.         do {
  364.                 if(step==CODE_INFO)
  365.                         usleep(100000);
  366.                 i=recv_data(fd, buf+len, buf_len-len);
  367.                 if(i>0) len+=i;
  368.                 if(check_pkg(step, buf, len)>=0)
  369.                         break;
  370.         } while(i>0);
  371.         return len;
  372. }

  373. int check_recv(int expect_code, char *buf, int buf_len) {
  374.         int i;
  375.         print_dbg(RECV, buf, buf_len);
  376.         i=check_pkg(expect_code, buf, buf_len);
  377.         if(i<0) {
  378.                 printf("\nError received data\n");
  379.                 close_port();
  380.                 exit(1);
  381.         }
  382.         return i;
  383. }

  384. void mcu_info(char *buf, int buf_len) {
  385.         int i, len;
  386.         ppkg_head ph;
  387.         ppkg_tail pt;
  388.         ph=(ppkg_head)buf;
  389.         len=ntohs(ph->lenth);
  390.         pt=(ppkg_tail)((char *)ph+len-1);

  391. /*
  392. MCU Type is: STC11F04E
  393. MCU Firmware Version: 6.5K
  394. Next Power-Up-Reset, use External Crystal/Clock
  395. RESET/P3.6 is used as RESET
  396. Power-Up Reset,add extra Reset-Delay-Time
  397. Oscillator Gain:                 High gain
  398. P1.0/P1.1 are not related to STC ISP Programming
  399. Next ISP Programming Code,don't erase EEPROM data
  400. Wait n clocks after MCU is waked up: 32768
  401. Low Voltage Reset, when MCU-VCC < 4.1V
  402. WDT_CONTR be write-protected except CLR_WDT:NO
  403. WDT is enabled automatically during power-up:NO
  404. Stop WatchDog Timer counting in Idle mode:  YES
  405. Pre-scale time of WDT(did not start): 256
  406. MCU Clock:12.019038MHz.
  407. */
  408.         i=sizeof(pkg_head)+16;
  409.         printf("\n\nMCU Type: \n");
  410.         printf("MCU Firmware Version: %1d.%1d%c\n", buf[i]>>4&0x0f, buf[i]&0x0f, buf[i+1]);
  411.         i=ntohl(*((int *)((char *)pt-4)));
  412.         printf("MCU Internal Clock: %2d.%6dMhz\n", i/1000000, i%1000000);
  413. }

  414. //return: pkg length
  415. int make_pkg(int code, char *inbuf, int ibuf_len, char *outbuf, int obuf_len)
  416. {
  417.         int i, len;
  418.         ppkg_head ph;
  419.         ppkg_tail pt;
  420.         ppkg_data_head pd;

  421.         static char request_mcu[]={
  422. 0x46,0xB9,0x6A,0x00,0x0D,0x50,0x09,0x00,0x36,0x01,0xE2,0x24,0x02,0x0D,0x16};
  423.         static char erase[]={
  424. 0x46,0xB9,0x6A,0x00,0x8C,0x84,0xFF,0x00,0x02,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  425.         static char end[]={
  426. 0x46,0xB9,0x6A,0x00,0x0D,0x69,0x09,0x00,0x36,0x01,0xE2,0x24,0x02,0x26,0x16};
  427.         static char bye[]={
  428. 0xFE,0xFE,0xFE,0xFE,0x46,0xB9,0x6A,0x00,0x07,0x82,0x00,0xF3,0x16};

  429. /* 38400bps @ 6.2MHz, internal clock */
  430. #ifdef MCU_6TO6
  431.         static char inform_change[]={
  432. 0x46,0xB9,0x6A,0x00,0x0D,0x8F,0xC0,0xF6,0x3F,0x14,0x2D,0x84,0x03,0xC0,0x16};
  433.         static char confirm_newrate[]={
  434. 0x46,0xB9,0x6A,0x00,0x0C,0x8E,0xC0,0xF6,0x3F,0x14,0x2D,0x03,0x3A,0x16};
  435.         static char config[]={
  436. 0x46,0xB9,0x6A,0x00,0x1B,0x8D,0xBF,0x7D,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x5E,0x90,0x04,0x11,0x2A,0x16};
  437. #endif

  438. /* 38400bps @ 6.2MHz, change 6.2MHz to 12MHz */
  439. #ifdef MCU_6TO12
  440.         static char inform_change[]={
  441. 0x46,0xB9,0x6A,0x00,0x0D,0x8F,0xC0,0xF6,0x3F,0x14,0x2D,0x84,0x03,0xC0,0x16};
  442.         static char confirm_newrate[]={
  443. 0x46,0xB9,0x6A,0x00,0x0C,0x8E,0xC0,0xF6,0x3F,0x14,0x2D,0x03,0x3A,0x16};
  444.         static char config[]={
  445. 0x46,0xB9,0x6A,0x00,0x1B,0x8D,0xBF,0x7F,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x5E,0x27,0x41,0x11,0x00,0x16};
  446. #endif

  447. /* 57600bps @ 12MHz, change back to 6.2MHz if run conf_mcu() */
  448. #ifdef MCU_CLOCK_12MHZ
  449.         static char inform_change[]={
  450. 0x46,0xB9,0x6A,0x00,0x0D,0x8F,0xC0,0xF3,0x3F,0x1A,0x2D,0x83,0x03,0xC2,0x16};
  451.         static char confirm_newrate[]={
  452. 0x46,0xB9,0x6A,0x00,0x0C,0x8E,0xC0,0xF3,0x3F,0x1A,0x2D,0x03,0x3D,0x16};
  453.         static char config[]={
  454. 0x46,0xB9,0x6A,0x00,0x1B,0x8D,0xBF,0x7D,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xB7,0x65,0x5E,0x11,0xB2,0x16};
  455. #endif

  456.         switch(code) {
  457.         case CODE_INFO:
  458.                 len=sizeof(request_mcu);
  459.                 memcpy(outbuf, request_mcu, len);
  460.                 break;
  461.         case CODE_MODI:
  462.                 len=sizeof(inform_change);
  463.                 memcpy(outbuf, inform_change, len);
  464.                 break;
  465.         case CODE_NEWB:
  466.                 len=sizeof(confirm_newrate);
  467.                 memcpy(outbuf, confirm_newrate, len);
  468.                 break;
  469.         case CODE_ERASE:
  470.                 len=sizeof(erase);
  471.                 memcpy(outbuf, erase, len);
  472.                 *(short int *)(outbuf+7)=htons((file_length+255)>>8);
  473.                 for(i=0x80; i>=0x0e; i--)
  474.                         outbuf[len++]=i;
  475.                 i=htons(checksum(outbuf+2, len-2));
  476.                 *(int *)(outbuf+len)=i;
  477.                 len+=2;
  478.                 outbuf[len++]=PKG_SIGN3;
  479.                 break;
  480.         case CODE_DATA:
  481.                 ph=(ppkg_head)outbuf;
  482.                 ph->sign=htons(PKG_SIGN);
  483.                 ph->type=PKG_TYPE2;
  484.                 i=sizeof(pkg_head)+sizeof(pkg_data_head);
  485.                 len=i+ibuf_len+sizeof(pkg_tail);
  486.                 ph->lenth=htons(len-2);
  487.                 ph->code=CODE_DATA;
  488.                 pd=(ppkg_data_head)(outbuf+sizeof(pkg_head));
  489.                 pd->dummy=htons(0x0000);
  490.                 pd->addr=htons(block_no*BLOCK_SIZE);
  491.                 pd->lenth=htons(ibuf_len);
  492.                 memcpy(outbuf+i, inbuf, ibuf_len);
  493.                 pt=(ppkg_tail)(outbuf+i+ibuf_len);
  494.                 pt->cksum=htons(checksum(outbuf+2, i+ibuf_len-2));
  495.                 pt->sign=PKG_SIGN3;
  496.                 break;
  497.         case CODE_END:
  498.                 len=sizeof(end);
  499.                 memcpy(outbuf, end, len);
  500.                 break;
  501.         case CODE_CONF:
  502.                 len=sizeof(config);
  503.                 memcpy(outbuf, config, len);
  504.                 break;
  505.         case CODE_BYE:
  506.                 len=sizeof(bye);
  507.                 memcpy(outbuf, bye, len);
  508.                 break;
  509.         default:
  510.                 fprintf(stderr, "make_pkg(): invalid package code\n");
  511.                 len=0;
  512.         }
  513.         return len;
  514. }

  515. // return: 0: fail; 1: success
  516. int conf_mcu(char *port_name, int baud_rate)
  517. {
  518.         int i, len=0;
  519.         char recv_buf[BUFFSIZE], send_buf[BUFFSIZE];

  520.         reopen_port(port_name, baud_rate);
  521.         step=CODE_CONF;
  522.         len=make_pkg(step, recv_buf, len, send_buf, BUFFSIZE);
  523.         len=send_mcu(port_fd, send_buf, len);
  524.         step=CODE_INFO;
  525.         len=recv_mcu(port_fd, recv_buf, BUFFSIZE);
  526.         i=check_recv(step, recv_buf, len);
  527.         step=CODE_BYE;
  528.         len=make_pkg(step, recv_buf+i, len-i, send_buf, BUFFSIZE);
  529.         len=send_data(port_fd, send_buf, len);
  530.         close_port();
  531.         if(i>=0)
  532.                 i=1;
  533.         else
  534.                 i=0;
  535.         return i;
  536. }

  537. void help(char *cmd_name)
  538. {
  539.         printf("STC MCU flash ROM programmer, Version " VERSION " (2011), GPLv2 Lisence\n");
  540.         printf("Warning: this is not an official release, use it on your own risk.\n\n");
  541.         printf("Surpport MCU type: STC11F04E\n\n");
  542.         printf("Usage:\n  %s [options] [.bin filename]\n\n", cmd_name);
  543.         printf("Options:\n  -h\t\tprint this text\n"
  544.         "  -d dev\tuse given device, default: " DEFAULT_PORT "\n"
  545.         "  -D\t\tenable debug output\n");
  546.         exit(0);
  547. }

  548. int main(int argc, char *argv[])
  549. {
  550.         static char default_dev[]=DEFAULT_PORT;
  551.         char *port_name=default_dev;
  552.         char *file_name=NULL;
  553.         int i, len;
  554.         char recv_buf[BUFFSIZE], send_buf[BUFFSIZE];

  555.         while((i=getopt(argc, argv, "hd:D"))!=-1) {
  556.                 switch(i) {
  557.                 case 'h':
  558.                         help(argv[0]);
  559.                         break;
  560.                 case 'd':
  561.                         port_name=optarg;
  562.                         break;
  563.                 case 'D':
  564.                         debug=1;
  565.                         break;
  566.                 case '?':
  567.                         exit(1);
  568.                 }
  569.         }
  570.         for(; optind<argc; optind++) {
  571.                 file_name=argv[optind];
  572.                 break;
  573.         }
  574.         if(file_name!=NULL) {
  575.                 if(strcasestr(file_name, ".bin")==NULL) {
  576.                         fprintf(stderr, "Invalid file name\n");
  577.                         exit(1);
  578.                 }
  579.                 rom_file=fopen(file_name, "rb");
  580.                 if(rom_file==NULL) {
  581.                         fprintf(stderr, "Cannot open file\n");
  582.                         exit(1);
  583.                 }
  584.                 i=fileno(rom_file);
  585.                 if(fstat(i, (struct stat *)recv_buf)==-1) {
  586.                         perror("Cannot get length of the file\n");
  587.                         close_port();
  588.                         exit(1);
  589.                 }
  590.                 file_length=((struct stat *)recv_buf)->st_size;
  591.         }

  592.         printf("Use port %s\n", port_name);
  593.         printf("Connecting to target MCU at 2400bps ...   ");
  594.         if((port_fd=open_port(port_name, LOW_BAUD))==-1)
  595.                 exit(1);

  596.         // Power off and power on MCU via DTR & RTS signal
  597.     ioctl(port_fd, TIOCMGET, &i);
  598.         i&=~(TIOCM_RTS | TIOCM_DTR);
  599.         ioctl(port_fd, TIOCMSET, &i);
  600.         usleep(100000);
  601.         i|=TIOCM_RTS | TIOCM_DTR;
  602.         ioctl(port_fd, TIOCMSET, &i);

  603.         step=CODE_INFO;
  604.         for(i=150; i>0; i--) {
  605.                 len=send_data(port_fd, "\x7f\x7f\x7f\x7f", 4);
  606.                 if(len<1) {
  607.                         printf("\b\bSend data failed\n");
  608.                         close_port();
  609.                         exit(1);
  610.                 }

  611.                 if(i%5==0) {
  612.                         printf("\b\b%2d", i/5);
  613.                         fflush(stdout);
  614.                 }

  615.                 len=recv_mcu(port_fd, recv_buf, BUFFSIZE);
  616.                 if(len>=PKG_MINIMAL_LEN)
  617.                         break;
  618.         }
  619.         if(len<PKG_MINIMAL_LEN) {
  620.                 printf("\b\bFailed\n");
  621.                 close_port();
  622.                 exit(1);
  623.         }

  624.         gettimeofday(&start_tv, NULL);
  625.         i=check_recv(step, recv_buf, len);
  626.         mcu_info(recv_buf+i, len-i);
  627.         if(rom_file==NULL) {
  628.                 close_port();
  629.                 exit(0);
  630.         }

  631.         // confirm MCU, procedure: make_pkg -> send -> recv -> check_recv
  632.         len=make_pkg(step, recv_buf+i, len-i, send_buf, BUFFSIZE);
  633.         len=send_mcu(port_fd, send_buf, len);
  634.         step=CODE_MODI;
  635.         len=recv_mcu(port_fd, recv_buf, BUFFSIZE);
  636.         i=check_recv(step, recv_buf, len);

  637.         // Inform to modify baud rate
  638.         if(debug) printf("\nInform MCU to modify baud rate ...\n");
  639.         len=make_pkg(step, recv_buf+i, len-i, send_buf, BUFFSIZE);
  640.         len=send_mcu(port_fd, send_buf, len);
  641.         reopen_port(port_name, HIGH_BAUD);
  642.         len=recv_mcu(port_fd, recv_buf, BUFFSIZE);
  643.         i=check_recv(step, recv_buf, len);

  644.         // Send at 2400bps to confirm the new baud rate
  645.         if(debug) printf("\nConfirm MCU with new baud rate ... \n");
  646.         step=CODE_NEWB;
  647.         reopen_port(port_name, LOW_BAUD);
  648.         len=make_pkg(step, recv_buf+i, len-i, send_buf, BUFFSIZE);
  649.         len=send_mcu(port_fd, send_buf, len);

  650.         // Change to new baud rate
  651.         printf("\nReconnecting to target MCU at " MSG_HIGH_BAUD " ... ");
  652.         step=CODE_ERASE;
  653.         reopen_port(port_name, HIGH_BAUD);
  654.         
  655.         ********余下代码下载附件*********
复制代码

所有资料51hei提供下载:
stc-isp.rar (5.88 KB, 下载次数: 66)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:479409 发表于 2019-3-25 08:46 | 显示全部楼层
51hei团团 发表于 2019-3-25 03:29
高手,能不能请教下如何编译,这些头文件怎么办?

忘了说明,这个是在Linux下用。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表