飞思卡尔 s19 转 bin
来源:互联网 发布:里约奥运会网络直播权 编辑:程序博客网 时间:2024/06/05 19:15
1. S19文件格式详解
S-record格式文件是Freescale CodeWarrior编译器生成的后缀名为.S19的程序文件,是一段直接烧写进MCU的ASCII码,英文全称问Motorola format for EEPROM programming。
【注意:编者】:
上面“是一段直接烧写进MCU的ASCII码”,这样说可能会误导初学者,因为并不是直接将ASCII码写进MCU,写进MCU前还要对S19文件进行一个解析,把有用的机器代码分解出来,然后再进行写入,写入的也不是ASCII而是二进制码。
网上有关S-record格式文件的资料很少,经过我的收集和实验,整理出以下文档,方便大家对Freescale单片机做深入了解。
1、格式定义及含义
S-record每行最大是78个字节,156个字符
S-record format
type count address data checksum
type(类型):2个字符。用来描述记录的类型 (S0,S1,S2,S3,S5,S7,S8,S9)。
count(计数):2个字符。 用来组成和说明了一个16进制的值,显示了在记录中剩余成对字符的计数。
address(地址):4或6或8个字节。用来组成和说明了一个16进制的值,显示了数据应该装载的地址, 这部分的长度取决于载入地址的字节数。2个字节的地址占用4个字符,3个字节的地址占用6个字符,4个字节的地址占用8个字符。
data(数据):0—64字符。用来组成和说明一个代表了内存载入数据或者描述信息的16进制的值。
checksum(校验和):2个字符。这些字符当被配对并换算成16进制数据的时候形成了一个最低有效字符节,该字符节用来表达作为补充数据,地址和数据库的字符对所代表的(字节的)补码的byte总和。即计数值、地址场和数据场的若干字符以两个字符为一对,将它们相加求和,和的溢出部分不计,只保留最低两位字符NN,checksum =0xFF-0xNN。
S0 Record:记录类型是“S0” (0x5330)。地址场没有被用,用零置位(0x0000)。数据场中的信息被划分为以下四个子域:
name(名称):20个字符,用来编码单元名称
ver(版本):2个字符,用来编码版本号
rev(修订版本):2个字符,用来编码修订版本号
description(描述):0-36个字符,用来编码文本注释
此行表示程序的开始,不需烧入memory。
S1 Record:记录类型是“S1” (0x5331)。地址场由2个字节地址来说明。数据场由可载入的数据组成。
S2 Record:记录类型是“S2” (0x5332)。地址场由3个字节地址来说明。数据场由可载入的数据组成。
S3 Record:记录类型是“S3” (0x5333)。地址场由4个字节地址来说明。数据场由可载入的数据组成。
S5 Record:记录类型是“S5” (0x5335)。地址场由2字节的值说明,包含了先前传输的S1、S2、S3记录的计数。没有数据场。
S7 Record:记录类型是“S7” (0x5337)。地址场由4字节的地址说明,包含了开始执行地址。没有数据场。此行表示程序的结束,不需烧入memory。
S8 Record:记录类型是“S8” (0x5338)。地址场由3字节的地址说明,包含了开始执行地址。没有数据场。此行表示程序的结束,不需烧入memory。
S9 Record:记录类型是“S9” (0x5339)。地址场由2字节的地址说明,包含了开始执行地址。没有数据场。此行表示程序的结束,不需烧入memory。
根据不同的描述信息,在以上三种不同的结束行中选择一种使用
2、EXAMPLE
2.1 example I
S19文件首行: S0 21 0000 36384B50524F47202020313143524541544544204259204541535936384B 6D
首行翻译信息: S0 0000 6 8 K P R O G 1 1 C R E A T E D B Y E A S Y 6 8 K
色块图例:module name version number revision number checksum
checksum的算法:
0x21+0x00+0x00+0x36+0x38+0x4B+0x50+0x52+0x4F+0x47+0x20+0x20+0x20+0x31+0x31+0x43+0x52+0x45+0x41+0x54+0x45+0x44
+0x20+0x42+0x59+0x20+0x45+0x41+0x53+0x59+0x36+0x38+0x4B=0x792
checksum=0xFF-0x92=6D
注意:EASy68K总是用S8 record作为结束行。
2.2 example II
S1 23 C000 CF1400790011CC09395B105A124A8046304A8000300001C01BCB73140007340027
色块图例:type count address data checksum
2.3 example III
S2 24 308000 C61E877C1516C6197B151ACE04C07E15187A153EC74A90F9301D026A01C6017B F0
色块图例:type count address data checksum
3、另附Freescale HCS12DP256B 16位单片机空程序S19文件:
S0520000453A5C576F6F64795C4C6561726E696E675C50726F6772616D6D655C42444DD2FDB5BCB3CCD0F25C44556D795C447032 35365C62696E5C48435331325F53657269616C5F4D6F6E69746F722E6162735A
S123C000CF1100790011CC09395B105A124A8004304A8000300000C01BC01F00000000001B
S104C020001B
S105FFFEC0003D
S22430800010EF20FEFEC017FDC015270E35ED31EC3169700434FB310326F2FEC019EC31274F
S2113080200BED31180A30700434F920F10AE7
S804000000FB
2. 参考代码
#include <stdint.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#define MAX_EXTENSION_SIZE 16#define MAX_LINE_SIZE 1024#define MAX_FILE_NAME_SIZE 260typedef char filetype[MAX_FILE_NAME_SIZE];filetype Filename; FILE *fin,*fout;int filemode;unsigned char Ascii2Int(unsigned char tmp0, unsigned char tmp1){ unsigned char s[2]; unsigned char value; s[0] = 0; s[1] = 0; if (tmp0 >= '0' && tmp0 <= '9') s[0] = tmp0 - '0'; else if (tmp0 >= 'a' && tmp0 <='f') s[0] = tmp0 - 'a' + 0xA; else if (tmp0 >= 'A' && tmp0 <= 'F') s[0] = tmp0 - 0x61 + 0XA; if (tmp1 >= '0' && tmp1 <= '9') s[1] = tmp1 - '0'; else if (tmp1 >= 'a' && tmp1 <= 'f') s[1] = tmp1 - 'a' + 0xA; else if (tmp1 >= 'A' && tmp1 <= 'F') s[1] = tmp1 - 'A' + 0xA; value = s[0]<<4; value = value + s[1]; return value;}void PutExtension(char *Flnm, char *Extension){ char *Period; /* location of period in file name */ char Samename = -1; /* This assumes DOS like file names */ /* Don't use strchr(): consider the following filename: ../my.dir/file.hex */ if ((Period = strrchr(Flnm,'.')) != NULL) *(Period) = '\0'; if (strcmp(Extension, Period + 1) == 0) Samename = 0; strcat(Flnm,"."); strcat(Flnm, Extension); if (0 == Samename) { printf ("Input and output filenames (%s) are the same.", Flnm); }}int main(int argc, char *argv[]){ unsigned char tmp[2]; char buf[20]; unsigned char value = 0; unsigned char chksum = 0; unsigned char num = 0; unsigned char func = 0xff; int addr = 0; int size = 0; /* line inputted from file */ char Line[MAX_LINE_SIZE]; char Extension[MAX_EXTENSION_SIZE]; strcpy(Extension, "bin"); /*读取文件名*/ strncpy(Filename, argv[argc -1], sizeof(Filename)); /*打开或创建两个文件*/ fin = fopen(Filename, "r"); PutExtension(Filename, Extension); fout = fopen(Filename,"wb"); while(!feof(fin)) { /*读取一行数据,以's'开始*/ while (1) { fread(tmp, sizeof(char), 1, fin); /*寻找行首*/ if (tmp[0]=='S'||tmp[0]=='s') break; if (feof(fin)) { fclose(fin); fclose(fout); printf("file convert ok!\n"); return; } } chksum = 0; addr = 0; /*读取's'后面的字符: type*/ fread(tmp, sizeof(char), 1, fin); func = tmp[0]; /*获取数据数量,两个字符: count*/ fread(tmp, sizeof(char), 2, fin); num = Ascii2Int(tmp[0], tmp[1]); chksum += num; /*类型type, 处理每一行的地址address数据*/ switch (func) { case '0': fread(tmp, sizeof(char), 2, fin); value = Ascii2Int(tmp[0], tmp[1]); chksum += value; addr += value; addr = addr<<8; fread(tmp, sizeof(char), 2, fin); value = Ascii2Int(tmp[0], tmp[1]); chksum += value; addr += value; num -= 2; break; case '1': fread(tmp, sizeof(char), 2, fin); value = Ascii2Int(tmp[0], tmp[1]); chksum += value; addr += value; addr=addr<<8; fread(tmp, sizeof(char), 2, fin); value = Ascii2Int(tmp[0], tmp[1]); chksum += value; addr += value; num -= 2; break; case '2': fread(tmp, sizeof(char), 2, fin); value = Ascii2Int(tmp[0], tmp[1]); chksum += value; addr += value; addr = addr<<8; fread(tmp, sizeof(char), 2, fin); value = Ascii2Int(tmp[0], tmp[1]); chksum += value; addr += value; addr = addr<<8; fread(tmp,sizeof(char), 2, fin); value = Ascii2Int(tmp[0], tmp[1]); chksum += value; addr += value; num -= 3; break; case '3': fread(tmp, sizeof(char), 2, fin); value=Ascii2Int(tmp[0], tmp[1]); chksum += value; addr += value; addr = addr<<8; fread(tmp, sizeof(char), 2, fin); value = Ascii2Int(tmp[0], tmp[1]); chksum += value; addr += value; addr = addr<<8; fread(tmp, sizeof(char), 2, fin); value = Ascii2Int(tmp[0], tmp[1]); chksum += value; addr += value; addr = addr<<8; fread(tmp, sizeof(char), 2, fin); value = Ascii2Int(tmp[0], tmp[1]); chksum += value; addr += value; num -= 4; break; case '5': break; case '7': break; case '8': break; case '9': break; default : break; }#if 0 switch (func) { case '0': printf("\n module version:\n"); break; case '1': //Memo1->Lines->Add(" \n地址 "); //sprintf(buf," 0x%x ",addr); //Memo1->Text=Memo1->Text+buf; //Memo1->Text=Memo1->Text+"-数据信息:"; break; case '2': //Memo1->Lines->Add(" \n地址 "); //sprintf(buf," 0x%x ",addr); //Memo1->Text=Memo1->Text+buf; //Memo1->Text=Memo1->Text+"-数据信息:"; break; case '3': //Memo1->Lines->Add(" \n地址 "); //sprintf(buf," 0x%x ",addr); //Memo1->Text=Memo1->Text+buf; //Memo1->Text=Memo1->Text+"-数据信息:"; break; case '5': printf("\n data line count:\n"); break; case '7': printf(" \n program start address:\n"); break; case '8': printf(" \n program start address:\n"); break; case '9': printf(" \n program start address:\n"); break; }#endif /*循环读取一行数据, 写入.bin文件中*/ while (num > 1) { fread(tmp, sizeof(char), 2, fin); num--; value = Ascii2Int(tmp[0], tmp[1]); switch (func) { case '0':// sprintf(buf," 0x%2x ",value);// printf("s0 text: %s\n", buf); break; case '1':// sprintf(buf," 0x%2x ",value);// printf("s0 text: %s\n", buf); fwrite(&value, sizeof(char), 1, fout); size++; break; case '2':// sprintf(buf," 0x%2x ",value);// printf("s0 text: %s\n", buf); fwrite(&value, sizeof(char), 1, fout); size++; break; case '3':// sprintf(buf," 0x%2x ",value);// printf("s0 text: %s\n", buf); fwrite(&value, sizeof(char), 1, fout); size++; break; case '5':// sprintf(buf," 0x%2x ",value);// printf("s5 text: %s\n", buf); break; case '7':// sprintf(buf," 0x%2x ",value);// printf("s7 text: %s\n", buf); break; case '8':// sprintf(buf," 0x%2x ",value);// printf("s8 text: %s\n", buf); break; case '9':// sprintf(buf," 0x%2x ",value);// printf("s9 text: %s\n", buf); break; } chksum += value; } /*获取check sum*/ fread(tmp, sizeof(char), 2, fin); value = Ascii2Int(tmp[0], tmp[1]); if(value != 0xff - chksum) printf("crc sum error! text_value:0x%x, clc_chksum:0x%x\n", value, (0xff - chksum)); else printf("crc sum ok! text_value:0x%x, clc_chksum:0x%x\n", value, (0xff - chksum)); }}
3 . 参考代码2
#include <stdint.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#define MAX_EXTENSION_SIZE 16#define MAX_LINE_SIZE 1024#define MAX_FILE_NAME_SIZE 260typedef char filetype[MAX_FILE_NAME_SIZE];typedef struct { unsigned int file_size; unsigned int start_addr; unsigned int end_addr; FILE *file_in, *file_out;} update_file_info, * p_update_file_info;update_file_info g_update_ecu_file_info;void get_line(char* str, FILE *in){ char *result; result = fgets(str, MAX_LINE_SIZE, in); if ((NULL == result) && !feof (in)) printf("Error occurred while reading from file\n");}void put_extension(char *file_name, char *extension){ /* location of period in file name */ char *Period; int ret = -1; /*find '.': the last postion*/ if (NULL != (Period = strrchr(file_name,'.'))) *(Period) = '\0'; if (strcmp(extension, Period + 1) == 0) ret = 0; strcat(file_name, "."); strcat(file_name, extension);}void s19_to_bin(char *path){ /*保存行内容*/ char *p_line = NULL; char extension[MAX_EXTENSION_SIZE] = {0}; filetype filename; char *p = NULL; unsigned char *memory_block = NULL; unsigned int memory_block_position; /*记录行数*/ unsigned int record_line = 0; int ret; unsigned int i; /*行信息*/ unsigned int type; unsigned int data_length; unsigned int address; char *p_data = NULL; unsigned char check_sum = 0; unsigned int temp2; unsigned int max_data_length; g_update_ecu_file_info.start_addr = (unsigned int)(-1); g_update_ecu_file_info.end_addr = 0; p_line = (char *)malloc(MAX_LINE_SIZE * sizeof(char)); if (NULL == p_line) printf("malloc line buffer error. \n"); p_data = (char *)malloc(MAX_LINE_SIZE * sizeof(char)); if (NULL == p_data) printf("malloc data buffer error. \n"); /* default is for binary file extension */ strncpy(extension, "bin", sizeof(extension)); /* get filename */ if (strlen(path) < MAX_FILE_NAME_SIZE) { strcpy(filename, path); } else { printf("filename length exceeds %d characters.\n", MAX_FILE_NAME_SIZE); } /* Just a normal file name */ g_update_ecu_file_info.file_in = fopen(filename, "r"); put_extension(filename, extension); g_update_ecu_file_info.file_out = fopen(filename,"wb"); /*1. calc the size by address*/ do { /* Read a line from input file. */ get_line(p_line, g_update_ecu_file_info.file_in); record_line++; i = strlen(p_line); if (--i != 0) { if (p_line[i] == '\n') p_line[i] = '\0'; ret = sscanf(p_line, "S%1x%2x", &type, &data_length); if (2 != ret) printf("Error in line %d of hex file\n", record_line);// printf("type:%d, data_length:%d, record_line:%d\n", type, data_length, record_line); switch (type) { case 0: ret = sscanf(p_line, "S%1x%2x%4x%s",&type, &data_length, &address, p_data); if (4 != ret) printf("Error in line %d of hex file\n", record_line); break; case 1: ret = sscanf(p_line, "S%1x%2x%4x%s",&type, &data_length, &address, p_data); if (4 != ret) printf("Error in line %d of hex file\n", record_line); printf("address: 0x%x\n", address); if (g_update_ecu_file_info.start_addr > address) g_update_ecu_file_info.start_addr = address; address = address + data_length - 1; if (g_update_ecu_file_info.end_addr < address) g_update_ecu_file_info.end_addr = address; break; case 2: ret = sscanf(p_line, "S%1x%2x%6x%s",&type, &data_length, &address, p_data); if (4 != ret) printf("Error in line %d of hex file\n", record_line); if (g_update_ecu_file_info.start_addr > address) g_update_ecu_file_info.start_addr = address; address = address + data_length - 1; if (g_update_ecu_file_info.end_addr < address) g_update_ecu_file_info.end_addr = address; break; case 3: ret = sscanf(p_line, "S%1x%2x%8x%s",&type, &data_length, &address, p_data); if (4 != ret) printf("Error in line %d of hex file\n", record_line); if (g_update_ecu_file_info.start_addr > address) g_update_ecu_file_info.start_addr = address; address = address + data_length - 1; if (g_update_ecu_file_info.end_addr < address) g_update_ecu_file_info.end_addr = address; break; case 5: ret = sscanf(p_line, "S%1x%2x%4x%s",&type, &data_length, &address, p_data); if (4 != ret) printf("Error in line %d of hex file\n", record_line); break; case 7: ret = sscanf(p_line, "S%1x%2x%8x%s",&type, &data_length, &address, p_data); if (4 != ret) printf("Error in line %d of hex file\n", record_line); break; case 8: ret = sscanf(p_line, "S%1x%2x%6x%s",&type, &data_length, &address, p_data); if (4 != ret) printf("Error in line %d of hex file\n", record_line); break; case 9: ret = sscanf(p_line, "S%1x%2x%4x%s",&type, &data_length, &address, p_data); if (4 != ret) printf("Error in line %d of hex file\n", record_line); break; default: break; } } } while (!feof(g_update_ecu_file_info.file_in)); /*calc the data size*/ max_data_length = g_update_ecu_file_info.end_addr - g_update_ecu_file_info.start_addr + 1; g_update_ecu_file_info.file_size = max_data_length; printf("start addr:0x%08x\n", g_update_ecu_file_info.start_addr); printf("end addr:0x%08x\n", g_update_ecu_file_info.end_addr); printf("data size: %d Bytes\n", g_update_ecu_file_info.file_size); memory_block = (unsigned char *)malloc(max_data_length * sizeof(unsigned char)); if (NULL == memory_block) printf("malloc memory_block buffer error. \n"); memset (memory_block, 0xFF, max_data_length); /*****************2. deal with data***********************/ record_line = 0; /*init file inner pointer*/ rewind(g_update_ecu_file_info.file_in); /* Read the file & process the lines. */ /* repeat until EOF(Filin) */ do { /* Read a line from input file. */ get_line(p_line, g_update_ecu_file_info.file_in); record_line++; i = strlen(p_line); if (--i != 0) { if (p_line[i] == '\n') p_line[i] = '\0'; ret = sscanf(p_line, "S%1x%2x", &type, &data_length); if (2 != ret) printf("Error in line %d of hex file\n", record_line);// printf("type:%d, data_length:%d, record_line:%d\n", type, data_length, record_line); switch (type) { case 0: ret = sscanf(p_line, "S%1x%2x%4x%s",&type, &data_length, &address, p_data); if (4 != ret) printf("Error in line %d of hex file\n", record_line); check_sum = data_length + (address >> 8) + (address & 0xff); break; case 1: ret = sscanf(p_line, "S%1x%2x%4x%s",&type, &data_length, &address, p_data); if (4 != ret) printf("Error in line %d of hex file\n", record_line); check_sum = data_length + (address >> 8) + (address & 0xff); printf("type:%d, data_length:0x%x, address: 0x%x, record_line:%d \n", type, data_length, address, record_line); printf("p_data: %s\n", p_data); /*行内容:data段的起始位置*/ p = (char *)p_data; /*计算相对于最低位置的地址*/ memory_block_position = address - g_update_ecu_file_info.start_addr; /*开始存储数据*/ if (memory_block_position < g_update_ecu_file_info.file_size) { /*save data*/ data_length = data_length - 3; do { ret = sscanf(p, "%2x", &temp2); if (1 != ret) printf("ReadDataBytes: error in line %d of hex file\n", record_line); p += 2; memory_block[memory_block_position++] = temp2; check_sum = (check_sum + temp2) & 0xFF; } while (--data_length != 0); } else printf("Overlapped record detected\n"); /* Read the Checksum value. */ ret = sscanf(p, "%2x",&temp2); if (1 != ret) printf("Error in line %d of hex file\n", record_line); /* Verify Checksum value. */ if(temp2 != 0xff - check_sum) printf("crc sum error! text_value:0x%x, clc_chksum:0x%x\n", temp2, (0xff - check_sum)); break; case 2: ret = sscanf(p_line, "S%1x%2x%6x%s",&type, &data_length, &address, p_data); if (4 != ret) printf("Error in line %d of hex file\n", record_line); check_sum = data_length + (address >> 16) + ((address >> 8)&0xff) + (address & 0xff); /*行内容:data段的起始位置*/ p = (char *)p_data; /*计算相对于最低位置的地址*/ memory_block_position = address - g_update_ecu_file_info.start_addr; /*开始存储数据*/ if (memory_block_position < g_update_ecu_file_info.file_size) { /*save data*/ data_length = data_length - 4; do { ret = sscanf(p, "%2x", &temp2); if (1 != ret) printf("ReadDataBytes: error in line %d of hex file\n", record_line); p += 2; memory_block[memory_block_position++] = temp2; check_sum = (check_sum + temp2) & 0xFF; } while (--data_length != 0); } else printf("Overlapped record detected\n"); /* Read the Checksum value. */ ret = sscanf(p, "%2x",&temp2); if (1 != ret) printf("Error in line %d of hex file\n", record_line); /* Verify Checksum value. */ if(temp2 != 0xff - check_sum) printf("crc sum error! text_value:0x%x, clc_chksum:0x%x\n", temp2, (0xff - check_sum)); break; case 3: ret = sscanf(p_line, "S%1x%2x%8x%s",&type, &data_length, &address, p_data); if (4 != ret) printf("Error in line %d of hex file\n", record_line); check_sum = data_length + (address >> 24) + ((address >> 16) & 0xff) + ((address >> 8)&0xff) + (address & 0xff); /*行内容:data段的起始位置*/ p = (char *)p_data; /*计算相对于最低位置的地址*/ memory_block_position = address - g_update_ecu_file_info.start_addr; /*开始存储数据*/ if (memory_block_position < g_update_ecu_file_info.file_size) { /*save data*/ data_length = data_length - 5; do { ret = sscanf(p, "%2x", &temp2); if (1 != ret) printf("ReadDataBytes: error in line %d of hex file\n", record_line); p += 2; memory_block[memory_block_position++] = temp2; check_sum = (check_sum + temp2) & 0xFF; } while (--data_length != 0); } else printf("Overlapped record detected\n"); /* Read the Checksum value. */ ret = sscanf(p, "%2x",&temp2); if (1 != ret) printf("Error in line %d of hex file\n", record_line); /* Verify Checksum value. */ if(temp2 != 0xff - check_sum) printf("crc sum error! text_value:0x%x, clc_chksum:0x%x\n", temp2, (0xff - check_sum)); break; case 5: ret = sscanf(p_line, "S%1x%2x%4x%s",&type, &data_length, &address, p_data); if (4 != ret) printf("Error in line %d of hex file\n", record_line); check_sum = data_length + (address >> 8) + (address & 0xff); break; case 7: ret = sscanf(p_line, "S%1x%2x%8x%s",&type, &data_length, &address, p_data); if (4 != ret) printf("Error in line %d of hex file\n", record_line); check_sum = data_length + (address >> 24) + ((address >> 16) & 0xff) + ((address >> 8)&0xff) + (address & 0xff); break; case 8: ret = sscanf(p_line, "S%1x%2x%6x%s",&type, &data_length, &address, p_data); if (4 != ret) printf("Error in line %d of hex file\n", record_line); check_sum = data_length + (address >> 16) + ((address >> 8)&0xff) + (address & 0xff); break; case 9: ret = sscanf(p_line, "S%1x%2x%4x%s",&type, &data_length, &address, p_data); if (4 != ret) printf("Error in line %d of hex file\n", record_line); check_sum = data_length + (address >> 8) + (address & 0xff); break; default: break; } } }while (!feof(g_update_ecu_file_info.file_in)); /*write binary file*/ fwrite (memory_block, g_update_ecu_file_info.file_size, 1, g_update_ecu_file_info.file_out); fflush(g_update_ecu_file_info.file_out); fclose(g_update_ecu_file_info.file_in); fclose(g_update_ecu_file_info.file_out); free(memory_block); memory_block = NULL; free(p_line); p_line = NULL; free(p_data); p_data = NULL;}int main(int argc, char *argv[]){ s19_to_bin(argv[argc-1]); return 0;}
- 飞思卡尔 s19 转 bin
- 飞思卡尔单片机[STM8单片机]S19文件格式详解
- 飞思卡尔单片机[STM8单片机]S19文件格式详解
- BIN 转化为 S19 格式及 S19 格式解析
- 实现IAR下S19、Bin、Hex文件格式转换小技巧
- KEIL5或KEIL4生成.S19文件 .BIN文件方法
- 轻松玩转K60--飞思卡尔
- 飞思卡尔
- 飞思卡尔
- 飞思卡尔感悟
- 【飞思卡尔】
- 飞思卡尔
- 飞思卡尔mx6_sabresd_board_init
- S19格式文件详解(S-record)【转】
- 飞思卡尔测速仪器
- 飞思卡尔智能小车
- 飞思卡尔PWM模块
- 飞思卡尔ATD模块
- 创建带表头结点的单向链表,并实现各种功能
- 知识点总结之学习方式
- Gossip算法
- loadrunner 之 Web services 脚本例子
- QT——label
- 飞思卡尔 s19 转 bin
- ORACLE 触发器禁用
- 算法提高 队列操作
- 一致性哈希(Consistent Hashing)
- Cannot add performance counter
- 8.2再谈排序与检索
- Flex 布局教程:语法篇
- 简单的并差集算法实例
- wmi入门