convert end of line

This commit is contained in:
Bernard Xiong
2013-01-08 05:05:02 -08:00
parent b3cf278502
commit 72782e9203
229 changed files with 37399 additions and 37399 deletions

View File

@@ -1,129 +1,129 @@
/*
* 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 diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
#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__ */

View File

@@ -1,79 +1,79 @@
/*
* 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 */

View File

@@ -1,120 +1,120 @@
/*
* 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

View File

@@ -1,231 +1,231 @@
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

View File

@@ -1,14 +1,14 @@
/*
* 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.
*/

View File

@@ -1,44 +1,44 @@
/*
* 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
*/
/*@}*/

View File

@@ -1,19 +1,19 @@
/*
* 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).
*/

View File

@@ -1,85 +1,85 @@
/*
* 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);
/*@}*/

View File

@@ -1,138 +1,138 @@
/*
* 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
*/
/*@}*/

View File

@@ -1,49 +1,49 @@
/*
* 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
*/

View File

@@ -1,14 +1,14 @@
/*
* 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.
*/

View File

@@ -1,79 +1,79 @@
/*
* 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)
{
}

View File

@@ -1,56 +1,56 @@
/*
* 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

View File

@@ -1,64 +1,64 @@
/*
* File : readspeed.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>
void readspeed(const char* filename, int block_size)
{
int fd;
char *buff_ptr;
rt_size_t total_length;
rt_tick_t tick;
fd = open(filename, 0, O_RDONLY);
if (fd < 0)
{
rt_kprintf("open file:%s failed\n", filename);
return;
}
buff_ptr = rt_malloc(block_size);
if (buff_ptr == RT_NULL)
{
rt_kprintf("no memory\n");
close(fd);
return;
}
tick = rt_tick_get();
total_length = 0;
while (1)
{
int length;
length = read(fd, buff_ptr, block_size);
if (length <= 0) break;
total_length += length;
}
tick = rt_tick_get() - tick;
/* close file and release memory */
close(fd);
rt_free(buff_ptr);
/* calculate read speed */
rt_kprintf("File read speed: %d byte/s\n", total_length /tick * RT_TICK_PER_SECOND);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(readspeed, perform file read test);
#endif
/*
* File : readspeed.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>
void readspeed(const char* filename, int block_size)
{
int fd;
char *buff_ptr;
rt_size_t total_length;
rt_tick_t tick;
fd = open(filename, 0, O_RDONLY);
if (fd < 0)
{
rt_kprintf("open file:%s failed\n", filename);
return;
}
buff_ptr = rt_malloc(block_size);
if (buff_ptr == RT_NULL)
{
rt_kprintf("no memory\n");
close(fd);
return;
}
tick = rt_tick_get();
total_length = 0;
while (1)
{
int length;
length = read(fd, buff_ptr, block_size);
if (length <= 0) break;
total_length += length;
}
tick = rt_tick_get() - tick;
/* close file and release memory */
close(fd);
rt_free(buff_ptr);
/* calculate read speed */
rt_kprintf("File read speed: %d byte/s\n", total_length /tick * RT_TICK_PER_SECOND);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(readspeed, perform file read test);
#endif

View File

@@ -1,123 +1,123 @@
/*
* 代码清单:文件读写例子
*
* 这个例子演示了如何读写一个文件,特别是写的时候应该如何操作。
*/
#include <rtthread.h>
#include <dfs_posix.h> /* 当需要使用文件操作时,需要包含这个头文件 */
#define TEST_FN "/test.dat"
/* 测试用的数据和缓冲 */
static char test_data[120], buffer[120];
/* 文件读写测试 */
void readwrite(const char* filename)
{
int fd;
int index, length;
/* 只写 & 创建 打开 */
fd = open(TEST_FN, O_WRONLY | O_CREAT | O_TRUNC, 0);
if (fd < 0)
{
rt_kprintf("open file for write failed\n");
return;
}
/* 准备写入数据 */
for (index = 0; index < sizeof(test_data); index ++)
{
test_data[index] = index + 27;
}
/* 写入数据 */
length = write(fd, test_data, sizeof(test_data));
if (length != sizeof(test_data))
{
rt_kprintf("write data failed\n");
close(fd);
return;
}
/* 关闭文件 */
close(fd);
/* 只写并在末尾添加打开 */
fd = open(TEST_FN, O_WRONLY | O_CREAT | O_APPEND, 0);
if (fd < 0)
{
rt_kprintf("open file for append write failed\n");
return;
}
length = write(fd, test_data, sizeof(test_data));
if (length != sizeof(test_data))
{
rt_kprintf("append write data failed\n");
close(fd);
return;
}
/* 关闭文件 */
close(fd);
/* 只读打开进行数据校验 */
fd = open(TEST_FN, O_RDONLY, 0);
if (fd < 0)
{
rt_kprintf("check: open file for read failed\n");
return;
}
/* 读取数据(应该为第一次写入的数据) */
length = read(fd, buffer, sizeof(buffer));
if (length != sizeof(buffer))
{
rt_kprintf("check: read file failed\n");
close(fd);
return;
}
/* 检查数据是否正确 */
for (index = 0; index < sizeof(test_data); index ++)
{
if (test_data[index] != buffer[index])
{
rt_kprintf("check: check data failed at %d\n", index);
close(fd);
return;
}
}
/* 读取数据(应该为第二次写入的数据) */
length = read(fd, buffer, sizeof(buffer));
if (length != sizeof(buffer))
{
rt_kprintf("check: read file failed\n");
close(fd);
return;
}
/* 检查数据是否正确 */
for (index = 0; index < sizeof(test_data); index ++)
{
if (test_data[index] != buffer[index])
{
rt_kprintf("check: check data failed at %d\n", index);
close(fd);
return;
}
}
/* 检查数据完毕,关闭文件 */
close(fd);
/* 打印结果 */
rt_kprintf("read/write done.\n");
}
#ifdef RT_USING_FINSH
#include <finsh.h>
/* 输出函数到finsh shell命令行中 */
FINSH_FUNCTION_EXPORT(readwrite, perform file read and write test);
#endif
/*
* 代码清单:文件读写例子
*
* 这个例子演示了如何读写一个文件,特别是写的时候应该如何操作。
*/
#include <rtthread.h>
#include <dfs_posix.h> /* 当需要使用文件操作时,需要包含这个头文件 */
#define TEST_FN "/test.dat"
/* 测试用的数据和缓冲 */
static char test_data[120], buffer[120];
/* 文件读写测试 */
void readwrite(const char* filename)
{
int fd;
int index, length;
/* 只写 & 创建 打开 */
fd = open(TEST_FN, O_WRONLY | O_CREAT | O_TRUNC, 0);
if (fd < 0)
{
rt_kprintf("open file for write failed\n");
return;
}
/* 准备写入数据 */
for (index = 0; index < sizeof(test_data); index ++)
{
test_data[index] = index + 27;
}
/* 写入数据 */
length = write(fd, test_data, sizeof(test_data));
if (length != sizeof(test_data))
{
rt_kprintf("write data failed\n");
close(fd);
return;
}
/* 关闭文件 */
close(fd);
/* 只写并在末尾添加打开 */
fd = open(TEST_FN, O_WRONLY | O_CREAT | O_APPEND, 0);
if (fd < 0)
{
rt_kprintf("open file for append write failed\n");
return;
}
length = write(fd, test_data, sizeof(test_data));
if (length != sizeof(test_data))
{
rt_kprintf("append write data failed\n");
close(fd);
return;
}
/* 关闭文件 */
close(fd);
/* 只读打开进行数据校验 */
fd = open(TEST_FN, O_RDONLY, 0);
if (fd < 0)
{
rt_kprintf("check: open file for read failed\n");
return;
}
/* 读取数据(应该为第一次写入的数据) */
length = read(fd, buffer, sizeof(buffer));
if (length != sizeof(buffer))
{
rt_kprintf("check: read file failed\n");
close(fd);
return;
}
/* 检查数据是否正确 */
for (index = 0; index < sizeof(test_data); index ++)
{
if (test_data[index] != buffer[index])
{
rt_kprintf("check: check data failed at %d\n", index);
close(fd);
return;
}
}
/* 读取数据(应该为第二次写入的数据) */
length = read(fd, buffer, sizeof(buffer));
if (length != sizeof(buffer))
{
rt_kprintf("check: read file failed\n");
close(fd);
return;
}
/* 检查数据是否正确 */
for (index = 0; index < sizeof(test_data); index ++)
{
if (test_data[index] != buffer[index])
{
rt_kprintf("check: check data failed at %d\n", index);
close(fd);
return;
}
}
/* 检查数据完毕,关闭文件 */
close(fd);
/* 打印结果 */
rt_kprintf("read/write done.\n");
}
#ifdef RT_USING_FINSH
#include <finsh.h>
/* 输出函数到finsh shell命令行中 */
FINSH_FUNCTION_EXPORT(readwrite, perform file read and write test);
#endif

View File

@@ -1,50 +1,50 @@
/*
* File : seekdir.c
* This file is part of RT-TestCase in RT-Thread RTOS
* COPYRIGHT (C) 2011, 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
* 2011-06-02 Bernard first version
*/
#include <dfs_posix.h>
void seekdir_test(void)
{
DIR * dirp;
long save3 = 0;
long cur;
int i = 0;
struct dirent *dp;
dirp = opendir ("/");
save3 = telldir(dirp);
for (dp = readdir(dirp); dp != RT_NULL; dp = readdir(dirp))
{
rt_kprintf("direntry: %s\n", dp->d_name);
/* 保存第三个目录项的目录指针 */
if (i++ == 3)
{
save3 = telldir(dirp);
}
}
/* 回到刚才保存的第三个目录项的目录指针 */
seekdir (dirp, save3);
rt_kprintf("seek dientry to: %d\n", save3);
for (dp = readdir(dirp); dp != RT_NULL; dp = readdir(dirp))
{
rt_kprintf("direntry: %s\n", dp->d_name);
}
/* 关闭目录 */
closedir (dirp);
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(seekdir_test, perform directory seek test);
/*
* File : seekdir.c
* This file is part of RT-TestCase in RT-Thread RTOS
* COPYRIGHT (C) 2011, 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
* 2011-06-02 Bernard first version
*/
#include <dfs_posix.h>
void seekdir_test(void)
{
DIR * dirp;
long save3 = 0;
long cur;
int i = 0;
struct dirent *dp;
dirp = opendir ("/");
save3 = telldir(dirp);
for (dp = readdir(dirp); dp != RT_NULL; dp = readdir(dirp))
{
rt_kprintf("direntry: %s\n", dp->d_name);
/* 保存第三个目录项的目录指针 */
if (i++ == 3)
{
save3 = telldir(dirp);
}
}
/* 回到刚才保存的第三个目录项的目录指针 */
seekdir (dirp, save3);
rt_kprintf("seek dientry to: %d\n", save3);
for (dp = readdir(dirp); dp != RT_NULL; dp = readdir(dirp))
{
rt_kprintf("direntry: %s\n", dp->d_name);
}
/* 关闭目录 */
closedir (dirp);
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(seekdir_test, perform directory seek test);

View File

@@ -1,72 +1,72 @@
/*
* File : writespeed.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>
void writespeed(const char* filename, int total_length, int block_size)
{
int fd, index, length;
char *buff_ptr;
rt_tick_t tick;
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0);
if (fd < 0)
{
rt_kprintf("open file:%s failed\n", filename);
return;
}
buff_ptr = rt_malloc(block_size);
if (buff_ptr == RT_NULL)
{
rt_kprintf("no memory\n");
close(fd);
return;
}
/* prepare write data */
for (index = 0; index < block_size; index++)
{
buff_ptr[index] = index;
}
index = 0;
/* get the beginning tick */
tick = rt_tick_get();
while (index < total_length / block_size)
{
length = write(fd, buff_ptr, block_size);
if (length != block_size)
{
rt_kprintf("write failed\n");
break;
}
index ++;
}
tick = rt_tick_get() - tick;
/* close file and release memory */
close(fd);
rt_free(buff_ptr);
/* calculate write speed */
rt_kprintf("File write speed: %d byte/s\n", total_length / tick * RT_TICK_PER_SECOND);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(writespeed, perform file write test);
#endif
/*
* File : writespeed.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>
void writespeed(const char* filename, int total_length, int block_size)
{
int fd, index, length;
char *buff_ptr;
rt_tick_t tick;
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0);
if (fd < 0)
{
rt_kprintf("open file:%s failed\n", filename);
return;
}
buff_ptr = rt_malloc(block_size);
if (buff_ptr == RT_NULL)
{
rt_kprintf("no memory\n");
close(fd);
return;
}
/* prepare write data */
for (index = 0; index < block_size; index++)
{
buff_ptr[index] = index;
}
index = 0;
/* get the beginning tick */
tick = rt_tick_get();
while (index < total_length / block_size)
{
length = write(fd, buff_ptr, block_size);
if (length != block_size)
{
rt_kprintf("write failed\n");
break;
}
index ++;
}
tick = rt_tick_get() - tick;
/* close file and release memory */
close(fd);
rt_free(buff_ptr);
/* calculate write speed */
rt_kprintf("File write speed: %d byte/s\n", total_length / tick * RT_TICK_PER_SECOND);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(writespeed, perform file write test);
#endif

View File

@@ -1,39 +1,39 @@
from building import *
src = Split("""
tc_comm.c
thread_static.c
thread_dynamic.c
thread_priority.c
thread_same_priority.c
thread_static_simple.c
thread_dynamic_simple.c
thread_delete.c
thread_detach.c
thread_yield.c
thread_suspend.c
thread_resume.c
semaphore_static.c
semaphore_dynamic.c
semaphore_priority.c
semaphore_buffer_worker.c
semaphore_producer_consumer.c
mutex_simple.c
event_simple.c
mbox_simple.c
mbox_send_wait.c
messageq_simple.c
timer_static.c
timer_dynamic.c
timer_stop_self.c
timer_control.c
timer_timeout.c
heap_malloc.c
heap_realloc.c
memp_simple.c
tc_sample.c
""")
group = DefineGroup('examples', src, depend = ['RT_USING_TC'])
Return('group')
from building import *
src = Split("""
tc_comm.c
thread_static.c
thread_dynamic.c
thread_priority.c
thread_same_priority.c
thread_static_simple.c
thread_dynamic_simple.c
thread_delete.c
thread_detach.c
thread_yield.c
thread_suspend.c
thread_resume.c
semaphore_static.c
semaphore_dynamic.c
semaphore_priority.c
semaphore_buffer_worker.c
semaphore_producer_consumer.c
mutex_simple.c
event_simple.c
mbox_simple.c
mbox_send_wait.c
messageq_simple.c
timer_static.c
timer_dynamic.c
timer_stop_self.c
timer_control.c
timer_timeout.c
heap_malloc.c
heap_realloc.c
memp_simple.c
tc_sample.c
""")
group = DefineGroup('examples', src, depend = ['RT_USING_TC'])
Return('group')

View File

@@ -1,72 +1,72 @@
#include <rtthread.h>
#include "tc_comm.h"
/*
* This is an example for heap malloc
*/
static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len)
{
while (len)
{
if (*ptr != value) return RT_FALSE;
ptr ++;
len --;
}
return RT_TRUE;
}
static void heap_malloc_init()
{
rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5;
ptr1 = rt_malloc(1);
ptr2 = rt_malloc(13);
ptr3 = rt_malloc(31);
ptr4 = rt_malloc(127);
ptr5 = rt_malloc(0);
memset(ptr1, 1, 1);
memset(ptr2, 2, 13);
memset(ptr3, 3, 31);
memset(ptr4, 4, 127);
if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed;
if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed;
if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed;
if (mem_check(ptr4, 4, 127) != RT_FALSE) goto _failed;
rt_free(ptr4);
rt_free(ptr3);
rt_free(ptr3);
rt_free(ptr1);
if (ptr5 != RT_NULL)
{
rt_free(ptr5);
}
tc_done(TC_STAT_PASSED);
_failed:
tc_done(TC_STAT_FAILED);
}
#ifdef RT_USING_TC
int _tc_heap_malloc()
{
heap_malloc_init();
return 0;
}
FINSH_FUNCTION_EXPORT(_tc_heap_malloc, a heap malloc test);
#else
int rt_application_init()
{
heap_malloc_init();
return 0;
}
#endif
#include <rtthread.h>
#include "tc_comm.h"
/*
* This is an example for heap malloc
*/
static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len)
{
while (len)
{
if (*ptr != value) return RT_FALSE;
ptr ++;
len --;
}
return RT_TRUE;
}
static void heap_malloc_init()
{
rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5;
ptr1 = rt_malloc(1);
ptr2 = rt_malloc(13);
ptr3 = rt_malloc(31);
ptr4 = rt_malloc(127);
ptr5 = rt_malloc(0);
memset(ptr1, 1, 1);
memset(ptr2, 2, 13);
memset(ptr3, 3, 31);
memset(ptr4, 4, 127);
if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed;
if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed;
if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed;
if (mem_check(ptr4, 4, 127) != RT_FALSE) goto _failed;
rt_free(ptr4);
rt_free(ptr3);
rt_free(ptr3);
rt_free(ptr1);
if (ptr5 != RT_NULL)
{
rt_free(ptr5);
}
tc_done(TC_STAT_PASSED);
_failed:
tc_done(TC_STAT_FAILED);
}
#ifdef RT_USING_TC
int _tc_heap_malloc()
{
heap_malloc_init();
return 0;
}
FINSH_FUNCTION_EXPORT(_tc_heap_malloc, a heap malloc test);
#else
int rt_application_init()
{
heap_malloc_init();
return 0;
}
#endif

