提交 72782e92 编写于 作者: B Bernard Xiong

convert end of line

上级 b3cf2785
/*
* crc calculation stuff
*/
/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
static unsigned short crctab[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
/*
* updcrc macro derived from article Copyright (C) 1986 Stephen Satchell.
* NOTE: First srgument must be in range 0 to 255.
* Second argument is referenced twice.
*
* Programmers may incorporate any or all code into their programs,
* giving proper credit within the source. Publication of the
* source routines is permitted so long as proper credit is given
* to Stephen Satchell, Satchell Evaluations and Chuck Forsberg,
* Omen Technology.
*/
#define updcrc16(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
/*
* Copyright (C) 1986 Gary S. Brown. You may use this program, or
* code or tables extracted from it, as desired without restriction.
*/
/* First, the polynomial itself and its table of feedback terms. The */
/* polynomial is */
/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
/* Note that we take it "backwards" and put the highest-order term in */
/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
/* the MSB being 1. */
/* Note that the usual hardware shift register implementation, which */
/* is what we're using (we're merely optimizing it by doing eight-bit */
/* chunks at a time) shifts bits into the lowest-order term. In our */
/* implementation, that means shifting towards the right. Why do we */
/* do it this way? Because the calculated CRC must be transmitted in */
/* order from highest-order term to lowest-order term. UARTs transmit */
/* characters in order from LSB to MSB. By storing the CRC this way, */
/* we hand it to the UART in the order low-byte to high-byte; the UART */
/* sends each low-bit to hight-bit; and the result is transmission bit */
/* by bit from highest- to lowest-order term without requiring any bit */
/* shuffling on our part. Reception works similarly. */
/* The feedback terms table consists of 256, 32-bit entries. Notes: */
/* */
/* The table can be generated at runtime if desired; code to do so */
/* is shown later. It might not be obvious, but the feedback */
/* terms simply represent the results of eight shift/xor opera- */
/* tions for all combinations of data and CRC register values. */
/* */
/* The values must be right-shifted by eight bits by the "updcrc" */
/* logic; the shift must be unsigned (bring in zeroes). On some */
/* hardware you could probably optimize the shift in assembler by */
/* using byte-swap instructions. */
static unsigned long cr3tab[] = { /* CRC polynomial 0xedb88320 */
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
#define updcrc32(b, c) (cr3tab[((int)c ^ b) & 0xff] ^ ((c >> 8) & 0x00FFFFFF))
/* End of crc.c */
/*
* crc calculation stuff
*/
/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
static unsigned short crctab[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
/*
* updcrc macro derived from article Copyright (C) 1986 Stephen Satchell.
* NOTE: First srgument must be in range 0 to 255.
* Second argument is referenced twice.
*
* Programmers may incorporate any or all code into their programs,
* giving proper credit within the source. Publication of the
* source routines is permitted so long as proper credit is given
* to Stephen Satchell, Satchell Evaluations and Chuck Forsberg,
* Omen Technology.
*/
#define updcrc16(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
/*
* Copyright (C) 1986 Gary S. Brown. You may use this program, or
* code or tables extracted from it, as desired without restriction.
*/
/* First, the polynomial itself and its table of feedback terms. The */
/* polynomial is */
/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
/* Note that we take it "backwards" and put the highest-order term in */
/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
/* the MSB being 1. */
/* Note that the usual hardware shift register implementation, which */
/* is what we're using (we're merely optimizing it by doing eight-bit */
/* chunks at a time) shifts bits into the lowest-order term. In our */
/* implementation, that means shifting towards the right. Why do we */
/* do it this way? Because the calculated CRC must be transmitted in */
/* order from highest-order term to lowest-order term. UARTs transmit */
/* characters in order from LSB to MSB. By storing the CRC this way, */
/* we hand it to the UART in the order low-byte to high-byte; the UART */
/* sends each low-bit to hight-bit; and the result is transmission bit */
/* by bit from highest- to lowest-order term without requiring any bit */
/* shuffling on our part. Reception works similarly. */
/* The feedback terms table consists of 256, 32-bit entries. Notes: */
/* */
/* The table can be generated at runtime if desired; code to do so */
/* is shown later. It might not be obvious, but the feedback */
/* terms simply represent the results of eight shift/xor opera- */
/* tions for all combinations of data and CRC register values. */
/* */
/* The values must be right-shifted by eight bits by the "updcrc" */
/* logic; the shift must be unsigned (bring in zeroes). On some */
/* hardware you could probably optimize the shift in assembler by */
/* using byte-swap instructions. */
static unsigned long cr3tab[] = { /* CRC polynomial 0xedb88320 */
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
#define updcrc32(b, c) (cr3tab[((int)c ^ b) & 0xff] ^ ((c >> 8) & 0x00FFFFFF))
/* End of crc.c */
/*
* File : rz.c
* the implemention of receiving files from the remote computers
* File : rz.c
* the implemention of receiving files from the remote computers
* through the zmodem protocol.
* Change Logs:
* Date Author Notes
* 2011-03-29 itspy
* 2011-12-12 aozima fixed syntax error.
*/
#include <rtthread.h>
#include <finsh.h>
#include <shell.h>
#include <rtdef.h>
#include <dfs.h>
#include <dfs_file.h>
#include <dfs_posix.h>
#include <stdio.h>
#include "zdef.h"
void zr_start(char *path);
static rt_err_t zrec_init(rt_uint8_t *rxbuf, struct zfile *zf);
static rt_err_t zrec_files(struct zfile *zf);
static rt_err_t zwrite_file(rt_uint8_t *buf, rt_uint16_t size, struct zfile *zf);
static rt_err_t zrec_file_data(rt_uint8_t *buf, struct zfile *zf);;
static rt_err_t zrec_file(rt_uint8_t *rxbuf, struct zfile *zf);
static rt_err_t zget_file_info(char *name, struct zfile *zf);
static rt_err_t zwrite_file(rt_uint8_t *buf, rt_uint16_t size, struct zfile *zf);
static void zrec_ack_bibi(void);
/* start zmodem receive proccess */
void zr_start(char *path)
{
struct zfile *zf;
rt_uint8_t n;
char ch,*p,*q;
rt_err_t res = -RT_ERROR;
zf = rt_malloc(sizeof(struct zfile));
if (zf == RT_NULL)
{
rt_kprintf("zf: out of memory\r\n");
return;
}
memset(zf, 0, sizeof(struct zfile));
zf->fname = path;
zf->fd = -1;
res = zrec_files(zf);
p = zf->fname;
for (;;)
{
q = strstr(p,"/");
if (q == RT_NULL) break;
p = q+1;
}
if (res == RT_EOK)
{
rt_kprintf("\b\b\bfile: %s \r\n",p);
rt_kprintf("size: %ld bytes\r\n",zf->bytes_received);
rt_kprintf("receive completed.\r\n");
close(zf->fd);
rt_free(zf->fname);
}
else
{
rt_kprintf("\b\b\bfile: %s \r\n",p);
rt_kprintf("size: 0 bytes\r\n");
rt_kprintf("receive failed.\r\n");
if (zf->fd >= 0)
{
close(zf->fd);
unlink(zf->fname); /* remove this file */
rt_free(zf->fname);
}
}
rt_free(zf);
/* waiting,clear console buffer */
rt_thread_delay(RT_TICK_PER_SECOND/2);
while(1)
{
n=rt_device_read(shell->device, 0, &ch, 1);
if (n == 0) break;
}
return ;
}
/* receiver init, wait for ack */
static rt_err_t zrec_init(rt_uint8_t *rxbuf, struct zfile *zf)
{
rt_uint8_t err_cnt = 0;
rt_err_t res = -RT_ERROR;
for (;;)
{
zput_pos(0L);
tx_header[ZF0] = ZF0_CMD;
tx_header[ZF1] = ZF1_CMD;
tx_header[ZF2] = ZF2_CMD;
zsend_hex_header(ZRINIT, tx_header);
again:
res = zget_header(rx_header);
switch(res)
{
case ZFILE:
ZF0_CMD = rx_header[ZF0];
ZF1_CMD = rx_header[ZF1];
ZF2_CMD = rx_header[ZF2];
ZF3_CMD = rx_header[ZF3];
res = zget_data(rxbuf, RX_BUFFER_SIZE);
if (res == GOTCRCW)
{
if ((res =zget_file_info((char*)rxbuf,zf))!= RT_EOK)
{
zsend_hex_header(ZSKIP, tx_header);
return (res);
}
return RT_EOK;;
}
zsend_hex_header(ZNAK, tx_header);
goto again;
case ZSINIT:
if (zget_data((rt_uint8_t*)Attn, ZATTNLEN) == GOTCRCW) /* send zack */
{
zsend_hex_header(ZACK, tx_header);
goto again;
}
zsend_hex_header(ZNAK, tx_header); /* send znak */
goto again;
case ZRQINIT:
continue;
case ZEOF:
continue;
case ZCOMPL:
goto again;
case ZFIN: /* end file session */
zrec_ack_bibi();
return res;
default:
if (++err_cnt >1000) return -RT_ERROR;
continue;
}
}
}
/* receive files */
static rt_err_t zrec_files(struct zfile *zf)
{
rt_uint8_t *rxbuf;
rt_err_t res = -RT_ERROR;
zinit_parameter();
rxbuf = rt_malloc(RX_BUFFER_SIZE*sizeof(rt_uint8_t));
if (rxbuf == RT_NULL)
{
rt_kprintf("rxbuf: out of memory\r\n");
return -RT_ERROR;
}
rt_kprintf("\r\nrz: ready...\r\n"); /* here ready to receive things */
if ((res = zrec_init(rxbuf,zf))!= RT_EOK)
{
rt_kprintf("\b\b\breceive init failed\r\n");
rt_free(rxbuf);
return -RT_ERROR;
}
res = zrec_file(rxbuf,zf);
if (res == ZFIN)
{
rt_free(rxbuf);
return RT_EOK; /* if finish session */
}
else if (res == ZCAN)
{
rt_free(rxbuf);
return ZCAN; /* cancel by sender */
}
else
{
zsend_can();
rt_free(rxbuf);
return res;
}
}
/* receive file */
static rt_err_t zrec_file(rt_uint8_t *rxbuf, struct zfile *zf)
{
rt_err_t res = - RT_ERROR;
rt_uint16_t err_cnt = 0;
do
{
zput_pos(zf->bytes_received);
zsend_hex_header(ZRPOS, tx_header);
again:
res = zget_header(rx_header);
switch (res)
{
case ZDATA:
zget_pos(Rxpos);
if (Rxpos != zf->bytes_received)
{
zsend_break(Attn);
continue;
}
err_cnt = 0;
res = zrec_file_data(rxbuf,zf);
if (res == -RT_ERROR)
{
zsend_break(Attn);
continue;
}
else if (res == GOTCAN) return res;
else goto again;
case ZRPOS:
zget_pos(Rxpos);
continue;
case ZEOF:
err_cnt = 0;
zget_pos(Rxpos);
if (Rxpos != zf->bytes_received || Rxpos != zf->bytes_total)
{
continue;
}
return (zrec_init(rxbuf,zf)); /* resend ZRINIT packet,ready to receive next file */
case ZFIN:
zrec_ack_bibi();
return ZCOMPL;
case ZCAN:
#ifdef ZDEBUG
rt_kprintf("error code: sender cancelled \r\n");
#endif
zf->bytes_received = 0L; /* throw the received data */
return res;
case ZSKIP:
return res;
case -RT_ERROR:
zsend_break(Attn);
continue;
case ZNAK:
case TIMEOUT:
default:
continue;
}
} while(++err_cnt < 100);
return res;
}
/* proccess file infomation */
static rt_err_t zget_file_info(char *name, struct zfile *zf)
{
char *p;
char *full_path,*ptr;
rt_uint16_t i,len;
rt_err_t res = -RT_ERROR;
struct statfs buf;
struct stat finfo;
if (zf->fname == RT_NULL) /* extract file path */
{
len = strlen(name)+2;
}
else
len = strlen(zf->fname)+strlen(name)+2;
full_path = rt_malloc(len);
if (full_path == RT_NULL)
{
zsend_can();
rt_kprintf("\b\b\bfull_path: out of memory\n");
rt_free(full_path);
return -RT_ERROR;
}
memset(full_path,0,len);
for (i=0,ptr=zf->fname;i<len-strlen(name)-2;i++)
full_path[i] = *ptr++;
full_path[len-strlen(name)-2] = '/';
/* check if is a directory */
if ((zf->fd=open(full_path, DFS_O_DIRECTORY,0)) < 0)
{
zsend_can();
rt_kprintf("\b\b\bcan not open file:%s\r\n",zf->fname+1);
close(zf->fd);
zf->fd = -1;
rt_free(full_path);
return res;
}
fstat(zf->fd, &finfo);
if ((finfo.st_mode&S_IFDIR) != S_IFDIR)
{
close(zf->fd);
zf->fd = -1;
return res;
}
close(zf->fd);
/* get fullpath && file attributes */
strcat(full_path,name);
zf->fname = full_path;
p = strlen(name)+name+1;
sscanf((const char *)p, "%ld%lo%o", &zf->bytes_total,&zf->ctime,&zf->mode);
#if defined(RT_USING_DFS) && defined(DFS_USING_WORKDIR)
dfs_statfs(working_directory,&buf);
if (zf->bytes_total > (buf.f_blocks * buf.f_bfree))
{
zsend_can();
rt_kprintf("\b\b\bnot enough disk space\r\n");
zf->fd = -1;
rt_free(full_path);
return -RT_ERROR;
}
#else
buf = buf;
#endif
zf->bytes_received = 0L;
if ((zf->fd = open(zf->fname,DFS_O_CREAT|DFS_O_WRONLY,0)) < 0) /* create or replace exist file */
{
zsend_can();
rt_kprintf("\b\b\bcan not create file:%s \r\n",zf->fname);
return -RT_ERROR;
}
return RT_EOK;
}
/* receive file data,continously, no ack */
static rt_err_t zrec_file_data(rt_uint8_t *buf, struct zfile *zf)
{
rt_err_t res = -RT_ERROR;
more_data:
res = zget_data(buf,RX_BUFFER_SIZE);
switch(res)
{
case GOTCRCW: /* zack received */
zwrite_file(buf,Rxcount,zf);
zf->bytes_received += Rxcount;
zput_pos(zf->bytes_received);
zsend_line(XON);
zsend_hex_header(ZACK, tx_header);
return RT_EOK;
case GOTCRCQ:
zwrite_file(buf,Rxcount,zf);
zf->bytes_received += Rxcount;
zput_pos(zf->bytes_received);
zsend_hex_header(ZACK, tx_header);
goto more_data;
case GOTCRCG:
zwrite_file(buf,Rxcount,zf);
zf->bytes_received += Rxcount;
goto more_data;
case GOTCRCE:
zwrite_file(buf,Rxcount,zf);
zf->bytes_received += Rxcount;
return RT_EOK;
case GOTCAN:
#ifdef ZDEBUG
rt_kprintf("error code : ZCAN \r\n");
#endif
return res;
case TIMEOUT:
return res;
case -RT_ERROR:
zsend_break(Attn);
return res;
default:
return res;
}
}
/* write file */
static rt_err_t zwrite_file(rt_uint8_t *buf,rt_uint16_t size, struct zfile *zf)
{
return (write(zf->fd,buf,size));
}
/* ack bibi */
static void zrec_ack_bibi(void)
{
rt_uint8_t i;
zput_pos(0L);
for (i=0;i<3;i++)
{
zsend_hex_header(ZFIN, tx_header);
switch (zread_line(100))
{
case 'O':
zread_line(1);
return;
case RCDO:
return;
case TIMEOUT:
default:
break;
}
}
}
/* end of rz.c */
*/
#include <rtthread.h>
#include <finsh.h>
#include <shell.h>
#include <rtdef.h>
#include <dfs.h>
#include <dfs_file.h>
#include <dfs_posix.h>
#include <stdio.h>
#include "zdef.h"
void zr_start(char *path);
static rt_err_t zrec_init(rt_uint8_t *rxbuf, struct zfile *zf);
static rt_err_t zrec_files(struct zfile *zf);
static rt_err_t zwrite_file(rt_uint8_t *buf, rt_uint16_t size, struct zfile *zf);
static rt_err_t zrec_file_data(rt_uint8_t *buf, struct zfile *zf);;
static rt_err_t zrec_file(rt_uint8_t *rxbuf, struct zfile *zf);
static rt_err_t zget_file_info(char *name, struct zfile *zf);
static rt_err_t zwrite_file(rt_uint8_t *buf, rt_uint16_t size, struct zfile *zf);
static void zrec_ack_bibi(void);
/* start zmodem receive proccess */
void zr_start(char *path)
{
struct zfile *zf;
rt_uint8_t n;
char ch,*p,*q;
rt_err_t res = -RT_ERROR;
zf = rt_malloc(sizeof(struct zfile));
if (zf == RT_NULL)
{
rt_kprintf("zf: out of memory\r\n");
return;
}
memset(zf, 0, sizeof(struct zfile));
zf->fname = path;
zf->fd = -1;
res = zrec_files(zf);
p = zf->fname;
for (;;)
{
q = strstr(p,"/");
if (q == RT_NULL) break;
p = q+1;
}
if (res == RT_EOK)
{
rt_kprintf("\b\b\bfile: %s \r\n",p);
rt_kprintf("size: %ld bytes\r\n",zf->bytes_received);
rt_kprintf("receive completed.\r\n");
close(zf->fd);
rt_free(zf->fname);
}
else
{
rt_kprintf("\b\b\bfile: %s \r\n",p);
rt_kprintf("size: 0 bytes\r\n");
rt_kprintf("receive failed.\r\n");
if (zf->fd >= 0)
{
close(zf->fd);
unlink(zf->fname); /* remove this file */
rt_free(zf->fname);
}
}
rt_free(zf);
/* waiting,clear console buffer */
rt_thread_delay(RT_TICK_PER_SECOND/2);
while(1)
{
n=rt_device_read(shell->device, 0, &ch, 1);
if (n == 0) break;
}
return ;
}
/* receiver init, wait for ack */
static rt_err_t zrec_init(rt_uint8_t *rxbuf, struct zfile *zf)
{
rt_uint8_t err_cnt = 0;
rt_err_t res = -RT_ERROR;
for (;;)
{
zput_pos(0L);
tx_header[ZF0] = ZF0_CMD;
tx_header[ZF1] = ZF1_CMD;
tx_header[ZF2] = ZF2_CMD;
zsend_hex_header(ZRINIT, tx_header);
again:
res = zget_header(rx_header);
switch(res)
{
case ZFILE:
ZF0_CMD = rx_header[ZF0];
ZF1_CMD = rx_header[ZF1];
ZF2_CMD = rx_header[ZF2];
ZF3_CMD = rx_header[ZF3];
res = zget_data(rxbuf, RX_BUFFER_SIZE);
if (res == GOTCRCW)
{
if ((res =zget_file_info((char*)rxbuf,zf))!= RT_EOK)
{
zsend_hex_header(ZSKIP, tx_header);
return (res);
}
return RT_EOK;;
}
zsend_hex_header(ZNAK, tx_header);
goto again;
case ZSINIT:
if (zget_data((rt_uint8_t*)Attn, ZATTNLEN) == GOTCRCW) /* send zack */
{
zsend_hex_header(ZACK, tx_header);
goto again;
}
zsend_hex_header(ZNAK, tx_header); /* send znak */
goto again;
case ZRQINIT:
continue;
case ZEOF:
continue;
case ZCOMPL:
goto again;
case ZFIN: /* end file session */
zrec_ack_bibi();
return res;
default:
if (++err_cnt >1000) return -RT_ERROR;
continue;
}
}
}
/* receive files */
static rt_err_t zrec_files(struct zfile *zf)
{
rt_uint8_t *rxbuf;
rt_err_t res = -RT_ERROR;
zinit_parameter();
rxbuf = rt_malloc(RX_BUFFER_SIZE*sizeof(rt_uint8_t));
if (rxbuf == RT_NULL)
{
rt_kprintf("rxbuf: out of memory\r\n");
return -RT_ERROR;
}
rt_kprintf("\r\nrz: ready...\r\n"); /* here ready to receive things */
if ((res = zrec_init(rxbuf,zf))!= RT_EOK)
{
rt_kprintf("\b\b\breceive init failed\r\n");
rt_free(rxbuf);
return -RT_ERROR;
}
res = zrec_file(rxbuf,zf);
if (res == ZFIN)
{
rt_free(rxbuf);
return RT_EOK; /* if finish session */
}
else if (res == ZCAN)
{
rt_free(rxbuf);
return ZCAN; /* cancel by sender */
}
else
{
zsend_can();
rt_free(rxbuf);
return res;
}
}
/* receive file */
static rt_err_t zrec_file(rt_uint8_t *rxbuf, struct zfile *zf)
{
rt_err_t res = - RT_ERROR;
rt_uint16_t err_cnt = 0;
do
{
zput_pos(zf->bytes_received);
zsend_hex_header(ZRPOS, tx_header);
again:
res = zget_header(rx_header);
switch (res)
{
case ZDATA:
zget_pos(Rxpos);
if (Rxpos != zf->bytes_received)
{
zsend_break(Attn);
continue;
}
err_cnt = 0;
res = zrec_file_data(rxbuf,zf);
if (res == -RT_ERROR)
{
zsend_break(Attn);
continue;
}
else if (res == GOTCAN) return res;
else goto again;
case ZRPOS:
zget_pos(Rxpos);
continue;
case ZEOF:
err_cnt = 0;
zget_pos(Rxpos);
if (Rxpos != zf->bytes_received || Rxpos != zf->bytes_total)
{
continue;
}
return (zrec_init(rxbuf,zf)); /* resend ZRINIT packet,ready to receive next file */
case ZFIN:
zrec_ack_bibi();
return ZCOMPL;
case ZCAN:
#ifdef ZDEBUG
rt_kprintf("error code: sender cancelled \r\n");
#endif
zf->bytes_received = 0L; /* throw the received data */
return res;
case ZSKIP:
return res;
case -RT_ERROR:
zsend_break(Attn);
continue;
case ZNAK:
case TIMEOUT:
default:
continue;
}
} while(++err_cnt < 100);
return res;
}
/* proccess file infomation */
static rt_err_t zget_file_info(char *name, struct zfile *zf)
{
char *p;
char *full_path,*ptr;
rt_uint16_t i,len;
rt_err_t res = -RT_ERROR;
struct statfs buf;
struct stat finfo;
if (zf->fname == RT_NULL) /* extract file path */
{
len = strlen(name)+2;
}
else
len = strlen(zf->fname)+strlen(name)+2;
full_path = rt_malloc(len);
if (full_path == RT_NULL)
{
zsend_can();
rt_kprintf("\b\b\bfull_path: out of memory\n");
rt_free(full_path);
return -RT_ERROR;
}
memset(full_path,0,len);
for (i=0,ptr=zf->fname;i<len-strlen(name)-2;i++)
full_path[i] = *ptr++;
full_path[len-strlen(name)-2] = '/';
/* check if is a directory */
if ((zf->fd=open(full_path, DFS_O_DIRECTORY,0)) < 0)
{
zsend_can();
rt_kprintf("\b\b\bcan not open file:%s\r\n",zf->fname+1);
close(zf->fd);
zf->fd = -1;
rt_free(full_path);
return res;
}
fstat(zf->fd, &finfo);
if ((finfo.st_mode&S_IFDIR) != S_IFDIR)
{
close(zf->fd);
zf->fd = -1;
return res;
}
close(zf->fd);
/* get fullpath && file attributes */
strcat(full_path,name);
zf->fname = full_path;
p = strlen(name)+name+1;
sscanf((const char *)p, "%ld%lo%o", &zf->bytes_total,&zf->ctime,&zf->mode);
#if defined(RT_USING_DFS) && defined(DFS_USING_WORKDIR)
dfs_statfs(working_directory,&buf);
if (zf->bytes_total > (buf.f_blocks * buf.f_bfree))
{
zsend_can();
rt_kprintf("\b\b\bnot enough disk space\r\n");
zf->fd = -1;
rt_free(full_path);
return -RT_ERROR;
}
#else
buf = buf;
#endif
zf->bytes_received = 0L;
if ((zf->fd = open(zf->fname,DFS_O_CREAT|DFS_O_WRONLY,0)) < 0) /* create or replace exist file */
{
zsend_can();
rt_kprintf("\b\b\bcan not create file:%s \r\n",zf->fname);
return -RT_ERROR;
}
return RT_EOK;
}
/* receive file data,continously, no ack */
static rt_err_t zrec_file_data(rt_uint8_t *buf, struct zfile *zf)
{
rt_err_t res = -RT_ERROR;
more_data:
res = zget_data(buf,RX_BUFFER_SIZE);
switch(res)
{
case GOTCRCW: /* zack received */
zwrite_file(buf,Rxcount,zf);
zf->bytes_received += Rxcount;
zput_pos(zf->bytes_received);
zsend_line(XON);
zsend_hex_header(ZACK, tx_header);
return RT_EOK;
case GOTCRCQ:
zwrite_file(buf,Rxcount,zf);
zf->bytes_received += Rxcount;
zput_pos(zf->bytes_received);
zsend_hex_header(ZACK, tx_header);
goto more_data;
case GOTCRCG:
zwrite_file(buf,Rxcount,zf);
zf->bytes_received += Rxcount;
goto more_data;
case GOTCRCE:
zwrite_file(buf,Rxcount,zf);
zf->bytes_received += Rxcount;
return RT_EOK;
case GOTCAN:
#ifdef ZDEBUG
rt_kprintf("error code : ZCAN \r\n");
#endif
return res;
case TIMEOUT:
return res;
case -RT_ERROR:
zsend_break(Attn);
return res;
default:
return res;
}
}
/* write file */
static rt_err_t zwrite_file(rt_uint8_t *buf,rt_uint16_t size, struct zfile *zf)
{
return (write(zf->fd,buf,size));
}
/* ack bibi */
static void zrec_ack_bibi(void)
{
rt_uint8_t i;
zput_pos(0L);
for (i=0;i<3;i++)
{
zsend_hex_header(ZFIN, tx_header);
switch (zread_line(100))
{
case 'O':
zread_line(1);
return;
case RCDO:
return;
case TIMEOUT:
default:
break;
}
}
}
/* end of rz.c */
/*
* File : sz.c
* the implemention of sending files to the remote computers
* File : sz.c
* the implemention of sending files to the remote computers
* through the zmodem protocol.
* Change Logs:
* Date Author Notes
* 2011-03-29 itspy
*/
#include <rtthread.h>
#include <finsh.h>
#include <shell.h>
#include <rtdef.h>
#include <dfs.h>
#include <dfs_file.h>
#include <dfs_posix.h>
#include "zdef.h"
static rt_uint8_t TX_BUFFER[TX_BUFFER_SIZE]; /* sender buffer */
static rt_uint8_t file_cnt = 0; /* count of number of files opened */
static rt_uint8_t Rxflags = 0; /* rx parameter flags */
static rt_uint8_t ZF2_OP; /* file transfer option */
void zs_start(char *path);
static void zsend_init(void);
static rt_err_t zsend_files(struct zfile *zf);
static rt_err_t zsend_file(struct zfile *zf, rt_uint8_t *buf, rt_uint16_t len);
static rt_err_t zsend_file_data(struct zfile *zf);
static rt_uint16_t zfill_buffer(struct zfile *zf, rt_uint8_t *buf, rt_uint16_t size);
static rt_err_t zget_sync(void);
static void zsay_bibi(void);
/* start zmodem send process */
void zs_start(char *path)
{
struct zfile *zf;
rt_err_t res = RT_ERROR;
char *p,*q;
zf = rt_malloc(sizeof(struct zfile));
if (zf == RT_NULL)
{
rt_kprintf("zf: out of memory\r\n");
return;
}
rt_kprintf("\r\nsz: ready...\r\n"); /* here ready to send things */
memset(zf, 0, sizeof(struct zfile));
zf->fname = path;
zf->fd = -1;
res = zsend_files(zf);
p = zf->fname;
for (;;)
{
q = strstr(p,"/");
if (q == RT_NULL) break;
p = q+1;
}
if (res == RT_EOK)
{
rt_kprintf("\r\nfile: %s \r\nsize: %ld bytes\r\nsend completed.\r\n",
p,zf->bytes_received);
}
else
{
rt_kprintf("\r\nfile: %s \r\nsize: 0 bytes\r\nsend failed.\r\n",p);
}
rt_free(zf);
return;
}
/* init the parameters */
static void zsend_init(void)
{
rt_err_t res = -RT_ERROR;
zinit_parameter();
for(;;) /* wait ZPAD */
{
res = zread_line(800);
if (res == ZPAD) break;
}
for (;;)
{
res = zget_header(rx_header);
if (res == ZRINIT) break;
}
if ((rx_header[ZF1] & ZRQNVH))
{
zput_pos(0x80L); /* Show we can var header */
zsend_hex_header(ZRQINIT, tx_header);
}
Rxflags = rx_header[ZF0] & 0377;
if (Rxflags & CANFC32) Txfcs32 = 1; /* used 32bits CRC check */
if (ZF2_OP == ZTRLE && (Rxflags & CANRLE)) /* for RLE packet */
Txfcs32 = 2;
else
ZF2_OP = 0;
/* send SINIT cmd */
return;
}
/* send files */
static rt_err_t zsend_files(struct zfile *zf)
{
char *p,*q;
char *str = "/";
struct stat finfo;
rt_err_t res = -RT_ERROR;
if (zf->fname == RT_NULL)
{
rt_kprintf("\r\nerror: no file to be send.\r\n");
return res;
}
if ((zf->fd=open(zf->fname, DFS_O_RDONLY,0)) <0)
{
rt_kprintf("\r\ncan not open file:%s\r\n",zf->fname+1);
return res;
}
zf->file_end = 0;
++file_cnt;
/* extract file name */
p = zf->fname;
for (;;)
{
q = strstr(p,str);
if (q == RT_NULL) break;
p = q+1;
}
q = (char*)TX_BUFFER;
for (;;)
{
*q++ = *p++;
if (*p == 0) break;
}
*q++ = 0;
p=q;
while (q < (char*)(TX_BUFFER + 1024))
*q++ = 0;
/* get file attributes */
fstat(zf->fd,&finfo);
Left_sizes += finfo.st_size;
rt_sprintf(p, "%lu %lo %o 3 %d %ld", (long)finfo.st_size, finfo.st_mtime,
finfo.st_mode, file_cnt, Left_sizes);
Left_sizes -= finfo.st_size;
TX_BUFFER[127] = (finfo.st_size + 127) >>7;
TX_BUFFER[126] = (finfo.st_size + 127) >>15;
zsend_init();
/* start sending files */
res = zsend_file(zf,TX_BUFFER, (p-(char*)TX_BUFFER)+strlen(p)+1);
zsay_bibi();
close(zf->fd);
return res;
}
/* send file name and related info */
static rt_err_t zsend_file(struct zfile *zf, rt_uint8_t *buf, rt_uint16_t len)
{
rt_uint8_t cnt;
rt_err_t res = -RT_ERROR;
for (cnt=0;cnt<5;cnt++)
{
tx_header[ZF0] = ZF0_CMD; /* file conversion option */
tx_header[ZF1] = ZF1_CMD; /* file management option */
tx_header[ZF2] = (ZF3_CMD|ZF2_OP); /* file transfer option */
tx_header[ZF3] = ZF3_CMD;
zsend_bin_header(ZFILE, tx_header);
zsend_bin_data(buf, len, ZCRCW);
loop:
res = zget_header(rx_header);
switch (res)
{
case ZRINIT:
while ((res = zread_line(50)) > 0)
{
if (res == ZPAD)
{
goto loop;
}
}
break;
case ZCAN:
case TIMEOUT:
case ZABORT:
case ZFIN:
break;
case -RT_ERROR:
case ZNAK:
break;
case ZCRC: /* no CRC request */
goto loop;
case ZFERR:
case ZSKIP:
break;
case ZRPOS: /* here we want */
zget_pos(Rxpos);
Txpos = Rxpos;
return(zsend_file_data(zf));
default:
break;
}
}
return res;
}
/* send the file data */
static rt_err_t zsend_file_data(struct zfile *zf)
{
rt_int16_t cnt;
rt_uint8_t cmd;
rt_err_t res = -RT_ERROR;
/* send ZDATA packet, start to send data */
start_send:
zput_pos(Txpos);
zsend_bin_header(ZDATA, tx_header);
do
{
cnt = zfill_buffer(zf,TX_BUFFER,RX_BUFFER_SIZE);
if (cnt < RX_BUFFER_SIZE )
cmd = ZCRCE;
else
cmd = ZCRCG;
zsend_bin_data(TX_BUFFER, cnt, cmd);
zf->bytes_received= Txpos += cnt;
if (cmd == ZCRCW)
goto get_syn1;
} while (cnt == RX_BUFFER_SIZE);
for (;;) /* get ack and check if send finish */
{
zput_pos(Txpos);
zsend_bin_header(ZEOF, tx_header);
get_syn1:
res = zget_sync();
switch (res)
{
case ZACK:
goto get_syn1;
case ZNAK:
continue;
case ZRPOS: /* resend here */
lseek(zf->fd,Txpos,0);
goto start_send;
case ZRINIT: /* send finish,then begin to send next file */
return RT_EOK;
case ZSKIP:
case -RT_ERROR:
return res;
default:
return res;
}
}
}
/* fill file data to buffer*/
static rt_uint16_t zfill_buffer(struct zfile *zf, rt_uint8_t *buf, rt_uint16_t size)
{
return (read(zf->fd,buf,size));
}
/* wait sync(ack) from the receiver */
static rt_err_t zget_sync(void)
{
rt_err_t res = -RT_ERROR;
for (;;)
{
res = zget_header(rx_header);
switch (res)
{
case ZCAN:
case ZABORT:
case ZFIN:
case TIMEOUT:
return -RT_ERROR;
case ZRPOS: /* get pos, need to resend */
zget_pos(Rxpos);
Txpos = Rxpos;
return res;
case ZACK:
return res;
case ZRINIT: /* get ZRINIT indicate that the prev file send completed */
return res;
case ZSKIP:
return res;
case -RT_ERROR:
default:
zsend_bin_header(ZNAK, tx_header);
continue;
}
}
}
/* say "bibi" to the receiver */
static void zsay_bibi(void)
{
for (;;)
{
zput_pos(0L); /* reninit position of next file*/
zsend_hex_header(ZFIN, tx_header); /* send finished session cmd */
switch (zget_header(rx_header))
{
case ZFIN:
zsend_line('O');
zsend_line('O');
case ZCAN:
case TIMEOUT:
return;
}
}
}
/* end of sz.c */
*/
#include <rtthread.h>
#include <finsh.h>
#include <shell.h>
#include <rtdef.h>
#include <dfs.h>
#include <dfs_file.h>
#include <dfs_posix.h>
#include "zdef.h"
static rt_uint8_t TX_BUFFER[TX_BUFFER_SIZE]; /* sender buffer */
static rt_uint8_t file_cnt = 0; /* count of number of files opened */
static rt_uint8_t Rxflags = 0; /* rx parameter flags */
static rt_uint8_t ZF2_OP; /* file transfer option */
void zs_start(char *path);
static void zsend_init(void);
static rt_err_t zsend_files(struct zfile *zf);
static rt_err_t zsend_file(struct zfile *zf, rt_uint8_t *buf, rt_uint16_t len);
static rt_err_t zsend_file_data(struct zfile *zf);
static rt_uint16_t zfill_buffer(struct zfile *zf, rt_uint8_t *buf, rt_uint16_t size);
static rt_err_t zget_sync(void);
static void zsay_bibi(void);
/* start zmodem send process */
void zs_start(char *path)
{
struct zfile *zf;
rt_err_t res = RT_ERROR;
char *p,*q;
zf = rt_malloc(sizeof(struct zfile));
if (zf == RT_NULL)
{
rt_kprintf("zf: out of memory\r\n");
return;
}
rt_kprintf("\r\nsz: ready...\r\n"); /* here ready to send things */
memset(zf, 0, sizeof(struct zfile));
zf->fname = path;
zf->fd = -1;
res = zsend_files(zf);
p = zf->fname;
for (;;)
{
q = strstr(p,"/");
if (q == RT_NULL) break;
p = q+1;
}
if (res == RT_EOK)
{
rt_kprintf("\r\nfile: %s \r\nsize: %ld bytes\r\nsend completed.\r\n",
p,zf->bytes_received);
}
else
{
rt_kprintf("\r\nfile: %s \r\nsize: 0 bytes\r\nsend failed.\r\n",p);
}
rt_free(zf);
return;
}
/* init the parameters */
static void zsend_init(void)
{
rt_err_t res = -RT_ERROR;
zinit_parameter();
for(;;) /* wait ZPAD */
{
res = zread_line(800);
if (res == ZPAD) break;
}
for (;;)
{
res = zget_header(rx_header);
if (res == ZRINIT) break;
}
if ((rx_header[ZF1] & ZRQNVH))
{
zput_pos(0x80L); /* Show we can var header */
zsend_hex_header(ZRQINIT, tx_header);
}
Rxflags = rx_header[ZF0] & 0377;
if (Rxflags & CANFC32) Txfcs32 = 1; /* used 32bits CRC check */
if (ZF2_OP == ZTRLE && (Rxflags & CANRLE)) /* for RLE packet */
Txfcs32 = 2;
else
ZF2_OP = 0;
/* send SINIT cmd */
return;
}
/* send files */
static rt_err_t zsend_files(struct zfile *zf)
{
char *p,*q;
char *str = "/";
struct stat finfo;
rt_err_t res = -RT_ERROR;
if (zf->fname == RT_NULL)
{
rt_kprintf("\r\nerror: no file to be send.\r\n");
return res;
}
if ((zf->fd=open(zf->fname, DFS_O_RDONLY,0)) <0)
{
rt_kprintf("\r\ncan not open file:%s\r\n",zf->fname+1);
return res;
}
zf->file_end = 0;
++file_cnt;
/* extract file name */
p = zf->fname;
for (;;)
{
q = strstr(p,str);
if (q == RT_NULL) break;
p = q+1;
}
q = (char*)TX_BUFFER;
for (;;)
{
*q++ = *p++;
if (*p == 0) break;
}
*q++ = 0;
p=q;
while (q < (char*)(TX_BUFFER + 1024))
*q++ = 0;
/* get file attributes */
fstat(zf->fd,&finfo);
Left_sizes += finfo.st_size;
rt_sprintf(p, "%lu %lo %o 3 %d %ld", (long)finfo.st_size, finfo.st_mtime,
finfo.st_mode, file_cnt, Left_sizes);
Left_sizes -= finfo.st_size;
TX_BUFFER[127] = (finfo.st_size + 127) >>7;
TX_BUFFER[126] = (finfo.st_size + 127) >>15;
zsend_init();
/* start sending files */
res = zsend_file(zf,TX_BUFFER, (p-(char*)TX_BUFFER)+strlen(p)+1);
zsay_bibi();
close(zf->fd);
return res;
}
/* send file name and related info */
static rt_err_t zsend_file(struct zfile *zf, rt_uint8_t *buf, rt_uint16_t len)
{
rt_uint8_t cnt;
rt_err_t res = -RT_ERROR;
for (cnt=0;cnt<5;cnt++)
{
tx_header[ZF0] = ZF0_CMD; /* file conversion option */
tx_header[ZF1] = ZF1_CMD; /* file management option */
tx_header[ZF2] = (ZF3_CMD|ZF2_OP); /* file transfer option */
tx_header[ZF3] = ZF3_CMD;
zsend_bin_header(ZFILE, tx_header);
zsend_bin_data(buf, len, ZCRCW);
loop:
res = zget_header(rx_header);
switch (res)
{
case ZRINIT:
while ((res = zread_line(50)) > 0)
{
if (res == ZPAD)
{
goto loop;
}
}
break;
case ZCAN:
case TIMEOUT:
case ZABORT:
case ZFIN:
break;
case -RT_ERROR:
case ZNAK:
break;
case ZCRC: /* no CRC request */
goto loop;
case ZFERR:
case ZSKIP:
break;
case ZRPOS: /* here we want */
zget_pos(Rxpos);
Txpos = Rxpos;
return(zsend_file_data(zf));
default:
break;
}
}
return res;
}
/* send the file data */
static rt_err_t zsend_file_data(struct zfile *zf)
{
rt_int16_t cnt;
rt_uint8_t cmd;
rt_err_t res = -RT_ERROR;
/* send ZDATA packet, start to send data */
start_send:
zput_pos(Txpos);
zsend_bin_header(ZDATA, tx_header);
do
{
cnt = zfill_buffer(zf,TX_BUFFER,RX_BUFFER_SIZE);
if (cnt < RX_BUFFER_SIZE )
cmd = ZCRCE;
else
cmd = ZCRCG;
zsend_bin_data(TX_BUFFER, cnt, cmd);
zf->bytes_received= Txpos += cnt;
if (cmd == ZCRCW)
goto get_syn1;
} while (cnt == RX_BUFFER_SIZE);
for (;;) /* get ack and check if send finish */
{
zput_pos(Txpos);
zsend_bin_header(ZEOF, tx_header);
get_syn1:
res = zget_sync();
switch (res)
{
case ZACK:
goto get_syn1;
case ZNAK:
continue;
case ZRPOS: /* resend here */
lseek(zf->fd,Txpos,0);
goto start_send;
case ZRINIT: /* send finish,then begin to send next file */
return RT_EOK;
case ZSKIP:
case -RT_ERROR:
return res;
default:
return res;
}
}
}
/* fill file data to buffer*/
static rt_uint16_t zfill_buffer(struct zfile *zf, rt_uint8_t *buf, rt_uint16_t size)
{
return (read(zf->fd,buf,size));
}
/* wait sync(ack) from the receiver */
static rt_err_t zget_sync(void)
{
rt_err_t res = -RT_ERROR;
for (;;)
{
res = zget_header(rx_header);
switch (res)
{
case ZCAN:
case ZABORT:
case ZFIN:
case TIMEOUT:
return -RT_ERROR;
case ZRPOS: /* get pos, need to resend */
zget_pos(Rxpos);
Txpos = Rxpos;
return res;
case ZACK:
return res;
case ZRINIT: /* get ZRINIT indicate that the prev file send completed */
return res;
case ZSKIP:
return res;
case -RT_ERROR:
default:
zsend_bin_header(ZNAK, tx_header);
continue;
}
}
}
/* say "bibi" to the receiver */
static void zsay_bibi(void)
{
for (;;)
{
zput_pos(0L); /* reninit position of next file*/
zsend_hex_header(ZFIN, tx_header); /* send finished session cmd */
switch (zget_header(rx_header))
{
case ZFIN:
zsend_line('O');
zsend_line('O');
case ZCAN:
case TIMEOUT:
return;
}
}
}
/* end of sz.c */
此差异已折叠。
#ifndef __ZDEF_H__
#define __ZDEF_H__
#include <rtthread.h>
#ifndef __ZDEF_H__
#define __ZDEF_H__
#include <rtthread.h>
#include "crc.h"
#define ZPAD '*' /* 052 padding character begins frames */
#define ZDLE 030 /* ctrl-X ZMODEM escape - `ala BISYNC DLE */
......@@ -121,7 +121,7 @@ extern char Attn[ZATTNLEN+1]; /* Attention string rx sends to tx on err */
/* globals used by ZMODEM functions */
extern rt_uint8_t Rxframeind; /* ZBIN ZBIN32, or ZHEX type of frame */
extern char header_type; /* type of header received */
extern char header_type; /* type of header received */
extern rt_uint8_t rx_header[4]; /* received header */
extern rt_uint8_t tx_header[4]; /* transmitted header */
extern rt_uint8_t Txfcs32; /* TRUE means send binary frames with 32 bit FCS */
......@@ -129,18 +129,18 @@ extern rt_uint16_t Rxcount; /* count of data bytes received */
extern rt_uint16_t Rxtimeout; /* tenths of seconds to wait for something */
extern rt_uint32_t Rxpos; /* received file position */
extern rt_uint32_t Txpos; /* transmitted file position */
extern rt_uint8_t Txfcs32; /* TURE means send binary frames with 32 bit FCS */
extern rt_uint8_t Txfcs32; /* TURE means send binary frames with 32 bit FCS */
/* ward Christensen / CP/M parameters - Don't change these! */
#define ENQ 005
#define CAN ('X'&037)
#define XOFF ('s'&037)
#define XON ('q'&037)
#define SOH 1
#define STX 2
#define ETX 3
#define SYN 026
#define ESC 033
#define STX 2
#define ETX 3
#define SYN 026
#define ESC 033
#define WANTG 0107 /* send G not NAK to get nonstop batch xmsn */
#define EOT 4
#define ACK 6
......@@ -154,64 +154,64 @@ extern rt_uint8_t Txfcs32; /* TURE means send binary frames with 32 bit
#define RETRYMAX 5
#define WCEOT (-10)
#define BITRATE 115200
#define TX_BUFFER_SIZE 1024
#define RX_BUFFER_SIZE 1024 /* sender or receiver's max buffer size */
#define BITRATE 115200
#define TX_BUFFER_SIZE 1024
#define RX_BUFFER_SIZE 1024 /* sender or receiver's max buffer size */
extern char ZF0_CMD; /* local ZMODEM file conversion request */
extern char ZF1_CMD; /* local ZMODEM file management request */
extern char ZF2_CMD; /* local ZMODEM file management request */
extern char ZF3_CMD; /* local ZMODEM file management request */
extern rt_uint32_t Baudrate ;
extern rt_uint32_t Left_bytes;
extern rt_uint32_t Left_sizes;
struct zmodemf
{
struct rt_semaphore zsem;
rt_device_t device;
};
extern struct zmodemf zmodem;
struct zfile
{
char *fname;
extern char ZF1_CMD; /* local ZMODEM file management request */
extern char ZF2_CMD; /* local ZMODEM file management request */
extern char ZF3_CMD; /* local ZMODEM file management request */
extern rt_uint32_t Baudrate ;
extern rt_uint32_t Left_bytes;
extern rt_uint32_t Left_sizes;
struct zmodemf
{
struct rt_semaphore zsem;
rt_device_t device;
};
extern struct zmodemf zmodem;
struct zfile
{
char *fname;
rt_int32_t fd;
rt_uint32_t ctime;
rt_uint32_t ctime;
rt_uint32_t mode;
rt_uint32_t bytes_total;
rt_uint32_t bytes_sent;
rt_uint32_t bytes_received;
rt_uint32_t file_end;
};
extern struct finsh_shell* shell;
#define ZDEBUG 0
/* sz.c */
extern void zs_start(char *path);
/* rz.c */
extern void zr_start(char *path);
/* zcore.c */
extern void zinit_parameter(void);
extern rt_int16_t zget_header(rt_uint8_t *hdr);
extern void zsend_bin_header(rt_uint8_t type, rt_uint8_t *hdr);
extern void zsend_hex_header(rt_uint8_t type, rt_uint8_t *hdr);
extern rt_int16_t zget_data(rt_uint8_t *buf, rt_uint16_t len);
extern void zsend_bin_data(rt_uint8_t *buf, rt_int16_t len, rt_uint8_t frameend);
extern void zput_pos(rt_uint32_t pos);
extern void zget_pos(rt_uint32_t pos);
/* zdevice.c */
extern rt_uint32_t get_device_baud(void);
extern void zsend_byte(rt_uint16_t c);
extern void zsend_line(rt_uint16_t c);
extern rt_int16_t zread_line(rt_uint16_t timeout);
extern void zsend_break(char *cmd);
rt_uint32_t file_end;
};
extern struct finsh_shell* shell;
#define ZDEBUG 0
/* sz.c */
extern void zs_start(char *path);
/* rz.c */
extern void zr_start(char *path);
/* zcore.c */
extern void zinit_parameter(void);
extern rt_int16_t zget_header(rt_uint8_t *hdr);
extern void zsend_bin_header(rt_uint8_t type, rt_uint8_t *hdr);
extern void zsend_hex_header(rt_uint8_t type, rt_uint8_t *hdr);
extern rt_int16_t zget_data(rt_uint8_t *buf, rt_uint16_t len);
extern void zsend_bin_data(rt_uint8_t *buf, rt_int16_t len, rt_uint8_t frameend);
extern void zput_pos(rt_uint32_t pos);
extern void zget_pos(rt_uint32_t pos);
/* zdevice.c */
extern rt_uint32_t get_device_baud(void);
extern void zsend_byte(rt_uint16_t c);
extern void zsend_line(rt_uint16_t c);
extern rt_int16_t zread_line(rt_uint16_t timeout);
extern void zsend_break(char *cmd);
extern void zsend_can(void);
#endif /* __ZDEF_H__ */
/*
* File : zdevice.c
* File : zdevice.c
* the implemention of zmodem protocol.
* Change Logs:
* Date Author Notes
* 2011-03-29 itspy
*/
#include <rtthread.h>
#include <finsh.h>
#include <shell.h>
#include <rtdef.h>
#include <dfs.h>
#include <dfs_file.h>
#include <dfs_posix.h>
#include "zdef.h"
*/
#include <rtthread.h>
#include <finsh.h>
#include <shell.h>
#include <rtdef.h>
#include <dfs.h>
#include <dfs_file.h>
#include <dfs_posix.h>
#include "zdef.h"
rt_uint32_t Line_left = 0; /* left number of data in the read line buffer*/
rt_uint32_t Left_sizes = 0; /* left file sizes */
rt_uint32_t Line_left = 0; /* left number of data in the read line buffer*/
rt_uint32_t Left_sizes = 0; /* left file sizes */
rt_uint32_t Baudrate = BITRATE; /* console baudrate */
rt_uint32_t get_device_baud(void)
{
return(Baudrate);
}
rt_uint32_t get_sys_time(void)
{
return(0L);
}
void zsend_byte(rt_uint16_t ch)
{
rt_device_write(zmodem.device, 0, &ch,1);
return;
}
void zsend_line(rt_uint16_t c)
{
rt_uint16_t ch;
ch = (c & 0377);
rt_device_write(zmodem.device, 0, &ch, 1);
return;
}
rt_uint32_t get_device_baud(void)
{
return(Baudrate);
}
rt_uint32_t get_sys_time(void)
{
return(0L);
}
void zsend_byte(rt_uint16_t ch)
{
rt_device_write(zmodem.device, 0, &ch,1);
return;
}
void zsend_line(rt_uint16_t c)
{
rt_uint16_t ch;
ch = (c & 0377);
rt_device_write(zmodem.device, 0, &ch, 1);
return;
}
rt_int16_t zread_line(rt_uint16_t timeout)
{
char *str;
static char buf[10];
if (Line_left > 0)
{
Line_left -= 1;
return (*str++ & 0377);
}
Line_left = 0;
timeout/=5;
while (1)
{
Line_left = rt_device_read(shell->device, 0, buf, 1);
if (Line_left)
{
Line_left = Line_left;
str = buf;
break;
}
}
if (Line_left < 1) return TIMEOUT;
Line_left -=1;
char *str;
static char buf[10];
if (Line_left > 0)
{
Line_left -= 1;
return (*str++ & 0377);
}
Line_left = 0;
timeout/=5;
while (1)
{
Line_left = rt_device_read(shell->device, 0, buf, 1);
if (Line_left)
{
Line_left = Line_left;
str = buf;
break;
}
}
if (Line_left < 1) return TIMEOUT;
Line_left -=1;
return (*str++ & 0377);
}
......@@ -82,33 +82,33 @@ rt_int16_t zread_line(rt_uint16_t timeout)
* and \335 (break signal)
*/
void zsend_break(char *cmd)
{
{
while (*cmd++)
while (*cmd++)
{
switch (*cmd)
switch (*cmd)
{
case '\336':
case '\336':
continue;
case '\335':
rt_thread_delay(RT_TICK_PER_SECOND);
case '\335':
rt_thread_delay(RT_TICK_PER_SECOND);
continue;
default:
zsend_line(*cmd);
zsend_line(*cmd);
break;
}
}
}
}
/* send cancel string to get the other end to shut up */
void zsend_can(void)
{
static char cmd[] = {24,24,24,24,24,24,24,24,24,24,0};
static char cmd[] = {24,24,24,24,24,24,24,24,24,24,0};
zsend_break(cmd);
zsend_break(cmd);
rt_kprintf("\x0d");
Line_left=0; /* clear Line_left */
Line_left=0; /* clear Line_left */
return;
}
}
/* end of zdevice.c */
/*
* File : zstart.c
* File : zstart.c
* the implemention of zmodem protocol.
* Change Logs:
* Date Author Notes
* 2011-03-29 itspy
*/
#include <rtthread.h>
#include <finsh.h>
#include <shell.h>
#include <dfs.h>
#include <dfs_file.h>
#include "zdef.h"
struct zmodemf zmodem;
rt_err_t zmodem_rx_ind(rt_device_t dev, rt_size_t size)
{
/* release semaphore */
rt_sem_release(&zmodem.zsem);
return RT_EOK;
}
void finsh_rz(void *parameter)
{
char *path;
rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
rt_uint8_t flag;
flag = RT_DEVICE_FLAG_STREAM;
zmodem.device->flag &=(~flag);
rt_sem_init(&(zmodem.zsem), "zsem", 0, 0);
path = rt_thread_self()->parameter;
/* save old rx_indicate */
rx_indicate = zmodem.device->rx_indicate;
/* set new rx_indicate */
rt_device_set_rx_indicate(zmodem.device, RT_NULL);
/* start receive remote files */
zr_start(path);
zmodem.device->flag |=flag;
/* recovery old rx_indicate */
rt_device_set_rx_indicate(zmodem.device, rx_indicate);
/* finsh>> */
rt_kprintf(FINSH_PROMPT);
}
void finsh_sz(void *parameter)
{
char *path;
rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
rt_uint8_t flag;
flag = RT_DEVICE_FLAG_STREAM;
zmodem.device->flag &=(~flag);
rt_sem_init(&(zmodem.zsem), "zsem", 0, 0);
path = rt_thread_self()->parameter;
/* save old rx_indicate */
rx_indicate = zmodem.device->rx_indicate;
/* set new rx_indicate */
rt_device_set_rx_indicate(zmodem.device, zmodem_rx_ind);
zs_start(path);
zmodem.device->flag |=flag;
/* recovery old rx_indicate */
rt_device_set_rx_indicate(zmodem.device, rx_indicate);
/* finsh>> */
rt_kprintf(FINSH_PROMPT);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
#include <shell.h>
static void rz(char *para)
{
rt_thread_t init_thread;
rt_device_t device;
const char* device_name = finsh_get_device();
device = rt_device_find(device_name);
if( device == RT_NULL )
{
rt_kprintf("%s not find\r\n",device_name);
}
zmodem.device = device;
init_thread = rt_thread_create("rz",
finsh_rz,
(void*)para,
2048,
rt_thread_self()->current_priority+1,
20);
if (init_thread != RT_NULL) rt_thread_startup(init_thread);
}
FINSH_FUNCTION_EXPORT(rz, receive files by zmodem protocol)
static void sz(char *para)
{
rt_thread_t init_thread;
rt_device_t device;
const char* device_name = finsh_get_device();
device = rt_device_find(device_name);
if( device == RT_NULL )
{
rt_kprintf("%s not find\r\n",device_name);
}
zmodem.device = device;
init_thread = rt_thread_create("sz",
finsh_sz,
(void*)para,
2048,
rt_thread_self()->current_priority+1,
20);
if (init_thread != RT_NULL) rt_thread_startup(init_thread);
}
FINSH_FUNCTION_EXPORT(sz, send files by zmodem protocol)
#endif
*/
#include <rtthread.h>
#include <finsh.h>
#include <shell.h>
#include <dfs.h>
#include <dfs_file.h>
#include "zdef.h"
struct zmodemf zmodem;
rt_err_t zmodem_rx_ind(rt_device_t dev, rt_size_t size)
{
/* release semaphore */
rt_sem_release(&zmodem.zsem);
return RT_EOK;
}
void finsh_rz(void *parameter)
{
char *path;
rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
rt_uint8_t flag;
flag = RT_DEVICE_FLAG_STREAM;
zmodem.device->flag &=(~flag);
rt_sem_init(&(zmodem.zsem), "zsem", 0, 0);
path = rt_thread_self()->parameter;
/* save old rx_indicate */
rx_indicate = zmodem.device->rx_indicate;
/* set new rx_indicate */
rt_device_set_rx_indicate(zmodem.device, RT_NULL);
/* start receive remote files */
zr_start(path);
zmodem.device->flag |=flag;
/* recovery old rx_indicate */
rt_device_set_rx_indicate(zmodem.device, rx_indicate);
/* finsh>> */
rt_kprintf(FINSH_PROMPT);
}
void finsh_sz(void *parameter)
{
char *path;
rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
rt_uint8_t flag;
flag = RT_DEVICE_FLAG_STREAM;
zmodem.device->flag &=(~flag);
rt_sem_init(&(zmodem.zsem), "zsem", 0, 0);
path = rt_thread_self()->parameter;
/* save old rx_indicate */
rx_indicate = zmodem.device->rx_indicate;
/* set new rx_indicate */
rt_device_set_rx_indicate(zmodem.device, zmodem_rx_ind);
zs_start(path);
zmodem.device->flag |=flag;
/* recovery old rx_indicate */
rt_device_set_rx_indicate(zmodem.device, rx_indicate);
/* finsh>> */
rt_kprintf(FINSH_PROMPT);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
#include <shell.h>
static void rz(char *para)
{
rt_thread_t init_thread;
rt_device_t device;
const char* device_name = finsh_get_device();
device = rt_device_find(device_name);
if( device == RT_NULL )
{
rt_kprintf("%s not find\r\n",device_name);
}
zmodem.device = device;
init_thread = rt_thread_create("rz",
finsh_rz,
(void*)para,
2048,
rt_thread_self()->current_priority+1,
20);
if (init_thread != RT_NULL) rt_thread_startup(init_thread);
}
FINSH_FUNCTION_EXPORT(rz, receive files by zmodem protocol)
static void sz(char *para)
{
rt_thread_t init_thread;
rt_device_t device;
const char* device_name = finsh_get_device();
device = rt_device_find(device_name);
if( device == RT_NULL )
{
rt_kprintf("%s not find\r\n",device_name);
}
zmodem.device = device;
init_thread = rt_thread_create("sz",
finsh_sz,
(void*)para,
2048,
rt_thread_self()->current_priority+1,
20);
if (init_thread != RT_NULL) rt_thread_startup(init_thread);
}
FINSH_FUNCTION_EXPORT(sz, send files by zmodem protocol)
#endif
RT-Thread Coding Style
This is an developing instruction for RT-Thread developers. As an open source
software, RT-Thread is done by the cooperation of different people. This
document is a guide for RT-Thread developers and please obey it if you are.
RT-Thread users could also get to know some conventions in the code through it
and thus easier to understand the implementations of RT-Thread.
1. Directory Naming
In normal conditions, please name directories in lower-case. Directories should
have descriptive names. For example, the port of a chip should be composed of
the name of the chip and the category of the chip. Directories under components/
should stand for what the component does.
2. File Naming
In normal conditions, please name files in lower-case. If the file is
referencing other places, it can have the original name. To avoid naming
collision, do not use general names or the names that are frequently used.
3. Header Files
To avoid include the same header file for multiple times, you need to define a
symbol like this:
#ifndef __FILE_H__
#define __FILE_H__
/* header file content */
#endif
The symbol should begin and end with "__" to avoid naming collision. The words
of the file name should be connected by "_".
4. Header File Comments
In every header file, there should be copyright information and Change Log
record like this:
/*
* File : rtthread.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE.
*
* Change Logs:
* Date Author Notes
* 2006-03-18 Bernard the first version
* 2006-04-26 Bernard add semaphore APIs
* …
*/
5. Structure Defines
Please name structures in lower-case and connect words with "_". For example:
struct rt_list_node
{
struct rt_list_node *next;
struct rt_list_node *prev;
};
Braces should have their own lines and the members should be defines with
indent.
The names of type defines such like structure types should be the structure name
plus "_t". For example:
typedef struct rt_list_node rt_list_t;
In order to be easily referenced, the types of objects in kernel is pointer. For
example:
typedef struct rt_timer* rt_timer_t;
6. Micros
In RT-Thread, please use upper-case names for micro definitions. Words are
connected by "_". Like:
#define RT_TRUE 1
7. Function Naming and Declaration
Please name functions in lower-case and separate words with "_". API provided to
upper application should be declared in header files. If the function don't have
parameters, it should be declared as void:
rt_thread_t rt_thread_self(void);
8. Commenting
Please use English to comment. There shouldn't be too much comments and the
comments should describe what does the code do. And it should describe how the
complicated algorithm works. Comments to statements should be placed before them
or right of them. Anther places are illegal.
9. Indent
Please use TAB or 4 spaces to indent. It's preferred to use 4 spaces. If no
other special meanings, the indent should begin right after "{":
if (condition)
{
/* others */
}
The only one exception is switch. In switch-case statements, "case" should be
aligned with "switch":
switch (value)
{
case value1:
break;
}
"case" is aligned with "switch", the following code block should be indented.
10. Braces and Spaces
For ease of reading, it is advised that braces should occupy the whole line
instead of following other statements. Like:
if (condition)
{
/* others */
}
When matching braces have their own lines, the reader would identify the code
blocks easily.
There should be a space before parentheses when it's not a function call. For
example:
if (x <= y)
{
/* others */
}
for (index = 0; index < MAX_NUMBER; index ++)
{
/* others */
}
In expressions, there should be a space between most binary and ternary
operators and the strings. No spaces around(inside) parentheses, like:
if ( x <= y )
{
/* other */
}
This is a bad practice.
11. trace, log Informations
In RT-Thread, rt_kprintf is a commonly used logging routine. In RT-Thread
rt_kprintf is implemented as a polling, non-interrupting string output. It is
suitable in "instant" situations such as interrupt context. The polling method
would have influence to the timing sequence of the log output.
It is not recommended to use rt_kprintf frequently. Unless you are aware of that
it's not a big deal to run slower.
Logging should be off by default and can be turned on by a switch(e.g. a
variable or a micro). When logging, it should be easy to understand and easy to
determine where the problem is.
12. Functions
Functions in kernel should be K.I.S.S. If the function is too long, you should
split it into smaller ones and make each of them simplified and easy to
understand.
13. Objects
The kernel of RT-Thread uses object-oriented tech in C. The naming convention
is: structure names are the object names, object names + verb phrases are the
method names of objects:
struct rt_timer
{
struct rt_object parent;
/* other fields */
};
typedef struct rt_timer* rt_timer_t;
The definition of structure rt_timer stands for the object definition of timer
object.
rt_timer_t rt_timer_create(const char* name,
void (*timeout)(void* parameter), void* parameter,
rt_tick_t time, rt_uint8_t flag);
rt_err_t rt_timer_delete(rt_timer_t timer);
rt_err_t rt_timer_start(rt_timer_t timer);
rt_err_t rt_timer_stop(rt_timer_t timer);
rt_timer + verb phrase stands for the method that could be used on timer object.
When creating a new object, think twice on memory allocations: whether a static
object could be created or it could only created dynamically on heap.
14. Use astyle to format the code automatically
parameters: --style=allman
--indent=spaces=4
--pad-oper
--pad-header
--unpad-paren
--suffix=none
--align-pointer=name
--lineend=linux
--convert-tabs
--verbose
RT-Thread Coding Style
This is an developing instruction for RT-Thread developers. As an open source
software, RT-Thread is done by the cooperation of different people. This
document is a guide for RT-Thread developers and please obey it if you are.
RT-Thread users could also get to know some conventions in the code through it
and thus easier to understand the implementations of RT-Thread.
1. Directory Naming
In normal conditions, please name directories in lower-case. Directories should
have descriptive names. For example, the port of a chip should be composed of
the name of the chip and the category of the chip. Directories under components/
should stand for what the component does.
2. File Naming
In normal conditions, please name files in lower-case. If the file is
referencing other places, it can have the original name. To avoid naming
collision, do not use general names or the names that are frequently used.
3. Header Files
To avoid include the same header file for multiple times, you need to define a
symbol like this:
#ifndef __FILE_H__
#define __FILE_H__
/* header file content */
#endif
The symbol should begin and end with "__" to avoid naming collision. The words
of the file name should be connected by "_".
4. Header File Comments
In every header file, there should be copyright information and Change Log
record like this:
/*
* File : rtthread.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE.
*
* Change Logs:
* Date Author Notes
* 2006-03-18 Bernard the first version
* 2006-04-26 Bernard add semaphore APIs
* …
*/
5. Structure Defines
Please name structures in lower-case and connect words with "_". For example:
struct rt_list_node
{
struct rt_list_node *next;
struct rt_list_node *prev;
};
Braces should have their own lines and the members should be defines with
indent.
The names of type defines such like structure types should be the structure name
plus "_t". For example:
typedef struct rt_list_node rt_list_t;
In order to be easily referenced, the types of objects in kernel is pointer. For
example:
typedef struct rt_timer* rt_timer_t;
6. Micros
In RT-Thread, please use upper-case names for micro definitions. Words are
connected by "_". Like:
#define RT_TRUE 1
7. Function Naming and Declaration
Please name functions in lower-case and separate words with "_". API provided to
upper application should be declared in header files. If the function don't have
parameters, it should be declared as void:
rt_thread_t rt_thread_self(void);
8. Commenting
Please use English to comment. There shouldn't be too much comments and the
comments should describe what does the code do. And it should describe how the
complicated algorithm works. Comments to statements should be placed before them
or right of them. Anther places are illegal.
9. Indent
Please use TAB or 4 spaces to indent. It's preferred to use 4 spaces. If no
other special meanings, the indent should begin right after "{":
if (condition)
{
/* others */
}
The only one exception is switch. In switch-case statements, "case" should be
aligned with "switch":
switch (value)
{
case value1:
break;
}
"case" is aligned with "switch", the following code block should be indented.
10. Braces and Spaces
For ease of reading, it is advised that braces should occupy the whole line
instead of following other statements. Like:
if (condition)
{
/* others */
}
When matching braces have their own lines, the reader would identify the code
blocks easily.
There should be a space before parentheses when it's not a function call. For
example:
if (x <= y)
{
/* others */
}
for (index = 0; index < MAX_NUMBER; index ++)
{
/* others */
}
In expressions, there should be a space between most binary and ternary
operators and the strings. No spaces around(inside) parentheses, like:
if ( x <= y )
{
/* other */
}
This is a bad practice.
11. trace, log Informations
In RT-Thread, rt_kprintf is a commonly used logging routine. In RT-Thread
rt_kprintf is implemented as a polling, non-interrupting string output. It is
suitable in "instant" situations such as interrupt context. The polling method
would have influence to the timing sequence of the log output.
It is not recommended to use rt_kprintf frequently. Unless you are aware of that
it's not a big deal to run slower.
Logging should be off by default and can be turned on by a switch(e.g. a
variable or a micro). When logging, it should be easy to understand and easy to
determine where the problem is.
12. Functions
Functions in kernel should be K.I.S.S. If the function is too long, you should
split it into smaller ones and make each of them simplified and easy to
understand.
13. Objects
The kernel of RT-Thread uses object-oriented tech in C. The naming convention
is: structure names are the object names, object names + verb phrases are the
method names of objects:
struct rt_timer
{
struct rt_object parent;
/* other fields */
};
typedef struct rt_timer* rt_timer_t;
The definition of structure rt_timer stands for the object definition of timer
object.
rt_timer_t rt_timer_create(const char* name,
void (*timeout)(void* parameter), void* parameter,
rt_tick_t time, rt_uint8_t flag);
rt_err_t rt_timer_delete(rt_timer_t timer);
rt_err_t rt_timer_start(rt_timer_t timer);
rt_err_t rt_timer_stop(rt_timer_t timer);
rt_timer + verb phrase stands for the method that could be used on timer object.
When creating a new object, think twice on memory allocations: whether a static
object could be created or it could only created dynamically on heap.
14. Use astyle to format the code automatically
parameters: --style=allman
--indent=spaces=4
--pad-oper
--pad-header
--unpad-paren
--suffix=none
--align-pointer=name
--lineend=linux
--convert-tabs
--verbose
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup BasicDef Basic Definitions
*
* @brief Basic data type in RT-Thread RTOS.
*
* These are the basic definitions which used in RT-Thread RTOS. In general,
* RT-Thread kernel uses its own definition of the basic data types, such as
* rt_uint32_t, rt_uint8_t, etc., which does not depend on the compiler or
* architecture.
*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup BasicDef Basic Definitions
*
* @brief Basic data type in RT-Thread RTOS.
*
* These are the basic definitions which used in RT-Thread RTOS. In general,
* RT-Thread kernel uses its own definition of the basic data types, such as
* rt_uint32_t, rt_uint8_t, etc., which does not depend on the compiler or
* architecture.
*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup DFS Device Virtual File System
*
* @brief DFS is a virtual file system in RT-Thread RTOS.
*
* The DFS (Device Virtual File System) is a vfs file system of RT-Thread RTOS,
* which is focused on embedded device. VFS is an abstraction layer on top of a
* more concrete file system. The purpose of a VFS is to allow client applications
* to access different types of concrete file systems in a uniform way.
*
* @image html dfs.png "Figure 4: Device Virtual File System Architecture"
*
* The DFS specifies an interface between the kernel and a concrete file system.
* Therefore, it is easy to add support for new file system types to the kernel
* simply by fulfilling the interface.
*/
/**
* @addtogroup DFS
*/
/*@{*/
/**
* @defgroup Fd File Descriptor
*
*/
/**
* @defgroup FsApi File System API
*/
/**
* @defgroup FileApi File API
*/
/**
* @defgroup FsPosixApi File POSIX API
*/
/*@}*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup DFS Device Virtual File System
*
* @brief DFS is a virtual file system in RT-Thread RTOS.
*
* The DFS (Device Virtual File System) is a vfs file system of RT-Thread RTOS,
* which is focused on embedded device. VFS is an abstraction layer on top of a
* more concrete file system. The purpose of a VFS is to allow client applications
* to access different types of concrete file systems in a uniform way.
*
* @image html dfs.png "Figure 4: Device Virtual File System Architecture"
*
* The DFS specifies an interface between the kernel and a concrete file system.
* Therefore, it is easy to add support for new file system types to the kernel
* simply by fulfilling the interface.
*/
/**
* @addtogroup DFS
*/
/*@{*/
/**
* @defgroup Fd File Descriptor
*
*/
/**
* @defgroup FsApi File System API
*/
/**
* @defgroup FileApi File API
*/
/**
* @defgroup FsPosixApi File POSIX API
*/
/*@}*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup finsh finsh shell
*
* @brief finsh shell is a user command shell in RT-Thread RTOS.
*
* finsh shell is a user command shell in RT-Thread RTOS, which is a shell can
* accept C-expression like syntax in command. From finsh shell, user can access
* system area, such as memory, variables and function by input C-expression in
* command.
*
* @image html finsh.png "Figure 3: finsh shell architecture"
* There is a shell thread, which named as "tshell", in the finsh shell, it read
* user command from console device, and then invokes system function or access
* system variable to output result (by rt_kprintf).
*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup finsh finsh shell
*
* @brief finsh shell is a user command shell in RT-Thread RTOS.
*
* finsh shell is a user command shell in RT-Thread RTOS, which is a shell can
* accept C-expression like syntax in command. From finsh shell, user can access
* system area, such as memory, variables and function by input C-expression in
* command.
*
* @image html finsh.png "Figure 3: finsh shell architecture"
* There is a shell thread, which named as "tshell", in the finsh shell, it read
* user command from console device, and then invokes system function or access
* system variable to output result (by rt_kprintf).
*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup bsp Hardware Related Package
*
* @brief Hardware Related Package includes board support package(BSP) and CSP(Chip
* Support Package).
*
* Board Support Package(BSP) is the hardware related wrapper, for example, peripherals
* in board, the pinmux setting etc. In RT-Thread RTOS, the bsp is placed under bsp
* directory.
*
* Chip Support Package (CSP) is a software set that contains chip specific software.
* A CSP usually includes operating system porting and peripheral device drivers inside
* chip. In RT-Thread RTOS, the csp is placed under libcpu directory.
*/
/**
* @addtogroup bsp
*/
/*@{*/
/**
* This function will return current system interrupt status and disable system
* interrupt.
*
* @return the current system interrupt status
*/
rt_base_t rt_hw_interrupt_disable(void);
/**
* This function will set the specified interrupt status, which shall saved by
* rt_hw_intterrupt_disable function. If the saved interrupt status is interrupt
* opened, this function will open system interrupt status.
*/
void rt_hw_interrupt_enable(rt_base_t level);
/**
* This function initializes interrupt.
*/
void rt_hw_interrupt_init(void);
/**
* This function masks the specified interrupt.
*
* @param vector the interrupt number to be masked.
*
* @note not all of platform provide this function.
*/
void rt_hw_interrupt_mask(int vector);
/**
* This function umasks the specified interrupt.
*
* @param vector the interrupt number to be unmasked.
*
* @note not all of platform provide this function.
*/
void rt_hw_interrupt_umask(int vector);
/**
* This function will install specified interrupt handler.
*
* @param vector the interrupt number to be installed.
* @param new_handler the new interrupt handler.
* @param old_handler the old interrupt handler. This parameter can be RT_NULL.
*
* @note not all of platform provide this function.
*/
void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler,
rt_isr_handler_t *old_handler);
/**
* This function will reset whole platform.
*/
void rt_hw_cpu_reset(void);
/**
* This function will halt whole platform.
*/
void rt_hw_cpu_shutdown(void);
/*@}*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup bsp Hardware Related Package
*
* @brief Hardware Related Package includes board support package(BSP) and CSP(Chip
* Support Package).
*
* Board Support Package(BSP) is the hardware related wrapper, for example, peripherals
* in board, the pinmux setting etc. In RT-Thread RTOS, the bsp is placed under bsp
* directory.
*
* Chip Support Package (CSP) is a software set that contains chip specific software.
* A CSP usually includes operating system porting and peripheral device drivers inside
* chip. In RT-Thread RTOS, the csp is placed under libcpu directory.
*/
/**
* @addtogroup bsp
*/
/*@{*/
/**
* This function will return current system interrupt status and disable system
* interrupt.
*
* @return the current system interrupt status
*/
rt_base_t rt_hw_interrupt_disable(void);
/**
* This function will set the specified interrupt status, which shall saved by
* rt_hw_intterrupt_disable function. If the saved interrupt status is interrupt
* opened, this function will open system interrupt status.
*/
void rt_hw_interrupt_enable(rt_base_t level);
/**
* This function initializes interrupt.
*/
void rt_hw_interrupt_init(void);
/**
* This function masks the specified interrupt.
*
* @param vector the interrupt number to be masked.
*
* @note not all of platform provide this function.
*/
void rt_hw_interrupt_mask(int vector);
/**
* This function umasks the specified interrupt.
*
* @param vector the interrupt number to be unmasked.
*
* @note not all of platform provide this function.
*/
void rt_hw_interrupt_umask(int vector);
/**
* This function will install specified interrupt handler.
*
* @param vector the interrupt number to be installed.
* @param new_handler the new interrupt handler.
* @param old_handler the old interrupt handler. This parameter can be RT_NULL.
*
* @note not all of platform provide this function.
*/
void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler,
rt_isr_handler_t *old_handler);
/**
* This function will reset whole platform.
*/
void rt_hw_cpu_reset(void);
/**
* This function will halt whole platform.
*/
void rt_hw_cpu_shutdown(void);
/*@}*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup Kernel RT-Thread Kernel API
*
* The Kernel APIs are the core APIs of RT-Thread, which supports the following
* features:
* - Multi-thread management
* - Synchronization mechanisms
* - Inter-thread communication
* - Memory management
* - Asynchronous timer
*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup Kernel RT-Thread Kernel API
*
* The Kernel APIs are the core APIs of RT-Thread, which supports the following
* features:
* - Multi-thread management
* - Synchronization mechanisms
* - Inter-thread communication
* - Memory management
* - Asynchronous timer
*/
/**
* @addtogroup Kernel
*/
*/
/*@{*/
/**
* @defgroup Thread Thread Management
* @brief the thread management
*
* RT-Thread operating system supports multitask systems, which are based on thread
* scheduling.
* - The scheduling is a full preemptive priority-based scheduling algorithm.
* - 8/32/256 priority levels are supported, in which 0 is the highest and 7/31/255 the lowest.
* The 7/31/255th priority is used for idle thread.
* - Threads running at same priority level are supported. The shared time-slice
* round-robin scheduling is used for this case.
* - The time of scheduler to choose the next highest ready thread is determinant.
* - There are four status in thread management
* -# Initialization
* -# Running/Ready
* -# Blocked
* -# Closed
* - The number of threads in the system is unlimited, only related with RAM.
*/
/**
* @defgroup Clock Clock and Timer Management
* * @brief clock and system timer management
*
* RT-Thread uses clock tick to implement shared time-slice scheduling.
*
* The timing sensitivity of thread is implemented by timers. The timer can be set as
* one-shot or periodic timeout.
*/
/**
* @defgroup KernelObject Kernel Object Management
* @brief kernel object management
*
* The Kernel object system can access and manage all of the kernel objects.
*
* Kernel objects include most of the facilities in the kernel:
* - thread
* - semaphore and mutex
* - event/fast event, mailbox, messagequeue
* - memory pool
* - timer
* @image html Kernel_Object.png "Figure 2: Kernel Object"
* @image rtf Kernel_Object.png "Figure 2: Kernel Object"
*
* Kernel objects can be static objects, whose memory is allocated in compiling.
* It can be dynamic objects as well, whose memory is allocated from system heaps
* in runtime.
*/
/**
* @defgroup IPC Inter-Thread Communication
* @brief inter-thread communication
*
* RT-Thread operating system supports the traditional semaphore and mutex.
* - Mutex objects use inherited priority to prevent priority reversion.
* - The semaphore release action is safe for interrupt service routine.
*
* Moreover, the blocked queue for thread to obtain semaphore or mutex can be sorted
* by priority or FIFO. There are two flags to indicate this mechanism.
* - RT_IPC_FLAG_FIFO
* when the resource is available, thread pended on this resource at first would get
* the resource.
* - RT_IPC_FLAG_PRIO
* when the resource is available, thread pended on this resource who had the most high
* priority would get the resource.
*
* RT-Thread operating systems supports event/fast event, mail box and message queue.
* - The event mechanism is used to awake a thead by setting one or more corresponding
* bit of a binary number when an event ocurs.
* - The fast event supports event thread queue. Once a one bit event occurs, the corresponding
* blocked thread can be found out timing accurately, then will be waked up.
* - In mailbox, the mail length is fixed to 4 byte, which is more effective than message queue.
* - The send action for communication facilities is also safe for interrupt service routine.
*/
/**
* @defgroup MM Memory Management
* @brief memory management for memory pool and heap memory
*
* RT-Thread operating system supports two types memory management:
* - Static memory pool management
* - Dynamic memory heap management.
*
* The time to allocate a memory block from the memory pool is determinant. When
* the memory pool is empty, the allocated thread can be blocked (or immediately return,
* or waiting for sometime to return, which are determined by a timeout parameter).
* When other thread releases memory blocks to this memory pool, the blocked thread is
* wake up.
*
* There are two methods in dynamic memory heap management, one is used for small memory,
* such as less than 1MB. Another is a SLAB like memory management, which is suitable
* for large memory system. All of them has no real-time character.
*/
/**
* @defgroup Device Device System
* @brief device I/O subsystem
*
* The Device System is designed as simple and minimum layer to help communication between
* applications and drivers.
*
* The Device System provide five interfaces to driver:
* - open, open a device
* - close, close a device
* - read, read some data from a device
* - write, write some data to a device
* - control, send some control command to a device
*/
/**
* @defgroup Hook Runtime Trace and Record
* @brief the hook function set in runtime
*
/**
* @defgroup Thread Thread Management
* @brief the thread management
*
* RT-Thread operating system supports multitask systems, which are based on thread
* scheduling.
* - The scheduling is a full preemptive priority-based scheduling algorithm.
* - 8/32/256 priority levels are supported, in which 0 is the highest and 7/31/255 the lowest.
* The 7/31/255th priority is used for idle thread.
* - Threads running at same priority level are supported. The shared time-slice
* round-robin scheduling is used for this case.
* - The time of scheduler to choose the next highest ready thread is determinant.
* - There are four status in thread management
* -# Initialization
* -# Running/Ready
* -# Blocked
* -# Closed
* - The number of threads in the system is unlimited, only related with RAM.
*/
/**
* @defgroup Clock Clock and Timer Management
* * @brief clock and system timer management
*
* RT-Thread uses clock tick to implement shared time-slice scheduling.
*
* The timing sensitivity of thread is implemented by timers. The timer can be set as
* one-shot or periodic timeout.
*/
/**
* @defgroup KernelObject Kernel Object Management
* @brief kernel object management
*
* The Kernel object system can access and manage all of the kernel objects.
*
* Kernel objects include most of the facilities in the kernel:
* - thread
* - semaphore and mutex
* - event/fast event, mailbox, messagequeue
* - memory pool
* - timer
* @image html Kernel_Object.png "Figure 2: Kernel Object"
* @image rtf Kernel_Object.png "Figure 2: Kernel Object"
*
* Kernel objects can be static objects, whose memory is allocated in compiling.
* It can be dynamic objects as well, whose memory is allocated from system heaps
* in runtime.
*/
/**
* @defgroup IPC Inter-Thread Communication
* @brief inter-thread communication
*
* RT-Thread operating system supports the traditional semaphore and mutex.
* - Mutex objects use inherited priority to prevent priority reversion.
* - The semaphore release action is safe for interrupt service routine.
*
* Moreover, the blocked queue for thread to obtain semaphore or mutex can be sorted
* by priority or FIFO. There are two flags to indicate this mechanism.
* - RT_IPC_FLAG_FIFO
* when the resource is available, thread pended on this resource at first would get
* the resource.
* - RT_IPC_FLAG_PRIO
* when the resource is available, thread pended on this resource who had the most high
* priority would get the resource.
*
* RT-Thread operating systems supports event/fast event, mail box and message queue.
* - The event mechanism is used to awake a thead by setting one or more corresponding
* bit of a binary number when an event ocurs.
* - The fast event supports event thread queue. Once a one bit event occurs, the corresponding
* blocked thread can be found out timing accurately, then will be waked up.
* - In mailbox, the mail length is fixed to 4 byte, which is more effective than message queue.
* - The send action for communication facilities is also safe for interrupt service routine.
*/
/**
* @defgroup MM Memory Management
* @brief memory management for memory pool and heap memory
*
* RT-Thread operating system supports two types memory management:
* - Static memory pool management
* - Dynamic memory heap management.
*
* The time to allocate a memory block from the memory pool is determinant. When
* the memory pool is empty, the allocated thread can be blocked (or immediately return,
* or waiting for sometime to return, which are determined by a timeout parameter).
* When other thread releases memory blocks to this memory pool, the blocked thread is
* wake up.
*
* There are two methods in dynamic memory heap management, one is used for small memory,
* such as less than 1MB. Another is a SLAB like memory management, which is suitable
* for large memory system. All of them has no real-time character.
*/
/**
* @defgroup Device Device System
* @brief device I/O subsystem
*
* The Device System is designed as simple and minimum layer to help communication between
* applications and drivers.
*
* The Device System provide five interfaces to driver:
* - open, open a device
* - close, close a device
* - read, read some data from a device
* - write, write some data to a device
* - control, send some control command to a device
*/
/**
* @defgroup Hook Runtime Trace and Record
* @brief the hook function set in runtime
*
* In order to trace and record RT-Thread activity in runtime, a hook mechanism
* is introduced.
*
......@@ -141,20 +141,20 @@
* - object hook, invoked at object created, deleted, taken and put etc.
* - scheduler hook, invoked at thread switch and idle thread loop.
* - memory hook, invoked when allocate or free memory block.
* - timer hook, invoked when timer is timeout.
*/
/**
* @defgroup KernelService Other useful kernel service
* @brief other useful service in the kernel
*/
/**
* @defgroup Error Error Code
* @brief error code
*
* The error code is defined to identify which kind of error occurs. When some
* bad things happen, the current thread's errno will be set. see @ref _rt_errno
*/
/*@}*/
* - timer hook, invoked when timer is timeout.
*/
/**
* @defgroup KernelService Other useful kernel service
* @brief other useful service in the kernel
*/
/**
* @defgroup Error Error Code
* @brief error code
*
* The error code is defined to identify which kind of error occurs. When some
* bad things happen, the current thread's errno will be set. see @ref _rt_errno
*/
/*@}*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @mainpage Introduction
* @author RT-Thread Development Team
* @version 1.1.0
*
* RT-Thread RTOS is an open source embedded real-time operating system and is
* designed specifically for small memory footprint platforms. The real-time and
* embedded characters are the most significant advantages of RT-Thread.
*
* - Real-Time Character
*
* RT-Thread has a real-time operating system kernel, with fully preempted
* multi-thread scheduler, inter-thread communication with timing sensitivity
* and transparent interrupt handling.
*
* - Embedded Character
*
* RT-Thread is suitable for embedded systems for small footprint characters.
* The kernel is implemented as a simple C library. The simplest application
* costs less than 1 Kbytes RAM on the ARM Cortex-M platform.
*
* @section kernel_arch RT-Thread Architecture
*
* RT-Thread system architecture is like:
* @image html System_Arch.png "Figure 1: RT-Thread Architecture"
*
* @section kernel_service Kernel API
*
* The Kernel APIs are the core APIs of RT-Thread, which supports the following
* features:
* - Multi-thread management and scheduler
* - Synchronization mechanisms, semaphore, recursive mutex and event set
* - Inter-thread communication, mailbox and message queue
* - Memory management, memory pool and dynamic heap memory management
* - Asynchronous timer
*
* For more details, please refer to @ref Kernel
*
* @section system_init System Initialization
*
* Once RT-Thread operating system starts up, the facility in system must be initialized
* firstly.
*
* For more details, please refer to @ref SystemInit
*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @mainpage Introduction
* @author RT-Thread Development Team
* @version 1.1.0
*
* RT-Thread RTOS is an open source embedded real-time operating system and is
* designed specifically for small memory footprint platforms. The real-time and
* embedded characters are the most significant advantages of RT-Thread.
*
* - Real-Time Character
*
* RT-Thread has a real-time operating system kernel, with fully preempted
* multi-thread scheduler, inter-thread communication with timing sensitivity
* and transparent interrupt handling.
*
* - Embedded Character
*
* RT-Thread is suitable for embedded systems for small footprint characters.
* The kernel is implemented as a simple C library. The simplest application
* costs less than 1 Kbytes RAM on the ARM Cortex-M platform.
*
* @section kernel_arch RT-Thread Architecture
*
* RT-Thread system architecture is like:
* @image html System_Arch.png "Figure 1: RT-Thread Architecture"
*
* @section kernel_service Kernel API
*
* The Kernel APIs are the core APIs of RT-Thread, which supports the following
* features:
* - Multi-thread management and scheduler
* - Synchronization mechanisms, semaphore, recursive mutex and event set
* - Inter-thread communication, mailbox and message queue
* - Memory management, memory pool and dynamic heap memory management
* - Asynchronous timer
*
* For more details, please refer to @ref Kernel
*
* @section system_init System Initialization
*
* Once RT-Thread operating system starts up, the facility in system must be initialized
* firstly.
*
* For more details, please refer to @ref SystemInit
*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup Module Application Module
*
* @brief Application Module is a feature let user to execute application in RT-Thread RTOS.
*
* Application Module is implemented as dynamic object loader, but it can handle
* the dependences relationship between application and dynamic library, moreover,
* it also can handle the kernel object destroy and memory release issue when application
* (abnormally) exit.
*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup Module Application Module
*
* @brief Application Module is a feature let user to execute application in RT-Thread RTOS.
*
* Application Module is implemented as dynamic object loader, but it can handle
* the dependences relationship between application and dynamic library, moreover,
* it also can handle the kernel object destroy and memory release issue when application
* (abnormally) exit.
*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup SystemInit System Initialization
*
* @brief System initialization procedure.
*
* When RT-Thread operating system starts up, the basic operating system facility
* initialization routines must be invoked.
*
* The suggested initialization sequence is:
*
* - initialize device hardware
* rt_hw_board_init();
*
* User can put the low level hardware initialization in this function, such as
* DDR memory setting, pinmux setting, console device setting etc.
*
* - show version
* rt_show_version();
*
* - initialize system tick
* rt_system_tick_init();
*
* - initialize kernel object [deprecated]
* rt_system_object_init();
*
* - initialize timer system
* rt_system_timer_init();
*
* - initialize system heap memory
* rt_system_heap_init(__bss_end, __end_of_memory);
*
* - initialize module system
* rt_system_module_init();
*
* - initialize scheduler system
* rt_system_scheduler_init();
*
* - initialize application
* rt_application_init();
*
* - initialize system timer thread
* rt_system_timer_thread_init();
*
* - initialize idle thread
* rt_thread_idle_init();
*
* - start scheduler
* rt_system_scheduler_start();
*/
/**
* @ingroup SystemInit
*
* This function will initialize user application.
*
* This function will be invoked when system initialization and system scheduler
* has not started. User can allocate memory, create thread, semaphore etc. However,
* user shall not suspend 'current' thread.
*/
void rt_application_init()
{
}
/**
* @ingroup SystemInit
*
* This function will initialize system heap memory.
*
* @param begin_addr the beginning address of system heap memory.
* @param end_addr the end address of system heap memory.
*
*/
void rt_system_heap_init(void* begin_addr, void* end_addr)
{
}
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup SystemInit System Initialization
*
* @brief System initialization procedure.
*
* When RT-Thread operating system starts up, the basic operating system facility
* initialization routines must be invoked.
*
* The suggested initialization sequence is:
*
* - initialize device hardware
* rt_hw_board_init();
*
* User can put the low level hardware initialization in this function, such as
* DDR memory setting, pinmux setting, console device setting etc.
*
* - show version
* rt_show_version();
*
* - initialize system tick
* rt_system_tick_init();
*
* - initialize kernel object [deprecated]
* rt_system_object_init();
*
* - initialize timer system
* rt_system_timer_init();
*
* - initialize system heap memory
* rt_system_heap_init(__bss_end, __end_of_memory);
*
* - initialize module system
* rt_system_module_init();
*
* - initialize scheduler system
* rt_system_scheduler_init();
*
* - initialize application
* rt_application_init();
*
* - initialize system timer thread
* rt_system_timer_thread_init();
*
* - initialize idle thread
* rt_thread_idle_init();
*
* - start scheduler
* rt_system_scheduler_start();
*/
/**
* @ingroup SystemInit
*
* This function will initialize user application.
*
* This function will be invoked when system initialization and system scheduler
* has not started. User can allocate memory, create thread, semaphore etc. However,
* user shall not suspend 'current' thread.
*/
void rt_application_init()
{
}
/**
* @ingroup SystemInit
*
* This function will initialize system heap memory.
*
* @param begin_addr the beginning address of system heap memory.
* @param end_addr the end address of system heap memory.
*
*/
void rt_system_heap_init(void* begin_addr, void* end_addr)
{
}
/*
* File : listdir.c
* This file is part of RT-TestCase in RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-02-10 Bernard first version
*/
#include <rtthread.h>
#include <dfs_posix.h>
static char fullpath[256];
void list_dir(const char* path)
{
DIR *dir;
dir = opendir(path);
if (dir != RT_NULL)
{
struct dirent* dirent;
struct stat s;
do
{
dirent = readdir(dir);
if (dirent == RT_NULL) break;
rt_memset(&s, 0, sizeof(struct stat));
/* build full path for each file */
rt_sprintf(fullpath, "%s/%s", path, dirent->d_name);
stat(fullpath, &s);
if ( s.st_mode & DFS_S_IFDIR )
{
rt_kprintf("%s\t\t<DIR>\n", dirent->d_name);
}
else
{
rt_kprintf("%s\t\t%lu\n", dirent->d_name, s.st_size);
}
} while (dirent != RT_NULL);
closedir(dir);
}
else rt_kprintf("open %s directory failed\n", path);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(list_dir, list directory);
#endif
/*
* File : listdir.c
* This file is part of RT-TestCase in RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-02-10 Bernard first version
*/
#include <rtthread.h>
#include <dfs_posix.h>
static char fullpath[256];
void list_dir(const char* path)
{
DIR *dir;
dir = opendir(path);
if (dir != RT_NULL)
{
struct dirent* dirent;
struct stat s;
do
{
dirent = readdir(dir);
if (dirent == RT_NULL) break;
rt_memset(&s, 0, sizeof(struct stat));
/* build full path for each file */
rt_sprintf(fullpath, "%s/%s", path, dirent->d_name);
stat(fullpath, &s);
if ( s.st_mode & DFS_S_IFDIR )
{
rt_kprintf("%s\t\t<DIR>\n", dirent->d_name);
}
else
{
rt_kprintf("%s\t\t%lu\n", dirent->d_name, s.st_size);
}
} while (dirent != RT_NULL);
closedir(dir);
}
else rt_kprintf("open %s directory failed\n", path);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(list_dir, list directory);
#endif
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
from building import *
src = Glob('*.c')
group = DefineGroup('libc_test', src, depend = ['RT_USING_NEWLIB', 'RT_USING_PTHREADS'])
Return('group')
from building import *
src = Glob('*.c')
group = DefineGroup('libc_test', src, depend = ['RT_USING_NEWLIB', 'RT_USING_PTHREADS'])
Return('group')
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
example:
1.edit rtconfig.py to config toolchain and bsp
2.scons --app=basicapp
3.copy basicapp/build/$bsp/basicapp.so to filesystem
example:
1.edit rtconfig.py to config toolchain and bsp
2.scons --app=basicapp
3.copy basicapp/build/$bsp/basicapp.so to filesystem
此差异已折叠。
import rtconfig
Import('RTT_ROOT')
from building import *
src = Glob('*.c')
group = DefineGroup('', src, depend = [''])
import rtconfig
Import('RTT_ROOT')
from building import *
src = Glob('*.c')
group = DefineGroup('', src, depend = [''])
Return('group')
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册