mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-02-06 00:45:22 +08:00
convert end of line
This commit is contained in:
@@ -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
@@ -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__ */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
@@ -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).
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
/*@}*/
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
/*@}*/
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user