View File

@@ -1,83 +1,83 @@
#include <rtthread.h>
#include "tc_comm.h"
/*
* This is an example for heap malloc
*/
static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len)
{
while (len)
{
if (*ptr != value) return RT_FALSE;
ptr ++;
len --;
}
return RT_TRUE;
}
static void heap_realloc_init()
{
rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5;
ptr1 = rt_malloc(1);
ptr2 = rt_malloc(13);
ptr3 = rt_malloc(31);
ptr4 = rt_malloc(127);
ptr5 = rt_malloc(0);
memset(ptr1, 1, 1);
memset(ptr2, 2, 13);
memset(ptr3, 3, 31);
memset(ptr4, 4, 127);
if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed;
if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed;
if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed;
if (mem_check(ptr4, 4, 127) != RT_FALSE) goto _failed;
ptr1 = rt_realloc(ptr1, 13);
ptr2 = rt_realloc(ptr2, 31);
ptr3 = rt_realloc(ptr3, 127);
ptr4 = rt_realloc(ptr4, 1);
ptr5 = rt_realloc(ptr5, 0);
if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed;
if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed;
if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed;
if (mem_check(ptr4, 4, 1) != RT_FALSE) goto _failed;
rt_free(ptr4);
rt_free(ptr3);
rt_free(ptr3);
rt_free(ptr1);
if (ptr5 != RT_NULL)
{
rt_free(ptr5);
}
tc_done(TC_STAT_PASSED);
_failed:
tc_done(TC_STAT_FAILED);
}
#ifdef RT_USING_TC
int _tc_heap_realloc()
{
heap_realloc_init();
return 0;
}
FINSH_FUNCTION_EXPORT(_tc_heap_realloc, a heap re-malloc test);
#else
int rt_application_init()
{
heap_realloc_init();
return 0;
}
#endif
#include <rtthread.h>
#include "tc_comm.h"
/*
* This is an example for heap malloc
*/
static rt_bool_t mem_check(rt_uint8_t *ptr, rt_uint8_t value, rt_uint32_t len)
{
while (len)
{
if (*ptr != value) return RT_FALSE;
ptr ++;
len --;
}
return RT_TRUE;
}
static void heap_realloc_init()
{
rt_uint8_t *ptr1, *ptr2, *ptr3, *ptr4, *ptr5;
ptr1 = rt_malloc(1);
ptr2 = rt_malloc(13);
ptr3 = rt_malloc(31);
ptr4 = rt_malloc(127);
ptr5 = rt_malloc(0);
memset(ptr1, 1, 1);
memset(ptr2, 2, 13);
memset(ptr3, 3, 31);
memset(ptr4, 4, 127);
if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed;
if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed;
if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed;
if (mem_check(ptr4, 4, 127) != RT_FALSE) goto _failed;
ptr1 = rt_realloc(ptr1, 13);
ptr2 = rt_realloc(ptr2, 31);
ptr3 = rt_realloc(ptr3, 127);
ptr4 = rt_realloc(ptr4, 1);
ptr5 = rt_realloc(ptr5, 0);
if (mem_check(ptr1, 1, 1) != RT_FALSE) goto _failed;
if (mem_check(ptr2, 2, 13) != RT_FALSE) goto _failed;
if (mem_check(ptr3, 3, 31) != RT_FALSE) goto _failed;
if (mem_check(ptr4, 4, 1) != RT_FALSE) goto _failed;
rt_free(ptr4);
rt_free(ptr3);
rt_free(ptr3);
rt_free(ptr1);
if (ptr5 != RT_NULL)
{
rt_free(ptr5);
}
tc_done(TC_STAT_PASSED);
_failed:
tc_done(TC_STAT_FAILED);
}
#ifdef RT_USING_TC
int _tc_heap_realloc()
{
heap_realloc_init();
return 0;
}
FINSH_FUNCTION_EXPORT(_tc_heap_realloc, a heap re-malloc test);
#else
int rt_application_init()
{
heap_realloc_init();
return 0;
}
#endif

View File

@@ -1,163 +1,163 @@
/*
* 程序清单:
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 指向线程控制块的指针 */
static rt_thread_t tid1 = RT_NULL;
static rt_thread_t tid2 = RT_NULL;
static rt_thread_t tid3 = RT_NULL;
static rt_mutex_t mutex = RT_NULL;
/* 线程1入口 */
static void thread1_entry(void* parameter)
{
/* 先让低优先级线程运行 */
rt_thread_delay(10);
/* 此时thread3持有mutex并且thread2等待持有mutex */
/* 检查thread2与thread3的优先级情况 */
if (tid2->current_priority != tid3->current_priority)
{
/* 优先级不相同,测试失败 */
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return;
}
}
/* 线程2入口 */
static void thread2_entry(void* parameter)
{
rt_err_t result;
/* 先让低优先级线程运行 */
rt_thread_delay(5);
while (1)
{
/*
* 试图持有互斥锁此时thread3持有应把thread3的优先级提升到thread2相同
* 的优先级
*/
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
if (result == RT_EOK)
{
/* 释放互斥锁 */
rt_mutex_release(mutex);
}
}
}
/* 线程3入口 */
static void thread3_entry(void* parameter)
{
rt_tick_t tick;
rt_err_t result;
while (1)
{
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
}
/* 做一个长时间的循环总共50个OS Tick */
tick = rt_tick_get();
while (rt_tick_get() - tick < 50) ;
rt_mutex_release(mutex);
rt_mutex_release(mutex);
}
}
int mutex_simple_init()
{
/* 创建互斥锁 */
mutex = rt_mutex_create("mutex", RT_IPC_FLAG_FIFO);
if (mutex == RT_NULL)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
/* 创建线程1 */
tid1 = rt_thread_create("t1",
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
if (tid1 != RT_NULL)
rt_thread_startup(tid1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建线程2 */
tid2 = rt_thread_create("t2",
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid2 != RT_NULL)
rt_thread_startup(tid2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建线程3 */
tid3 = rt_thread_create("t3",
thread3_entry, RT_NULL, /* 线程入口是thread3_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
if (tid3 != RT_NULL)
rt_thread_startup(tid3);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除线程 */
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid1);
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid2);
if (tid3 != RT_NULL && tid3->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid3);
if (mutex != RT_NULL)
{
rt_mutex_delete(mutex);
}
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_mutex_simple()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
mutex_simple_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_mutex_simple, sime mutex example);
#else
/* 用户应用入口 */
int rt_application_init()
{
mutex_simple_init();
return 0;
}
#endif
/*
* 程序清单:
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 指向线程控制块的指针 */
static rt_thread_t tid1 = RT_NULL;
static rt_thread_t tid2 = RT_NULL;
static rt_thread_t tid3 = RT_NULL;
static rt_mutex_t mutex = RT_NULL;
/* 线程1入口 */
static void thread1_entry(void* parameter)
{
/* 先让低优先级线程运行 */
rt_thread_delay(10);
/* 此时thread3持有mutex并且thread2等待持有mutex */
/* 检查thread2与thread3的优先级情况 */
if (tid2->current_priority != tid3->current_priority)
{
/* 优先级不相同,测试失败 */
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return;
}
}
/* 线程2入口 */
static void thread2_entry(void* parameter)
{
rt_err_t result;
/* 先让低优先级线程运行 */
rt_thread_delay(5);
while (1)
{
/*
* 试图持有互斥锁此时thread3持有应把thread3的优先级提升到thread2相同
* 的优先级
*/
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
if (result == RT_EOK)
{
/* 释放互斥锁 */
rt_mutex_release(mutex);
}
}
}
/* 线程3入口 */
static void thread3_entry(void* parameter)
{
rt_tick_t tick;
rt_err_t result;
while (1)
{
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
}
/* 做一个长时间的循环总共50个OS Tick */
tick = rt_tick_get();
while (rt_tick_get() - tick < 50) ;
rt_mutex_release(mutex);
rt_mutex_release(mutex);
}
}
int mutex_simple_init()
{
/* 创建互斥锁 */
mutex = rt_mutex_create("mutex", RT_IPC_FLAG_FIFO);
if (mutex == RT_NULL)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
/* 创建线程1 */
tid1 = rt_thread_create("t1",
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
if (tid1 != RT_NULL)
rt_thread_startup(tid1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建线程2 */
tid2 = rt_thread_create("t2",
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid2 != RT_NULL)
rt_thread_startup(tid2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建线程3 */
tid3 = rt_thread_create("t3",
thread3_entry, RT_NULL, /* 线程入口是thread3_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
if (tid3 != RT_NULL)
rt_thread_startup(tid3);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除线程 */
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid1);
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid2);
if (tid3 != RT_NULL && tid3->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid3);
if (mutex != RT_NULL)
{
rt_mutex_delete(mutex);
}
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_mutex_simple()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
mutex_simple_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_mutex_simple, sime mutex example);
#else
/* 用户应用入口 */
int rt_application_init()
{
mutex_simple_init();
return 0;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,128 +1,128 @@
/*
* 程序清单:动态信号量
*
* 这个例子中将创建一个动态信号量初始值为0 )及一个动态线程,在这个动态线程中
* 将试图采用超时方式去持有信号量,应该超时返回。然后这个线程释放一次信号量,并
* 在后面继续采用永久等待方式去持有信号量, 成功获得信号量后返回。
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 指向线程控制块的指针 */
static rt_thread_t tid = RT_NULL;
/* 指向信号量的指针 */
static rt_sem_t sem = RT_NULL;
/* 线程入口 */
static void thread_entry(void* parameter)
{
rt_err_t result;
rt_tick_t tick;
/* 获得当前的OS Tick */
tick = rt_tick_get();
/* 试图持有一个信号量如果10个OS Tick依然没拿到则超时返回 */
result = rt_sem_take(sem, 10);
if (result == -RT_ETIMEOUT)
{
/* 判断是否刚好过去10个OS Tick */
if (rt_tick_get() - tick != 10)
{
/* 如果失败,则测试失败 */
tc_done(TC_STAT_FAILED);
rt_sem_delete(sem);
return;
}
rt_kprintf("take semaphore timeout\n");
}
else
{
/* 因为并没释放信号量,应该是超时返回,否则测试失败 */
tc_done(TC_STAT_FAILED);
rt_sem_delete(sem);
return;
}
/* 释放一次信号量 */
rt_sem_release(sem);
/* 继续持有信号量,并永远等待直到持有到信号量 */
result = rt_sem_take(sem, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
/* 返回不正确,测试失败 */
tc_done(TC_STAT_FAILED);
rt_sem_delete(sem);
return;
}
/* 测试成功 */
tc_done(TC_STAT_PASSED);
/* 删除信号量 */
rt_sem_delete(sem);
}
int semaphore_dynamic_init()
{
/* 创建一个信号量初始值是0 */
sem = rt_sem_create("sem", 0, RT_IPC_FLAG_FIFO);
if (sem == RT_NULL)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
/* 创建线程 */
tid = rt_thread_create("thread",
thread_entry, RT_NULL, /* 线程入口是thread_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid != RT_NULL)
rt_thread_startup(tid);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除线程 */
if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE)
{
rt_thread_delete(tid);
/* 删除信号量 */
rt_sem_delete(sem);
}
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_semaphore_dynamic()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
semaphore_dynamic_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_semaphore_dynamic, a dynamic semaphore example);
#else
/* 用户应用入口 */
int rt_application_init()
{
semaphore_dynamic_init();
return 0;
}
#endif
/*
* 程序清单:动态信号量
*
* 这个例子中将创建一个动态信号量初始值为0 )及一个动态线程,在这个动态线程中
* 将试图采用超时方式去持有信号量,应该超时返回。然后这个线程释放一次信号量,并
* 在后面继续采用永久等待方式去持有信号量, 成功获得信号量后返回。
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 指向线程控制块的指针 */
static rt_thread_t tid = RT_NULL;
/* 指向信号量的指针 */
static rt_sem_t sem = RT_NULL;
/* 线程入口 */
static void thread_entry(void* parameter)
{
rt_err_t result;
rt_tick_t tick;
/* 获得当前的OS Tick */
tick = rt_tick_get();
/* 试图持有一个信号量如果10个OS Tick依然没拿到则超时返回 */
result = rt_sem_take(sem, 10);
if (result == -RT_ETIMEOUT)
{
/* 判断是否刚好过去10个OS Tick */
if (rt_tick_get() - tick != 10)
{
/* 如果失败,则测试失败 */
tc_done(TC_STAT_FAILED);
rt_sem_delete(sem);
return;
}
rt_kprintf("take semaphore timeout\n");
}
else
{
/* 因为并没释放信号量,应该是超时返回,否则测试失败 */
tc_done(TC_STAT_FAILED);
rt_sem_delete(sem);
return;
}
/* 释放一次信号量 */
rt_sem_release(sem);
/* 继续持有信号量,并永远等待直到持有到信号量 */
result = rt_sem_take(sem, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
/* 返回不正确,测试失败 */
tc_done(TC_STAT_FAILED);
rt_sem_delete(sem);
return;
}
/* 测试成功 */
tc_done(TC_STAT_PASSED);
/* 删除信号量 */
rt_sem_delete(sem);
}
int semaphore_dynamic_init()
{
/* 创建一个信号量初始值是0 */
sem = rt_sem_create("sem", 0, RT_IPC_FLAG_FIFO);
if (sem == RT_NULL)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
/* 创建线程 */
tid = rt_thread_create("thread",
thread_entry, RT_NULL, /* 线程入口是thread_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid != RT_NULL)
rt_thread_startup(tid);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除线程 */
if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE)
{
rt_thread_delete(tid);
/* 删除信号量 */
rt_sem_delete(sem);
}
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_semaphore_dynamic()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
semaphore_dynamic_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_semaphore_dynamic, a dynamic semaphore example);
#else
/* 用户应用入口 */
int rt_application_init()
{
semaphore_dynamic_init();
return 0;
}
#endif

View File

@@ -1,128 +1,128 @@
#include <rtthread.h>
#include "tc_comm.h"
static rt_sem_t sem;
static rt_uint8_t t1_count, t2_count;
static rt_thread_t t1, t2, worker;
static void thread1_entry(void* parameter)
{
rt_err_t result;
while (1)
{
result = rt_sem_take(sem, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
tc_done(TC_STAT_FAILED);
return;
}
t1_count ++;
rt_kprintf("thread1: got semaphore, count: %d\n", t1_count);
}
}
static void thread2_entry(void* parameter)
{
rt_err_t result;
while (1)
{
result = rt_sem_take(sem, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
tc_done(TC_STAT_FAILED);
return;
}
t2_count ++;
rt_kprintf("thread2: got semaphore, count: %d\n", t2_count);
}
}
static void worker_thread_entry(void* parameter)
{
rt_thread_delay(10);
while (1)
{
rt_sem_release(sem);
rt_thread_delay(5);
}
}
int semaphore_priority_init()
{
sem = rt_sem_create("sem", 0, RT_IPC_FLAG_PRIO);
if (sem == RT_NULL)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
t1_count = t2_count = 0;
t1 = rt_thread_create("t1",
thread1_entry, RT_NULL,
THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
if (t1 != RT_NULL)
rt_thread_startup(t1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
t2 = rt_thread_create("t2",
thread2_entry, RT_NULL,
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
if (t2 != RT_NULL)
rt_thread_startup(t2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
worker = rt_thread_create("worker",
worker_thread_entry, RT_NULL,
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (worker != RT_NULL)
rt_thread_startup(worker);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* lock scheduler */
rt_enter_critical();
/* delete t1, t2 and worker thread */
rt_thread_delete(t1);
rt_thread_delete(t2);
rt_thread_delete(worker);
if (t1_count > t2_count)
tc_done(TC_STAT_FAILED);
else
tc_done(TC_STAT_PASSED);
/* unlock scheduler */
rt_exit_critical();
}
int _tc_semaphore_priority()
{
/* set tc cleanup */
tc_cleanup(_tc_cleanup);
semaphore_priority_init();
return 50;
}
FINSH_FUNCTION_EXPORT(_tc_semaphore_priority, a priority semaphore test);
#else
int rt_application_init()
{
semaphore_priority_init();
return 0;
}
#endif
#include <rtthread.h>
#include "tc_comm.h"
static rt_sem_t sem;
static rt_uint8_t t1_count, t2_count;
static rt_thread_t t1, t2, worker;
static void thread1_entry(void* parameter)
{
rt_err_t result;
while (1)
{
result = rt_sem_take(sem, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
tc_done(TC_STAT_FAILED);
return;
}
t1_count ++;
rt_kprintf("thread1: got semaphore, count: %d\n", t1_count);
}
}
static void thread2_entry(void* parameter)
{
rt_err_t result;
while (1)
{
result = rt_sem_take(sem, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
tc_done(TC_STAT_FAILED);
return;
}
t2_count ++;
rt_kprintf("thread2: got semaphore, count: %d\n", t2_count);
}
}
static void worker_thread_entry(void* parameter)
{
rt_thread_delay(10);
while (1)
{
rt_sem_release(sem);
rt_thread_delay(5);
}
}
int semaphore_priority_init()
{
sem = rt_sem_create("sem", 0, RT_IPC_FLAG_PRIO);
if (sem == RT_NULL)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
t1_count = t2_count = 0;
t1 = rt_thread_create("t1",
thread1_entry, RT_NULL,
THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
if (t1 != RT_NULL)
rt_thread_startup(t1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
t2 = rt_thread_create("t2",
thread2_entry, RT_NULL,
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
if (t2 != RT_NULL)
rt_thread_startup(t2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
worker = rt_thread_create("worker",
worker_thread_entry, RT_NULL,
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (worker != RT_NULL)
rt_thread_startup(worker);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* lock scheduler */
rt_enter_critical();
/* delete t1, t2 and worker thread */
rt_thread_delete(t1);
rt_thread_delete(t2);
rt_thread_delete(worker);
if (t1_count > t2_count)
tc_done(TC_STAT_FAILED);
else
tc_done(TC_STAT_PASSED);
/* unlock scheduler */
rt_exit_critical();
}
int _tc_semaphore_priority()
{
/* set tc cleanup */
tc_cleanup(_tc_cleanup);
semaphore_priority_init();
return 50;
}
FINSH_FUNCTION_EXPORT(_tc_semaphore_priority, a priority semaphore test);
#else
int rt_application_init()
{
semaphore_priority_init();
return 0;
}
#endif

View File

@@ -1,154 +1,154 @@
/*
* 程序清单:生产者消费者例子
*
* 这个例子中将创建两个线程用于实现生产者消费者问题
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 定义最大5个元素能够被产生 */
#define MAXSEM 5
/* 用于放置生产的整数数组 */
rt_uint32_t array[MAXSEM];
/* 指向生产者、消费者在array数组中的读写位置 */
static rt_uint32_t set, get;
/* 指向线程控制块的指针 */
static rt_thread_t producer_tid = RT_NULL;
static rt_thread_t consumer_tid = RT_NULL;
struct rt_semaphore sem_lock;
struct rt_semaphore sem_empty, sem_full;
/* 生成者线程入口 */
void producer_thread_entry(void* parameter)
{
int cnt = 0;
/* 运行100次 */
while( cnt < 100)
{
/* 获取一个空位 */
rt_sem_take(&sem_empty, RT_WAITING_FOREVER);
/* 修改array内容上锁 */
rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
array[set%MAXSEM] = cnt + 1;
rt_kprintf("the producer generates a number: %d\n", array[set%MAXSEM]);
set++;
rt_sem_release(&sem_lock);
/* 发布一个满位 */
rt_sem_release(&sem_full);
cnt++;
/* 暂停一段时间 */
rt_thread_delay(50);
}
rt_kprintf("the producer exit!\n");
}
/* 消费者线程入口 */
void consumer_thread_entry(void* parameter)
{
rt_uint32_t no;
rt_uint32_t sum;
/* 第n个线程由入口参数传进来 */
no = (rt_uint32_t)parameter;
while(1)
{
/* 获取一个满位 */
rt_sem_take(&sem_full, RT_WAITING_FOREVER);
/* 临界区,上锁进行操作 */
rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
sum += array[get%MAXSEM];
rt_kprintf("the consumer[%d] get a number: %d\n", no, array[get%MAXSEM] );
get++;
rt_sem_release(&sem_lock);
/* 释放一个空位 */
rt_sem_release(&sem_empty);
/* 生产者生产到100个数目停止消费者线程相应停止 */
if (get == 100) break;
/* 暂停一小会时间 */
rt_thread_delay(10);
}
rt_kprintf("the consumer[%d] sum is %d \n ", no, sum);
rt_kprintf("the consumer[%d] exit!\n");
}
int semaphore_producer_consumer_init()
{
/* 初始化3个信号量 */
rt_sem_init(&sem_lock , "lock", 1, RT_IPC_FLAG_FIFO);
rt_sem_init(&sem_empty, "empty", MAXSEM, RT_IPC_FLAG_FIFO);
rt_sem_init(&sem_full , "full", 0, RT_IPC_FLAG_FIFO);
/* 创建线程1 */
producer_tid = rt_thread_create("producer",
producer_thread_entry, RT_NULL, /* 线程入口是producer_thread_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
if (producer_tid != RT_NULL)
rt_thread_startup(producer_tid);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建线程2 */
consumer_tid = rt_thread_create("consumer",
consumer_thread_entry, RT_NULL, /* 线程入口是consumer_thread_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
if (consumer_tid != RT_NULL)
rt_thread_startup(consumer_tid);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除线程 */
if (producer_tid != RT_NULL && producer_tid->stat != RT_THREAD_CLOSE)
rt_thread_delete(producer_tid);
if (consumer_tid != RT_NULL && consumer_tid->stat != RT_THREAD_CLOSE)
rt_thread_delete(consumer_tid);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_semaphore_producer_consumer()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
semaphore_producer_consumer_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_semaphore_producer_consumer, producer and consumer example);
#else
/* 用户应用入口 */
int rt_application_init()
{
semaphore_producer_consumer_init();
return 0;
}
#endif
/*
* 程序清单:生产者消费者例子
*
* 这个例子中将创建两个线程用于实现生产者消费者问题
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 定义最大5个元素能够被产生 */
#define MAXSEM 5
/* 用于放置生产的整数数组 */
rt_uint32_t array[MAXSEM];
/* 指向生产者、消费者在array数组中的读写位置 */
static rt_uint32_t set, get;
/* 指向线程控制块的指针 */
static rt_thread_t producer_tid = RT_NULL;
static rt_thread_t consumer_tid = RT_NULL;
struct rt_semaphore sem_lock;
struct rt_semaphore sem_empty, sem_full;
/* 生成者线程入口 */
void producer_thread_entry(void* parameter)
{
int cnt = 0;
/* 运行100次 */
while( cnt < 100)
{
/* 获取一个空位 */
rt_sem_take(&sem_empty, RT_WAITING_FOREVER);
/* 修改array内容上锁 */
rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
array[set%MAXSEM] = cnt + 1;
rt_kprintf("the producer generates a number: %d\n", array[set%MAXSEM]);
set++;
rt_sem_release(&sem_lock);
/* 发布一个满位 */
rt_sem_release(&sem_full);
cnt++;
/* 暂停一段时间 */
rt_thread_delay(50);
}
rt_kprintf("the producer exit!\n");
}
/* 消费者线程入口 */
void consumer_thread_entry(void* parameter)
{
rt_uint32_t no;
rt_uint32_t sum;
/* 第n个线程由入口参数传进来 */
no = (rt_uint32_t)parameter;
while(1)
{
/* 获取一个满位 */
rt_sem_take(&sem_full, RT_WAITING_FOREVER);
/* 临界区,上锁进行操作 */
rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
sum += array[get%MAXSEM];
rt_kprintf("the consumer[%d] get a number: %d\n", no, array[get%MAXSEM] );
get++;
rt_sem_release(&sem_lock);
/* 释放一个空位 */
rt_sem_release(&sem_empty);
/* 生产者生产到100个数目停止消费者线程相应停止 */
if (get == 100) break;
/* 暂停一小会时间 */
rt_thread_delay(10);
}
rt_kprintf("the consumer[%d] sum is %d \n ", no, sum);
rt_kprintf("the consumer[%d] exit!\n");
}
int semaphore_producer_consumer_init()
{
/* 初始化3个信号量 */
rt_sem_init(&sem_lock , "lock", 1, RT_IPC_FLAG_FIFO);
rt_sem_init(&sem_empty, "empty", MAXSEM, RT_IPC_FLAG_FIFO);
rt_sem_init(&sem_full , "full", 0, RT_IPC_FLAG_FIFO);
/* 创建线程1 */
producer_tid = rt_thread_create("producer",
producer_thread_entry, RT_NULL, /* 线程入口是producer_thread_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
if (producer_tid != RT_NULL)
rt_thread_startup(producer_tid);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建线程2 */
consumer_tid = rt_thread_create("consumer",
consumer_thread_entry, RT_NULL, /* 线程入口是consumer_thread_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
if (consumer_tid != RT_NULL)
rt_thread_startup(consumer_tid);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除线程 */
if (producer_tid != RT_NULL && producer_tid->stat != RT_THREAD_CLOSE)
rt_thread_delete(producer_tid);
if (consumer_tid != RT_NULL && consumer_tid->stat != RT_THREAD_CLOSE)
rt_thread_delete(consumer_tid);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_semaphore_producer_consumer()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
semaphore_producer_consumer_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_semaphore_producer_consumer, producer and consumer example);
#else
/* 用户应用入口 */
int rt_application_init()
{
semaphore_producer_consumer_init();
return 0;
}
#endif

View File

@@ -1,132 +1,132 @@
/*
* 程序清单:静态信号量
*
* 这个例子中将创建一个静态信号量初始值为0 )及一个静态线程,在这个静态线程中
* 将试图采用超时方式去持有信号量,应该超时返回。然后这个线程释放一次信号量,并
* 在后面继续采用永久等待方式去持有信号量, 成功获得信号量后返回。
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 线程控制块及栈 */
static struct rt_thread thread;
static rt_uint8_t thread_stack[THREAD_STACK_SIZE];
/* 信号量控制块 */
static struct rt_semaphore sem;
/* 线程入口 */
static void thread_entry(void* parameter)
{
rt_err_t result;
rt_tick_t tick;
/* 获得当前的OS Tick */
tick = rt_tick_get();
/* 试图持有信号量最大等待10个OS Tick后返回 */
result = rt_sem_take(&sem, 10);
if (result == -RT_ETIMEOUT)
{
/* 超时后判断是否刚好是10个OS Tick */
if (rt_tick_get() - tick != 10)
{
tc_done(TC_STAT_FAILED);
rt_sem_detach(&sem);
return;
}
rt_kprintf("take semaphore timeout\n");
}
else
{
/* 因为没有其他地方是否信号量,所以不应该成功持有信号量,否则测试失败 */
tc_done(TC_STAT_FAILED);
rt_sem_detach(&sem);
return;
}
/* 释放一次信号量 */
rt_sem_release(&sem);
/* 永久等待方式持有信号量 */
result = rt_sem_take(&sem, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
/* 不成功则测试失败 */
tc_done(TC_STAT_FAILED);
rt_sem_detach(&sem);
return;
}
/* 测试通过 */
tc_done(TC_STAT_PASSED);
/* 脱离信号量对象 */
rt_sem_detach(&sem);
}
int semaphore_static_init()
{
rt_err_t result;
/* 初始化信号量初始值是0 */
result = rt_sem_init(&sem, "sem", 0, RT_IPC_FLAG_FIFO);
if (result != RT_EOK)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
/* 初始化线程1 */
result = rt_thread_init(&thread, "thread", /* 线程名thread */
thread_entry, RT_NULL, /* 线程的入口是thread_entry入口参数是RT_NULL*/
&thread_stack[0], sizeof(thread_stack), /* 线程栈是thread_stack */
THREAD_PRIORITY, 10);
if (result == RT_EOK) /* 如果返回正确启动线程1 */
rt_thread_startup(&thread);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 执行线程脱离 */
if (thread.stat != RT_THREAD_CLOSE)
{
rt_thread_detach(&thread);
/* 执行信号量对象脱离 */
rt_sem_detach(&sem);
}
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_semaphore_static()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
semaphore_static_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_semaphore_static, a static semaphore example);
#else
/* 用户应用入口 */
int rt_application_init()
{
thread_static_init();
return 0;
}
#endif
/*
* 程序清单:静态信号量
*
* 这个例子中将创建一个静态信号量初始值为0 )及一个静态线程,在这个静态线程中
* 将试图采用超时方式去持有信号量,应该超时返回。然后这个线程释放一次信号量,并
* 在后面继续采用永久等待方式去持有信号量, 成功获得信号量后返回。
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 线程控制块及栈 */
static struct rt_thread thread;
static rt_uint8_t thread_stack[THREAD_STACK_SIZE];
/* 信号量控制块 */
static struct rt_semaphore sem;
/* 线程入口 */
static void thread_entry(void* parameter)
{
rt_err_t result;
rt_tick_t tick;
/* 获得当前的OS Tick */
tick = rt_tick_get();
/* 试图持有信号量最大等待10个OS Tick后返回 */
result = rt_sem_take(&sem, 10);
if (result == -RT_ETIMEOUT)
{
/* 超时后判断是否刚好是10个OS Tick */
if (rt_tick_get() - tick != 10)
{
tc_done(TC_STAT_FAILED);
rt_sem_detach(&sem);
return;
}
rt_kprintf("take semaphore timeout\n");
}
else
{
/* 因为没有其他地方是否信号量,所以不应该成功持有信号量,否则测试失败 */
tc_done(TC_STAT_FAILED);
rt_sem_detach(&sem);
return;
}
/* 释放一次信号量 */
rt_sem_release(&sem);
/* 永久等待方式持有信号量 */
result = rt_sem_take(&sem, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
/* 不成功则测试失败 */
tc_done(TC_STAT_FAILED);
rt_sem_detach(&sem);
return;
}
/* 测试通过 */
tc_done(TC_STAT_PASSED);
/* 脱离信号量对象 */
rt_sem_detach(&sem);
}
int semaphore_static_init()
{
rt_err_t result;
/* 初始化信号量初始值是0 */
result = rt_sem_init(&sem, "sem", 0, RT_IPC_FLAG_FIFO);
if (result != RT_EOK)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
/* 初始化线程1 */
result = rt_thread_init(&thread, "thread", /* 线程名thread */
thread_entry, RT_NULL, /* 线程的入口是thread_entry入口参数是RT_NULL*/
&thread_stack[0], sizeof(thread_stack), /* 线程栈是thread_stack */
THREAD_PRIORITY, 10);
if (result == RT_EOK) /* 如果返回正确启动线程1 */
rt_thread_startup(&thread);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 执行线程脱离 */
if (thread.stat != RT_THREAD_CLOSE)
{
rt_thread_detach(&thread);
/* 执行信号量对象脱离 */
rt_sem_detach(&sem);
}
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_semaphore_static()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
semaphore_static_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_semaphore_static, a static semaphore example);
#else
/* 用户应用入口 */
int rt_application_init()
{
thread_static_init();
return 0;
}
#endif

View File

@@ -1,176 +1,176 @@
#include "tc_comm.h"
#ifdef RT_USING_FINSH
#include <finsh.h>
#endif
#ifdef RT_USING_TC
#define TC_PRIORITY 25
#define TC_STACK_SIZE 0x400
static rt_uint8_t _tc_stat;
static struct rt_semaphore _tc_sem;
static struct rt_thread _tc_thread;
static rt_uint8_t _tc_stack[TC_STACK_SIZE];
static char _tc_prefix[64];
static const char* _tc_current;
static void (*_tc_cleanup)(void) = RT_NULL;
static rt_uint32_t _tc_scale = 1;
FINSH_VAR_EXPORT(_tc_scale, finsh_type_int, the testcase timer timeout scale)
void tc_thread_entry(void* parameter)
{
struct finsh_syscall* index;
/* create tc semaphore */
rt_sem_init(&_tc_sem, "tc", 0, RT_IPC_FLAG_FIFO);
while (_tc_stat & TC_STAT_RUNNING)
{
for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index))
{
/* search testcase */
if (rt_strstr(index->name, _tc_prefix) == index->name)
{
long tick;
_tc_current = index->name + 4;
rt_kprintf("Run TestCase: %s\n", _tc_current);
_tc_stat = TC_STAT_PASSED | TC_STAT_RUNNING;
tick = index->func();
if (tick > 0)
{
rt_sem_take(&_tc_sem, tick * _tc_scale);
if (_tc_cleanup != RT_NULL)
{
/* perform testcase cleanup */
_tc_cleanup();
_tc_cleanup = RT_NULL;
}
rt_sem_trytake(&_tc_sem);/* by nl1031 */
if (_tc_stat & TC_STAT_FAILED)
rt_kprintf("TestCase[%s] failed\n", _tc_current);
else
rt_kprintf("TestCase[%s] passed\n", _tc_current);
}
else
{
if (_tc_cleanup != RT_NULL)
{
/* perform testcase cleanup */
_tc_cleanup();
_tc_cleanup = RT_NULL;
}
}
}
}
}
rt_kprintf("RT-Thread TestCase Running Done!\n");
/* detach tc semaphore */
rt_sem_detach(&_tc_sem);
}
void tc_stop()
{
_tc_stat &= ~TC_STAT_RUNNING;
rt_thread_delay(RT_TICK_PER_SECOND/2);
if (_tc_thread.stat != RT_THREAD_INIT)
{
/* lock scheduler */
rt_enter_critical();
/* detach old tc thread */
rt_thread_detach(&_tc_thread);
rt_sem_detach(&_tc_sem);
/* unlock scheduler */
rt_exit_critical();
}
rt_thread_delay(RT_TICK_PER_SECOND/2);
}
FINSH_FUNCTION_EXPORT(tc_stop, stop testcase thread);
void tc_done(rt_uint8_t stat)
{
_tc_stat |= stat;
_tc_stat &= ~TC_STAT_RUNNING;
/* release semaphore */
rt_sem_release(&_tc_sem);
}
void tc_stat(rt_uint8_t stat)
{
if (stat & TC_STAT_FAILED)
{
rt_kprintf("TestCases[%s] failed\n", _tc_current);
}
_tc_stat |= stat;
}
void tc_cleanup(void (*cleanup)())
{
_tc_cleanup = cleanup;
}
void tc_start(const char* tc_prefix)
{
rt_err_t result;
/* tesecase prefix is null */
if (tc_prefix == RT_NULL)
{
rt_kprintf("TestCase Usage: tc_start(prefix)\n\n");
rt_kprintf("list_tc() can list all testcases.\n");
return ;
}
/* init tc thread */
if (_tc_stat & TC_STAT_RUNNING)
{
/* stop old tc thread */
tc_stop();
}
rt_memset(_tc_prefix, 0, sizeof(_tc_prefix));
rt_snprintf(_tc_prefix, sizeof(_tc_prefix), "_tc_%s", tc_prefix);
result = rt_thread_init(&_tc_thread, "tc",
tc_thread_entry, RT_NULL,
&_tc_stack[0], sizeof(_tc_stack),
TC_PRIORITY - 3, 5);
/* set tc stat */
_tc_stat = TC_STAT_RUNNING | TC_STAT_FAILED;
if (result == RT_EOK)
rt_thread_startup(&_tc_thread);
}
FINSH_FUNCTION_EXPORT(tc_start, start testcase with testcase prefix or name);
void list_tc()
{
struct finsh_syscall* index;
rt_kprintf("TestCases List:\n");
for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index))
{
/* search testcase */
if (rt_strstr(index->name, "_tc_") == index->name)
{
#ifdef FINSH_USING_DESCRIPTION
rt_kprintf("%-16s -- %s\n", index->name + 4, index->desc);
#else
rt_kprintf("%s\n", index->name + 4);
#endif
}
}
}
FINSH_FUNCTION_EXPORT(list_tc, list all testcases);
#endif
#include "tc_comm.h"
#ifdef RT_USING_FINSH
#include <finsh.h>
#endif
#ifdef RT_USING_TC
#define TC_PRIORITY 25
#define TC_STACK_SIZE 0x400
static rt_uint8_t _tc_stat;
static struct rt_semaphore _tc_sem;
static struct rt_thread _tc_thread;
static rt_uint8_t _tc_stack[TC_STACK_SIZE];
static char _tc_prefix[64];
static const char* _tc_current;
static void (*_tc_cleanup)(void) = RT_NULL;
static rt_uint32_t _tc_scale = 1;
FINSH_VAR_EXPORT(_tc_scale, finsh_type_int, the testcase timer timeout scale)
void tc_thread_entry(void* parameter)
{
struct finsh_syscall* index;
/* create tc semaphore */
rt_sem_init(&_tc_sem, "tc", 0, RT_IPC_FLAG_FIFO);
while (_tc_stat & TC_STAT_RUNNING)
{
for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index))
{
/* search testcase */
if (rt_strstr(index->name, _tc_prefix) == index->name)
{
long tick;
_tc_current = index->name + 4;
rt_kprintf("Run TestCase: %s\n", _tc_current);
_tc_stat = TC_STAT_PASSED | TC_STAT_RUNNING;
tick = index->func();
if (tick > 0)
{
rt_sem_take(&_tc_sem, tick * _tc_scale);
if (_tc_cleanup != RT_NULL)
{
/* perform testcase cleanup */
_tc_cleanup();
_tc_cleanup = RT_NULL;
}
rt_sem_trytake(&_tc_sem);/* by nl1031 */
if (_tc_stat & TC_STAT_FAILED)
rt_kprintf("TestCase[%s] failed\n", _tc_current);
else
rt_kprintf("TestCase[%s] passed\n", _tc_current);
}
else
{
if (_tc_cleanup != RT_NULL)
{
/* perform testcase cleanup */
_tc_cleanup();
_tc_cleanup = RT_NULL;
}
}
}
}
}
rt_kprintf("RT-Thread TestCase Running Done!\n");
/* detach tc semaphore */
rt_sem_detach(&_tc_sem);
}
void tc_stop()
{
_tc_stat &= ~TC_STAT_RUNNING;
rt_thread_delay(RT_TICK_PER_SECOND/2);
if (_tc_thread.stat != RT_THREAD_INIT)
{
/* lock scheduler */
rt_enter_critical();
/* detach old tc thread */
rt_thread_detach(&_tc_thread);
rt_sem_detach(&_tc_sem);
/* unlock scheduler */
rt_exit_critical();
}
rt_thread_delay(RT_TICK_PER_SECOND/2);
}
FINSH_FUNCTION_EXPORT(tc_stop, stop testcase thread);
void tc_done(rt_uint8_t stat)
{
_tc_stat |= stat;
_tc_stat &= ~TC_STAT_RUNNING;
/* release semaphore */
rt_sem_release(&_tc_sem);
}
void tc_stat(rt_uint8_t stat)
{
if (stat & TC_STAT_FAILED)
{
rt_kprintf("TestCases[%s] failed\n", _tc_current);
}
_tc_stat |= stat;
}
void tc_cleanup(void (*cleanup)())
{
_tc_cleanup = cleanup;
}
void tc_start(const char* tc_prefix)
{
rt_err_t result;
/* tesecase prefix is null */
if (tc_prefix == RT_NULL)
{
rt_kprintf("TestCase Usage: tc_start(prefix)\n\n");
rt_kprintf("list_tc() can list all testcases.\n");
return ;
}
/* init tc thread */
if (_tc_stat & TC_STAT_RUNNING)
{
/* stop old tc thread */
tc_stop();
}
rt_memset(_tc_prefix, 0, sizeof(_tc_prefix));
rt_snprintf(_tc_prefix, sizeof(_tc_prefix), "_tc_%s", tc_prefix);
result = rt_thread_init(&_tc_thread, "tc",
tc_thread_entry, RT_NULL,
&_tc_stack[0], sizeof(_tc_stack),
TC_PRIORITY - 3, 5);
/* set tc stat */
_tc_stat = TC_STAT_RUNNING | TC_STAT_FAILED;
if (result == RT_EOK)
rt_thread_startup(&_tc_thread);
}
FINSH_FUNCTION_EXPORT(tc_start, start testcase with testcase prefix or name);
void list_tc()
{
struct finsh_syscall* index;
rt_kprintf("TestCases List:\n");
for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index))
{
/* search testcase */
if (rt_strstr(index->name, "_tc_") == index->name)
{
#ifdef FINSH_USING_DESCRIPTION
rt_kprintf("%-16s -- %s\n", index->name + 4, index->desc);
#else
rt_kprintf("%s\n", index->name + 4);
#endif
}
}
}
FINSH_FUNCTION_EXPORT(list_tc, list all testcases);
#endif

View File

@@ -1,43 +1,43 @@
#ifndef __TC_COMM_H__
#define __TC_COMM_H__
/*
* RT-Thread TestCase
*
*/
#include <rtthread.h>
#ifdef RT_USING_FINSH
#include <finsh.h>
#endif
#if RT_THREAD_PRIORITY_MAX == 8
#define THREAD_PRIORITY 6
#elif RT_THREAD_PRIORITY_MAX == 32
#define THREAD_PRIORITY 25
#elif RT_THREAD_PRIORITY_MAX == 256
#define THREAD_PRIORITY 200
#endif
#define THREAD_STACK_SIZE 512
#define THREAD_TIMESLICE 5
#define TC_STAT_END 0x00
#define TC_STAT_RUNNING 0x01
#define TC_STAT_FAILED 0x10
#define TC_STAT_PASSED 0x00
#ifdef RT_USING_TC
void tc_start(const char* tc_prefix);
void tc_stop(void);
void tc_done(rt_uint8_t state);
void tc_stat(rt_uint8_t state);
void tc_cleanup(void (*cleanup)(void));
#else
#define tc_start(x)
#define tc_stop()
#define tc_done(s)
#define tc_stat(s)
#define tc_cleanup(c)
#endif
#endif
#ifndef __TC_COMM_H__
#define __TC_COMM_H__
/*
* RT-Thread TestCase
*
*/
#include <rtthread.h>
#ifdef RT_USING_FINSH
#include <finsh.h>
#endif
#if RT_THREAD_PRIORITY_MAX == 8
#define THREAD_PRIORITY 6
#elif RT_THREAD_PRIORITY_MAX == 32
#define THREAD_PRIORITY 25
#elif RT_THREAD_PRIORITY_MAX == 256
#define THREAD_PRIORITY 200
#endif
#define THREAD_STACK_SIZE 512
#define THREAD_TIMESLICE 5
#define TC_STAT_END 0x00
#define TC_STAT_RUNNING 0x01
#define TC_STAT_FAILED 0x10
#define TC_STAT_PASSED 0x00
#ifdef RT_USING_TC
void tc_start(const char* tc_prefix);
void tc_stop(void);
void tc_done(rt_uint8_t state);
void tc_stat(rt_uint8_t state);
void tc_cleanup(void (*cleanup)(void));
#else
#define tc_start(x)
#define tc_stop()
#define tc_done(s)
#define tc_stat(s)
#define tc_cleanup(c)
#endif
#endif

View File

@@ -1,70 +1,70 @@
#include <rtthread.h>
#include "tc_comm.h"
/*
* This is an example for delay thread
*/
static struct rt_thread thread;
static char thread_stack[THREAD_STACK_SIZE];
static void thread_entry(void* parameter)
{
rt_tick_t tick;
rt_kprintf("thread inited ok\n");
rt_kprintf("thread delay 10 tick\n");
tick = rt_tick_get();
rt_thread_delay(10);
if (rt_tick_get() - tick > 10)
{
tc_done(TC_STAT_FAILED);
return;
}
rt_kprintf("thread delay 15 tick\n");
tick = rt_tick_get();
rt_thread_delay(15);
if (rt_tick_get() - tick > 15)
{
tc_done(TC_STAT_FAILED);
return;
}
rt_kprintf("thread exit\n");
tc_done(TC_STAT_PASSED);
}
rt_err_t thread_delay_init()
{
rt_err_t result;
result = rt_thread_init(&thread,
"test",
thread_entry, RT_NULL,
&thread_stack[0], sizeof(thread_stack),
THREAD_PRIORITY, 10);
if (result == RT_EOK)
rt_thread_startup(&thread);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return result;
}
#ifdef RT_USING_TC
int _tc_thread_delay()
{
thread_delay_init();
return 30;
}
FINSH_FUNCTION_EXPORT(_tc_thread_delay, a thread delay test);
#else
int rt_application_init()
{
thread_delay_init();
return 0;
}
#endif
#include <rtthread.h>
#include "tc_comm.h"
/*
* This is an example for delay thread
*/
static struct rt_thread thread;
static char thread_stack[THREAD_STACK_SIZE];
static void thread_entry(void* parameter)
{
rt_tick_t tick;
rt_kprintf("thread inited ok\n");
rt_kprintf("thread delay 10 tick\n");
tick = rt_tick_get();
rt_thread_delay(10);
if (rt_tick_get() - tick > 10)
{
tc_done(TC_STAT_FAILED);
return;
}
rt_kprintf("thread delay 15 tick\n");
tick = rt_tick_get();
rt_thread_delay(15);
if (rt_tick_get() - tick > 15)
{
tc_done(TC_STAT_FAILED);
return;
}
rt_kprintf("thread exit\n");
tc_done(TC_STAT_PASSED);
}
rt_err_t thread_delay_init()
{
rt_err_t result;
result = rt_thread_init(&thread,
"test",
thread_entry, RT_NULL,
&thread_stack[0], sizeof(thread_stack),
THREAD_PRIORITY, 10);
if (result == RT_EOK)
rt_thread_startup(&thread);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return result;
}
#ifdef RT_USING_TC
int _tc_thread_delay()
{
thread_delay_init();
return 30;
}
FINSH_FUNCTION_EXPORT(_tc_thread_delay, a thread delay test);
#else
int rt_application_init()
{
thread_delay_init();
return 0;
}
#endif

View File

@@ -1,144 +1,144 @@
/*
* 程序清单:删除线程
*
* 这个例子会创建两个线程,在一个线程中删除另外一个线程。
*/
#include <rtthread.h>
#include "tc_comm.h"
/*
* 线程删除(rt_thread_delete)函数仅适合于动态线程,为了在一个线程
* 中访问另一个线程的控制块,所以把线程块指针声明成全局类型以供全
* 局访问
*/
static rt_thread_t tid1 = RT_NULL, tid2 = RT_NULL;
/* 线程1的入口函数 */
static void thread1_entry(void* parameter)
{
rt_uint32_t count = 0;
while (1)
{
/* 线程1采用低优先级运行一直打印计数值 */
// rt_kprintf("thread count: %d\n", count ++);
count ++;
}
}
static void thread1_cleanup(struct rt_thread *tid)
{
if (tid != tid1)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return ;
}
rt_kprintf("thread1 end\n");
tid1 = RT_NULL;
}
/* 线程2的入口函数 */
static void thread2_entry(void* parameter)
{
/* 线程2拥有较高的优先级以抢占线程1而获得执行 */
/* 线程2启动后先睡眠10个OS Tick */
rt_thread_delay(10);
/*
* 线程2唤醒后直接删除线程1删除线程1后线程1自动脱离就绪线程
* 队列
*/
rt_thread_delete(tid1);
/*
* 线程2继续休眠10个OS Tick然后退出线程2休眠后应切换到idle线程
* idle线程将执行真正的线程1控制块和线程栈的删除
*/
rt_thread_delay(10);
}
static void thread2_cleanup(struct rt_thread *tid)
{
/*
* 线程2运行结束后也将自动被删除(线程控制块和线程栈在idle线
* 程中释放)
*/
if (tid != tid2)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return ;
}
rt_kprintf("thread2 end\n");
tid2 = RT_NULL;
tc_done(TC_STAT_PASSED);
}
/* 线程删除示例的初始化 */
int thread_delete_init()
{
/* 创建线程1 */
tid1 = rt_thread_create("t1", /* 线程1的名称是t1 */
thread1_entry, RT_NULL, /* 入口是thread1_entry参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid1 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */
{
tid1->cleanup = thread1_cleanup;
rt_thread_startup(tid1);
}
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建线程1 */
tid2 = rt_thread_create("t2", /* 线程1的名称是t2 */
thread2_entry, RT_NULL, /* 入口是thread2_entry参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
if (tid2 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */
{
tid2->cleanup = thread2_cleanup;
rt_thread_startup(tid2);
}
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* lock scheduler */
rt_enter_critical();
/* delete thread */
if (tid1 != RT_NULL)
{
rt_kprintf("tid1 is bad\n");
tc_stat(TC_STAT_FAILED);
}
if (tid2 != RT_NULL)
{
rt_kprintf("tid2 is bad\n");
tc_stat(TC_STAT_FAILED);
}
/* unlock scheduler */
rt_exit_critical();
}
int _tc_thread_delete()
{
/* set tc cleanup */
tc_cleanup(_tc_cleanup);
thread_delete_init();
return 27;
}
FINSH_FUNCTION_EXPORT(_tc_thread_delete, a thread delete example);
#else
int rt_application_init()
{
thread_delete_init();
return 0;
}
#endif
/*
* 程序清单:删除线程
*
* 这个例子会创建两个线程,在一个线程中删除另外一个线程。
*/
#include <rtthread.h>
#include "tc_comm.h"
/*
* 线程删除(rt_thread_delete)函数仅适合于动态线程,为了在一个线程
* 中访问另一个线程的控制块,所以把线程块指针声明成全局类型以供全
* 局访问
*/
static rt_thread_t tid1 = RT_NULL, tid2 = RT_NULL;
/* 线程1的入口函数 */
static void thread1_entry(void* parameter)
{
rt_uint32_t count = 0;
while (1)
{
/* 线程1采用低优先级运行一直打印计数值 */
// rt_kprintf("thread count: %d\n", count ++);
count ++;
}
}
static void thread1_cleanup(struct rt_thread *tid)
{
if (tid != tid1)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return ;
}
rt_kprintf("thread1 end\n");
tid1 = RT_NULL;
}
/* 线程2的入口函数 */
static void thread2_entry(void* parameter)
{
/* 线程2拥有较高的优先级以抢占线程1而获得执行 */
/* 线程2启动后先睡眠10个OS Tick */
rt_thread_delay(10);
/*
* 线程2唤醒后直接删除线程1删除线程1后线程1自动脱离就绪线程
* 队列
*/
rt_thread_delete(tid1);
/*
* 线程2继续休眠10个OS Tick然后退出线程2休眠后应切换到idle线程
* idle线程将执行真正的线程1控制块和线程栈的删除
*/
rt_thread_delay(10);
}
static void thread2_cleanup(struct rt_thread *tid)
{
/*
* 线程2运行结束后也将自动被删除(线程控制块和线程栈在idle线
* 程中释放)
*/
if (tid != tid2)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return ;
}
rt_kprintf("thread2 end\n");
tid2 = RT_NULL;
tc_done(TC_STAT_PASSED);
}
/* 线程删除示例的初始化 */
int thread_delete_init()
{
/* 创建线程1 */
tid1 = rt_thread_create("t1", /* 线程1的名称是t1 */
thread1_entry, RT_NULL, /* 入口是thread1_entry参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid1 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */
{
tid1->cleanup = thread1_cleanup;
rt_thread_startup(tid1);
}
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建线程1 */
tid2 = rt_thread_create("t2", /* 线程1的名称是t2 */
thread2_entry, RT_NULL, /* 入口是thread2_entry参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
if (tid2 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */
{
tid2->cleanup = thread2_cleanup;
rt_thread_startup(tid2);
}
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* lock scheduler */
rt_enter_critical();
/* delete thread */
if (tid1 != RT_NULL)
{
rt_kprintf("tid1 is bad\n");
tc_stat(TC_STAT_FAILED);
}
if (tid2 != RT_NULL)
{
rt_kprintf("tid2 is bad\n");
tc_stat(TC_STAT_FAILED);
}
/* unlock scheduler */
rt_exit_critical();
}
int _tc_thread_delete()
{
/* set tc cleanup */
tc_cleanup(_tc_cleanup);
thread_delete_init();
return 27;
}
FINSH_FUNCTION_EXPORT(_tc_thread_delete, a thread delete example);
#else
int rt_application_init()
{
thread_delete_init();
return 0;
}
#endif

View File

@@ -1,118 +1,118 @@
/*
* 程序清单:线程脱离
*
* 这个例子会创建两个线程,在其中一个线程中执行对另一个线程的脱离。
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 线程1控制块 */
static struct rt_thread thread1;
/* 线程1栈 */
static rt_uint8_t thread1_stack[THREAD_STACK_SIZE];
/* 线程2控制块 */
static struct rt_thread thread2;
/* 线程2栈 */
static rt_uint8_t thread2_stack[THREAD_STACK_SIZE];
/* 线程1入口 */
static void thread1_entry(void* parameter)
{
rt_uint32_t count = 0;
while (1)
{
/* 线程1采用低优先级运行一直打印计数值 */
rt_kprintf("thread count: %d\n", count ++);
}
}
/* 线程2入口 */
static void thread2_entry(void* parameter)
{
/* 线程2拥有较高的优先级以抢占线程1而获得执行 */
/* 线程2启动后先睡眠10个OS Tick */
rt_thread_delay(10);
/*
* 线程2唤醒后直接执行线程1脱离线程1将从就绪线程队列中删除
*/
rt_thread_detach(&thread1);
/*
* 线程2继续休眠10个OS Tick然后退出
*/
rt_thread_delay(10);
/*
* 线程2运行结束后也将自动被从就绪队列中删除并脱离线程队列
*/
}
int thread_detach_init()
{
rt_err_t result;
/* 初始化线程1 */
result = rt_thread_init(&thread1, "t1", /* 线程名t1 */
thread1_entry, RT_NULL, /* 线程的入口是thread1_entry入口参数是RT_NULL*/
&thread1_stack[0], sizeof(thread1_stack), /* 线程栈是thread1_stack */
THREAD_PRIORITY, 10);
if (result == RT_EOK) /* 如果返回正确启动线程1 */
rt_thread_startup(&thread1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 初始化线程2 */
result = rt_thread_init(&thread2, "t2", /* 线程名t2 */
thread2_entry, RT_NULL, /* 线程的入口是thread2_entry入口参数是RT_NULL*/
&thread2_stack[0], sizeof(thread2_stack), /* 线程栈是thread2_stack */
THREAD_PRIORITY - 1, 10);
if (result == RT_EOK) /* 如果返回正确启动线程2 */
rt_thread_startup(&thread2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 执行线程脱离 */
if (thread1.stat != RT_THREAD_CLOSE)
rt_thread_detach(&thread1);
if (thread2.stat != RT_THREAD_CLOSE)
rt_thread_detach(&thread2);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_thread_detach()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
thread_detach_init();
/* 返回TestCase运行的最长时间 */
return 25;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_thread_detach, a static thread example);
#else
/* 用户应用入口 */
int rt_application_init()
{
thread_detach_init();
return 0;
}
#endif
/*
* 程序清单:线程脱离
*
* 这个例子会创建两个线程,在其中一个线程中执行对另一个线程的脱离。
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 线程1控制块 */
static struct rt_thread thread1;
/* 线程1栈 */
static rt_uint8_t thread1_stack[THREAD_STACK_SIZE];
/* 线程2控制块 */
static struct rt_thread thread2;
/* 线程2栈 */
static rt_uint8_t thread2_stack[THREAD_STACK_SIZE];
/* 线程1入口 */
static void thread1_entry(void* parameter)
{
rt_uint32_t count = 0;
while (1)
{
/* 线程1采用低优先级运行一直打印计数值 */
rt_kprintf("thread count: %d\n", count ++);
}
}
/* 线程2入口 */
static void thread2_entry(void* parameter)
{
/* 线程2拥有较高的优先级以抢占线程1而获得执行 */
/* 线程2启动后先睡眠10个OS Tick */
rt_thread_delay(10);
/*
* 线程2唤醒后直接执行线程1脱离线程1将从就绪线程队列中删除
*/
rt_thread_detach(&thread1);
/*
* 线程2继续休眠10个OS Tick然后退出
*/
rt_thread_delay(10);
/*
* 线程2运行结束后也将自动被从就绪队列中删除并脱离线程队列
*/
}
int thread_detach_init()
{
rt_err_t result;
/* 初始化线程1 */
result = rt_thread_init(&thread1, "t1", /* 线程名t1 */
thread1_entry, RT_NULL, /* 线程的入口是thread1_entry入口参数是RT_NULL*/
&thread1_stack[0], sizeof(thread1_stack), /* 线程栈是thread1_stack */
THREAD_PRIORITY, 10);
if (result == RT_EOK) /* 如果返回正确启动线程1 */
rt_thread_startup(&thread1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 初始化线程2 */
result = rt_thread_init(&thread2, "t2", /* 线程名t2 */
thread2_entry, RT_NULL, /* 线程的入口是thread2_entry入口参数是RT_NULL*/
&thread2_stack[0], sizeof(thread2_stack), /* 线程栈是thread2_stack */
THREAD_PRIORITY - 1, 10);
if (result == RT_EOK) /* 如果返回正确启动线程2 */
rt_thread_startup(&thread2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 执行线程脱离 */
if (thread1.stat != RT_THREAD_CLOSE)
rt_thread_detach(&thread1);
if (thread2.stat != RT_THREAD_CLOSE)
rt_thread_detach(&thread2);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_thread_detach()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
thread_detach_init();
/* 返回TestCase运行的最长时间 */
return 25;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_thread_detach, a static thread example);
#else
/* 用户应用入口 */
int rt_application_init()
{
thread_detach_init();
return 0;
}
#endif

View File

@@ -1,44 +1,44 @@
#include <rtthread.h>
#include "tc_comm.h"
static void thread_entry(void* parameter)
{
rt_kprintf("thread dynamicly created ok\n");
rt_thread_delay(10);
rt_kprintf("thread exit\n");
tc_done(TC_STAT_PASSED);
}
int thread_dynamic_init()
{
rt_thread_t tid;
tid = rt_thread_create("test",
thread_entry, RT_NULL,
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid != RT_NULL)
rt_thread_startup(tid);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
int _tc_thread_dynamic()
{
thread_dynamic_init();
return 20;
}
FINSH_FUNCTION_EXPORT(_tc_thread_dynamic, a dynamic thread test);
#else
int rt_application_init()
{
thread_dynamic_init();
return 0;
}
#endif
#include <rtthread.h>
#include "tc_comm.h"
static void thread_entry(void* parameter)
{
rt_kprintf("thread dynamicly created ok\n");
rt_thread_delay(10);
rt_kprintf("thread exit\n");
tc_done(TC_STAT_PASSED);
}
int thread_dynamic_init()
{
rt_thread_t tid;
tid = rt_thread_create("test",
thread_entry, RT_NULL,
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid != RT_NULL)
rt_thread_startup(tid);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
int _tc_thread_dynamic()
{
thread_dynamic_init();
return 20;
}
FINSH_FUNCTION_EXPORT(_tc_thread_dynamic, a dynamic thread test);
#else
int rt_application_init()
{
thread_dynamic_init();
return 0;
}
#endif

View File

@@ -1,89 +1,89 @@
/*
* 程序清单:动态线程
*
* 这个程序会初始化2个动态线程它们拥有共同的入口函数但参数不相同
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 指向线程控制块的指针 */
static rt_thread_t tid1 = RT_NULL;
static rt_thread_t tid2 = RT_NULL;
/* 线程入口 */
static void thread_entry(void* parameter)
{
rt_uint32_t count = 0;
rt_uint32_t no = (rt_uint32_t) parameter; /* 获得正确的入口参数 */
while (1)
{
/* 打印线程计数值输出 */
rt_kprintf("thread%d count: %d\n", no, count ++);
/* 休眠10个OS Tick */
rt_thread_delay(10);
}
}
int thread_dynamic_simple_init()
{
/* 创建线程1 */
tid1 = rt_thread_create("t1",
thread_entry, (void*)1, /* 线程入口是thread_entry, 入口参数是1 */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid1 != RT_NULL)
rt_thread_startup(tid1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建线程2 */
tid2 = rt_thread_create("t2",
thread_entry, (void*)2, /* 线程入口是thread_entry, 入口参数是2 */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid2 != RT_NULL)
rt_thread_startup(tid2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除线程 */
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid1);
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid2);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_thread_dynamic_simple()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
thread_dynamic_simple_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_thread_dynamic_simple, a dynamic thread example);
#else
/* 用户应用入口 */
int rt_application_init()
{
thread_dynamic_simple_init();
return 0;
}
#endif
/*
* 程序清单:动态线程
*
* 这个程序会初始化2个动态线程它们拥有共同的入口函数但参数不相同
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 指向线程控制块的指针 */
static rt_thread_t tid1 = RT_NULL;
static rt_thread_t tid2 = RT_NULL;
/* 线程入口 */
static void thread_entry(void* parameter)
{
rt_uint32_t count = 0;
rt_uint32_t no = (rt_uint32_t) parameter; /* 获得正确的入口参数 */
while (1)
{
/* 打印线程计数值输出 */
rt_kprintf("thread%d count: %d\n", no, count ++);
/* 休眠10个OS Tick */
rt_thread_delay(10);
}
}
int thread_dynamic_simple_init()
{
/* 创建线程1 */
tid1 = rt_thread_create("t1",
thread_entry, (void*)1, /* 线程入口是thread_entry, 入口参数是1 */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid1 != RT_NULL)
rt_thread_startup(tid1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建线程2 */
tid2 = rt_thread_create("t2",
thread_entry, (void*)2, /* 线程入口是thread_entry, 入口参数是2 */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid2 != RT_NULL)
rt_thread_startup(tid2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除线程 */
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid1);
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid2);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_thread_dynamic_simple()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
thread_dynamic_simple_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_thread_dynamic_simple, a dynamic thread example);
#else
/* 用户应用入口 */
int rt_application_init()
{
thread_dynamic_simple_init();
return 0;
}
#endif

View File

@@ -1,105 +1,105 @@
#include <rtthread.h>
#include "tc_comm.h"
struct rt_thread thread1;
struct rt_thread thread2;
static char thread1_stack[THREAD_STACK_SIZE];
static char thread2_stack[THREAD_STACK_SIZE];
static rt_uint32_t count = 0;
/*
* the priority of thread1 > the priority of thread2
*/
static void thread1_entry(void* parameter)
{
while (1)
{
count ++;
rt_kprintf("count = %d\n", count);
rt_thread_delay(10);
}
}
static void thread2_entry(void* parameter)
{
rt_tick_t tick;
tick = rt_tick_get();
while (1)
{
if (rt_tick_get() - tick >= 50)
{
if (count == 0)
tc_done(TC_STAT_FAILED);
else
tc_done(TC_STAT_PASSED);
break;
}
}
}
int thread_priority_init()
{
rt_err_t result;
result = rt_thread_init(&thread1,
"t1",
thread1_entry, RT_NULL,
&thread1_stack[0], sizeof(thread1_stack),
THREAD_PRIORITY - 1, THREAD_TIMESLICE);
if (result == RT_EOK)
rt_thread_startup(&thread1);
else
tc_stat(TC_STAT_FAILED);
rt_thread_init(&thread2,
"t2",
thread2_entry, RT_NULL,
&thread2_stack[0], sizeof(thread2_stack),
THREAD_PRIORITY + 1, THREAD_TIMESLICE);
if (result == RT_EOK)
rt_thread_startup(&thread2);
else
tc_stat(TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* lock scheduler */
rt_enter_critical();
if (thread1.stat != RT_THREAD_CLOSE)
rt_thread_detach(&thread1);
if (thread2.stat != RT_THREAD_CLOSE)
rt_thread_detach(&thread2);
/* unlock scheduler */
rt_exit_critical();
}
int _tc_thread_priority()
{
count = 0;
/* set tc cleanup */
tc_cleanup(_tc_cleanup);
thread_priority_init();
return RT_TICK_PER_SECOND;
}
FINSH_FUNCTION_EXPORT(_tc_thread_priority, a priority thread test);
#else
int rt_application_init()
{
thread_priority_init();
return 0;
}
#endif
#include <rtthread.h>
#include "tc_comm.h"
struct rt_thread thread1;
struct rt_thread thread2;
static char thread1_stack[THREAD_STACK_SIZE];
static char thread2_stack[THREAD_STACK_SIZE];
static rt_uint32_t count = 0;
/*
* the priority of thread1 > the priority of thread2
*/
static void thread1_entry(void* parameter)
{
while (1)
{
count ++;
rt_kprintf("count = %d\n", count);
rt_thread_delay(10);
}
}
static void thread2_entry(void* parameter)
{
rt_tick_t tick;
tick = rt_tick_get();
while (1)
{
if (rt_tick_get() - tick >= 50)
{
if (count == 0)
tc_done(TC_STAT_FAILED);
else
tc_done(TC_STAT_PASSED);
break;
}
}
}
int thread_priority_init()
{
rt_err_t result;
result = rt_thread_init(&thread1,
"t1",
thread1_entry, RT_NULL,
&thread1_stack[0], sizeof(thread1_stack),
THREAD_PRIORITY - 1, THREAD_TIMESLICE);
if (result == RT_EOK)
rt_thread_startup(&thread1);
else
tc_stat(TC_STAT_FAILED);
rt_thread_init(&thread2,
"t2",
thread2_entry, RT_NULL,
&thread2_stack[0], sizeof(thread2_stack),
THREAD_PRIORITY + 1, THREAD_TIMESLICE);
if (result == RT_EOK)
rt_thread_startup(&thread2);
else
tc_stat(TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* lock scheduler */
rt_enter_critical();
if (thread1.stat != RT_THREAD_CLOSE)
rt_thread_detach(&thread1);
if (thread2.stat != RT_THREAD_CLOSE)
rt_thread_detach(&thread2);
/* unlock scheduler */
rt_exit_critical();
}
int _tc_thread_priority()
{
count = 0;
/* set tc cleanup */
tc_cleanup(_tc_cleanup);
thread_priority_init();
return RT_TICK_PER_SECOND;
}
FINSH_FUNCTION_EXPORT(_tc_thread_priority, a priority thread test);
#else
int rt_application_init()
{
thread_priority_init();
return 0;
}
#endif

View File

@@ -1,123 +1,123 @@
/*
* 程序清单:唤醒线程
*
* 这个例子中将创建两个动态线程,低优先级线程将挂起自身,然后
* 高优先级线程将在一定时刻后唤醒低优先级线程。
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 指向线程控制块的指针 */
static rt_thread_t tid1 = RT_NULL;
static rt_thread_t tid2 = RT_NULL;
/* 线程1入口 */
static void thread1_entry(void* parameter)
{
/* 低优先级线程1开始运行 */
rt_kprintf("thread1 startup%d\n");
/* 挂起自身 */
rt_kprintf("suspend thread self\n");
rt_thread_suspend(tid1);
/* 主动执行线程调度 */
rt_schedule();
/* 当线程1被唤醒时 */
rt_kprintf("thread1 resumed\n");
}
static void thread_cleanup(rt_thread_t tid)
{
if (tid == tid1)
{
tid1 = RT_NULL;
}
if (tid == tid2)
{
tid = RT_NULL;
}
}
/* 线程2入口 */
static void thread2_entry(void* parameter)
{
/* 延时10个OS Tick */
rt_thread_delay(10);
/* 唤醒线程1 */
rt_thread_resume(tid1);
rt_kprintf("thread2: to resume thread1\n");
/* 延时10个OS Tick */
rt_thread_delay(10);
/* 线程2自动退出 */
}
int thread_resume_init()
{
/* 创建线程1 */
tid1 = rt_thread_create("thread",
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid1 != RT_NULL)
{
tid1->cleanup = thread_cleanup;
rt_thread_startup(tid1);
}
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建线程2 */
tid2 = rt_thread_create("thread",
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
if (tid2 != RT_NULL)
{
tid2->cleanup = thread_cleanup;
rt_thread_startup(tid2);
}
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除线程 */
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid1);
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid2);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_thread_resume()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
thread_resume_init();
/* 返回TestCase运行的最长时间 */
return 25;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_thread_resume, a thread resume example);
#else
/* 用户应用入口 */
int rt_application_init()
{
thread_resume_init();
return 0;
}
#endif
/*
* 程序清单:唤醒线程
*
* 这个例子中将创建两个动态线程,低优先级线程将挂起自身,然后
* 高优先级线程将在一定时刻后唤醒低优先级线程。
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 指向线程控制块的指针 */
static rt_thread_t tid1 = RT_NULL;
static rt_thread_t tid2 = RT_NULL;
/* 线程1入口 */
static void thread1_entry(void* parameter)
{
/* 低优先级线程1开始运行 */
rt_kprintf("thread1 startup%d\n");
/* 挂起自身 */
rt_kprintf("suspend thread self\n");
rt_thread_suspend(tid1);
/* 主动执行线程调度 */
rt_schedule();
/* 当线程1被唤醒时 */
rt_kprintf("thread1 resumed\n");
}
static void thread_cleanup(rt_thread_t tid)
{
if (tid == tid1)
{
tid1 = RT_NULL;
}
if (tid == tid2)
{
tid = RT_NULL;
}
}
/* 线程2入口 */
static void thread2_entry(void* parameter)
{
/* 延时10个OS Tick */
rt_thread_delay(10);
/* 唤醒线程1 */
rt_thread_resume(tid1);
rt_kprintf("thread2: to resume thread1\n");
/* 延时10个OS Tick */
rt_thread_delay(10);
/* 线程2自动退出 */
}
int thread_resume_init()
{
/* 创建线程1 */
tid1 = rt_thread_create("thread",
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid1 != RT_NULL)
{
tid1->cleanup = thread_cleanup;
rt_thread_startup(tid1);
}
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建线程2 */
tid2 = rt_thread_create("thread",
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
if (tid2 != RT_NULL)
{
tid2->cleanup = thread_cleanup;
rt_thread_startup(tid2);
}
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除线程 */
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid1);
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid2);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_thread_resume()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
thread_resume_init();
/* 返回TestCase运行的最长时间 */
return 25;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_thread_resume, a thread resume example);
#else
/* 用户应用入口 */
int rt_application_init()
{
thread_resume_init();
return 0;
}
#endif

View File

@@ -1,96 +1,96 @@
#include <rtthread.h>
#include "tc_comm.h"
static struct rt_thread thread1;
static struct rt_thread thread2;
static char thread1_stack[THREAD_STACK_SIZE];
static char thread2_stack[THREAD_STACK_SIZE];
volatile static rt_uint32_t t1_count = 0;
volatile static rt_uint32_t t2_count = 0;
static void thread1_entry(void* parameter)
{
while (1)
{
t1_count ++;
}
}
static void thread2_entry(void* parameter)
{
while (1)
{
t2_count ++;
}
}
rt_err_t thread_same_priority_init()
{
rt_err_t result;
result = rt_thread_init(&thread1,
"t1",
thread1_entry, RT_NULL,
&thread1_stack[0], sizeof(thread1_stack),
THREAD_PRIORITY, 10);
if (result == RT_EOK)
rt_thread_startup(&thread1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
result = rt_thread_init(&thread2,
"t2",
thread2_entry, RT_NULL,
&thread2_stack[0], sizeof(thread2_stack),
THREAD_PRIORITY, 5);
if (result == RT_EOK)
rt_thread_startup(&thread2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return result;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* lock scheduler */
rt_enter_critical();
if (thread1.stat != RT_THREAD_CLOSE)
rt_thread_detach(&thread1);
if (thread2.stat != RT_THREAD_CLOSE)
rt_thread_detach(&thread2);
/* unlock scheduler */
rt_exit_critical();
rt_kprintf("t1_count=%d t2_count=%d\n",t1_count,t2_count);
if (t1_count / t2_count != 2)
tc_stat(TC_STAT_END | TC_STAT_FAILED);
else
tc_done(TC_STAT_PASSED);
}
int _tc_thread_same_priority()
{
t1_count = 0;
t2_count = 0;
/* set tc cleanup */
tc_cleanup(_tc_cleanup);
thread_same_priority_init();
return 100;
}
FINSH_FUNCTION_EXPORT(_tc_thread_same_priority, a same priority thread test);
#else
int rt_application_init()
{
thread_same_priority_init();
return 0;
}
#endif
#include <rtthread.h>
#include "tc_comm.h"
static struct rt_thread thread1;
static struct rt_thread thread2;
static char thread1_stack[THREAD_STACK_SIZE];
static char thread2_stack[THREAD_STACK_SIZE];
volatile static rt_uint32_t t1_count = 0;
volatile static rt_uint32_t t2_count = 0;
static void thread1_entry(void* parameter)
{
while (1)
{
t1_count ++;
}
}
static void thread2_entry(void* parameter)
{
while (1)
{
t2_count ++;
}
}
rt_err_t thread_same_priority_init()
{
rt_err_t result;
result = rt_thread_init(&thread1,
"t1",
thread1_entry, RT_NULL,
&thread1_stack[0], sizeof(thread1_stack),
THREAD_PRIORITY, 10);
if (result == RT_EOK)
rt_thread_startup(&thread1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
result = rt_thread_init(&thread2,
"t2",
thread2_entry, RT_NULL,
&thread2_stack[0], sizeof(thread2_stack),
THREAD_PRIORITY, 5);
if (result == RT_EOK)
rt_thread_startup(&thread2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return result;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* lock scheduler */
rt_enter_critical();
if (thread1.stat != RT_THREAD_CLOSE)
rt_thread_detach(&thread1);
if (thread2.stat != RT_THREAD_CLOSE)
rt_thread_detach(&thread2);
/* unlock scheduler */
rt_exit_critical();
rt_kprintf("t1_count=%d t2_count=%d\n",t1_count,t2_count);
if (t1_count / t2_count != 2)
tc_stat(TC_STAT_END | TC_STAT_FAILED);
else
tc_done(TC_STAT_PASSED);
}
int _tc_thread_same_priority()
{
t1_count = 0;
t2_count = 0;
/* set tc cleanup */
tc_cleanup(_tc_cleanup);
thread_same_priority_init();
return 100;
}
FINSH_FUNCTION_EXPORT(_tc_thread_same_priority, a same priority thread test);
#else
int rt_application_init()
{
thread_same_priority_init();
return 0;
}
#endif

View File

@@ -1,52 +1,52 @@
#include <rtthread.h>
#include "tc_comm.h"
/*
* This is an example for static thread
*/
static struct rt_thread thread;
static char thread_stack[THREAD_STACK_SIZE];
static void thread_entry(void* parameter)
{
rt_kprintf("thread staticly inited ok\n");
rt_thread_delay(10);
rt_kprintf("thread exit\n");
tc_done(TC_STAT_PASSED);
}
rt_err_t thread_static_init()
{
rt_err_t result;
result = rt_thread_init(&thread,
"test",
thread_entry, RT_NULL,
&thread_stack[0], sizeof(thread_stack),
THREAD_PRIORITY, 10);
if (result == RT_EOK)
rt_thread_startup(&thread);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return result;
}
#ifdef RT_USING_TC
int _tc_thread_static()
{
thread_static_init();
return 20;
}
FINSH_FUNCTION_EXPORT(_tc_thread_static, a static thread test);
#else
int rt_application_init()
{
thread_static_init();
return 0;
}
#endif
#include <rtthread.h>
#include "tc_comm.h"
/*
* This is an example for static thread
*/
static struct rt_thread thread;
static char thread_stack[THREAD_STACK_SIZE];
static void thread_entry(void* parameter)
{
rt_kprintf("thread staticly inited ok\n");
rt_thread_delay(10);
rt_kprintf("thread exit\n");
tc_done(TC_STAT_PASSED);
}
rt_err_t thread_static_init()
{
rt_err_t result;
result = rt_thread_init(&thread,
"test",
thread_entry, RT_NULL,
&thread_stack[0], sizeof(thread_stack),
THREAD_PRIORITY, 10);
if (result == RT_EOK)
rt_thread_startup(&thread);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return result;
}
#ifdef RT_USING_TC
int _tc_thread_static()
{
thread_static_init();
return 20;
}
FINSH_FUNCTION_EXPORT(_tc_thread_static, a static thread test);
#else
int rt_application_init()
{
thread_static_init();
return 0;
}
#endif

View File

@@ -1,99 +1,99 @@
/*
* 程序清单:静态线程
*
* 这个程序会初始化2个静态线程它们拥有共同的入口函数但参数不相同
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 线程1控制块 */
static struct rt_thread thread1;
/* 线程1栈 */
static rt_uint8_t thread1_stack[THREAD_STACK_SIZE];
/* 线程2控制块 */
static struct rt_thread thread2;
/* 线程2栈 */
static rt_uint8_t thread2_stack[THREAD_STACK_SIZE];
/* 线程入口 */
static void thread_entry(void* parameter)
{
rt_uint32_t count = 0;
rt_uint32_t no = (rt_uint32_t) parameter; /* 获得正确的入口参数 */
while (1)
{
/* 打印线程计数值输出 */
rt_kprintf("thread%d count: %d\n", no, count ++);
/* 休眠10个OS Tick */
rt_thread_delay(10);
}
}
int thread_static_simple_init()
{
rt_err_t result;
/* 初始化线程1 */
result = rt_thread_init(&thread1, "t1", /* 线程名t1 */
thread_entry, (void*)1, /* 线程的入口是thread_entry入口参数是1 */
&thread1_stack[0], sizeof(thread1_stack), /* 线程栈是thread1_stack */
THREAD_PRIORITY, 10);
if (result == RT_EOK) /* 如果返回正确启动线程1 */
rt_thread_startup(&thread1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 初始化线程2 */
result = rt_thread_init(&thread2, "t2", /* 线程名t2 */
thread_entry, RT_NULL, /* 线程的入口是thread_entry入口参数是2 */
&thread2_stack[0], sizeof(thread2_stack), /* 线程栈是thread2_stack */
THREAD_PRIORITY + 1, 10);
if (result == RT_EOK) /* 如果返回正确启动线程2 */
rt_thread_startup(&thread2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 执行线程脱离 */
if (thread1.stat != RT_THREAD_CLOSE)
rt_thread_detach(&thread1);
if (thread2.stat != RT_THREAD_CLOSE)
rt_thread_detach(&thread2);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_thread_static_simple()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
thread_static_simple_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_thread_static_simple, a static thread example);
#else
/* 用户应用入口 */
int rt_application_init()
{
thread_static_simple_init();
return 0;
}
#endif
/*
* 程序清单:静态线程
*
* 这个程序会初始化2个静态线程它们拥有共同的入口函数但参数不相同
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 线程1控制块 */
static struct rt_thread thread1;
/* 线程1栈 */
static rt_uint8_t thread1_stack[THREAD_STACK_SIZE];
/* 线程2控制块 */
static struct rt_thread thread2;
/* 线程2栈 */
static rt_uint8_t thread2_stack[THREAD_STACK_SIZE];
/* 线程入口 */
static void thread_entry(void* parameter)
{
rt_uint32_t count = 0;
rt_uint32_t no = (rt_uint32_t) parameter; /* 获得正确的入口参数 */
while (1)
{
/* 打印线程计数值输出 */
rt_kprintf("thread%d count: %d\n", no, count ++);
/* 休眠10个OS Tick */
rt_thread_delay(10);
}
}
int thread_static_simple_init()
{
rt_err_t result;
/* 初始化线程1 */
result = rt_thread_init(&thread1, "t1", /* 线程名t1 */
thread_entry, (void*)1, /* 线程的入口是thread_entry入口参数是1 */
&thread1_stack[0], sizeof(thread1_stack), /* 线程栈是thread1_stack */
THREAD_PRIORITY, 10);
if (result == RT_EOK) /* 如果返回正确启动线程1 */
rt_thread_startup(&thread1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 初始化线程2 */
result = rt_thread_init(&thread2, "t2", /* 线程名t2 */
thread_entry, RT_NULL, /* 线程的入口是thread_entry入口参数是2 */
&thread2_stack[0], sizeof(thread2_stack), /* 线程栈是thread2_stack */
THREAD_PRIORITY + 1, 10);
if (result == RT_EOK) /* 如果返回正确启动线程2 */
rt_thread_startup(&thread2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 执行线程脱离 */
if (thread1.stat != RT_THREAD_CLOSE)
rt_thread_detach(&thread1);
if (thread2.stat != RT_THREAD_CLOSE)
rt_thread_detach(&thread2);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_thread_static_simple()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
thread_static_simple_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_thread_static_simple, a static thread example);
#else
/* 用户应用入口 */
int rt_application_init()
{
thread_static_simple_init();
return 0;
}
#endif

View File

@@ -1,101 +1,101 @@
/*
* 程序清单:挂起线程
*
* 这个例子中将创建两个动态线程,高优先级线程将在一定时刻后挂起低优先级线程。
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 指向线程控制块的指针 */
static rt_thread_t tid1 = RT_NULL;
static rt_thread_t tid2 = RT_NULL;
/* 线程1入口 */
static void thread1_entry(void* parameter)
{
rt_uint32_t count = 0;
while (1)
{
/* 线程1采用低优先级运行一直打印计数值 */
rt_kprintf("thread count: %d\n", count ++);
}
}
/* 线程2入口 */
static void thread2_entry(void* parameter)
{
/* 延时10个OS Tick */
rt_thread_delay(10);
/* 挂起线程1 */
rt_thread_suspend(tid1);
/* 延时10个OS Tick */
rt_thread_delay(10);
/* 线程2自动退出 */
tid2 = RT_NULL;
}
int thread_suspend_init()
{
/* 创建线程1 */
tid1 = rt_thread_create("thread",
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid1 != RT_NULL)
rt_thread_startup(tid1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建线程2 */
tid2 = rt_thread_create("thread",
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
if (tid2 != RT_NULL)
rt_thread_startup(tid2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除线程 */
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid1);
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid2);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_thread_suspend()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
thread_suspend_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_thread_suspend, a thread suspend example);
#else
/* 用户应用入口 */
int rt_application_init()
{
thread_suspend_init();
return 0;
}
#endif
/*
* 程序清单:挂起线程
*
* 这个例子中将创建两个动态线程,高优先级线程将在一定时刻后挂起低优先级线程。
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 指向线程控制块的指针 */
static rt_thread_t tid1 = RT_NULL;
static rt_thread_t tid2 = RT_NULL;
/* 线程1入口 */
static void thread1_entry(void* parameter)
{
rt_uint32_t count = 0;
while (1)
{
/* 线程1采用低优先级运行一直打印计数值 */
rt_kprintf("thread count: %d\n", count ++);
}
}
/* 线程2入口 */
static void thread2_entry(void* parameter)
{
/* 延时10个OS Tick */
rt_thread_delay(10);
/* 挂起线程1 */
rt_thread_suspend(tid1);
/* 延时10个OS Tick */
rt_thread_delay(10);
/* 线程2自动退出 */
tid2 = RT_NULL;
}
int thread_suspend_init()
{
/* 创建线程1 */
tid1 = rt_thread_create("thread",
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid1 != RT_NULL)
rt_thread_startup(tid1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建线程2 */
tid2 = rt_thread_create("thread",
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
if (tid2 != RT_NULL)
rt_thread_startup(tid2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除线程 */
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid1);
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid2);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_thread_suspend()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
thread_suspend_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_thread_suspend, a thread suspend example);
#else
/* 用户应用入口 */
int rt_application_init()
{
thread_suspend_init();
return 0;
}
#endif

View File

@@ -1,101 +1,101 @@
/*
* 程序清单:
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 指向线程控制块的指针 */
static rt_thread_t tid1 = RT_NULL;
static rt_thread_t tid2 = RT_NULL;
/* 线程1入口 */
static void thread1_entry(void* parameter)
{
rt_uint32_t count = 0;
while (1)
{
/* 打印线程1的输出 */
rt_kprintf("thread1: count = %d\n", count ++);
/* 执行yield后应该切换到thread2执行 */
rt_thread_yield();
}
}
/* 线程2入口 */
static void thread2_entry(void* parameter)
{
rt_uint32_t count = 0;
while (1)
{
/* 打印线程2的输出 */
rt_kprintf("thread2: count = %d\n", count ++);
/* 执行yield后应该切换到thread1执行 */
rt_thread_yield();
}
}
int thread_yield_init()
{
/* 创建线程1 */
tid1 = rt_thread_create("thread",
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid1 != RT_NULL)
rt_thread_startup(tid1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建线程2 */
tid2 = rt_thread_create("thread",
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid2 != RT_NULL)
rt_thread_startup(tid2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除线程 */
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid1);
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid2);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_thread_yield()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
thread_yield_init();
/* 返回TestCase运行的最长时间 */
return 30;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_thread_yield, a thread yield example);
#else
/* 用户应用入口 */
int rt_application_init()
{
thread_yield_init();
return 0;
}
#endif
/*
* 程序清单:
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 指向线程控制块的指针 */
static rt_thread_t tid1 = RT_NULL;
static rt_thread_t tid2 = RT_NULL;
/* 线程1入口 */
static void thread1_entry(void* parameter)
{
rt_uint32_t count = 0;
while (1)
{
/* 打印线程1的输出 */
rt_kprintf("thread1: count = %d\n", count ++);
/* 执行yield后应该切换到thread2执行 */
rt_thread_yield();
}
}
/* 线程2入口 */
static void thread2_entry(void* parameter)
{
rt_uint32_t count = 0;
while (1)
{
/* 打印线程2的输出 */
rt_kprintf("thread2: count = %d\n", count ++);
/* 执行yield后应该切换到thread1执行 */
rt_thread_yield();
}
}
int thread_yield_init()
{
/* 创建线程1 */
tid1 = rt_thread_create("thread",
thread1_entry, RT_NULL, /* 线程入口是thread1_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid1 != RT_NULL)
rt_thread_startup(tid1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建线程2 */
tid2 = rt_thread_create("thread",
thread2_entry, RT_NULL, /* 线程入口是thread2_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid2 != RT_NULL)
rt_thread_startup(tid2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除线程 */
if (tid1 != RT_NULL && tid1->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid1);
if (tid2 != RT_NULL && tid2->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid2);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_thread_yield()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
thread_yield_init();
/* 返回TestCase运行的最长时间 */
return 30;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_thread_yield, a thread yield example);
#else
/* 用户应用入口 */
int rt_application_init()
{
thread_yield_init();
return 0;
}
#endif

View File

@@ -1,84 +1,84 @@
/*
* 程序清单:动态定时器例程
*
* 这个例程会创建1个动态周期型定时器对象然后控制它进行定时时间长度的更改。
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 定时器的控制块 */
static rt_timer_t timer1;
static rt_uint8_t count;
/* 定时器超时函数 */
static void timeout1(void* parameter)
{
rt_tick_t timeout = 50;
rt_kprintf("periodic timer is timeout\n");
count ++;
/* 停止定时器自身 */
if (count >= 8)
{
/* 控制定时器然后更改超时时间长度 */
rt_timer_control(timer1, RT_TIMER_CTRL_SET_TIME, (void *)&timeout);
count = 0;
}
}
void timer_control_init()
{
/* 创建定时器1 */
timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */
timeout1, /* 超时时回调的处理函数 */
RT_NULL, /* 超时函数的入口参数 */
10, /* 定时长度以OS Tick为单位即10个OS Tick */
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
/* 启动定时器 */
if (timer1 != RT_NULL)
rt_timer_start(timer1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除定时器对象 */
rt_timer_delete(timer1);
timer1 = RT_NULL;
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_timer_control()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
/* 执行定时器例程 */
count = 0;
timer_control_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_timer_control, a timer control example);
#else
/* 用户应用入口 */
int rt_application_init()
{
timer_control_init();
return 0;
}
#endif
/*
* 程序清单:动态定时器例程
*
* 这个例程会创建1个动态周期型定时器对象然后控制它进行定时时间长度的更改。
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 定时器的控制块 */
static rt_timer_t timer1;
static rt_uint8_t count;
/* 定时器超时函数 */
static void timeout1(void* parameter)
{
rt_tick_t timeout = 50;
rt_kprintf("periodic timer is timeout\n");
count ++;
/* 停止定时器自身 */
if (count >= 8)
{
/* 控制定时器然后更改超时时间长度 */
rt_timer_control(timer1, RT_TIMER_CTRL_SET_TIME, (void *)&timeout);
count = 0;
}
}
void timer_control_init()
{
/* 创建定时器1 */
timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */
timeout1, /* 超时时回调的处理函数 */
RT_NULL, /* 超时函数的入口参数 */
10, /* 定时长度以OS Tick为单位即10个OS Tick */
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
/* 启动定时器 */
if (timer1 != RT_NULL)
rt_timer_start(timer1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除定时器对象 */
rt_timer_delete(timer1);
timer1 = RT_NULL;
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_timer_control()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
/* 执行定时器例程 */
count = 0;
timer_control_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_timer_control, a timer control example);
#else
/* 用户应用入口 */
int rt_application_init()
{
timer_control_init();
return 0;
}
#endif

View File

@@ -1,91 +1,91 @@
/*
* 程序清单:动态定时器例程
*
* 这个例程会创建两个动态定时器对象,一个是单次定时,一个是周期性的定时
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 定时器的控制块 */
static rt_timer_t timer1;
static rt_timer_t timer2;
/* 定时器1超时函数 */
static void timeout1(void* parameter)
{
rt_kprintf("periodic timer is timeout\n");
}
/* 定时器2超时函数 */
static void timeout2(void* parameter)
{
rt_kprintf("one shot timer is timeout\n");
}
void timer_create_init()
{
/* 创建定时器1 */
timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */
timeout1, /* 超时时回调的处理函数 */
RT_NULL, /* 超时函数的入口参数 */
10, /* 定时长度以OS Tick为单位即10个OS Tick */
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
/* 启动定时器 */
if (timer1 != RT_NULL)
rt_timer_start(timer1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建定时器2 */
timer2 = rt_timer_create("timer2", /* 定时器名字是 timer2 */
timeout2, /* 超时时回调的处理函数 */
RT_NULL, /* 超时函数的入口参数 */
30, /* 定时长度为30个OS Tick */
RT_TIMER_FLAG_ONE_SHOT); /* 单次定时器 */
/* 启动定时器 */
if (timer2 != RT_NULL)
rt_timer_start(timer2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除定时器对象 */
rt_timer_delete(timer1);
rt_timer_delete(timer2);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_timer_create()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
/* 执行定时器例程 */
timer_create_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_timer_create, a dynamic timer example);
#else
/* 用户应用入口 */
int rt_application_init()
{
timer_create_init();
return 0;
}
#endif
/*
* 程序清单:动态定时器例程
*
* 这个例程会创建两个动态定时器对象,一个是单次定时,一个是周期性的定时
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 定时器的控制块 */
static rt_timer_t timer1;
static rt_timer_t timer2;
/* 定时器1超时函数 */
static void timeout1(void* parameter)
{
rt_kprintf("periodic timer is timeout\n");
}
/* 定时器2超时函数 */
static void timeout2(void* parameter)
{
rt_kprintf("one shot timer is timeout\n");
}
void timer_create_init()
{
/* 创建定时器1 */
timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */
timeout1, /* 超时时回调的处理函数 */
RT_NULL, /* 超时函数的入口参数 */
10, /* 定时长度以OS Tick为单位即10个OS Tick */
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
/* 启动定时器 */
if (timer1 != RT_NULL)
rt_timer_start(timer1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建定时器2 */
timer2 = rt_timer_create("timer2", /* 定时器名字是 timer2 */
timeout2, /* 超时时回调的处理函数 */
RT_NULL, /* 超时函数的入口参数 */
30, /* 定时长度为30个OS Tick */
RT_TIMER_FLAG_ONE_SHOT); /* 单次定时器 */
/* 启动定时器 */
if (timer2 != RT_NULL)
rt_timer_start(timer2);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除定时器对象 */
rt_timer_delete(timer1);
rt_timer_delete(timer2);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_timer_create()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
/* 执行定时器例程 */
timer_create_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_timer_create, a dynamic timer example);
#else
/* 用户应用入口 */
int rt_application_init()
{
timer_create_init();
return 0;
}
#endif

View File

@@ -1,82 +1,82 @@
/*
* 程序清单:动态定时器例程
*
* 这个例程会创建1个动态周期型定时器对象
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 定时器的控制块 */
static rt_timer_t timer1;
static rt_uint8_t count;
/* 定时器超时函数 */
static void timeout1(void* parameter)
{
rt_kprintf("periodic timer is timeout\n");
count ++;
/* 停止定时器自身 */
if (count >= 8)
{
/* 停止定时器 */
rt_timer_stop(timer1);
count = 0;
}
}
void timer_stop_self_init()
{
/* 创建定时器1 */
timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */
timeout1, /* 超时时回调的处理函数 */
RT_NULL, /* 超时函数的入口参数 */
10, /* 定时长度以OS Tick为单位即10个OS Tick */
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
/* 启动定时器 */
if (timer1 != RT_NULL)
rt_timer_start(timer1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除定时器对象 */
rt_timer_delete(timer1);
timer1 = RT_NULL;
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_timer_stop_self()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
/* 执行定时器例程 */
count = 0;
timer_stop_self_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_timer_stop_self, a dynamic timer example);
#else
/* 用户应用入口 */
int rt_application_init()
{
timer_stop_self_init();
return 0;
}
#endif
/*
* 程序清单:动态定时器例程
*
* 这个例程会创建1个动态周期型定时器对象
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 定时器的控制块 */
static rt_timer_t timer1;
static rt_uint8_t count;
/* 定时器超时函数 */
static void timeout1(void* parameter)
{
rt_kprintf("periodic timer is timeout\n");
count ++;
/* 停止定时器自身 */
if (count >= 8)
{
/* 停止定时器 */
rt_timer_stop(timer1);
count = 0;
}
}
void timer_stop_self_init()
{
/* 创建定时器1 */
timer1 = rt_timer_create("timer1", /* 定时器名字是 timer1 */
timeout1, /* 超时时回调的处理函数 */
RT_NULL, /* 超时函数的入口参数 */
10, /* 定时长度以OS Tick为单位即10个OS Tick */
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
/* 启动定时器 */
if (timer1 != RT_NULL)
rt_timer_start(timer1);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除定时器对象 */
rt_timer_delete(timer1);
timer1 = RT_NULL;
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_timer_stop_self()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
/* 执行定时器例程 */
count = 0;
timer_stop_self_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_timer_stop_self, a dynamic timer example);
#else
/* 用户应用入口 */
int rt_application_init()
{
timer_stop_self_init();
return 0;
}
#endif

View File

@@ -1,122 +1,122 @@
/*
* 程序清单:消息队列例程
*
* 这个程序会创建3个动态线程一个线程会从消息队列中收取消息一个线程会定时给消
* 息队列发送消息;一个线程会定时给消息队列发送紧急消息。
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 指向线程控制块的指针 */
static rt_thread_t tid = RT_NULL;
/* 消息队列控制块 */
static struct rt_messagequeue mq;
/* 消息队列中用到的放置消息的内存池 */
static char msg_pool[2048];
/* 定时器的控制块 */
static struct rt_timer timer;
static rt_uint16_t no = 0;
static void timer_timeout(void* parameter)
{
char buf[32];
rt_uint32_t length;
length = rt_snprintf(buf, sizeof(buf), "message %d", no++);
rt_mq_send(&mq, &buf[0], length);
}
/* 线程入口函数 */
static void thread_entry(void* parameter)
{
char buf[64];
rt_err_t result;
/* 初始化定时器 */
rt_timer_init(&timer, "timer", /* 定时器名字是 timer1 */
timer_timeout, /* 超时时回调的处理函数 */
RT_NULL, /* 超时函数的入口参数 */
1, /* 定时长度以OS Tick为单位即1个OS Tick */
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
while (1)
{
rt_memset(&buf[0], 0, sizeof(buf));
/* 从消息队列中接收消息 */
result = rt_mq_recv(&mq, &buf[0], sizeof(buf), 1);
if (result == RT_EOK)
{
rt_kprintf("recv msg: %s\n", buf);
}
else if (result == -RT_ETIMEOUT)
{
rt_kprintf("recv msg timeout\n");
}
}
}
int timer_timeout_init()
{
/* 初始化消息队列 */
rt_mq_init(&mq, "mqt",
&msg_pool[0], /* 内存池指向msg_pool */
128 - sizeof(void*), /* 每个消息的大小是 128 - void* */
sizeof(msg_pool), /* 内存池的大小是msg_pool的大小 */
RT_IPC_FLAG_FIFO); /* 如果有多个线程等待,按照先来先得到的方法分配消息 */
/* 创建线程 */
tid = rt_thread_create("t",
thread_entry, RT_NULL, /* 线程入口是thread_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid != RT_NULL)
rt_thread_startup(tid);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除线程 */
if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid);
/* 执行消息队列对象脱离 */
rt_mq_detach(&mq);
/* 执行定时器脱离 */
rt_timer_detach(&timer);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_timer_timeout()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
timer_timeout_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_timer_timeout, a thread timer testcase);
#else
/* 用户应用入口 */
int rt_application_init()
{
timer_timeout_init();
return 0;
}
#endif
/*
* 程序清单:消息队列例程
*
* 这个程序会创建3个动态线程一个线程会从消息队列中收取消息一个线程会定时给消
* 息队列发送消息;一个线程会定时给消息队列发送紧急消息。
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 指向线程控制块的指针 */
static rt_thread_t tid = RT_NULL;
/* 消息队列控制块 */
static struct rt_messagequeue mq;
/* 消息队列中用到的放置消息的内存池 */
static char msg_pool[2048];
/* 定时器的控制块 */
static struct rt_timer timer;
static rt_uint16_t no = 0;
static void timer_timeout(void* parameter)
{
char buf[32];
rt_uint32_t length;
length = rt_snprintf(buf, sizeof(buf), "message %d", no++);
rt_mq_send(&mq, &buf[0], length);
}
/* 线程入口函数 */
static void thread_entry(void* parameter)
{
char buf[64];
rt_err_t result;
/* 初始化定时器 */
rt_timer_init(&timer, "timer", /* 定时器名字是 timer1 */
timer_timeout, /* 超时时回调的处理函数 */
RT_NULL, /* 超时函数的入口参数 */
1, /* 定时长度以OS Tick为单位即1个OS Tick */
RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
while (1)
{
rt_memset(&buf[0], 0, sizeof(buf));
/* 从消息队列中接收消息 */
result = rt_mq_recv(&mq, &buf[0], sizeof(buf), 1);
if (result == RT_EOK)
{
rt_kprintf("recv msg: %s\n", buf);
}
else if (result == -RT_ETIMEOUT)
{
rt_kprintf("recv msg timeout\n");
}
}
}
int timer_timeout_init()
{
/* 初始化消息队列 */
rt_mq_init(&mq, "mqt",
&msg_pool[0], /* 内存池指向msg_pool */
128 - sizeof(void*), /* 每个消息的大小是 128 - void* */
sizeof(msg_pool), /* 内存池的大小是msg_pool的大小 */
RT_IPC_FLAG_FIFO); /* 如果有多个线程等待,按照先来先得到的方法分配消息 */
/* 创建线程 */
tid = rt_thread_create("t",
thread_entry, RT_NULL, /* 线程入口是thread_entry, 入口参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid != RT_NULL)
rt_thread_startup(tid);
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除线程 */
if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid);
/* 执行消息队列对象脱离 */
rt_mq_detach(&mq);
/* 执行定时器脱离 */
rt_timer_detach(&timer);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_timer_timeout()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
timer_timeout_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_timer_timeout, a thread timer testcase);
#else
/* 用户应用入口 */
int rt_application_init()
{
timer_timeout_init();
return 0;
}
#endif

View File

@@ -1,6 +1,6 @@
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')

View File

@@ -1,56 +1,56 @@
/*
* dirent.c
*
* Created on: 2010-11-17
* Author: bernard
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
#include <dirent.h>
int libc_dirent()
{
DIR * dirp;
long int save3 = 0;
long int cur;
int i = 0;
int result = 0;
struct dirent *dp;
dirp = opendir("/");
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
{
/* save position 3 (after fourth entry) */
if (i++ == 3)
save3 = telldir(dirp);
printf("%s\n", dp->d_name);
/* stop at 400 (just to make sure dirp->__offset and dirp->__size are
scrambled */
if (i == 400)
break;
}
printf("going back past 4-th entry...\n");
/* go back to saved entry */
seekdir(dirp, save3);
/* Check whether telldir equals to save3 now. */
cur = telldir(dirp);
if (cur != save3)
{
printf("seekdir (d, %ld); telldir (d) == %ld\n", save3, cur);
result = 1;
}
/* print remaining files (3-last) */
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
printf("%s\n", dp->d_name);
closedir(dirp);
return result;
}
FINSH_FUNCTION_EXPORT(libc_dirent, dirent test for libc);
/*
* dirent.c
*
* Created on: 2010-11-17
* Author: bernard
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
#include <dirent.h>
int libc_dirent()
{
DIR * dirp;
long int save3 = 0;
long int cur;
int i = 0;
int result = 0;
struct dirent *dp;
dirp = opendir("/");
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
{
/* save position 3 (after fourth entry) */
if (i++ == 3)
save3 = telldir(dirp);
printf("%s\n", dp->d_name);
/* stop at 400 (just to make sure dirp->__offset and dirp->__size are
scrambled */
if (i == 400)
break;
}
printf("going back past 4-th entry...\n");
/* go back to saved entry */
seekdir(dirp, save3);
/* Check whether telldir equals to save3 now. */
cur = telldir(dirp);
if (cur != save3)
{
printf("seekdir (d, %ld); telldir (d) == %ld\n", save3, cur);
result = 1;
}
/* print remaining files (3-last) */
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
printf("%s\n", dp->d_name);
closedir(dirp);
return result;
}
FINSH_FUNCTION_EXPORT(libc_dirent, dirent test for libc);

Some files were not shown because too many files have changed in this diff Show More