convert end of line

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

View File

@ -1,129 +1,129 @@
/*
* crc calculation stuff
*/
/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
static unsigned short crctab[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
/*
* updcrc macro derived from article Copyright (C) 1986 Stephen Satchell.
* NOTE: First srgument must be in range 0 to 255.
* Second argument is referenced twice.
*
* Programmers may incorporate any or all code into their programs,
* giving proper credit within the source. Publication of the
* source routines is permitted so long as proper credit is given
* to Stephen Satchell, Satchell Evaluations and Chuck Forsberg,
* Omen Technology.
*/
#define updcrc16(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
/*
* Copyright (C) 1986 Gary S. Brown. You may use this program, or
* code or tables extracted from it, as desired without restriction.
*/
/* First, the polynomial itself and its table of feedback terms. The */
/* polynomial is */
/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
/* Note that we take it "backwards" and put the highest-order term in */
/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
/* the MSB being 1. */
/* Note that the usual hardware shift register implementation, which */
/* is what we're using (we're merely optimizing it by doing eight-bit */
/* chunks at a time) shifts bits into the lowest-order term. In our */
/* implementation, that means shifting towards the right. Why do we */
/* do it this way? Because the calculated CRC must be transmitted in */
/* order from highest-order term to lowest-order term. UARTs transmit */
/* characters in order from LSB to MSB. By storing the CRC this way, */
/* we hand it to the UART in the order low-byte to high-byte; the UART */
/* sends each low-bit to hight-bit; and the result is transmission bit */
/* by bit from highest- to lowest-order term without requiring any bit */
/* shuffling on our part. Reception works similarly. */
/* The feedback terms table consists of 256, 32-bit entries. Notes: */
/* */
/* The table can be generated at runtime if desired; code to do so */
/* is shown later. It might not be obvious, but the feedback */
/* terms simply represent the results of eight shift/xor opera- */
/* tions for all combinations of data and CRC register values. */
/* */
/* The values must be right-shifted by eight bits by the "updcrc" */
/* logic; the shift must be unsigned (bring in zeroes). On some */
/* hardware you could probably optimize the shift in assembler by */
/* using byte-swap instructions. */
static unsigned long cr3tab[] = { /* CRC polynomial 0xedb88320 */
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
#define updcrc32(b, c) (cr3tab[((int)c ^ b) & 0xff] ^ ((c >> 8) & 0x00FFFFFF))
/* End of crc.c */
/*
* crc calculation stuff
*/
/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
static unsigned short crctab[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
/*
* updcrc macro derived from article Copyright (C) 1986 Stephen Satchell.
* NOTE: First srgument must be in range 0 to 255.
* Second argument is referenced twice.
*
* Programmers may incorporate any or all code into their programs,
* giving proper credit within the source. Publication of the
* source routines is permitted so long as proper credit is given
* to Stephen Satchell, Satchell Evaluations and Chuck Forsberg,
* Omen Technology.
*/
#define updcrc16(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
/*
* Copyright (C) 1986 Gary S. Brown. You may use this program, or
* code or tables extracted from it, as desired without restriction.
*/
/* First, the polynomial itself and its table of feedback terms. The */
/* polynomial is */
/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
/* Note that we take it "backwards" and put the highest-order term in */
/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
/* the MSB being 1. */
/* Note that the usual hardware shift register implementation, which */
/* is what we're using (we're merely optimizing it by doing eight-bit */
/* chunks at a time) shifts bits into the lowest-order term. In our */
/* implementation, that means shifting towards the right. Why do we */
/* do it this way? Because the calculated CRC must be transmitted in */
/* order from highest-order term to lowest-order term. UARTs transmit */
/* characters in order from LSB to MSB. By storing the CRC this way, */
/* we hand it to the UART in the order low-byte to high-byte; the UART */
/* sends each low-bit to hight-bit; and the result is transmission bit */
/* by bit from highest- to lowest-order term without requiring any bit */
/* shuffling on our part. Reception works similarly. */
/* The feedback terms table consists of 256, 32-bit entries. Notes: */
/* */
/* The table can be generated at runtime if desired; code to do so */
/* is shown later. It might not be obvious, but the feedback */
/* terms simply represent the results of eight shift/xor opera- */
/* tions for all combinations of data and CRC register values. */
/* */
/* The values must be right-shifted by eight bits by the "updcrc" */
/* logic; the shift must be unsigned (bring in zeroes). On some */
/* hardware you could probably optimize the shift in assembler by */
/* using byte-swap instructions. */
static unsigned long cr3tab[] = { /* CRC polynomial 0xedb88320 */
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
#define updcrc32(b, c) (cr3tab[((int)c ^ b) & 0xff] ^ ((c >> 8) & 0x00FFFFFF))
/* End of crc.c */

View File

@ -1,401 +1,401 @@
/*
* File : rz.c
* the implemention of receiving files from the remote computers
* File : rz.c
* the implemention of receiving files from the remote computers
* through the zmodem protocol.
* Change Logs:
* Date Author Notes
* 2011-03-29 itspy
* 2011-12-12 aozima fixed syntax error.
*/
#include <rtthread.h>
#include <finsh.h>
#include <shell.h>
#include <rtdef.h>
#include <dfs.h>
#include <dfs_file.h>
#include <dfs_posix.h>
#include <stdio.h>
#include "zdef.h"
void zr_start(char *path);
static rt_err_t zrec_init(rt_uint8_t *rxbuf, struct zfile *zf);
static rt_err_t zrec_files(struct zfile *zf);
static rt_err_t zwrite_file(rt_uint8_t *buf, rt_uint16_t size, struct zfile *zf);
static rt_err_t zrec_file_data(rt_uint8_t *buf, struct zfile *zf);;
static rt_err_t zrec_file(rt_uint8_t *rxbuf, struct zfile *zf);
static rt_err_t zget_file_info(char *name, struct zfile *zf);
static rt_err_t zwrite_file(rt_uint8_t *buf, rt_uint16_t size, struct zfile *zf);
static void zrec_ack_bibi(void);
/* start zmodem receive proccess */
void zr_start(char *path)
{
struct zfile *zf;
rt_uint8_t n;
char ch,*p,*q;
rt_err_t res = -RT_ERROR;
zf = rt_malloc(sizeof(struct zfile));
if (zf == RT_NULL)
{
rt_kprintf("zf: out of memory\r\n");
return;
}
memset(zf, 0, sizeof(struct zfile));
zf->fname = path;
zf->fd = -1;
res = zrec_files(zf);
p = zf->fname;
for (;;)
{
q = strstr(p,"/");
if (q == RT_NULL) break;
p = q+1;
}
if (res == RT_EOK)
{
rt_kprintf("\b\b\bfile: %s \r\n",p);
rt_kprintf("size: %ld bytes\r\n",zf->bytes_received);
rt_kprintf("receive completed.\r\n");
close(zf->fd);
rt_free(zf->fname);
}
else
{
rt_kprintf("\b\b\bfile: %s \r\n",p);
rt_kprintf("size: 0 bytes\r\n");
rt_kprintf("receive failed.\r\n");
if (zf->fd >= 0)
{
close(zf->fd);
unlink(zf->fname); /* remove this file */
rt_free(zf->fname);
}
}
rt_free(zf);
/* waiting,clear console buffer */
rt_thread_delay(RT_TICK_PER_SECOND/2);
while(1)
{
n=rt_device_read(shell->device, 0, &ch, 1);
if (n == 0) break;
}
return ;
}
/* receiver init, wait for ack */
static rt_err_t zrec_init(rt_uint8_t *rxbuf, struct zfile *zf)
{
rt_uint8_t err_cnt = 0;
rt_err_t res = -RT_ERROR;
for (;;)
{
zput_pos(0L);
tx_header[ZF0] = ZF0_CMD;
tx_header[ZF1] = ZF1_CMD;
tx_header[ZF2] = ZF2_CMD;
zsend_hex_header(ZRINIT, tx_header);
again:
res = zget_header(rx_header);
switch(res)
{
case ZFILE:
ZF0_CMD = rx_header[ZF0];
ZF1_CMD = rx_header[ZF1];
ZF2_CMD = rx_header[ZF2];
ZF3_CMD = rx_header[ZF3];
res = zget_data(rxbuf, RX_BUFFER_SIZE);
if (res == GOTCRCW)
{
if ((res =zget_file_info((char*)rxbuf,zf))!= RT_EOK)
{
zsend_hex_header(ZSKIP, tx_header);
return (res);
}
return RT_EOK;;
}
zsend_hex_header(ZNAK, tx_header);
goto again;
case ZSINIT:
if (zget_data((rt_uint8_t*)Attn, ZATTNLEN) == GOTCRCW) /* send zack */
{
zsend_hex_header(ZACK, tx_header);
goto again;
}
zsend_hex_header(ZNAK, tx_header); /* send znak */
goto again;
case ZRQINIT:
continue;
case ZEOF:
continue;
case ZCOMPL:
goto again;
case ZFIN: /* end file session */
zrec_ack_bibi();
return res;
default:
if (++err_cnt >1000) return -RT_ERROR;
continue;
}
}
}
/* receive files */
static rt_err_t zrec_files(struct zfile *zf)
{
rt_uint8_t *rxbuf;
rt_err_t res = -RT_ERROR;
zinit_parameter();
rxbuf = rt_malloc(RX_BUFFER_SIZE*sizeof(rt_uint8_t));
if (rxbuf == RT_NULL)
{
rt_kprintf("rxbuf: out of memory\r\n");
return -RT_ERROR;
}
rt_kprintf("\r\nrz: ready...\r\n"); /* here ready to receive things */
if ((res = zrec_init(rxbuf,zf))!= RT_EOK)
{
rt_kprintf("\b\b\breceive init failed\r\n");
rt_free(rxbuf);
return -RT_ERROR;
}
res = zrec_file(rxbuf,zf);
if (res == ZFIN)
{
rt_free(rxbuf);
return RT_EOK; /* if finish session */
}
else if (res == ZCAN)
{
rt_free(rxbuf);
return ZCAN; /* cancel by sender */
}
else
{
zsend_can();
rt_free(rxbuf);
return res;
}
}
/* receive file */
static rt_err_t zrec_file(rt_uint8_t *rxbuf, struct zfile *zf)
{
rt_err_t res = - RT_ERROR;
rt_uint16_t err_cnt = 0;
do
{
zput_pos(zf->bytes_received);
zsend_hex_header(ZRPOS, tx_header);
again:
res = zget_header(rx_header);
switch (res)
{
case ZDATA:
zget_pos(Rxpos);
if (Rxpos != zf->bytes_received)
{
zsend_break(Attn);
continue;
}
err_cnt = 0;
res = zrec_file_data(rxbuf,zf);
if (res == -RT_ERROR)
{
zsend_break(Attn);
continue;
}
else if (res == GOTCAN) return res;
else goto again;
case ZRPOS:
zget_pos(Rxpos);
continue;
case ZEOF:
err_cnt = 0;
zget_pos(Rxpos);
if (Rxpos != zf->bytes_received || Rxpos != zf->bytes_total)
{
continue;
}
return (zrec_init(rxbuf,zf)); /* resend ZRINIT packet,ready to receive next file */
case ZFIN:
zrec_ack_bibi();
return ZCOMPL;
case ZCAN:
#ifdef ZDEBUG
rt_kprintf("error code: sender cancelled \r\n");
#endif
zf->bytes_received = 0L; /* throw the received data */
return res;
case ZSKIP:
return res;
case -RT_ERROR:
zsend_break(Attn);
continue;
case ZNAK:
case TIMEOUT:
default:
continue;
}
} while(++err_cnt < 100);
return res;
}
/* proccess file infomation */
static rt_err_t zget_file_info(char *name, struct zfile *zf)
{
char *p;
char *full_path,*ptr;
rt_uint16_t i,len;
rt_err_t res = -RT_ERROR;
struct statfs buf;
struct stat finfo;
if (zf->fname == RT_NULL) /* extract file path */
{
len = strlen(name)+2;
}
else
len = strlen(zf->fname)+strlen(name)+2;
full_path = rt_malloc(len);
if (full_path == RT_NULL)
{
zsend_can();
rt_kprintf("\b\b\bfull_path: out of memory\n");
rt_free(full_path);
return -RT_ERROR;
}
memset(full_path,0,len);
for (i=0,ptr=zf->fname;i<len-strlen(name)-2;i++)
full_path[i] = *ptr++;
full_path[len-strlen(name)-2] = '/';
/* check if is a directory */
if ((zf->fd=open(full_path, DFS_O_DIRECTORY,0)) < 0)
{
zsend_can();
rt_kprintf("\b\b\bcan not open file:%s\r\n",zf->fname+1);
close(zf->fd);
zf->fd = -1;
rt_free(full_path);
return res;
}
fstat(zf->fd, &finfo);
if ((finfo.st_mode&S_IFDIR) != S_IFDIR)
{
close(zf->fd);
zf->fd = -1;
return res;
}
close(zf->fd);
/* get fullpath && file attributes */
strcat(full_path,name);
zf->fname = full_path;
p = strlen(name)+name+1;
sscanf((const char *)p, "%ld%lo%o", &zf->bytes_total,&zf->ctime,&zf->mode);
#if defined(RT_USING_DFS) && defined(DFS_USING_WORKDIR)
dfs_statfs(working_directory,&buf);
if (zf->bytes_total > (buf.f_blocks * buf.f_bfree))
{
zsend_can();
rt_kprintf("\b\b\bnot enough disk space\r\n");
zf->fd = -1;
rt_free(full_path);
return -RT_ERROR;
}
#else
buf = buf;
#endif
zf->bytes_received = 0L;
if ((zf->fd = open(zf->fname,DFS_O_CREAT|DFS_O_WRONLY,0)) < 0) /* create or replace exist file */
{
zsend_can();
rt_kprintf("\b\b\bcan not create file:%s \r\n",zf->fname);
return -RT_ERROR;
}
return RT_EOK;
}
/* receive file data,continously, no ack */
static rt_err_t zrec_file_data(rt_uint8_t *buf, struct zfile *zf)
{
rt_err_t res = -RT_ERROR;
more_data:
res = zget_data(buf,RX_BUFFER_SIZE);
switch(res)
{
case GOTCRCW: /* zack received */
zwrite_file(buf,Rxcount,zf);
zf->bytes_received += Rxcount;
zput_pos(zf->bytes_received);
zsend_line(XON);
zsend_hex_header(ZACK, tx_header);
return RT_EOK;
case GOTCRCQ:
zwrite_file(buf,Rxcount,zf);
zf->bytes_received += Rxcount;
zput_pos(zf->bytes_received);
zsend_hex_header(ZACK, tx_header);
goto more_data;
case GOTCRCG:
zwrite_file(buf,Rxcount,zf);
zf->bytes_received += Rxcount;
goto more_data;
case GOTCRCE:
zwrite_file(buf,Rxcount,zf);
zf->bytes_received += Rxcount;
return RT_EOK;
case GOTCAN:
#ifdef ZDEBUG
rt_kprintf("error code : ZCAN \r\n");
#endif
return res;
case TIMEOUT:
return res;
case -RT_ERROR:
zsend_break(Attn);
return res;
default:
return res;
}
}
/* write file */
static rt_err_t zwrite_file(rt_uint8_t *buf,rt_uint16_t size, struct zfile *zf)
{
return (write(zf->fd,buf,size));
}
/* ack bibi */
static void zrec_ack_bibi(void)
{
rt_uint8_t i;
zput_pos(0L);
for (i=0;i<3;i++)
{
zsend_hex_header(ZFIN, tx_header);
switch (zread_line(100))
{
case 'O':
zread_line(1);
return;
case RCDO:
return;
case TIMEOUT:
default:
break;
}
}
}
/* end of rz.c */
*/
#include <rtthread.h>
#include <finsh.h>
#include <shell.h>
#include <rtdef.h>
#include <dfs.h>
#include <dfs_file.h>
#include <dfs_posix.h>
#include <stdio.h>
#include "zdef.h"
void zr_start(char *path);
static rt_err_t zrec_init(rt_uint8_t *rxbuf, struct zfile *zf);
static rt_err_t zrec_files(struct zfile *zf);
static rt_err_t zwrite_file(rt_uint8_t *buf, rt_uint16_t size, struct zfile *zf);
static rt_err_t zrec_file_data(rt_uint8_t *buf, struct zfile *zf);;
static rt_err_t zrec_file(rt_uint8_t *rxbuf, struct zfile *zf);
static rt_err_t zget_file_info(char *name, struct zfile *zf);
static rt_err_t zwrite_file(rt_uint8_t *buf, rt_uint16_t size, struct zfile *zf);
static void zrec_ack_bibi(void);
/* start zmodem receive proccess */
void zr_start(char *path)
{
struct zfile *zf;
rt_uint8_t n;
char ch,*p,*q;
rt_err_t res = -RT_ERROR;
zf = rt_malloc(sizeof(struct zfile));
if (zf == RT_NULL)
{
rt_kprintf("zf: out of memory\r\n");
return;
}
memset(zf, 0, sizeof(struct zfile));
zf->fname = path;
zf->fd = -1;
res = zrec_files(zf);
p = zf->fname;
for (;;)
{
q = strstr(p,"/");
if (q == RT_NULL) break;
p = q+1;
}
if (res == RT_EOK)
{
rt_kprintf("\b\b\bfile: %s \r\n",p);
rt_kprintf("size: %ld bytes\r\n",zf->bytes_received);
rt_kprintf("receive completed.\r\n");
close(zf->fd);
rt_free(zf->fname);
}
else
{
rt_kprintf("\b\b\bfile: %s \r\n",p);
rt_kprintf("size: 0 bytes\r\n");
rt_kprintf("receive failed.\r\n");
if (zf->fd >= 0)
{
close(zf->fd);
unlink(zf->fname); /* remove this file */
rt_free(zf->fname);
}
}
rt_free(zf);
/* waiting,clear console buffer */
rt_thread_delay(RT_TICK_PER_SECOND/2);
while(1)
{
n=rt_device_read(shell->device, 0, &ch, 1);
if (n == 0) break;
}
return ;
}
/* receiver init, wait for ack */
static rt_err_t zrec_init(rt_uint8_t *rxbuf, struct zfile *zf)
{
rt_uint8_t err_cnt = 0;
rt_err_t res = -RT_ERROR;
for (;;)
{
zput_pos(0L);
tx_header[ZF0] = ZF0_CMD;
tx_header[ZF1] = ZF1_CMD;
tx_header[ZF2] = ZF2_CMD;
zsend_hex_header(ZRINIT, tx_header);
again:
res = zget_header(rx_header);
switch(res)
{
case ZFILE:
ZF0_CMD = rx_header[ZF0];
ZF1_CMD = rx_header[ZF1];
ZF2_CMD = rx_header[ZF2];
ZF3_CMD = rx_header[ZF3];
res = zget_data(rxbuf, RX_BUFFER_SIZE);
if (res == GOTCRCW)
{
if ((res =zget_file_info((char*)rxbuf,zf))!= RT_EOK)
{
zsend_hex_header(ZSKIP, tx_header);
return (res);
}
return RT_EOK;;
}
zsend_hex_header(ZNAK, tx_header);
goto again;
case ZSINIT:
if (zget_data((rt_uint8_t*)Attn, ZATTNLEN) == GOTCRCW) /* send zack */
{
zsend_hex_header(ZACK, tx_header);
goto again;
}
zsend_hex_header(ZNAK, tx_header); /* send znak */
goto again;
case ZRQINIT:
continue;
case ZEOF:
continue;
case ZCOMPL:
goto again;
case ZFIN: /* end file session */
zrec_ack_bibi();
return res;
default:
if (++err_cnt >1000) return -RT_ERROR;
continue;
}
}
}
/* receive files */
static rt_err_t zrec_files(struct zfile *zf)
{
rt_uint8_t *rxbuf;
rt_err_t res = -RT_ERROR;
zinit_parameter();
rxbuf = rt_malloc(RX_BUFFER_SIZE*sizeof(rt_uint8_t));
if (rxbuf == RT_NULL)
{
rt_kprintf("rxbuf: out of memory\r\n");
return -RT_ERROR;
}
rt_kprintf("\r\nrz: ready...\r\n"); /* here ready to receive things */
if ((res = zrec_init(rxbuf,zf))!= RT_EOK)
{
rt_kprintf("\b\b\breceive init failed\r\n");
rt_free(rxbuf);
return -RT_ERROR;
}
res = zrec_file(rxbuf,zf);
if (res == ZFIN)
{
rt_free(rxbuf);
return RT_EOK; /* if finish session */
}
else if (res == ZCAN)
{
rt_free(rxbuf);
return ZCAN; /* cancel by sender */
}
else
{
zsend_can();
rt_free(rxbuf);
return res;
}
}
/* receive file */
static rt_err_t zrec_file(rt_uint8_t *rxbuf, struct zfile *zf)
{
rt_err_t res = - RT_ERROR;
rt_uint16_t err_cnt = 0;
do
{
zput_pos(zf->bytes_received);
zsend_hex_header(ZRPOS, tx_header);
again:
res = zget_header(rx_header);
switch (res)
{
case ZDATA:
zget_pos(Rxpos);
if (Rxpos != zf->bytes_received)
{
zsend_break(Attn);
continue;
}
err_cnt = 0;
res = zrec_file_data(rxbuf,zf);
if (res == -RT_ERROR)
{
zsend_break(Attn);
continue;
}
else if (res == GOTCAN) return res;
else goto again;
case ZRPOS:
zget_pos(Rxpos);
continue;
case ZEOF:
err_cnt = 0;
zget_pos(Rxpos);
if (Rxpos != zf->bytes_received || Rxpos != zf->bytes_total)
{
continue;
}
return (zrec_init(rxbuf,zf)); /* resend ZRINIT packet,ready to receive next file */
case ZFIN:
zrec_ack_bibi();
return ZCOMPL;
case ZCAN:
#ifdef ZDEBUG
rt_kprintf("error code: sender cancelled \r\n");
#endif
zf->bytes_received = 0L; /* throw the received data */
return res;
case ZSKIP:
return res;
case -RT_ERROR:
zsend_break(Attn);
continue;
case ZNAK:
case TIMEOUT:
default:
continue;
}
} while(++err_cnt < 100);
return res;
}
/* proccess file infomation */
static rt_err_t zget_file_info(char *name, struct zfile *zf)
{
char *p;
char *full_path,*ptr;
rt_uint16_t i,len;
rt_err_t res = -RT_ERROR;
struct statfs buf;
struct stat finfo;
if (zf->fname == RT_NULL) /* extract file path */
{
len = strlen(name)+2;
}
else
len = strlen(zf->fname)+strlen(name)+2;
full_path = rt_malloc(len);
if (full_path == RT_NULL)
{
zsend_can();
rt_kprintf("\b\b\bfull_path: out of memory\n");
rt_free(full_path);
return -RT_ERROR;
}
memset(full_path,0,len);
for (i=0,ptr=zf->fname;i<len-strlen(name)-2;i++)
full_path[i] = *ptr++;
full_path[len-strlen(name)-2] = '/';
/* check if is a directory */
if ((zf->fd=open(full_path, DFS_O_DIRECTORY,0)) < 0)
{
zsend_can();
rt_kprintf("\b\b\bcan not open file:%s\r\n",zf->fname+1);
close(zf->fd);
zf->fd = -1;
rt_free(full_path);
return res;
}
fstat(zf->fd, &finfo);
if ((finfo.st_mode&S_IFDIR) != S_IFDIR)
{
close(zf->fd);
zf->fd = -1;
return res;
}
close(zf->fd);
/* get fullpath && file attributes */
strcat(full_path,name);
zf->fname = full_path;
p = strlen(name)+name+1;
sscanf((const char *)p, "%ld%lo%o", &zf->bytes_total,&zf->ctime,&zf->mode);
#if defined(RT_USING_DFS) && defined(DFS_USING_WORKDIR)
dfs_statfs(working_directory,&buf);
if (zf->bytes_total > (buf.f_blocks * buf.f_bfree))
{
zsend_can();
rt_kprintf("\b\b\bnot enough disk space\r\n");
zf->fd = -1;
rt_free(full_path);
return -RT_ERROR;
}
#else
buf = buf;
#endif
zf->bytes_received = 0L;
if ((zf->fd = open(zf->fname,DFS_O_CREAT|DFS_O_WRONLY,0)) < 0) /* create or replace exist file */
{
zsend_can();
rt_kprintf("\b\b\bcan not create file:%s \r\n",zf->fname);
return -RT_ERROR;
}
return RT_EOK;
}
/* receive file data,continously, no ack */
static rt_err_t zrec_file_data(rt_uint8_t *buf, struct zfile *zf)
{
rt_err_t res = -RT_ERROR;
more_data:
res = zget_data(buf,RX_BUFFER_SIZE);
switch(res)
{
case GOTCRCW: /* zack received */
zwrite_file(buf,Rxcount,zf);
zf->bytes_received += Rxcount;
zput_pos(zf->bytes_received);
zsend_line(XON);
zsend_hex_header(ZACK, tx_header);
return RT_EOK;
case GOTCRCQ:
zwrite_file(buf,Rxcount,zf);
zf->bytes_received += Rxcount;
zput_pos(zf->bytes_received);
zsend_hex_header(ZACK, tx_header);
goto more_data;
case GOTCRCG:
zwrite_file(buf,Rxcount,zf);
zf->bytes_received += Rxcount;
goto more_data;
case GOTCRCE:
zwrite_file(buf,Rxcount,zf);
zf->bytes_received += Rxcount;
return RT_EOK;
case GOTCAN:
#ifdef ZDEBUG
rt_kprintf("error code : ZCAN \r\n");
#endif
return res;
case TIMEOUT:
return res;
case -RT_ERROR:
zsend_break(Attn);
return res;
default:
return res;
}
}
/* write file */
static rt_err_t zwrite_file(rt_uint8_t *buf,rt_uint16_t size, struct zfile *zf)
{
return (write(zf->fd,buf,size));
}
/* ack bibi */
static void zrec_ack_bibi(void)
{
rt_uint8_t i;
zput_pos(0L);
for (i=0;i<3;i++)
{
zsend_hex_header(ZFIN, tx_header);
switch (zread_line(100))
{
case 'O':
zread_line(1);
return;
case RCDO:
return;
case TIMEOUT:
default:
break;
}
}
}
/* end of rz.c */

View File

@ -1,321 +1,321 @@
/*
* File : sz.c
* the implemention of sending files to the remote computers
* File : sz.c
* the implemention of sending files to the remote computers
* through the zmodem protocol.
* Change Logs:
* Date Author Notes
* 2011-03-29 itspy
*/
#include <rtthread.h>
#include <finsh.h>
#include <shell.h>
#include <rtdef.h>
#include <dfs.h>
#include <dfs_file.h>
#include <dfs_posix.h>
#include "zdef.h"
static rt_uint8_t TX_BUFFER[TX_BUFFER_SIZE]; /* sender buffer */
static rt_uint8_t file_cnt = 0; /* count of number of files opened */
static rt_uint8_t Rxflags = 0; /* rx parameter flags */
static rt_uint8_t ZF2_OP; /* file transfer option */
void zs_start(char *path);
static void zsend_init(void);
static rt_err_t zsend_files(struct zfile *zf);
static rt_err_t zsend_file(struct zfile *zf, rt_uint8_t *buf, rt_uint16_t len);
static rt_err_t zsend_file_data(struct zfile *zf);
static rt_uint16_t zfill_buffer(struct zfile *zf, rt_uint8_t *buf, rt_uint16_t size);
static rt_err_t zget_sync(void);
static void zsay_bibi(void);
/* start zmodem send process */
void zs_start(char *path)
{
struct zfile *zf;
rt_err_t res = RT_ERROR;
char *p,*q;
zf = rt_malloc(sizeof(struct zfile));
if (zf == RT_NULL)
{
rt_kprintf("zf: out of memory\r\n");
return;
}
rt_kprintf("\r\nsz: ready...\r\n"); /* here ready to send things */
memset(zf, 0, sizeof(struct zfile));
zf->fname = path;
zf->fd = -1;
res = zsend_files(zf);
p = zf->fname;
for (;;)
{
q = strstr(p,"/");
if (q == RT_NULL) break;
p = q+1;
}
if (res == RT_EOK)
{
rt_kprintf("\r\nfile: %s \r\nsize: %ld bytes\r\nsend completed.\r\n",
p,zf->bytes_received);
}
else
{
rt_kprintf("\r\nfile: %s \r\nsize: 0 bytes\r\nsend failed.\r\n",p);
}
rt_free(zf);
return;
}
/* init the parameters */
static void zsend_init(void)
{
rt_err_t res = -RT_ERROR;
zinit_parameter();
for(;;) /* wait ZPAD */
{
res = zread_line(800);
if (res == ZPAD) break;
}
for (;;)
{
res = zget_header(rx_header);
if (res == ZRINIT) break;
}
if ((rx_header[ZF1] & ZRQNVH))
{
zput_pos(0x80L); /* Show we can var header */
zsend_hex_header(ZRQINIT, tx_header);
}
Rxflags = rx_header[ZF0] & 0377;
if (Rxflags & CANFC32) Txfcs32 = 1; /* used 32bits CRC check */
if (ZF2_OP == ZTRLE && (Rxflags & CANRLE)) /* for RLE packet */
Txfcs32 = 2;
else
ZF2_OP = 0;
/* send SINIT cmd */
return;
}
/* send files */
static rt_err_t zsend_files(struct zfile *zf)
{
char *p,*q;
char *str = "/";
struct stat finfo;
rt_err_t res = -RT_ERROR;
if (zf->fname == RT_NULL)
{
rt_kprintf("\r\nerror: no file to be send.\r\n");
return res;
}
if ((zf->fd=open(zf->fname, DFS_O_RDONLY,0)) <0)
{
rt_kprintf("\r\ncan not open file:%s\r\n",zf->fname+1);
return res;
}
zf->file_end = 0;
++file_cnt;
/* extract file name */
p = zf->fname;
for (;;)
{
q = strstr(p,str);
if (q == RT_NULL) break;
p = q+1;
}
q = (char*)TX_BUFFER;
for (;;)
{
*q++ = *p++;
if (*p == 0) break;
}
*q++ = 0;
p=q;
while (q < (char*)(TX_BUFFER + 1024))
*q++ = 0;
/* get file attributes */
fstat(zf->fd,&finfo);
Left_sizes += finfo.st_size;
rt_sprintf(p, "%lu %lo %o 3 %d %ld", (long)finfo.st_size, finfo.st_mtime,
finfo.st_mode, file_cnt, Left_sizes);
Left_sizes -= finfo.st_size;
TX_BUFFER[127] = (finfo.st_size + 127) >>7;
TX_BUFFER[126] = (finfo.st_size + 127) >>15;
zsend_init();
/* start sending files */
res = zsend_file(zf,TX_BUFFER, (p-(char*)TX_BUFFER)+strlen(p)+1);
zsay_bibi();
close(zf->fd);
return res;
}
/* send file name and related info */
static rt_err_t zsend_file(struct zfile *zf, rt_uint8_t *buf, rt_uint16_t len)
{
rt_uint8_t cnt;
rt_err_t res = -RT_ERROR;
for (cnt=0;cnt<5;cnt++)
{
tx_header[ZF0] = ZF0_CMD; /* file conversion option */
tx_header[ZF1] = ZF1_CMD; /* file management option */
tx_header[ZF2] = (ZF3_CMD|ZF2_OP); /* file transfer option */
tx_header[ZF3] = ZF3_CMD;
zsend_bin_header(ZFILE, tx_header);
zsend_bin_data(buf, len, ZCRCW);
loop:
res = zget_header(rx_header);
switch (res)
{
case ZRINIT:
while ((res = zread_line(50)) > 0)
{
if (res == ZPAD)
{
goto loop;
}
}
break;
case ZCAN:
case TIMEOUT:
case ZABORT:
case ZFIN:
break;
case -RT_ERROR:
case ZNAK:
break;
case ZCRC: /* no CRC request */
goto loop;
case ZFERR:
case ZSKIP:
break;
case ZRPOS: /* here we want */
zget_pos(Rxpos);
Txpos = Rxpos;
return(zsend_file_data(zf));
default:
break;
}
}
return res;
}
/* send the file data */
static rt_err_t zsend_file_data(struct zfile *zf)
{
rt_int16_t cnt;
rt_uint8_t cmd;
rt_err_t res = -RT_ERROR;
/* send ZDATA packet, start to send data */
start_send:
zput_pos(Txpos);
zsend_bin_header(ZDATA, tx_header);
do
{
cnt = zfill_buffer(zf,TX_BUFFER,RX_BUFFER_SIZE);
if (cnt < RX_BUFFER_SIZE )
cmd = ZCRCE;
else
cmd = ZCRCG;
zsend_bin_data(TX_BUFFER, cnt, cmd);
zf->bytes_received= Txpos += cnt;
if (cmd == ZCRCW)
goto get_syn1;
} while (cnt == RX_BUFFER_SIZE);
for (;;) /* get ack and check if send finish */
{
zput_pos(Txpos);
zsend_bin_header(ZEOF, tx_header);
get_syn1:
res = zget_sync();
switch (res)
{
case ZACK:
goto get_syn1;
case ZNAK:
continue;
case ZRPOS: /* resend here */
lseek(zf->fd,Txpos,0);
goto start_send;
case ZRINIT: /* send finish,then begin to send next file */
return RT_EOK;
case ZSKIP:
case -RT_ERROR:
return res;
default:
return res;
}
}
}
/* fill file data to buffer*/
static rt_uint16_t zfill_buffer(struct zfile *zf, rt_uint8_t *buf, rt_uint16_t size)
{
return (read(zf->fd,buf,size));
}
/* wait sync(ack) from the receiver */
static rt_err_t zget_sync(void)
{
rt_err_t res = -RT_ERROR;
for (;;)
{
res = zget_header(rx_header);
switch (res)
{
case ZCAN:
case ZABORT:
case ZFIN:
case TIMEOUT:
return -RT_ERROR;
case ZRPOS: /* get pos, need to resend */
zget_pos(Rxpos);
Txpos = Rxpos;
return res;
case ZACK:
return res;
case ZRINIT: /* get ZRINIT indicate that the prev file send completed */
return res;
case ZSKIP:
return res;
case -RT_ERROR:
default:
zsend_bin_header(ZNAK, tx_header);
continue;
}
}
}
/* say "bibi" to the receiver */
static void zsay_bibi(void)
{
for (;;)
{
zput_pos(0L); /* reninit position of next file*/
zsend_hex_header(ZFIN, tx_header); /* send finished session cmd */
switch (zget_header(rx_header))
{
case ZFIN:
zsend_line('O');
zsend_line('O');
case ZCAN:
case TIMEOUT:
return;
}
}
}
/* end of sz.c */
*/
#include <rtthread.h>
#include <finsh.h>
#include <shell.h>
#include <rtdef.h>
#include <dfs.h>
#include <dfs_file.h>
#include <dfs_posix.h>
#include "zdef.h"
static rt_uint8_t TX_BUFFER[TX_BUFFER_SIZE]; /* sender buffer */
static rt_uint8_t file_cnt = 0; /* count of number of files opened */
static rt_uint8_t Rxflags = 0; /* rx parameter flags */
static rt_uint8_t ZF2_OP; /* file transfer option */
void zs_start(char *path);
static void zsend_init(void);
static rt_err_t zsend_files(struct zfile *zf);
static rt_err_t zsend_file(struct zfile *zf, rt_uint8_t *buf, rt_uint16_t len);
static rt_err_t zsend_file_data(struct zfile *zf);
static rt_uint16_t zfill_buffer(struct zfile *zf, rt_uint8_t *buf, rt_uint16_t size);
static rt_err_t zget_sync(void);
static void zsay_bibi(void);
/* start zmodem send process */
void zs_start(char *path)
{
struct zfile *zf;
rt_err_t res = RT_ERROR;
char *p,*q;
zf = rt_malloc(sizeof(struct zfile));
if (zf == RT_NULL)
{
rt_kprintf("zf: out of memory\r\n");
return;
}
rt_kprintf("\r\nsz: ready...\r\n"); /* here ready to send things */
memset(zf, 0, sizeof(struct zfile));
zf->fname = path;
zf->fd = -1;
res = zsend_files(zf);
p = zf->fname;
for (;;)
{
q = strstr(p,"/");
if (q == RT_NULL) break;
p = q+1;
}
if (res == RT_EOK)
{
rt_kprintf("\r\nfile: %s \r\nsize: %ld bytes\r\nsend completed.\r\n",
p,zf->bytes_received);
}
else
{
rt_kprintf("\r\nfile: %s \r\nsize: 0 bytes\r\nsend failed.\r\n",p);
}
rt_free(zf);
return;
}
/* init the parameters */
static void zsend_init(void)
{
rt_err_t res = -RT_ERROR;
zinit_parameter();
for(;;) /* wait ZPAD */
{
res = zread_line(800);
if (res == ZPAD) break;
}
for (;;)
{
res = zget_header(rx_header);
if (res == ZRINIT) break;
}
if ((rx_header[ZF1] & ZRQNVH))
{
zput_pos(0x80L); /* Show we can var header */
zsend_hex_header(ZRQINIT, tx_header);
}
Rxflags = rx_header[ZF0] & 0377;
if (Rxflags & CANFC32) Txfcs32 = 1; /* used 32bits CRC check */
if (ZF2_OP == ZTRLE && (Rxflags & CANRLE)) /* for RLE packet */
Txfcs32 = 2;
else
ZF2_OP = 0;
/* send SINIT cmd */
return;
}
/* send files */
static rt_err_t zsend_files(struct zfile *zf)
{
char *p,*q;
char *str = "/";
struct stat finfo;
rt_err_t res = -RT_ERROR;
if (zf->fname == RT_NULL)
{
rt_kprintf("\r\nerror: no file to be send.\r\n");
return res;
}
if ((zf->fd=open(zf->fname, DFS_O_RDONLY,0)) <0)
{
rt_kprintf("\r\ncan not open file:%s\r\n",zf->fname+1);
return res;
}
zf->file_end = 0;
++file_cnt;
/* extract file name */
p = zf->fname;
for (;;)
{
q = strstr(p,str);
if (q == RT_NULL) break;
p = q+1;
}
q = (char*)TX_BUFFER;
for (;;)
{
*q++ = *p++;
if (*p == 0) break;
}
*q++ = 0;
p=q;
while (q < (char*)(TX_BUFFER + 1024))
*q++ = 0;
/* get file attributes */
fstat(zf->fd,&finfo);
Left_sizes += finfo.st_size;
rt_sprintf(p, "%lu %lo %o 3 %d %ld", (long)finfo.st_size, finfo.st_mtime,
finfo.st_mode, file_cnt, Left_sizes);
Left_sizes -= finfo.st_size;
TX_BUFFER[127] = (finfo.st_size + 127) >>7;
TX_BUFFER[126] = (finfo.st_size + 127) >>15;
zsend_init();
/* start sending files */
res = zsend_file(zf,TX_BUFFER, (p-(char*)TX_BUFFER)+strlen(p)+1);
zsay_bibi();
close(zf->fd);
return res;
}
/* send file name and related info */
static rt_err_t zsend_file(struct zfile *zf, rt_uint8_t *buf, rt_uint16_t len)
{
rt_uint8_t cnt;
rt_err_t res = -RT_ERROR;
for (cnt=0;cnt<5;cnt++)
{
tx_header[ZF0] = ZF0_CMD; /* file conversion option */
tx_header[ZF1] = ZF1_CMD; /* file management option */
tx_header[ZF2] = (ZF3_CMD|ZF2_OP); /* file transfer option */
tx_header[ZF3] = ZF3_CMD;
zsend_bin_header(ZFILE, tx_header);
zsend_bin_data(buf, len, ZCRCW);
loop:
res = zget_header(rx_header);
switch (res)
{
case ZRINIT:
while ((res = zread_line(50)) > 0)
{
if (res == ZPAD)
{
goto loop;
}
}
break;
case ZCAN:
case TIMEOUT:
case ZABORT:
case ZFIN:
break;
case -RT_ERROR:
case ZNAK:
break;
case ZCRC: /* no CRC request */
goto loop;
case ZFERR:
case ZSKIP:
break;
case ZRPOS: /* here we want */
zget_pos(Rxpos);
Txpos = Rxpos;
return(zsend_file_data(zf));
default:
break;
}
}
return res;
}
/* send the file data */
static rt_err_t zsend_file_data(struct zfile *zf)
{
rt_int16_t cnt;
rt_uint8_t cmd;
rt_err_t res = -RT_ERROR;
/* send ZDATA packet, start to send data */
start_send:
zput_pos(Txpos);
zsend_bin_header(ZDATA, tx_header);
do
{
cnt = zfill_buffer(zf,TX_BUFFER,RX_BUFFER_SIZE);
if (cnt < RX_BUFFER_SIZE )
cmd = ZCRCE;
else
cmd = ZCRCG;
zsend_bin_data(TX_BUFFER, cnt, cmd);
zf->bytes_received= Txpos += cnt;
if (cmd == ZCRCW)
goto get_syn1;
} while (cnt == RX_BUFFER_SIZE);
for (;;) /* get ack and check if send finish */
{
zput_pos(Txpos);
zsend_bin_header(ZEOF, tx_header);
get_syn1:
res = zget_sync();
switch (res)
{
case ZACK:
goto get_syn1;
case ZNAK:
continue;
case ZRPOS: /* resend here */
lseek(zf->fd,Txpos,0);
goto start_send;
case ZRINIT: /* send finish,then begin to send next file */
return RT_EOK;
case ZSKIP:
case -RT_ERROR:
return res;
default:
return res;
}
}
}
/* fill file data to buffer*/
static rt_uint16_t zfill_buffer(struct zfile *zf, rt_uint8_t *buf, rt_uint16_t size)
{
return (read(zf->fd,buf,size));
}
/* wait sync(ack) from the receiver */
static rt_err_t zget_sync(void)
{
rt_err_t res = -RT_ERROR;
for (;;)
{
res = zget_header(rx_header);
switch (res)
{
case ZCAN:
case ZABORT:
case ZFIN:
case TIMEOUT:
return -RT_ERROR;
case ZRPOS: /* get pos, need to resend */
zget_pos(Rxpos);
Txpos = Rxpos;
return res;
case ZACK:
return res;
case ZRINIT: /* get ZRINIT indicate that the prev file send completed */
return res;
case ZSKIP:
return res;
case -RT_ERROR:
default:
zsend_bin_header(ZNAK, tx_header);
continue;
}
}
}
/* say "bibi" to the receiver */
static void zsay_bibi(void)
{
for (;;)
{
zput_pos(0L); /* reninit position of next file*/
zsend_hex_header(ZFIN, tx_header); /* send finished session cmd */
switch (zget_header(rx_header))
{
case ZFIN:
zsend_line('O');
zsend_line('O');
case ZCAN:
case TIMEOUT:
return;
}
}
}
/* end of sz.c */

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
#ifndef __ZDEF_H__
#define __ZDEF_H__
#include <rtthread.h>
#ifndef __ZDEF_H__
#define __ZDEF_H__
#include <rtthread.h>
#include "crc.h"
#define ZPAD '*' /* 052 padding character begins frames */
#define ZDLE 030 /* ctrl-X ZMODEM escape - `ala BISYNC DLE */
@ -121,7 +121,7 @@ extern char Attn[ZATTNLEN+1]; /* Attention string rx sends to tx on err */
/* globals used by ZMODEM functions */
extern rt_uint8_t Rxframeind; /* ZBIN ZBIN32, or ZHEX type of frame */
extern char header_type; /* type of header received */
extern char header_type; /* type of header received */
extern rt_uint8_t rx_header[4]; /* received header */
extern rt_uint8_t tx_header[4]; /* transmitted header */
extern rt_uint8_t Txfcs32; /* TRUE means send binary frames with 32 bit FCS */
@ -129,18 +129,18 @@ extern rt_uint16_t Rxcount; /* count of data bytes received */
extern rt_uint16_t Rxtimeout; /* tenths of seconds to wait for something */
extern rt_uint32_t Rxpos; /* received file position */
extern rt_uint32_t Txpos; /* transmitted file position */
extern rt_uint8_t Txfcs32; /* TURE means send binary frames with 32 bit FCS */
extern rt_uint8_t Txfcs32; /* TURE means send binary frames with 32 bit FCS */
/* ward Christensen / CP/M parameters - Don't change these! */
#define ENQ 005
#define CAN ('X'&037)
#define XOFF ('s'&037)
#define XON ('q'&037)
#define SOH 1
#define STX 2
#define ETX 3
#define SYN 026
#define ESC 033
#define STX 2
#define ETX 3
#define SYN 026
#define ESC 033
#define WANTG 0107 /* send G not NAK to get nonstop batch xmsn */
#define EOT 4
#define ACK 6
@ -154,64 +154,64 @@ extern rt_uint8_t Txfcs32; /* TURE means send binary frames with 32 bit
#define RETRYMAX 5
#define WCEOT (-10)
#define BITRATE 115200
#define TX_BUFFER_SIZE 1024
#define RX_BUFFER_SIZE 1024 /* sender or receiver's max buffer size */
#define BITRATE 115200
#define TX_BUFFER_SIZE 1024
#define RX_BUFFER_SIZE 1024 /* sender or receiver's max buffer size */
extern char ZF0_CMD; /* local ZMODEM file conversion request */
extern char ZF1_CMD; /* local ZMODEM file management request */
extern char ZF2_CMD; /* local ZMODEM file management request */
extern char ZF3_CMD; /* local ZMODEM file management request */
extern rt_uint32_t Baudrate ;
extern rt_uint32_t Left_bytes;
extern rt_uint32_t Left_sizes;
struct zmodemf
{
struct rt_semaphore zsem;
rt_device_t device;
};
extern struct zmodemf zmodem;
struct zfile
{
char *fname;
extern char ZF1_CMD; /* local ZMODEM file management request */
extern char ZF2_CMD; /* local ZMODEM file management request */
extern char ZF3_CMD; /* local ZMODEM file management request */
extern rt_uint32_t Baudrate ;
extern rt_uint32_t Left_bytes;
extern rt_uint32_t Left_sizes;
struct zmodemf
{
struct rt_semaphore zsem;
rt_device_t device;
};
extern struct zmodemf zmodem;
struct zfile
{
char *fname;
rt_int32_t fd;
rt_uint32_t ctime;
rt_uint32_t ctime;
rt_uint32_t mode;
rt_uint32_t bytes_total;
rt_uint32_t bytes_sent;
rt_uint32_t bytes_received;
rt_uint32_t file_end;
};
extern struct finsh_shell* shell;
#define ZDEBUG 0
/* sz.c */
extern void zs_start(char *path);
/* rz.c */
extern void zr_start(char *path);
/* zcore.c */
extern void zinit_parameter(void);
extern rt_int16_t zget_header(rt_uint8_t *hdr);
extern void zsend_bin_header(rt_uint8_t type, rt_uint8_t *hdr);
extern void zsend_hex_header(rt_uint8_t type, rt_uint8_t *hdr);
extern rt_int16_t zget_data(rt_uint8_t *buf, rt_uint16_t len);
extern void zsend_bin_data(rt_uint8_t *buf, rt_int16_t len, rt_uint8_t frameend);
extern void zput_pos(rt_uint32_t pos);
extern void zget_pos(rt_uint32_t pos);
/* zdevice.c */
extern rt_uint32_t get_device_baud(void);
extern void zsend_byte(rt_uint16_t c);
extern void zsend_line(rt_uint16_t c);
extern rt_int16_t zread_line(rt_uint16_t timeout);
extern void zsend_break(char *cmd);
rt_uint32_t file_end;
};
extern struct finsh_shell* shell;
#define ZDEBUG 0
/* sz.c */
extern void zs_start(char *path);
/* rz.c */
extern void zr_start(char *path);
/* zcore.c */
extern void zinit_parameter(void);
extern rt_int16_t zget_header(rt_uint8_t *hdr);
extern void zsend_bin_header(rt_uint8_t type, rt_uint8_t *hdr);
extern void zsend_hex_header(rt_uint8_t type, rt_uint8_t *hdr);
extern rt_int16_t zget_data(rt_uint8_t *buf, rt_uint16_t len);
extern void zsend_bin_data(rt_uint8_t *buf, rt_int16_t len, rt_uint8_t frameend);
extern void zput_pos(rt_uint32_t pos);
extern void zget_pos(rt_uint32_t pos);
/* zdevice.c */
extern rt_uint32_t get_device_baud(void);
extern void zsend_byte(rt_uint16_t c);
extern void zsend_line(rt_uint16_t c);
extern rt_int16_t zread_line(rt_uint16_t timeout);
extern void zsend_break(char *cmd);
extern void zsend_can(void);
#endif /* __ZDEF_H__ */

View File

@ -1,79 +1,79 @@
/*
* File : zdevice.c
* File : zdevice.c
* the implemention of zmodem protocol.
* Change Logs:
* Date Author Notes
* 2011-03-29 itspy
*/
#include <rtthread.h>
#include <finsh.h>
#include <shell.h>
#include <rtdef.h>
#include <dfs.h>
#include <dfs_file.h>
#include <dfs_posix.h>
#include "zdef.h"
*/
#include <rtthread.h>
#include <finsh.h>
#include <shell.h>
#include <rtdef.h>
#include <dfs.h>
#include <dfs_file.h>
#include <dfs_posix.h>
#include "zdef.h"
rt_uint32_t Line_left = 0; /* left number of data in the read line buffer*/
rt_uint32_t Left_sizes = 0; /* left file sizes */
rt_uint32_t Line_left = 0; /* left number of data in the read line buffer*/
rt_uint32_t Left_sizes = 0; /* left file sizes */
rt_uint32_t Baudrate = BITRATE; /* console baudrate */
rt_uint32_t get_device_baud(void)
{
return(Baudrate);
}
rt_uint32_t get_sys_time(void)
{
return(0L);
}
void zsend_byte(rt_uint16_t ch)
{
rt_device_write(zmodem.device, 0, &ch,1);
return;
}
void zsend_line(rt_uint16_t c)
{
rt_uint16_t ch;
ch = (c & 0377);
rt_device_write(zmodem.device, 0, &ch, 1);
return;
}
rt_uint32_t get_device_baud(void)
{
return(Baudrate);
}
rt_uint32_t get_sys_time(void)
{
return(0L);
}
void zsend_byte(rt_uint16_t ch)
{
rt_device_write(zmodem.device, 0, &ch,1);
return;
}
void zsend_line(rt_uint16_t c)
{
rt_uint16_t ch;
ch = (c & 0377);
rt_device_write(zmodem.device, 0, &ch, 1);
return;
}
rt_int16_t zread_line(rt_uint16_t timeout)
{
char *str;
static char buf[10];
if (Line_left > 0)
{
Line_left -= 1;
return (*str++ & 0377);
}
Line_left = 0;
timeout/=5;
while (1)
{
Line_left = rt_device_read(shell->device, 0, buf, 1);
if (Line_left)
{
Line_left = Line_left;
str = buf;
break;
}
}
if (Line_left < 1) return TIMEOUT;
Line_left -=1;
char *str;
static char buf[10];
if (Line_left > 0)
{
Line_left -= 1;
return (*str++ & 0377);
}
Line_left = 0;
timeout/=5;
while (1)
{
Line_left = rt_device_read(shell->device, 0, buf, 1);
if (Line_left)
{
Line_left = Line_left;
str = buf;
break;
}
}
if (Line_left < 1) return TIMEOUT;
Line_left -=1;
return (*str++ & 0377);
}
@ -82,33 +82,33 @@ rt_int16_t zread_line(rt_uint16_t timeout)
* and \335 (break signal)
*/
void zsend_break(char *cmd)
{
{
while (*cmd++)
while (*cmd++)
{
switch (*cmd)
switch (*cmd)
{
case '\336':
case '\336':
continue;
case '\335':
rt_thread_delay(RT_TICK_PER_SECOND);
case '\335':
rt_thread_delay(RT_TICK_PER_SECOND);
continue;
default:
zsend_line(*cmd);
zsend_line(*cmd);
break;
}
}
}
}
/* send cancel string to get the other end to shut up */
void zsend_can(void)
{
static char cmd[] = {24,24,24,24,24,24,24,24,24,24,0};
static char cmd[] = {24,24,24,24,24,24,24,24,24,24,0};
zsend_break(cmd);
zsend_break(cmd);
rt_kprintf("\x0d");
Line_left=0; /* clear Line_left */
Line_left=0; /* clear Line_left */
return;
}
}
/* end of zdevice.c */

View File

@ -1,120 +1,120 @@
/*
* File : zstart.c
* File : zstart.c
* the implemention of zmodem protocol.
* Change Logs:
* Date Author Notes
* 2011-03-29 itspy
*/
#include <rtthread.h>
#include <finsh.h>
#include <shell.h>
#include <dfs.h>
#include <dfs_file.h>
#include "zdef.h"
struct zmodemf zmodem;
rt_err_t zmodem_rx_ind(rt_device_t dev, rt_size_t size)
{
/* release semaphore */
rt_sem_release(&zmodem.zsem);
return RT_EOK;
}
void finsh_rz(void *parameter)
{
char *path;
rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
rt_uint8_t flag;
flag = RT_DEVICE_FLAG_STREAM;
zmodem.device->flag &=(~flag);
rt_sem_init(&(zmodem.zsem), "zsem", 0, 0);
path = rt_thread_self()->parameter;
/* save old rx_indicate */
rx_indicate = zmodem.device->rx_indicate;
/* set new rx_indicate */
rt_device_set_rx_indicate(zmodem.device, RT_NULL);
/* start receive remote files */
zr_start(path);
zmodem.device->flag |=flag;
/* recovery old rx_indicate */
rt_device_set_rx_indicate(zmodem.device, rx_indicate);
/* finsh>> */
rt_kprintf(FINSH_PROMPT);
}
void finsh_sz(void *parameter)
{
char *path;
rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
rt_uint8_t flag;
flag = RT_DEVICE_FLAG_STREAM;
zmodem.device->flag &=(~flag);
rt_sem_init(&(zmodem.zsem), "zsem", 0, 0);
path = rt_thread_self()->parameter;
/* save old rx_indicate */
rx_indicate = zmodem.device->rx_indicate;
/* set new rx_indicate */
rt_device_set_rx_indicate(zmodem.device, zmodem_rx_ind);
zs_start(path);
zmodem.device->flag |=flag;
/* recovery old rx_indicate */
rt_device_set_rx_indicate(zmodem.device, rx_indicate);
/* finsh>> */
rt_kprintf(FINSH_PROMPT);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
#include <shell.h>
static void rz(char *para)
{
rt_thread_t init_thread;
rt_device_t device;
const char* device_name = finsh_get_device();
device = rt_device_find(device_name);
if( device == RT_NULL )
{
rt_kprintf("%s not find\r\n",device_name);
}
zmodem.device = device;
init_thread = rt_thread_create("rz",
finsh_rz,
(void*)para,
2048,
rt_thread_self()->current_priority+1,
20);
if (init_thread != RT_NULL) rt_thread_startup(init_thread);
}
FINSH_FUNCTION_EXPORT(rz, receive files by zmodem protocol)
static void sz(char *para)
{
rt_thread_t init_thread;
rt_device_t device;
const char* device_name = finsh_get_device();
device = rt_device_find(device_name);
if( device == RT_NULL )
{
rt_kprintf("%s not find\r\n",device_name);
}
zmodem.device = device;
init_thread = rt_thread_create("sz",
finsh_sz,
(void*)para,
2048,
rt_thread_self()->current_priority+1,
20);
if (init_thread != RT_NULL) rt_thread_startup(init_thread);
}
FINSH_FUNCTION_EXPORT(sz, send files by zmodem protocol)
#endif
*/
#include <rtthread.h>
#include <finsh.h>
#include <shell.h>
#include <dfs.h>
#include <dfs_file.h>
#include "zdef.h"
struct zmodemf zmodem;
rt_err_t zmodem_rx_ind(rt_device_t dev, rt_size_t size)
{
/* release semaphore */
rt_sem_release(&zmodem.zsem);
return RT_EOK;
}
void finsh_rz(void *parameter)
{
char *path;
rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
rt_uint8_t flag;
flag = RT_DEVICE_FLAG_STREAM;
zmodem.device->flag &=(~flag);
rt_sem_init(&(zmodem.zsem), "zsem", 0, 0);
path = rt_thread_self()->parameter;
/* save old rx_indicate */
rx_indicate = zmodem.device->rx_indicate;
/* set new rx_indicate */
rt_device_set_rx_indicate(zmodem.device, RT_NULL);
/* start receive remote files */
zr_start(path);
zmodem.device->flag |=flag;
/* recovery old rx_indicate */
rt_device_set_rx_indicate(zmodem.device, rx_indicate);
/* finsh>> */
rt_kprintf(FINSH_PROMPT);
}
void finsh_sz(void *parameter)
{
char *path;
rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
rt_uint8_t flag;
flag = RT_DEVICE_FLAG_STREAM;
zmodem.device->flag &=(~flag);
rt_sem_init(&(zmodem.zsem), "zsem", 0, 0);
path = rt_thread_self()->parameter;
/* save old rx_indicate */
rx_indicate = zmodem.device->rx_indicate;
/* set new rx_indicate */
rt_device_set_rx_indicate(zmodem.device, zmodem_rx_ind);
zs_start(path);
zmodem.device->flag |=flag;
/* recovery old rx_indicate */
rt_device_set_rx_indicate(zmodem.device, rx_indicate);
/* finsh>> */
rt_kprintf(FINSH_PROMPT);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
#include <shell.h>
static void rz(char *para)
{
rt_thread_t init_thread;
rt_device_t device;
const char* device_name = finsh_get_device();
device = rt_device_find(device_name);
if( device == RT_NULL )
{
rt_kprintf("%s not find\r\n",device_name);
}
zmodem.device = device;
init_thread = rt_thread_create("rz",
finsh_rz,
(void*)para,
2048,
rt_thread_self()->current_priority+1,
20);
if (init_thread != RT_NULL) rt_thread_startup(init_thread);
}
FINSH_FUNCTION_EXPORT(rz, receive files by zmodem protocol)
static void sz(char *para)
{
rt_thread_t init_thread;
rt_device_t device;
const char* device_name = finsh_get_device();
device = rt_device_find(device_name);
if( device == RT_NULL )
{
rt_kprintf("%s not find\r\n",device_name);
}
zmodem.device = device;
init_thread = rt_thread_create("sz",
finsh_sz,
(void*)para,
2048,
rt_thread_self()->current_priority+1,
20);
if (init_thread != RT_NULL) rt_thread_startup(init_thread);
}
FINSH_FUNCTION_EXPORT(sz, send files by zmodem protocol)
#endif

View File

@ -1,231 +1,231 @@
RT-Thread Coding Style
This is an developing instruction for RT-Thread developers. As an open source
software, RT-Thread is done by the cooperation of different people. This
document is a guide for RT-Thread developers and please obey it if you are.
RT-Thread users could also get to know some conventions in the code through it
and thus easier to understand the implementations of RT-Thread.
1. Directory Naming
In normal conditions, please name directories in lower-case. Directories should
have descriptive names. For example, the port of a chip should be composed of
the name of the chip and the category of the chip. Directories under components/
should stand for what the component does.
2. File Naming
In normal conditions, please name files in lower-case. If the file is
referencing other places, it can have the original name. To avoid naming
collision, do not use general names or the names that are frequently used.
3. Header Files
To avoid include the same header file for multiple times, you need to define a
symbol like this:
#ifndef __FILE_H__
#define __FILE_H__
/* header file content */
#endif
The symbol should begin and end with "__" to avoid naming collision. The words
of the file name should be connected by "_".
4. Header File Comments
In every header file, there should be copyright information and Change Log
record like this:
/*
* File : rtthread.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE.
*
* Change Logs:
* Date Author Notes
* 2006-03-18 Bernard the first version
* 2006-04-26 Bernard add semaphore APIs
* …
*/
5. Structure Defines
Please name structures in lower-case and connect words with "_". For example:
struct rt_list_node
{
struct rt_list_node *next;
struct rt_list_node *prev;
};
Braces should have their own lines and the members should be defines with
indent.
The names of type defines such like structure types should be the structure name
plus "_t". For example:
typedef struct rt_list_node rt_list_t;
In order to be easily referenced, the types of objects in kernel is pointer. For
example:
typedef struct rt_timer* rt_timer_t;
6. Micros
In RT-Thread, please use upper-case names for micro definitions. Words are
connected by "_". Like:
#define RT_TRUE 1
7. Function Naming and Declaration
Please name functions in lower-case and separate words with "_". API provided to
upper application should be declared in header files. If the function don't have
parameters, it should be declared as void:
rt_thread_t rt_thread_self(void);
8. Commenting
Please use English to comment. There shouldn't be too much comments and the
comments should describe what does the code do. And it should describe how the
complicated algorithm works. Comments to statements should be placed before them
or right of them. Anther places are illegal.
9. Indent
Please use TAB or 4 spaces to indent. It's preferred to use 4 spaces. If no
other special meanings, the indent should begin right after "{":
if (condition)
{
/* others */
}
The only one exception is switch. In switch-case statements, "case" should be
aligned with "switch":
switch (value)
{
case value1:
break;
}
"case" is aligned with "switch", the following code block should be indented.
10. Braces and Spaces
For ease of reading, it is advised that braces should occupy the whole line
instead of following other statements. Like:
if (condition)
{
/* others */
}
When matching braces have their own lines, the reader would identify the code
blocks easily.
There should be a space before parentheses when it's not a function call. For
example:
if (x <= y)
{
/* others */
}
for (index = 0; index < MAX_NUMBER; index ++)
{
/* others */
}
In expressions, there should be a space between most binary and ternary
operators and the strings. No spaces around(inside) parentheses, like:
if ( x <= y )
{
/* other */
}
This is a bad practice.
11. trace, log Informations
In RT-Thread, rt_kprintf is a commonly used logging routine. In RT-Thread
rt_kprintf is implemented as a polling, non-interrupting string output. It is
suitable in "instant" situations such as interrupt context. The polling method
would have influence to the timing sequence of the log output.
It is not recommended to use rt_kprintf frequently. Unless you are aware of that
it's not a big deal to run slower.
Logging should be off by default and can be turned on by a switch(e.g. a
variable or a micro). When logging, it should be easy to understand and easy to
determine where the problem is.
12. Functions
Functions in kernel should be K.I.S.S. If the function is too long, you should
split it into smaller ones and make each of them simplified and easy to
understand.
13. Objects
The kernel of RT-Thread uses object-oriented tech in C. The naming convention
is: structure names are the object names, object names + verb phrases are the
method names of objects:
struct rt_timer
{
struct rt_object parent;
/* other fields */
};
typedef struct rt_timer* rt_timer_t;
The definition of structure rt_timer stands for the object definition of timer
object.
rt_timer_t rt_timer_create(const char* name,
void (*timeout)(void* parameter), void* parameter,
rt_tick_t time, rt_uint8_t flag);
rt_err_t rt_timer_delete(rt_timer_t timer);
rt_err_t rt_timer_start(rt_timer_t timer);
rt_err_t rt_timer_stop(rt_timer_t timer);
rt_timer + verb phrase stands for the method that could be used on timer object.
When creating a new object, think twice on memory allocations: whether a static
object could be created or it could only created dynamically on heap.
14. Use astyle to format the code automatically
parameters: --style=allman
--indent=spaces=4
--pad-oper
--pad-header
--unpad-paren
--suffix=none
--align-pointer=name
--lineend=linux
--convert-tabs
--verbose
RT-Thread Coding Style
This is an developing instruction for RT-Thread developers. As an open source
software, RT-Thread is done by the cooperation of different people. This
document is a guide for RT-Thread developers and please obey it if you are.
RT-Thread users could also get to know some conventions in the code through it
and thus easier to understand the implementations of RT-Thread.
1. Directory Naming
In normal conditions, please name directories in lower-case. Directories should
have descriptive names. For example, the port of a chip should be composed of
the name of the chip and the category of the chip. Directories under components/
should stand for what the component does.
2. File Naming
In normal conditions, please name files in lower-case. If the file is
referencing other places, it can have the original name. To avoid naming
collision, do not use general names or the names that are frequently used.
3. Header Files
To avoid include the same header file for multiple times, you need to define a
symbol like this:
#ifndef __FILE_H__
#define __FILE_H__
/* header file content */
#endif
The symbol should begin and end with "__" to avoid naming collision. The words
of the file name should be connected by "_".
4. Header File Comments
In every header file, there should be copyright information and Change Log
record like this:
/*
* File : rtthread.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE.
*
* Change Logs:
* Date Author Notes
* 2006-03-18 Bernard the first version
* 2006-04-26 Bernard add semaphore APIs
* …
*/
5. Structure Defines
Please name structures in lower-case and connect words with "_". For example:
struct rt_list_node
{
struct rt_list_node *next;
struct rt_list_node *prev;
};
Braces should have their own lines and the members should be defines with
indent.
The names of type defines such like structure types should be the structure name
plus "_t". For example:
typedef struct rt_list_node rt_list_t;
In order to be easily referenced, the types of objects in kernel is pointer. For
example:
typedef struct rt_timer* rt_timer_t;
6. Micros
In RT-Thread, please use upper-case names for micro definitions. Words are
connected by "_". Like:
#define RT_TRUE 1
7. Function Naming and Declaration
Please name functions in lower-case and separate words with "_". API provided to
upper application should be declared in header files. If the function don't have
parameters, it should be declared as void:
rt_thread_t rt_thread_self(void);
8. Commenting
Please use English to comment. There shouldn't be too much comments and the
comments should describe what does the code do. And it should describe how the
complicated algorithm works. Comments to statements should be placed before them
or right of them. Anther places are illegal.
9. Indent
Please use TAB or 4 spaces to indent. It's preferred to use 4 spaces. If no
other special meanings, the indent should begin right after "{":
if (condition)
{
/* others */
}
The only one exception is switch. In switch-case statements, "case" should be
aligned with "switch":
switch (value)
{
case value1:
break;
}
"case" is aligned with "switch", the following code block should be indented.
10. Braces and Spaces
For ease of reading, it is advised that braces should occupy the whole line
instead of following other statements. Like:
if (condition)
{
/* others */
}
When matching braces have their own lines, the reader would identify the code
blocks easily.
There should be a space before parentheses when it's not a function call. For
example:
if (x <= y)
{
/* others */
}
for (index = 0; index < MAX_NUMBER; index ++)
{
/* others */
}
In expressions, there should be a space between most binary and ternary
operators and the strings. No spaces around(inside) parentheses, like:
if ( x <= y )
{
/* other */
}
This is a bad practice.
11. trace, log Informations
In RT-Thread, rt_kprintf is a commonly used logging routine. In RT-Thread
rt_kprintf is implemented as a polling, non-interrupting string output. It is
suitable in "instant" situations such as interrupt context. The polling method
would have influence to the timing sequence of the log output.
It is not recommended to use rt_kprintf frequently. Unless you are aware of that
it's not a big deal to run slower.
Logging should be off by default and can be turned on by a switch(e.g. a
variable or a micro). When logging, it should be easy to understand and easy to
determine where the problem is.
12. Functions
Functions in kernel should be K.I.S.S. If the function is too long, you should
split it into smaller ones and make each of them simplified and easy to
understand.
13. Objects
The kernel of RT-Thread uses object-oriented tech in C. The naming convention
is: structure names are the object names, object names + verb phrases are the
method names of objects:
struct rt_timer
{
struct rt_object parent;
/* other fields */
};
typedef struct rt_timer* rt_timer_t;
The definition of structure rt_timer stands for the object definition of timer
object.
rt_timer_t rt_timer_create(const char* name,
void (*timeout)(void* parameter), void* parameter,
rt_tick_t time, rt_uint8_t flag);
rt_err_t rt_timer_delete(rt_timer_t timer);
rt_err_t rt_timer_start(rt_timer_t timer);
rt_err_t rt_timer_stop(rt_timer_t timer);
rt_timer + verb phrase stands for the method that could be used on timer object.
When creating a new object, think twice on memory allocations: whether a static
object could be created or it could only created dynamically on heap.
14. Use astyle to format the code automatically
parameters: --style=allman
--indent=spaces=4
--pad-oper
--pad-header
--unpad-paren
--suffix=none
--align-pointer=name
--lineend=linux
--convert-tabs
--verbose

View File

@ -1,14 +1,14 @@
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup BasicDef Basic Definitions
*
* @brief Basic data type in RT-Thread RTOS.
*
* These are the basic definitions which used in RT-Thread RTOS. In general,
* RT-Thread kernel uses its own definition of the basic data types, such as
* rt_uint32_t, rt_uint8_t, etc., which does not depend on the compiler or
* architecture.
*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup BasicDef Basic Definitions
*
* @brief Basic data type in RT-Thread RTOS.
*
* These are the basic definitions which used in RT-Thread RTOS. In general,
* RT-Thread kernel uses its own definition of the basic data types, such as
* rt_uint32_t, rt_uint8_t, etc., which does not depend on the compiler or
* architecture.
*/

View File

@ -1,44 +1,44 @@
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup DFS Device Virtual File System
*
* @brief DFS is a virtual file system in RT-Thread RTOS.
*
* The DFS (Device Virtual File System) is a vfs file system of RT-Thread RTOS,
* which is focused on embedded device. VFS is an abstraction layer on top of a
* more concrete file system. The purpose of a VFS is to allow client applications
* to access different types of concrete file systems in a uniform way.
*
* @image html dfs.png "Figure 4: Device Virtual File System Architecture"
*
* The DFS specifies an interface between the kernel and a concrete file system.
* Therefore, it is easy to add support for new file system types to the kernel
* simply by fulfilling the interface.
*/
/**
* @addtogroup DFS
*/
/*@{*/
/**
* @defgroup Fd File Descriptor
*
*/
/**
* @defgroup FsApi File System API
*/
/**
* @defgroup FileApi File API
*/
/**
* @defgroup FsPosixApi File POSIX API
*/
/*@}*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup DFS Device Virtual File System
*
* @brief DFS is a virtual file system in RT-Thread RTOS.
*
* The DFS (Device Virtual File System) is a vfs file system of RT-Thread RTOS,
* which is focused on embedded device. VFS is an abstraction layer on top of a
* more concrete file system. The purpose of a VFS is to allow client applications
* to access different types of concrete file systems in a uniform way.
*
* @image html dfs.png "Figure 4: Device Virtual File System Architecture"
*
* The DFS specifies an interface between the kernel and a concrete file system.
* Therefore, it is easy to add support for new file system types to the kernel
* simply by fulfilling the interface.
*/
/**
* @addtogroup DFS
*/
/*@{*/
/**
* @defgroup Fd File Descriptor
*
*/
/**
* @defgroup FsApi File System API
*/
/**
* @defgroup FileApi File API
*/
/**
* @defgroup FsPosixApi File POSIX API
*/
/*@}*/

View File

@ -1,19 +1,19 @@
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup finsh finsh shell
*
* @brief finsh shell is a user command shell in RT-Thread RTOS.
*
* finsh shell is a user command shell in RT-Thread RTOS, which is a shell can
* accept C-expression like syntax in command. From finsh shell, user can access
* system area, such as memory, variables and function by input C-expression in
* command.
*
* @image html finsh.png "Figure 3: finsh shell architecture"
* There is a shell thread, which named as "tshell", in the finsh shell, it read
* user command from console device, and then invokes system function or access
* system variable to output result (by rt_kprintf).
*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup finsh finsh shell
*
* @brief finsh shell is a user command shell in RT-Thread RTOS.
*
* finsh shell is a user command shell in RT-Thread RTOS, which is a shell can
* accept C-expression like syntax in command. From finsh shell, user can access
* system area, such as memory, variables and function by input C-expression in
* command.
*
* @image html finsh.png "Figure 3: finsh shell architecture"
* There is a shell thread, which named as "tshell", in the finsh shell, it read
* user command from console device, and then invokes system function or access
* system variable to output result (by rt_kprintf).
*/

View File

@ -1,85 +1,85 @@
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup bsp Hardware Related Package
*
* @brief Hardware Related Package includes board support package(BSP) and CSP(Chip
* Support Package).
*
* Board Support Package(BSP) is the hardware related wrapper, for example, peripherals
* in board, the pinmux setting etc. In RT-Thread RTOS, the bsp is placed under bsp
* directory.
*
* Chip Support Package (CSP) is a software set that contains chip specific software.
* A CSP usually includes operating system porting and peripheral device drivers inside
* chip. In RT-Thread RTOS, the csp is placed under libcpu directory.
*/
/**
* @addtogroup bsp
*/
/*@{*/
/**
* This function will return current system interrupt status and disable system
* interrupt.
*
* @return the current system interrupt status
*/
rt_base_t rt_hw_interrupt_disable(void);
/**
* This function will set the specified interrupt status, which shall saved by
* rt_hw_intterrupt_disable function. If the saved interrupt status is interrupt
* opened, this function will open system interrupt status.
*/
void rt_hw_interrupt_enable(rt_base_t level);
/**
* This function initializes interrupt.
*/
void rt_hw_interrupt_init(void);
/**
* This function masks the specified interrupt.
*
* @param vector the interrupt number to be masked.
*
* @note not all of platform provide this function.
*/
void rt_hw_interrupt_mask(int vector);
/**
* This function umasks the specified interrupt.
*
* @param vector the interrupt number to be unmasked.
*
* @note not all of platform provide this function.
*/
void rt_hw_interrupt_umask(int vector);
/**
* This function will install specified interrupt handler.
*
* @param vector the interrupt number to be installed.
* @param new_handler the new interrupt handler.
* @param old_handler the old interrupt handler. This parameter can be RT_NULL.
*
* @note not all of platform provide this function.
*/
void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler,
rt_isr_handler_t *old_handler);
/**
* This function will reset whole platform.
*/
void rt_hw_cpu_reset(void);
/**
* This function will halt whole platform.
*/
void rt_hw_cpu_shutdown(void);
/*@}*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup bsp Hardware Related Package
*
* @brief Hardware Related Package includes board support package(BSP) and CSP(Chip
* Support Package).
*
* Board Support Package(BSP) is the hardware related wrapper, for example, peripherals
* in board, the pinmux setting etc. In RT-Thread RTOS, the bsp is placed under bsp
* directory.
*
* Chip Support Package (CSP) is a software set that contains chip specific software.
* A CSP usually includes operating system porting and peripheral device drivers inside
* chip. In RT-Thread RTOS, the csp is placed under libcpu directory.
*/
/**
* @addtogroup bsp
*/
/*@{*/
/**
* This function will return current system interrupt status and disable system
* interrupt.
*
* @return the current system interrupt status
*/
rt_base_t rt_hw_interrupt_disable(void);
/**
* This function will set the specified interrupt status, which shall saved by
* rt_hw_intterrupt_disable function. If the saved interrupt status is interrupt
* opened, this function will open system interrupt status.
*/
void rt_hw_interrupt_enable(rt_base_t level);
/**
* This function initializes interrupt.
*/
void rt_hw_interrupt_init(void);
/**
* This function masks the specified interrupt.
*
* @param vector the interrupt number to be masked.
*
* @note not all of platform provide this function.
*/
void rt_hw_interrupt_mask(int vector);
/**
* This function umasks the specified interrupt.
*
* @param vector the interrupt number to be unmasked.
*
* @note not all of platform provide this function.
*/
void rt_hw_interrupt_umask(int vector);
/**
* This function will install specified interrupt handler.
*
* @param vector the interrupt number to be installed.
* @param new_handler the new interrupt handler.
* @param old_handler the old interrupt handler. This parameter can be RT_NULL.
*
* @note not all of platform provide this function.
*/
void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler,
rt_isr_handler_t *old_handler);
/**
* This function will reset whole platform.
*/
void rt_hw_cpu_reset(void);
/**
* This function will halt whole platform.
*/
void rt_hw_cpu_shutdown(void);
/*@}*/

View File

@ -1,138 +1,138 @@
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup Kernel RT-Thread Kernel API
*
* The Kernel APIs are the core APIs of RT-Thread, which supports the following
* features:
* - Multi-thread management
* - Synchronization mechanisms
* - Inter-thread communication
* - Memory management
* - Asynchronous timer
*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup Kernel RT-Thread Kernel API
*
* The Kernel APIs are the core APIs of RT-Thread, which supports the following
* features:
* - Multi-thread management
* - Synchronization mechanisms
* - Inter-thread communication
* - Memory management
* - Asynchronous timer
*/
/**
* @addtogroup Kernel
*/
*/
/*@{*/
/**
* @defgroup Thread Thread Management
* @brief the thread management
*
* RT-Thread operating system supports multitask systems, which are based on thread
* scheduling.
* - The scheduling is a full preemptive priority-based scheduling algorithm.
* - 8/32/256 priority levels are supported, in which 0 is the highest and 7/31/255 the lowest.
* The 7/31/255th priority is used for idle thread.
* - Threads running at same priority level are supported. The shared time-slice
* round-robin scheduling is used for this case.
* - The time of scheduler to choose the next highest ready thread is determinant.
* - There are four status in thread management
* -# Initialization
* -# Running/Ready
* -# Blocked
* -# Closed
* - The number of threads in the system is unlimited, only related with RAM.
*/
/**
* @defgroup Clock Clock and Timer Management
* * @brief clock and system timer management
*
* RT-Thread uses clock tick to implement shared time-slice scheduling.
*
* The timing sensitivity of thread is implemented by timers. The timer can be set as
* one-shot or periodic timeout.
*/
/**
* @defgroup KernelObject Kernel Object Management
* @brief kernel object management
*
* The Kernel object system can access and manage all of the kernel objects.
*
* Kernel objects include most of the facilities in the kernel:
* - thread
* - semaphore and mutex
* - event/fast event, mailbox, messagequeue
* - memory pool
* - timer
* @image html Kernel_Object.png "Figure 2: Kernel Object"
* @image rtf Kernel_Object.png "Figure 2: Kernel Object"
*
* Kernel objects can be static objects, whose memory is allocated in compiling.
* It can be dynamic objects as well, whose memory is allocated from system heaps
* in runtime.
*/
/**
* @defgroup IPC Inter-Thread Communication
* @brief inter-thread communication
*
* RT-Thread operating system supports the traditional semaphore and mutex.
* - Mutex objects use inherited priority to prevent priority reversion.
* - The semaphore release action is safe for interrupt service routine.
*
* Moreover, the blocked queue for thread to obtain semaphore or mutex can be sorted
* by priority or FIFO. There are two flags to indicate this mechanism.
* - RT_IPC_FLAG_FIFO
* when the resource is available, thread pended on this resource at first would get
* the resource.
* - RT_IPC_FLAG_PRIO
* when the resource is available, thread pended on this resource who had the most high
* priority would get the resource.
*
* RT-Thread operating systems supports event/fast event, mail box and message queue.
* - The event mechanism is used to awake a thead by setting one or more corresponding
* bit of a binary number when an event ocurs.
* - The fast event supports event thread queue. Once a one bit event occurs, the corresponding
* blocked thread can be found out timing accurately, then will be waked up.
* - In mailbox, the mail length is fixed to 4 byte, which is more effective than message queue.
* - The send action for communication facilities is also safe for interrupt service routine.
*/
/**
* @defgroup MM Memory Management
* @brief memory management for memory pool and heap memory
*
* RT-Thread operating system supports two types memory management:
* - Static memory pool management
* - Dynamic memory heap management.
*
* The time to allocate a memory block from the memory pool is determinant. When
* the memory pool is empty, the allocated thread can be blocked (or immediately return,
* or waiting for sometime to return, which are determined by a timeout parameter).
* When other thread releases memory blocks to this memory pool, the blocked thread is
* wake up.
*
* There are two methods in dynamic memory heap management, one is used for small memory,
* such as less than 1MB. Another is a SLAB like memory management, which is suitable
* for large memory system. All of them has no real-time character.
*/
/**
* @defgroup Device Device System
* @brief device I/O subsystem
*
* The Device System is designed as simple and minimum layer to help communication between
* applications and drivers.
*
* The Device System provide five interfaces to driver:
* - open, open a device
* - close, close a device
* - read, read some data from a device
* - write, write some data to a device
* - control, send some control command to a device
*/
/**
* @defgroup Hook Runtime Trace and Record
* @brief the hook function set in runtime
*
/**
* @defgroup Thread Thread Management
* @brief the thread management
*
* RT-Thread operating system supports multitask systems, which are based on thread
* scheduling.
* - The scheduling is a full preemptive priority-based scheduling algorithm.
* - 8/32/256 priority levels are supported, in which 0 is the highest and 7/31/255 the lowest.
* The 7/31/255th priority is used for idle thread.
* - Threads running at same priority level are supported. The shared time-slice
* round-robin scheduling is used for this case.
* - The time of scheduler to choose the next highest ready thread is determinant.
* - There are four status in thread management
* -# Initialization
* -# Running/Ready
* -# Blocked
* -# Closed
* - The number of threads in the system is unlimited, only related with RAM.
*/
/**
* @defgroup Clock Clock and Timer Management
* * @brief clock and system timer management
*
* RT-Thread uses clock tick to implement shared time-slice scheduling.
*
* The timing sensitivity of thread is implemented by timers. The timer can be set as
* one-shot or periodic timeout.
*/
/**
* @defgroup KernelObject Kernel Object Management
* @brief kernel object management
*
* The Kernel object system can access and manage all of the kernel objects.
*
* Kernel objects include most of the facilities in the kernel:
* - thread
* - semaphore and mutex
* - event/fast event, mailbox, messagequeue
* - memory pool
* - timer
* @image html Kernel_Object.png "Figure 2: Kernel Object"
* @image rtf Kernel_Object.png "Figure 2: Kernel Object"
*
* Kernel objects can be static objects, whose memory is allocated in compiling.
* It can be dynamic objects as well, whose memory is allocated from system heaps
* in runtime.
*/
/**
* @defgroup IPC Inter-Thread Communication
* @brief inter-thread communication
*
* RT-Thread operating system supports the traditional semaphore and mutex.
* - Mutex objects use inherited priority to prevent priority reversion.
* - The semaphore release action is safe for interrupt service routine.
*
* Moreover, the blocked queue for thread to obtain semaphore or mutex can be sorted
* by priority or FIFO. There are two flags to indicate this mechanism.
* - RT_IPC_FLAG_FIFO
* when the resource is available, thread pended on this resource at first would get
* the resource.
* - RT_IPC_FLAG_PRIO
* when the resource is available, thread pended on this resource who had the most high
* priority would get the resource.
*
* RT-Thread operating systems supports event/fast event, mail box and message queue.
* - The event mechanism is used to awake a thead by setting one or more corresponding
* bit of a binary number when an event ocurs.
* - The fast event supports event thread queue. Once a one bit event occurs, the corresponding
* blocked thread can be found out timing accurately, then will be waked up.
* - In mailbox, the mail length is fixed to 4 byte, which is more effective than message queue.
* - The send action for communication facilities is also safe for interrupt service routine.
*/
/**
* @defgroup MM Memory Management
* @brief memory management for memory pool and heap memory
*
* RT-Thread operating system supports two types memory management:
* - Static memory pool management
* - Dynamic memory heap management.
*
* The time to allocate a memory block from the memory pool is determinant. When
* the memory pool is empty, the allocated thread can be blocked (or immediately return,
* or waiting for sometime to return, which are determined by a timeout parameter).
* When other thread releases memory blocks to this memory pool, the blocked thread is
* wake up.
*
* There are two methods in dynamic memory heap management, one is used for small memory,
* such as less than 1MB. Another is a SLAB like memory management, which is suitable
* for large memory system. All of them has no real-time character.
*/
/**
* @defgroup Device Device System
* @brief device I/O subsystem
*
* The Device System is designed as simple and minimum layer to help communication between
* applications and drivers.
*
* The Device System provide five interfaces to driver:
* - open, open a device
* - close, close a device
* - read, read some data from a device
* - write, write some data to a device
* - control, send some control command to a device
*/
/**
* @defgroup Hook Runtime Trace and Record
* @brief the hook function set in runtime
*
* In order to trace and record RT-Thread activity in runtime, a hook mechanism
* is introduced.
*
@ -141,20 +141,20 @@
* - object hook, invoked at object created, deleted, taken and put etc.
* - scheduler hook, invoked at thread switch and idle thread loop.
* - memory hook, invoked when allocate or free memory block.
* - timer hook, invoked when timer is timeout.
*/
/**
* @defgroup KernelService Other useful kernel service
* @brief other useful service in the kernel
*/
/**
* @defgroup Error Error Code
* @brief error code
*
* The error code is defined to identify which kind of error occurs. When some
* bad things happen, the current thread's errno will be set. see @ref _rt_errno
*/
/*@}*/
* - timer hook, invoked when timer is timeout.
*/
/**
* @defgroup KernelService Other useful kernel service
* @brief other useful service in the kernel
*/
/**
* @defgroup Error Error Code
* @brief error code
*
* The error code is defined to identify which kind of error occurs. When some
* bad things happen, the current thread's errno will be set. see @ref _rt_errno
*/
/*@}*/

View File

@ -1,49 +1,49 @@
/*
* This file is only used for doxygen document generation.
*/
/**
* @mainpage Introduction
* @author RT-Thread Development Team
* @version 1.1.0
*
* RT-Thread RTOS is an open source embedded real-time operating system and is
* designed specifically for small memory footprint platforms. The real-time and
* embedded characters are the most significant advantages of RT-Thread.
*
* - Real-Time Character
*
* RT-Thread has a real-time operating system kernel, with fully preempted
* multi-thread scheduler, inter-thread communication with timing sensitivity
* and transparent interrupt handling.
*
* - Embedded Character
*
* RT-Thread is suitable for embedded systems for small footprint characters.
* The kernel is implemented as a simple C library. The simplest application
* costs less than 1 Kbytes RAM on the ARM Cortex-M platform.
*
* @section kernel_arch RT-Thread Architecture
*
* RT-Thread system architecture is like:
* @image html System_Arch.png "Figure 1: RT-Thread Architecture"
*
* @section kernel_service Kernel API
*
* The Kernel APIs are the core APIs of RT-Thread, which supports the following
* features:
* - Multi-thread management and scheduler
* - Synchronization mechanisms, semaphore, recursive mutex and event set
* - Inter-thread communication, mailbox and message queue
* - Memory management, memory pool and dynamic heap memory management
* - Asynchronous timer
*
* For more details, please refer to @ref Kernel
*
* @section system_init System Initialization
*
* Once RT-Thread operating system starts up, the facility in system must be initialized
* firstly.
*
* For more details, please refer to @ref SystemInit
*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @mainpage Introduction
* @author RT-Thread Development Team
* @version 1.1.0
*
* RT-Thread RTOS is an open source embedded real-time operating system and is
* designed specifically for small memory footprint platforms. The real-time and
* embedded characters are the most significant advantages of RT-Thread.
*
* - Real-Time Character
*
* RT-Thread has a real-time operating system kernel, with fully preempted
* multi-thread scheduler, inter-thread communication with timing sensitivity
* and transparent interrupt handling.
*
* - Embedded Character
*
* RT-Thread is suitable for embedded systems for small footprint characters.
* The kernel is implemented as a simple C library. The simplest application
* costs less than 1 Kbytes RAM on the ARM Cortex-M platform.
*
* @section kernel_arch RT-Thread Architecture
*
* RT-Thread system architecture is like:
* @image html System_Arch.png "Figure 1: RT-Thread Architecture"
*
* @section kernel_service Kernel API
*
* The Kernel APIs are the core APIs of RT-Thread, which supports the following
* features:
* - Multi-thread management and scheduler
* - Synchronization mechanisms, semaphore, recursive mutex and event set
* - Inter-thread communication, mailbox and message queue
* - Memory management, memory pool and dynamic heap memory management
* - Asynchronous timer
*
* For more details, please refer to @ref Kernel
*
* @section system_init System Initialization
*
* Once RT-Thread operating system starts up, the facility in system must be initialized
* firstly.
*
* For more details, please refer to @ref SystemInit
*/

View File

@ -1,14 +1,14 @@
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup Module Application Module
*
* @brief Application Module is a feature let user to execute application in RT-Thread RTOS.
*
* Application Module is implemented as dynamic object loader, but it can handle
* the dependences relationship between application and dynamic library, moreover,
* it also can handle the kernel object destroy and memory release issue when application
* (abnormally) exit.
*/
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup Module Application Module
*
* @brief Application Module is a feature let user to execute application in RT-Thread RTOS.
*
* Application Module is implemented as dynamic object loader, but it can handle
* the dependences relationship between application and dynamic library, moreover,
* it also can handle the kernel object destroy and memory release issue when application
* (abnormally) exit.
*/

View File

@ -1,79 +1,79 @@
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup SystemInit System Initialization
*
* @brief System initialization procedure.
*
* When RT-Thread operating system starts up, the basic operating system facility
* initialization routines must be invoked.
*
* The suggested initialization sequence is:
*
* - initialize device hardware
* rt_hw_board_init();
*
* User can put the low level hardware initialization in this function, such as
* DDR memory setting, pinmux setting, console device setting etc.
*
* - show version
* rt_show_version();
*
* - initialize system tick
* rt_system_tick_init();
*
* - initialize kernel object [deprecated]
* rt_system_object_init();
*
* - initialize timer system
* rt_system_timer_init();
*
* - initialize system heap memory
* rt_system_heap_init(__bss_end, __end_of_memory);
*
* - initialize module system
* rt_system_module_init();
*
* - initialize scheduler system
* rt_system_scheduler_init();
*
* - initialize application
* rt_application_init();
*
* - initialize system timer thread
* rt_system_timer_thread_init();
*
* - initialize idle thread
* rt_thread_idle_init();
*
* - start scheduler
* rt_system_scheduler_start();
*/
/**
* @ingroup SystemInit
*
* This function will initialize user application.
*
* This function will be invoked when system initialization and system scheduler
* has not started. User can allocate memory, create thread, semaphore etc. However,
* user shall not suspend 'current' thread.
*/
void rt_application_init()
{
}
/**
* @ingroup SystemInit
*
* This function will initialize system heap memory.
*
* @param begin_addr the beginning address of system heap memory.
* @param end_addr the end address of system heap memory.
*
*/
void rt_system_heap_init(void* begin_addr, void* end_addr)
{
}
/*
* This file is only used for doxygen document generation.
*/
/**
* @defgroup SystemInit System Initialization
*
* @brief System initialization procedure.
*
* When RT-Thread operating system starts up, the basic operating system facility
* initialization routines must be invoked.
*
* The suggested initialization sequence is:
*
* - initialize device hardware
* rt_hw_board_init();
*
* User can put the low level hardware initialization in this function, such as
* DDR memory setting, pinmux setting, console device setting etc.
*
* - show version
* rt_show_version();
*
* - initialize system tick
* rt_system_tick_init();
*
* - initialize kernel object [deprecated]
* rt_system_object_init();
*
* - initialize timer system
* rt_system_timer_init();
*
* - initialize system heap memory
* rt_system_heap_init(__bss_end, __end_of_memory);
*
* - initialize module system
* rt_system_module_init();
*
* - initialize scheduler system
* rt_system_scheduler_init();
*
* - initialize application
* rt_application_init();
*
* - initialize system timer thread
* rt_system_timer_thread_init();
*
* - initialize idle thread
* rt_thread_idle_init();
*
* - start scheduler
* rt_system_scheduler_start();
*/
/**
* @ingroup SystemInit
*
* This function will initialize user application.
*
* This function will be invoked when system initialization and system scheduler
* has not started. User can allocate memory, create thread, semaphore etc. However,
* user shall not suspend 'current' thread.
*/
void rt_application_init()
{
}
/**
* @ingroup SystemInit
*
* This function will initialize system heap memory.
*
* @param begin_addr the beginning address of system heap memory.
* @param end_addr the end address of system heap memory.
*
*/
void rt_system_heap_init(void* begin_addr, void* end_addr)
{
}

View File

@ -1,56 +1,56 @@
/*
* File : listdir.c
* This file is part of RT-TestCase in RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-02-10 Bernard first version
*/
#include <rtthread.h>
#include <dfs_posix.h>
static char fullpath[256];
void list_dir(const char* path)
{
DIR *dir;
dir = opendir(path);
if (dir != RT_NULL)
{
struct dirent* dirent;
struct stat s;
do
{
dirent = readdir(dir);
if (dirent == RT_NULL) break;
rt_memset(&s, 0, sizeof(struct stat));
/* build full path for each file */
rt_sprintf(fullpath, "%s/%s", path, dirent->d_name);
stat(fullpath, &s);
if ( s.st_mode & DFS_S_IFDIR )
{
rt_kprintf("%s\t\t<DIR>\n", dirent->d_name);
}
else
{
rt_kprintf("%s\t\t%lu\n", dirent->d_name, s.st_size);
}
} while (dirent != RT_NULL);
closedir(dir);
}
else rt_kprintf("open %s directory failed\n", path);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(list_dir, list directory);
#endif
/*
* File : listdir.c
* This file is part of RT-TestCase in RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-02-10 Bernard first version
*/
#include <rtthread.h>
#include <dfs_posix.h>
static char fullpath[256];
void list_dir(const char* path)
{
DIR *dir;
dir = opendir(path);
if (dir != RT_NULL)
{
struct dirent* dirent;
struct stat s;
do
{
dirent = readdir(dir);
if (dirent == RT_NULL) break;
rt_memset(&s, 0, sizeof(struct stat));
/* build full path for each file */
rt_sprintf(fullpath, "%s/%s", path, dirent->d_name);
stat(fullpath, &s);
if ( s.st_mode & DFS_S_IFDIR )
{
rt_kprintf("%s\t\t<DIR>\n", dirent->d_name);
}
else
{
rt_kprintf("%s\t\t%lu\n", dirent->d_name, s.st_size);
}
} while (dirent != RT_NULL);
closedir(dir);
}
else rt_kprintf("open %s directory failed\n", path);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(list_dir, list directory);
#endif

View File

@ -1,64 +1,64 @@
/*
* File : readspeed.c
* This file is part of RT-TestCase in RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-02-10 Bernard first version
*/
#include <rtthread.h>
#include <dfs_posix.h>
void readspeed(const char* filename, int block_size)
{
int fd;
char *buff_ptr;
rt_size_t total_length;
rt_tick_t tick;
fd = open(filename, 0, O_RDONLY);
if (fd < 0)
{
rt_kprintf("open file:%s failed\n", filename);
return;
}
buff_ptr = rt_malloc(block_size);
if (buff_ptr == RT_NULL)
{
rt_kprintf("no memory\n");
close(fd);
return;
}
tick = rt_tick_get();
total_length = 0;
while (1)
{
int length;
length = read(fd, buff_ptr, block_size);
if (length <= 0) break;
total_length += length;
}
tick = rt_tick_get() - tick;
/* close file and release memory */
close(fd);
rt_free(buff_ptr);
/* calculate read speed */
rt_kprintf("File read speed: %d byte/s\n", total_length /tick * RT_TICK_PER_SECOND);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(readspeed, perform file read test);
#endif
/*
* File : readspeed.c
* This file is part of RT-TestCase in RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-02-10 Bernard first version
*/
#include <rtthread.h>
#include <dfs_posix.h>
void readspeed(const char* filename, int block_size)
{
int fd;
char *buff_ptr;
rt_size_t total_length;
rt_tick_t tick;
fd = open(filename, 0, O_RDONLY);
if (fd < 0)
{
rt_kprintf("open file:%s failed\n", filename);
return;
}
buff_ptr = rt_malloc(block_size);
if (buff_ptr == RT_NULL)
{
rt_kprintf("no memory\n");
close(fd);
return;
}
tick = rt_tick_get();
total_length = 0;
while (1)
{
int length;
length = read(fd, buff_ptr, block_size);
if (length <= 0) break;
total_length += length;
}
tick = rt_tick_get() - tick;
/* close file and release memory */
close(fd);
rt_free(buff_ptr);
/* calculate read speed */
rt_kprintf("File read speed: %d byte/s\n", total_length /tick * RT_TICK_PER_SECOND);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(readspeed, perform file read test);
#endif

View File

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

View File

@ -1,50 +1,50 @@
/*
* File : seekdir.c
* This file is part of RT-TestCase in RT-Thread RTOS
* COPYRIGHT (C) 2011, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2011-06-02 Bernard first version
*/
#include <dfs_posix.h>
void seekdir_test(void)
{
DIR * dirp;
long save3 = 0;
long cur;
int i = 0;
struct dirent *dp;
dirp = opendir ("/");
save3 = telldir(dirp);
for (dp = readdir(dirp); dp != RT_NULL; dp = readdir(dirp))
{
rt_kprintf("direntry: %s\n", dp->d_name);
/* 保存第三个目录项的目录指针 */
if (i++ == 3)
{
save3 = telldir(dirp);
}
}
/* 回到刚才保存的第三个目录项的目录指针 */
seekdir (dirp, save3);
rt_kprintf("seek dientry to: %d\n", save3);
for (dp = readdir(dirp); dp != RT_NULL; dp = readdir(dirp))
{
rt_kprintf("direntry: %s\n", dp->d_name);
}
/* 关闭目录 */
closedir (dirp);
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(seekdir_test, perform directory seek test);
/*
* File : seekdir.c
* This file is part of RT-TestCase in RT-Thread RTOS
* COPYRIGHT (C) 2011, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2011-06-02 Bernard first version
*/
#include <dfs_posix.h>
void seekdir_test(void)
{
DIR * dirp;
long save3 = 0;
long cur;
int i = 0;
struct dirent *dp;
dirp = opendir ("/");
save3 = telldir(dirp);
for (dp = readdir(dirp); dp != RT_NULL; dp = readdir(dirp))
{
rt_kprintf("direntry: %s\n", dp->d_name);
/* 保存第三个目录项的目录指针 */
if (i++ == 3)
{
save3 = telldir(dirp);
}
}
/* 回到刚才保存的第三个目录项的目录指针 */
seekdir (dirp, save3);
rt_kprintf("seek dientry to: %d\n", save3);
for (dp = readdir(dirp); dp != RT_NULL; dp = readdir(dirp))
{
rt_kprintf("direntry: %s\n", dp->d_name);
}
/* 关闭目录 */
closedir (dirp);
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(seekdir_test, perform directory seek test);

View File

@ -1,72 +1,72 @@
/*
* File : writespeed.c
* This file is part of RT-TestCase in RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-02-10 Bernard first version
*/
#include <rtthread.h>
#include <dfs_posix.h>
void writespeed(const char* filename, int total_length, int block_size)
{
int fd, index, length;
char *buff_ptr;
rt_tick_t tick;
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0);
if (fd < 0)
{
rt_kprintf("open file:%s failed\n", filename);
return;
}
buff_ptr = rt_malloc(block_size);
if (buff_ptr == RT_NULL)
{
rt_kprintf("no memory\n");
close(fd);
return;
}
/* prepare write data */
for (index = 0; index < block_size; index++)
{
buff_ptr[index] = index;
}
index = 0;
/* get the beginning tick */
tick = rt_tick_get();
while (index < total_length / block_size)
{
length = write(fd, buff_ptr, block_size);
if (length != block_size)
{
rt_kprintf("write failed\n");
break;
}
index ++;
}
tick = rt_tick_get() - tick;
/* close file and release memory */
close(fd);
rt_free(buff_ptr);
/* calculate write speed */
rt_kprintf("File write speed: %d byte/s\n", total_length / tick * RT_TICK_PER_SECOND);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(writespeed, perform file write test);
#endif
/*
* File : writespeed.c
* This file is part of RT-TestCase in RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-02-10 Bernard first version
*/
#include <rtthread.h>
#include <dfs_posix.h>
void writespeed(const char* filename, int total_length, int block_size)
{
int fd, index, length;
char *buff_ptr;
rt_tick_t tick;
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0);
if (fd < 0)
{
rt_kprintf("open file:%s failed\n", filename);
return;
}
buff_ptr = rt_malloc(block_size);
if (buff_ptr == RT_NULL)
{
rt_kprintf("no memory\n");
close(fd);
return;
}
/* prepare write data */
for (index = 0; index < block_size; index++)
{
buff_ptr[index] = index;
}
index = 0;
/* get the beginning tick */
tick = rt_tick_get();
while (index < total_length / block_size)
{
length = write(fd, buff_ptr, block_size);
if (length != block_size)
{
rt_kprintf("write failed\n");
break;
}
index ++;
}
tick = rt_tick_get() - tick;
/* close file and release memory */
close(fd);
rt_free(buff_ptr);
/* calculate write speed */
rt_kprintf("File write speed: %d byte/s\n", total_length / tick * RT_TICK_PER_SECOND);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(writespeed, perform file write test);
#endif

View File

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

View File

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

View File

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

View File

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

View File

@ -1,267 +1,267 @@
/*
*
*
* 线线worker一个是消费者线程thread
*
* worker负责把数据将写入到环形buffer中thread
* buffer中读出
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 一个环形buffer的实现 */
struct rb
{
rt_uint16_t read_index, write_index;
rt_uint8_t *buffer_ptr;
rt_uint16_t buffer_size;
};
/* 指向信号量控制块的指针 */
static rt_sem_t sem = RT_NULL;
/* 指向线程控制块的指针 */
static rt_thread_t tid = RT_NULL, worker = RT_NULL;
/* 环形buffer的内存块用数组体现出来 */
#define BUFFER_SIZE 256
#define BUFFER_ITEM 32
static rt_uint8_t working_buffer[BUFFER_SIZE];
struct rb working_rb;
/* 初始化环形buffersize指的是buffer的大小。注这里并没对数据地址对齐做处理 */
static void rb_init(struct rb* rb, rt_uint8_t *pool, rt_uint16_t size)
{
RT_ASSERT(rb != RT_NULL);
/* 对读写指针清零*/
rb->read_index = rb->write_index = 0;
/* 设置环形buffer的内存数据块 */
rb->buffer_ptr = pool;
rb->buffer_size = size;
}
/* 向环形buffer中写入数据 */
static rt_bool_t rb_put(struct rb* rb, const rt_uint8_t *ptr, rt_uint16_t length)
{
rt_size_t size;
/* 判断是否有足够的剩余空间 */
if (rb->read_index > rb->write_index)
size = rb->read_index - rb->write_index;
else
size = rb->buffer_size - rb->write_index + rb->read_index;
/* 没有多余的空间 */
if (size < length) return RT_FALSE;
if (rb->read_index > rb->write_index)
{
/* read_index - write_index 即为总的空余空间 */
memcpy(&rb->buffer_ptr[rb->write_index], ptr, length);
rb->write_index += length;
}
else
{
if (rb->buffer_size - rb->write_index > length)
{
/* write_index 后面剩余的空间有足够的长度 */
memcpy(&rb->buffer_ptr[rb->write_index], ptr, length);
rb->write_index += length;
}
else
{
/*
* write_index
*
*/
memcpy(&rb->buffer_ptr[rb->write_index], ptr,
rb->buffer_size - rb->write_index);
memcpy(&rb->buffer_ptr[0], &ptr[rb->buffer_size - rb->write_index],
length - (rb->buffer_size - rb->write_index));
rb->write_index = length - (rb->buffer_size - rb->write_index);
}
}
return RT_TRUE;
}
/* 从环形buffer中读出数据 */
static rt_bool_t rb_get(struct rb* rb, rt_uint8_t *ptr, rt_uint16_t length)
{
rt_size_t size;
/* 判断是否有足够的数据 */
if (rb->read_index > rb->write_index)
size = rb->buffer_size - rb->read_index + rb->write_index;
else
size = rb->write_index - rb->read_index;
/* 没有足够的数据 */
if (size < length) return RT_FALSE;
if (rb->read_index > rb->write_index)
{
if (rb->buffer_size - rb->read_index > length)
{
/* read_index的数据足够多直接复制 */
memcpy(ptr, &rb->buffer_ptr[rb->read_index], length);
rb->read_index += length;
}
else
{
/* read_index的数据不够需要分段复制 */
memcpy(ptr, &rb->buffer_ptr[rb->read_index],
rb->buffer_size - rb->read_index);
memcpy(&ptr[rb->buffer_size - rb->read_index], &rb->buffer_ptr[0],
length - rb->buffer_size + rb->read_index);
rb->read_index = length - rb->buffer_size + rb->read_index;
}
}
else
{
/*
* read_index要比write_index小
*
*/
memcpy(ptr, &rb->buffer_ptr[rb->read_index], length);
rb->read_index += length;
}
return RT_TRUE;
}
/* 生产者线程入口 */
static void thread_entry(void* parameter)
{
rt_bool_t result;
rt_uint8_t data_buffer[BUFFER_ITEM + 1];
while (1)
{
/* 持有信号量 */
rt_sem_take(sem, RT_WAITING_FOREVER);
/* 从环buffer中获得数据 */
result = rb_get(&working_rb, &data_buffer[0], BUFFER_ITEM);
/* 释放信号量 */
rt_sem_release(sem);
data_buffer[BUFFER_ITEM] = '\0';
if (result == RT_TRUE)
{
/* 获取数据成功,打印数据 */
rt_kprintf("%s\n", data_buffer);
}
/* 做一个5 OS Tick的休眠 */
rt_thread_delay(5);
}
}
/* worker线程入口 */
static void worker_entry(void* parameter)
{
rt_bool_t result;
rt_uint32_t index, setchar;
rt_uint8_t data_buffer[BUFFER_ITEM];
setchar = 0x21;
while (1)
{
/* 构造数据 */
for(index = 0; index < BUFFER_ITEM; index++)
{
data_buffer[index] = setchar;
if (++setchar == 0x7f)
setchar = 0x21;
}
/* 持有信号量 */
rt_sem_take(sem, RT_WAITING_FOREVER);
/* 把数据放到环形buffer中 */
result = rb_put(&working_rb, &data_buffer[0], BUFFER_ITEM);
/* 释放信号量 */
rt_sem_release(sem);
/* 放入成功做一个10 OS Tick的休眠 */
rt_thread_delay(10);
}
}
int semaphore_buffer_worker_init()
{
/* 初始化ring buffer */
rb_init(&working_rb, working_buffer, BUFFER_SIZE);
/* 创建信号量 */
sem = rt_sem_create("sem", 1, RT_IPC_FLAG_FIFO);
if (sem == RT_NULL)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
/* 创建线程1 */
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);
/* 创建线程2 */
worker = rt_thread_create("worker",
worker_entry, RT_NULL, /* 线程入口是worker_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()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除信号量 */
if (sem != RT_NULL)
rt_sem_delete(sem);
/* 删除线程 */
if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid);
if (worker != RT_NULL && worker->stat != RT_THREAD_CLOSE)
rt_thread_delete(worker);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_semaphore_buffer_worker()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
semaphore_buffer_worker_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_semaphore_buffer_worker, a buffer worker with semaphore example);
#else
/* 用户应用入口 */
int rt_application_init()
{
semaphore_buffer_worker_init();
return 0;
}
#endif
/*
*
*
* 线线worker一个是消费者线程thread
*
* worker负责把数据将写入到环形buffer中thread
* buffer中读出
*/
#include <rtthread.h>
#include "tc_comm.h"
/* 一个环形buffer的实现 */
struct rb
{
rt_uint16_t read_index, write_index;
rt_uint8_t *buffer_ptr;
rt_uint16_t buffer_size;
};
/* 指向信号量控制块的指针 */
static rt_sem_t sem = RT_NULL;
/* 指向线程控制块的指针 */
static rt_thread_t tid = RT_NULL, worker = RT_NULL;
/* 环形buffer的内存块用数组体现出来 */
#define BUFFER_SIZE 256
#define BUFFER_ITEM 32
static rt_uint8_t working_buffer[BUFFER_SIZE];
struct rb working_rb;
/* 初始化环形buffersize指的是buffer的大小。注这里并没对数据地址对齐做处理 */
static void rb_init(struct rb* rb, rt_uint8_t *pool, rt_uint16_t size)
{
RT_ASSERT(rb != RT_NULL);
/* 对读写指针清零*/
rb->read_index = rb->write_index = 0;
/* 设置环形buffer的内存数据块 */
rb->buffer_ptr = pool;
rb->buffer_size = size;
}
/* 向环形buffer中写入数据 */
static rt_bool_t rb_put(struct rb* rb, const rt_uint8_t *ptr, rt_uint16_t length)
{
rt_size_t size;
/* 判断是否有足够的剩余空间 */
if (rb->read_index > rb->write_index)
size = rb->read_index - rb->write_index;
else
size = rb->buffer_size - rb->write_index + rb->read_index;
/* 没有多余的空间 */
if (size < length) return RT_FALSE;
if (rb->read_index > rb->write_index)
{
/* read_index - write_index 即为总的空余空间 */
memcpy(&rb->buffer_ptr[rb->write_index], ptr, length);
rb->write_index += length;
}
else
{
if (rb->buffer_size - rb->write_index > length)
{
/* write_index 后面剩余的空间有足够的长度 */
memcpy(&rb->buffer_ptr[rb->write_index], ptr, length);
rb->write_index += length;
}
else
{
/*
* write_index
*
*/
memcpy(&rb->buffer_ptr[rb->write_index], ptr,
rb->buffer_size - rb->write_index);
memcpy(&rb->buffer_ptr[0], &ptr[rb->buffer_size - rb->write_index],
length - (rb->buffer_size - rb->write_index));
rb->write_index = length - (rb->buffer_size - rb->write_index);
}
}
return RT_TRUE;
}
/* 从环形buffer中读出数据 */
static rt_bool_t rb_get(struct rb* rb, rt_uint8_t *ptr, rt_uint16_t length)
{
rt_size_t size;
/* 判断是否有足够的数据 */
if (rb->read_index > rb->write_index)
size = rb->buffer_size - rb->read_index + rb->write_index;
else
size = rb->write_index - rb->read_index;
/* 没有足够的数据 */
if (size < length) return RT_FALSE;
if (rb->read_index > rb->write_index)
{
if (rb->buffer_size - rb->read_index > length)
{
/* read_index的数据足够多直接复制 */
memcpy(ptr, &rb->buffer_ptr[rb->read_index], length);
rb->read_index += length;
}
else
{
/* read_index的数据不够需要分段复制 */
memcpy(ptr, &rb->buffer_ptr[rb->read_index],
rb->buffer_size - rb->read_index);
memcpy(&ptr[rb->buffer_size - rb->read_index], &rb->buffer_ptr[0],
length - rb->buffer_size + rb->read_index);
rb->read_index = length - rb->buffer_size + rb->read_index;
}
}
else
{
/*
* read_index要比write_index小
*
*/
memcpy(ptr, &rb->buffer_ptr[rb->read_index], length);
rb->read_index += length;
}
return RT_TRUE;
}
/* 生产者线程入口 */
static void thread_entry(void* parameter)
{
rt_bool_t result;
rt_uint8_t data_buffer[BUFFER_ITEM + 1];
while (1)
{
/* 持有信号量 */
rt_sem_take(sem, RT_WAITING_FOREVER);
/* 从环buffer中获得数据 */
result = rb_get(&working_rb, &data_buffer[0], BUFFER_ITEM);
/* 释放信号量 */
rt_sem_release(sem);
data_buffer[BUFFER_ITEM] = '\0';
if (result == RT_TRUE)
{
/* 获取数据成功,打印数据 */
rt_kprintf("%s\n", data_buffer);
}
/* 做一个5 OS Tick的休眠 */
rt_thread_delay(5);
}
}
/* worker线程入口 */
static void worker_entry(void* parameter)
{
rt_bool_t result;
rt_uint32_t index, setchar;
rt_uint8_t data_buffer[BUFFER_ITEM];
setchar = 0x21;
while (1)
{
/* 构造数据 */
for(index = 0; index < BUFFER_ITEM; index++)
{
data_buffer[index] = setchar;
if (++setchar == 0x7f)
setchar = 0x21;
}
/* 持有信号量 */
rt_sem_take(sem, RT_WAITING_FOREVER);
/* 把数据放到环形buffer中 */
result = rb_put(&working_rb, &data_buffer[0], BUFFER_ITEM);
/* 释放信号量 */
rt_sem_release(sem);
/* 放入成功做一个10 OS Tick的休眠 */
rt_thread_delay(10);
}
}
int semaphore_buffer_worker_init()
{
/* 初始化ring buffer */
rb_init(&working_rb, working_buffer, BUFFER_SIZE);
/* 创建信号量 */
sem = rt_sem_create("sem", 1, RT_IPC_FLAG_FIFO);
if (sem == RT_NULL)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
/* 创建线程1 */
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);
/* 创建线程2 */
worker = rt_thread_create("worker",
worker_entry, RT_NULL, /* 线程入口是worker_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()
{
/* 调度器上锁,上锁后,将不再切换到其他线程,仅响应中断 */
rt_enter_critical();
/* 删除信号量 */
if (sem != RT_NULL)
rt_sem_delete(sem);
/* 删除线程 */
if (tid != RT_NULL && tid->stat != RT_THREAD_CLOSE)
rt_thread_delete(tid);
if (worker != RT_NULL && worker->stat != RT_THREAD_CLOSE)
rt_thread_delete(worker);
/* 调度器解锁 */
rt_exit_critical();
/* 设置TestCase状态 */
tc_done(TC_STAT_PASSED);
}
int _tc_semaphore_buffer_worker()
{
/* 设置TestCase清理回调函数 */
tc_cleanup(_tc_cleanup);
semaphore_buffer_worker_init();
/* 返回TestCase运行的最长时间 */
return 100;
}
/* 输出函数命令到finsh shell中 */
FINSH_FUNCTION_EXPORT(_tc_semaphore_buffer_worker, a buffer worker with semaphore example);
#else
/* 用户应用入口 */
int rt_application_init()
{
semaphore_buffer_worker_init();
return 0;
}
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,144 +1,144 @@
/*
* 线
*
* 线线线
*/
#include <rtthread.h>
#include "tc_comm.h"
/*
* 线(rt_thread_delete)线线
* 访线线
* 访
*/
static rt_thread_t tid1 = RT_NULL, tid2 = RT_NULL;
/* 线程1的入口函数 */
static void thread1_entry(void* parameter)
{
rt_uint32_t count = 0;
while (1)
{
/* 线程1采用低优先级运行一直打印计数值 */
// rt_kprintf("thread count: %d\n", count ++);
count ++;
}
}
static void thread1_cleanup(struct rt_thread *tid)
{
if (tid != tid1)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return ;
}
rt_kprintf("thread1 end\n");
tid1 = RT_NULL;
}
/* 线程2的入口函数 */
static void thread2_entry(void* parameter)
{
/* 线程2拥有较高的优先级以抢占线程1而获得执行 */
/* 线程2启动后先睡眠10个OS Tick */
rt_thread_delay(10);
/*
* 线2线1线1线1线
*
*/
rt_thread_delete(tid1);
/*
* 线210OS Tick然后退出线2idle线程
* 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);
/*
* 线210OS Tick然后退出线2idle线程
* idle线程将执行真正的线程1控制块和线程栈的删除
*/
rt_thread_delay(10);
}
static void thread2_cleanup(struct rt_thread *tid)
{
/*
* 线2(线线idle线
* )
*/
if (tid != tid2)
{
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return ;
}
rt_kprintf("thread2 end\n");
tid2 = RT_NULL;
tc_done(TC_STAT_PASSED);
}
/* 线程删除示例的初始化 */
int thread_delete_init()
{
/* 创建线程1 */
tid1 = rt_thread_create("t1", /* 线程1的名称是t1 */
thread1_entry, RT_NULL, /* 入口是thread1_entry参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid1 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */
{
tid1->cleanup = thread1_cleanup;
rt_thread_startup(tid1);
}
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
/* 创建线程1 */
tid2 = rt_thread_create("t2", /* 线程1的名称是t2 */
thread2_entry, RT_NULL, /* 入口是thread2_entry参数是RT_NULL */
THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
if (tid2 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */
{
tid2->cleanup = thread2_cleanup;
rt_thread_startup(tid2);
}
else
tc_stat(TC_STAT_END | TC_STAT_FAILED);
return 0;
}
#ifdef RT_USING_TC
static void _tc_cleanup()
{
/* lock scheduler */
rt_enter_critical();
/* delete thread */
if (tid1 != RT_NULL)
{
rt_kprintf("tid1 is bad\n");
tc_stat(TC_STAT_FAILED);
}
if (tid2 != RT_NULL)
{
rt_kprintf("tid2 is bad\n");
tc_stat(TC_STAT_FAILED);
}
/* unlock scheduler */
rt_exit_critical();
}
int _tc_thread_delete()
{
/* set tc cleanup */
tc_cleanup(_tc_cleanup);
thread_delete_init();
return 27;
}
FINSH_FUNCTION_EXPORT(_tc_thread_delete, a thread delete example);
#else
int rt_application_init()
{
thread_delete_init();
return 0;
}
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
from building import *
src = Glob('*.c')
group = DefineGroup('libc_test', src, depend = ['RT_USING_NEWLIB', 'RT_USING_PTHREADS'])
Return('group')
from building import *
src = Glob('*.c')
group = DefineGroup('libc_test', src, depend = ['RT_USING_NEWLIB', 'RT_USING_PTHREADS'])
Return('group')

View File

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

View File

@ -1,18 +1,18 @@
/*
* env.c
*
* Created on: 2010-11-17
* Author: bernard
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
int libc_env()
{
printf("PATH=%s\n", getenv("PATH"));
putenv("foo=bar");
printf("foo=%s\n", getenv("foo"));
return 0;
}
FINSH_FUNCTION_EXPORT(libc_env, get/set_env test);
/*
* env.c
*
* Created on: 2010-11-17
* Author: bernard
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
int libc_env()
{
printf("PATH=%s\n", getenv("PATH"));
putenv("foo=bar");
printf("foo=%s\n", getenv("foo"));
return 0;
}
FINSH_FUNCTION_EXPORT(libc_env, get/set_env test);

File diff suppressed because it is too large Load Diff

View File

@ -1,56 +1,56 @@
/*
* memory.c
*
* Created on: 2010-11-17
* Author: bernard
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
#include <errno.h>
static int errors = 0;
static void merror(const char *msg)
{
++errors;
printf("Error: %s\n", msg);
}
int libc_mem(void)
{
void *p;
int save;
errno = 0;
p = malloc(-1);
save = errno;
if (p != NULL)
merror("malloc (-1) succeeded.");
if (p == NULL && save != ENOMEM)
merror("errno is not set correctly");
p = malloc(10);
if (p == NULL)
merror("malloc (10) failed.");
/* realloc (p, 0) == free (p). */
p = realloc(p, 0);
if (p != NULL)
merror("realloc (p, 0) failed.");
p = malloc(0);
if (p == NULL)
{
printf("malloc(0) returns NULL\n");
}
p = realloc(p, 0);
if (p != NULL)
merror("realloc (p, 0) failed.");
return errors != 0;
}
FINSH_FUNCTION_EXPORT(libc_mem, memory test for libc);
/*
* memory.c
*
* Created on: 2010-11-17
* Author: bernard
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
#include <errno.h>
static int errors = 0;
static void merror(const char *msg)
{
++errors;
printf("Error: %s\n", msg);
}
int libc_mem(void)
{
void *p;
int save;
errno = 0;
p = malloc(-1);
save = errno;
if (p != NULL)
merror("malloc (-1) succeeded.");
if (p == NULL && save != ENOMEM)
merror("errno is not set correctly");
p = malloc(10);
if (p == NULL)
merror("malloc (10) failed.");
/* realloc (p, 0) == free (p). */
p = realloc(p, 0);
if (p != NULL)
merror("realloc (p, 0) failed.");
p = malloc(0);
if (p == NULL)
{
printf("malloc(0) returns NULL\n");
}
p = realloc(p, 0);
if (p != NULL)
merror("realloc (p, 0) failed.");
return errors != 0;
}
FINSH_FUNCTION_EXPORT(libc_mem, memory test for libc);

View File

@ -1,119 +1,119 @@
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <mqueue.h>
#define MQ_NAME_1 "testmsg1"
#define MQ_NAME_2 "testmsg2"
#define MSG_SIZE 128
#define MAX_MSG 3
const char *s_msg_ptr[] = {"msg test 1", "msg test 2", "msg test 3"};
char r_msg_ptr_1[MAX_MSG][MSG_SIZE];
char r_msg_ptr_2[MAX_MSG][MSG_SIZE];
pthread_t send1, send2, rev1, rev2;
int * send_1(void * mq)
{
int i;
mqd_t mq1 = *(mqd_t *)mq;
printf("Enter into send_1 \n");
for (i = 0; i < MAX_MSG; i++ ) {
if ( -1 == mq_send(mq1, s_msg_ptr[i], MSG_SIZE, i)) {
perror("mq_send doesn't return success \n");
pthread_exit((void *)1);
}
printf("[%d] send '%s' in thread send_1. \n", i+1, s_msg_ptr[i]);
}
pthread_exit((void *)0);
}
int * send_2(void * mq)
{
int i;
mqd_t mq2 = *(mqd_t *)mq;
printf("Enter into send_2 \n");
for (i = 0; i < MAX_MSG; i++ ) {
if ( -1 == mq_send(mq2, s_msg_ptr[i], MSG_SIZE, i)) {
perror("mq_send doesn't return success \n");
pthread_exit((void *)1);
}
printf("[%d] send '%s' in thread send_2. \n", i+1, s_msg_ptr[i]);
}
pthread_exit((void *)0);
}
int * receive_1(void * mq)
{
int i;
mqd_t mq1 = *(mqd_t *)mq;
printf("Enter into receive_1 \n");
for (i = 0; i< MAX_MSG; i++) {
if ( -1 == mq_receive(mq1, r_msg_ptr_1[i], MSG_SIZE, NULL) ) {
perror("mq_receive doesn't return success \n");
pthread_exit((void *)1);
}
printf("[%d] receive '%s' in thread receive_1. \n", i+1, r_msg_ptr_1[i]);
}
pthread_exit((void *)0);
}
int * receive_2(void * mq)
{
int i;
mqd_t mq2 = *(mqd_t *)mq;
printf("Enter into receive_2 \n");
for (i = 0; i< MAX_MSG; i++) {
if ( -1 == mq_receive(mq2, r_msg_ptr_2[i], MSG_SIZE, NULL) ) {
perror("mq_receive doesn't return success \n");
pthread_exit((void *)1);
}
printf("[%d] receive '%s' in thread receive_2. \n", i+1, r_msg_ptr_2[i]);
}
pthread_exit((void *)0);
}
int libc_mq()
{
mqd_t mq1 = 0, mq2 = 0;
struct mq_attr mqstat;
int oflag = O_CREAT|O_RDWR;
memset(&mqstat, 0, sizeof(mqstat));
mqstat.mq_maxmsg = MAX_MSG;
mqstat.mq_msgsize = MSG_SIZE;
mqstat.mq_flags = 0;
if( ((mqd_t) -1) == (mq1 = mq_open(MQ_NAME_1,oflag,0777, &mqstat)) ) {
printf("mq_open doesn't return success \n");
return -1;
}
if( ((mqd_t) -1) == (mq2 = mq_open(MQ_NAME_2,oflag,0777, &mqstat)) ) {
printf("mq_open doesn't return success \n");
return -1;
}
pthread_create(&send1, NULL, (void *)send_1, (void *)&mq1);
pthread_create(&send2, NULL, (void *)send_2, (void *)&mq2);
pthread_create(&rev1, NULL, (void *)receive_1, (void *)&mq1);
pthread_create(&rev2, NULL, (void *)receive_2, (void *)&mq2);
pthread_join(send1, NULL);
pthread_join(send2, NULL);
pthread_join(rev1, NULL);
pthread_join(rev2, NULL);
mq_close(mq1);
mq_close(mq2);
mq_unlink(MQ_NAME_1);
mq_unlink(MQ_NAME_2);
printf("PASSED\n");
return 0;
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(libc_mq, posix mqueue test);
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <mqueue.h>
#define MQ_NAME_1 "testmsg1"
#define MQ_NAME_2 "testmsg2"
#define MSG_SIZE 128
#define MAX_MSG 3
const char *s_msg_ptr[] = {"msg test 1", "msg test 2", "msg test 3"};
char r_msg_ptr_1[MAX_MSG][MSG_SIZE];
char r_msg_ptr_2[MAX_MSG][MSG_SIZE];
pthread_t send1, send2, rev1, rev2;
int * send_1(void * mq)
{
int i;
mqd_t mq1 = *(mqd_t *)mq;
printf("Enter into send_1 \n");
for (i = 0; i < MAX_MSG; i++ ) {
if ( -1 == mq_send(mq1, s_msg_ptr[i], MSG_SIZE, i)) {
perror("mq_send doesn't return success \n");
pthread_exit((void *)1);
}
printf("[%d] send '%s' in thread send_1. \n", i+1, s_msg_ptr[i]);
}
pthread_exit((void *)0);
}
int * send_2(void * mq)
{
int i;
mqd_t mq2 = *(mqd_t *)mq;
printf("Enter into send_2 \n");
for (i = 0; i < MAX_MSG; i++ ) {
if ( -1 == mq_send(mq2, s_msg_ptr[i], MSG_SIZE, i)) {
perror("mq_send doesn't return success \n");
pthread_exit((void *)1);
}
printf("[%d] send '%s' in thread send_2. \n", i+1, s_msg_ptr[i]);
}
pthread_exit((void *)0);
}
int * receive_1(void * mq)
{
int i;
mqd_t mq1 = *(mqd_t *)mq;
printf("Enter into receive_1 \n");
for (i = 0; i< MAX_MSG; i++) {
if ( -1 == mq_receive(mq1, r_msg_ptr_1[i], MSG_SIZE, NULL) ) {
perror("mq_receive doesn't return success \n");
pthread_exit((void *)1);
}
printf("[%d] receive '%s' in thread receive_1. \n", i+1, r_msg_ptr_1[i]);
}
pthread_exit((void *)0);
}
int * receive_2(void * mq)
{
int i;
mqd_t mq2 = *(mqd_t *)mq;
printf("Enter into receive_2 \n");
for (i = 0; i< MAX_MSG; i++) {
if ( -1 == mq_receive(mq2, r_msg_ptr_2[i], MSG_SIZE, NULL) ) {
perror("mq_receive doesn't return success \n");
pthread_exit((void *)1);
}
printf("[%d] receive '%s' in thread receive_2. \n", i+1, r_msg_ptr_2[i]);
}
pthread_exit((void *)0);
}
int libc_mq()
{
mqd_t mq1 = 0, mq2 = 0;
struct mq_attr mqstat;
int oflag = O_CREAT|O_RDWR;
memset(&mqstat, 0, sizeof(mqstat));
mqstat.mq_maxmsg = MAX_MSG;
mqstat.mq_msgsize = MSG_SIZE;
mqstat.mq_flags = 0;
if( ((mqd_t) -1) == (mq1 = mq_open(MQ_NAME_1,oflag,0777, &mqstat)) ) {
printf("mq_open doesn't return success \n");
return -1;
}
if( ((mqd_t) -1) == (mq2 = mq_open(MQ_NAME_2,oflag,0777, &mqstat)) ) {
printf("mq_open doesn't return success \n");
return -1;
}
pthread_create(&send1, NULL, (void *)send_1, (void *)&mq1);
pthread_create(&send2, NULL, (void *)send_2, (void *)&mq2);
pthread_create(&rev1, NULL, (void *)receive_1, (void *)&mq1);
pthread_create(&rev2, NULL, (void *)receive_2, (void *)&mq2);
pthread_join(send1, NULL);
pthread_join(send2, NULL);
pthread_join(rev1, NULL);
pthread_join(rev2, NULL);
mq_close(mq1);
mq_close(mq2);
mq_unlink(MQ_NAME_1);
mq_unlink(MQ_NAME_2);
printf("PASSED\n");
return 0;
}
#include <finsh.h>
FINSH_FUNCTION_EXPORT(libc_mq, posix mqueue test);

View File

@ -1,200 +1,200 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/fcntl.h>
#include <finsh.h>
char * format[] = {
"%",
"%0.",
"%.0",
"%+0.",
"%+.0",
"%.5",
"%+.5",
"%2.5",
"%22.5",
"%022.5",
"%#022.5",
"%-#022.5",
"%+#022.5",
"%-22.5",
"%+22.5",
"%--22.5",
"%++22.5",
"%+-22.5",
"%-+22.5",
"%-#022.5",
"%-#22.5",
"%-2.22",
"%+2.22",
"%-#02.22",
"%-#2.22",
"%-1.5",
"%1.5",
"%-#01.5",
"%-#1.5",
"%-#.5",
"%-#1.",
"%-#.",
NULL
};
static void
intchk (const char *fmt)
{
(void) printf("%15s :, \"", fmt);
(void) printf(fmt, 0);
(void) printf("\", \"");
(void) printf(fmt, 123);
(void) printf("\", \"");
(void) printf(fmt, -18);
(void) printf("\"\n");
}
static void
fltchk (const char *fmt)
{
(void) printf("%15s :, \"", fmt);
(void) printf(fmt, 0.0);
(void) printf("\", \"");
(void) printf(fmt, 123.0001);
(void) printf("\", \"");
(void) printf(fmt, -18.0002301);
(void) printf("\"\n");
}
int printf_test()
{
char buf[256];
int i;
printf("%s\n\n", "# vim:syntax=off:");
/* integers */
for(i=0;format[i];i++) {
strcpy(buf, format[i]);
strcat(buf, "d");
intchk(buf);
}
/* floats */
for(i=0;format[i];i++) {
strcpy(buf, format[i]);
strcat(buf, "f");
fltchk(buf);
}
/* hexa */
for(i=0;format[i];i++) {
strcpy(buf, format[i]);
strcat(buf, "x");
intchk(buf);
}
printf("#%.4x %4x#\n", 4, 88);
printf("#%4x#\n",4);
printf("#%#22.8x#\n",1234567);
printf("#%+2i#\n",18);
printf("#%i#\n",18);
printf("#%llu#\n",4294967297ULL);
printf("#%#x#\n",44444);
printf("#%-8i#\n",33);
printf("#%i#\n",18);
printf("#%d#\n",18);
printf("#%u#\n",18);
printf("#%lu#\n",18);
printf("#%li#\n",18);
printf("#%-+#06d#\n", -123);
printf("#%-+#6d#\n", -123);
printf("#%+#06d#\n", -123);
printf("#%06d#\n", -123);
printf("#%+15s#\n","ABCDEF");
/* from ncurses make_keys */
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 16, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 2, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 2, 16, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 0, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 0, 16, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 0, 0, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 16, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 2, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 2, 16, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 0, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 0, 16, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 0, 0, "KEY_A1", "key_a1");
printf("%*.*f\n", 0, 16, 0.0);
printf("%*.*f\n", 16, 16, 0.0);
printf("%*.*f\n", 2, 2, -0.0);
printf("%*.*f\n", 20, 0, -123.123);
printf("%*.*f\n", 10, 0, +123.123);
i = printf("\"%s\"\n","A");
printf("%i\n", i);
/* from glibc's tst-printf.c */
{
char buf[20];
char buf2[512];
int i;
printf ("snprintf (\"%%30s\", \"foo\") == %d, \"%.*s\"\n",
snprintf (buf, sizeof (buf), "%30s", "foo"), (int) sizeof (buf),
buf);
memset(buf2,0,sizeof(buf));
i=snprintf(buf2, 256, "%.9999u", 10);
printf("%i %i\n",i,strlen(buf2));
printf ("snprintf (\"%%.999999u\", 10) == %d\n",
snprintf(buf2, sizeof(buf2), "%.999999u", 10));
}
return 0;
}
void libc_printf()
{
printf("stdout test!!\n");
fprintf(stdout, "fprintf test!!\n");
fprintf(stderr, "fprintf test!!\n");
puts("puts test!!\n");
putc('1', stderr);
putc('2', stderr);
putc('\n', stderr);
printf_test();
}
FINSH_FUNCTION_EXPORT(libc_printf, printf test in libc);
void libc_dprintf()
{
int fd;
fd = open("/dev/console", O_WRONLY, 0);
if (fd >0)
{
dprintf(fd, "fd:%d printf test!!\n", fd);
close(fd);
}
}
FINSH_FUNCTION_EXPORT(libc_dprintf, dprintf test);
void libc_fdopen()
{
int fd;
FILE* fp;
fd = open("/dev/console", O_WRONLY, 0);
if (fd >0)
{
fp = fdopen(fd, "w");
fprintf(fp, "fdopen test, fd %d!!\n", fileno(fp));
fclose(fp);
}
}
FINSH_FUNCTION_EXPORT(libc_fdopen, fdopen test);
#include <stdio.h>
#include <stdlib.h>
#include <sys/fcntl.h>
#include <finsh.h>
char * format[] = {
"%",
"%0.",
"%.0",
"%+0.",
"%+.0",
"%.5",
"%+.5",
"%2.5",
"%22.5",
"%022.5",
"%#022.5",
"%-#022.5",
"%+#022.5",
"%-22.5",
"%+22.5",
"%--22.5",
"%++22.5",
"%+-22.5",
"%-+22.5",
"%-#022.5",
"%-#22.5",
"%-2.22",
"%+2.22",
"%-#02.22",
"%-#2.22",
"%-1.5",
"%1.5",
"%-#01.5",
"%-#1.5",
"%-#.5",
"%-#1.",
"%-#.",
NULL
};
static void
intchk (const char *fmt)
{
(void) printf("%15s :, \"", fmt);
(void) printf(fmt, 0);
(void) printf("\", \"");
(void) printf(fmt, 123);
(void) printf("\", \"");
(void) printf(fmt, -18);
(void) printf("\"\n");
}
static void
fltchk (const char *fmt)
{
(void) printf("%15s :, \"", fmt);
(void) printf(fmt, 0.0);
(void) printf("\", \"");
(void) printf(fmt, 123.0001);
(void) printf("\", \"");
(void) printf(fmt, -18.0002301);
(void) printf("\"\n");
}
int printf_test()
{
char buf[256];
int i;
printf("%s\n\n", "# vim:syntax=off:");
/* integers */
for(i=0;format[i];i++) {
strcpy(buf, format[i]);
strcat(buf, "d");
intchk(buf);
}
/* floats */
for(i=0;format[i];i++) {
strcpy(buf, format[i]);
strcat(buf, "f");
fltchk(buf);
}
/* hexa */
for(i=0;format[i];i++) {
strcpy(buf, format[i]);
strcat(buf, "x");
intchk(buf);
}
printf("#%.4x %4x#\n", 4, 88);
printf("#%4x#\n",4);
printf("#%#22.8x#\n",1234567);
printf("#%+2i#\n",18);
printf("#%i#\n",18);
printf("#%llu#\n",4294967297ULL);
printf("#%#x#\n",44444);
printf("#%-8i#\n",33);
printf("#%i#\n",18);
printf("#%d#\n",18);
printf("#%u#\n",18);
printf("#%lu#\n",18);
printf("#%li#\n",18);
printf("#%-+#06d#\n", -123);
printf("#%-+#6d#\n", -123);
printf("#%+#06d#\n", -123);
printf("#%06d#\n", -123);
printf("#%+15s#\n","ABCDEF");
/* from ncurses make_keys */
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 16, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 2, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 2, 16, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 16, 0, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 0, 16, "KEY_A1", "key_a1");
printf("{ %4d, %-*.*s },\t/* %s */\n", 139, 0, 0, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 16, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 2, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 2, 16, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 16, 0, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 0, 16, "KEY_A1", "key_a1");
printf("{ %4d, %*.*s },\t/* %s */\n", 139, 0, 0, "KEY_A1", "key_a1");
printf("%*.*f\n", 0, 16, 0.0);
printf("%*.*f\n", 16, 16, 0.0);
printf("%*.*f\n", 2, 2, -0.0);
printf("%*.*f\n", 20, 0, -123.123);
printf("%*.*f\n", 10, 0, +123.123);
i = printf("\"%s\"\n","A");
printf("%i\n", i);
/* from glibc's tst-printf.c */
{
char buf[20];
char buf2[512];
int i;
printf ("snprintf (\"%%30s\", \"foo\") == %d, \"%.*s\"\n",
snprintf (buf, sizeof (buf), "%30s", "foo"), (int) sizeof (buf),
buf);
memset(buf2,0,sizeof(buf));
i=snprintf(buf2, 256, "%.9999u", 10);
printf("%i %i\n",i,strlen(buf2));
printf ("snprintf (\"%%.999999u\", 10) == %d\n",
snprintf(buf2, sizeof(buf2), "%.999999u", 10));
}
return 0;
}
void libc_printf()
{
printf("stdout test!!\n");
fprintf(stdout, "fprintf test!!\n");
fprintf(stderr, "fprintf test!!\n");
puts("puts test!!\n");
putc('1', stderr);
putc('2', stderr);
putc('\n', stderr);
printf_test();
}
FINSH_FUNCTION_EXPORT(libc_printf, printf test in libc);
void libc_dprintf()
{
int fd;
fd = open("/dev/console", O_WRONLY, 0);
if (fd >0)
{
dprintf(fd, "fd:%d printf test!!\n", fd);
close(fd);
}
}
FINSH_FUNCTION_EXPORT(libc_dprintf, dprintf test);
void libc_fdopen()
{
int fd;
FILE* fp;
fd = open("/dev/console", O_WRONLY, 0);
if (fd >0)
{
fp = fdopen(fd, "w");
fprintf(fp, "fdopen test, fd %d!!\n", fileno(fp));
fclose(fp);
}
}
FINSH_FUNCTION_EXPORT(libc_fdopen, fdopen test);

View File

@ -1,43 +1,43 @@
/*
* rand.c
*
* Created on: 2010-11-17
* Author: bernard
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
int libc_rand(void)
{
int i1, i2;
int j1, j2;
/* The C standard says that "If rand is called before any calls to
srand have been made, the same sequence shall be generated as
when srand is first called with a seed value of 1." */
i1 = rand();
i2 = rand();
srand(1);
j1 = rand();
j2 = rand();
if (i1 < 0 || i2 < 0 || j1 < 0 || j2 < 0)
{
puts("Test FAILED!");
}
if (j1 == i1 && j2 == i2)
{
puts("Test succeeded.");
return 0;
}
else
{
if (j1 != i1)
printf("%d != %d\n", j1, i1);
if (j2 != i2)
printf("%d != %d\n", j2, i2);
puts("Test FAILED!");
return 1;
}
}
FINSH_FUNCTION_EXPORT(libc_rand, rand test for libc);
/*
* rand.c
*
* Created on: 2010-11-17
* Author: bernard
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
int libc_rand(void)
{
int i1, i2;
int j1, j2;
/* The C standard says that "If rand is called before any calls to
srand have been made, the same sequence shall be generated as
when srand is first called with a seed value of 1." */
i1 = rand();
i2 = rand();
srand(1);
j1 = rand();
j2 = rand();
if (i1 < 0 || i2 < 0 || j1 < 0 || j2 < 0)
{
puts("Test FAILED!");
}
if (j1 == i1 && j2 == i2)
{
puts("Test succeeded.");
return 0;
}
else
{
if (j1 != i1)
printf("%d != %d\n", j1, i1);
if (j2 != i2)
printf("%d != %d\n", j2, i2);
puts("Test FAILED!");
return 1;
}
}
FINSH_FUNCTION_EXPORT(libc_rand, rand test for libc);

View File

@ -1,65 +1,65 @@
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
static sem_t sema;
static void* other_thread()
{
printf("other_thread here!\n");
sleep(1);
while (1)
{
printf("other_thread: sem_post...\n");
if(sem_post(&sema) == -1)
printf("sem_post failed\n");
sleep(1);
}
printf("other_thread dies!\n");
pthread_exit(0);
}
static void test_thread(void* parameter)
{
pthread_t tid;
printf("main thread here!\n");
printf("sleep 5 seconds...");
sleep(5);
printf("done\n");
sem_init(&sema, 0, 0);
/* create the "other" thread */
if(pthread_create(&tid, 0, &other_thread, 0)!=0)
/* error */
printf("pthread_create OtherThread failed.\n");
else
printf("created OtherThread=%x\n", tid);
/* let the other thread run */
while (1)
{
printf("Main: sem_wait...\n");
if(sem_wait(&sema) == -1)
printf("sem_wait failed\n");
printf("Main back.\n\n");
}
pthread_exit(0);
}
#include <finsh.h>
void libc_sem()
{
rt_thread_t tid;
tid = rt_thread_create("semtest", test_thread, RT_NULL,
2048, 20, 5);
if (tid != RT_NULL)
{
rt_thread_startup(tid);
}
}
FINSH_FUNCTION_EXPORT(libc_sem, posix semaphore test);
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
static sem_t sema;
static void* other_thread()
{
printf("other_thread here!\n");
sleep(1);
while (1)
{
printf("other_thread: sem_post...\n");
if(sem_post(&sema) == -1)
printf("sem_post failed\n");
sleep(1);
}
printf("other_thread dies!\n");
pthread_exit(0);
}
static void test_thread(void* parameter)
{
pthread_t tid;
printf("main thread here!\n");
printf("sleep 5 seconds...");
sleep(5);
printf("done\n");
sem_init(&sema, 0, 0);
/* create the "other" thread */
if(pthread_create(&tid, 0, &other_thread, 0)!=0)
/* error */
printf("pthread_create OtherThread failed.\n");
else
printf("created OtherThread=%x\n", tid);
/* let the other thread run */
while (1)
{
printf("Main: sem_wait...\n");
if(sem_wait(&sema) == -1)
printf("sem_wait failed\n");
printf("Main back.\n\n");
}
pthread_exit(0);
}
#include <finsh.h>
void libc_sem()
{
rt_thread_t tid;
tid = rt_thread_create("semtest", test_thread, RT_NULL,
2048, 20, 5);
if (tid != RT_NULL)
{
rt_thread_startup(tid);
}
}
FINSH_FUNCTION_EXPORT(libc_sem, posix semaphore test);

View File

@ -1,24 +1,24 @@
/*
* time.c
*
* Created on: 2010-11-17
* Author: bernard
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
int speed()
{
int i;
time_t t;
printf("%d\n", time(0));
for (i = 0; i < 10000000; ++i)
t = time(0);
printf("%d\n", time(0));
return 0;
}
FINSH_FUNCTION_EXPORT(speed, speed test);
/*
* time.c
*
* Created on: 2010-11-17
* Author: bernard
*/
#include <stdio.h>
#include <stdlib.h>
#include <finsh.h>
int speed()
{
int i;
time_t t;
printf("%d\n", time(0));
for (i = 0; i < 10000000; ++i)
t = time(0);
printf("%d\n", time(0));
return 0;
}
FINSH_FUNCTION_EXPORT(speed, speed test);

View File

@ -1,4 +1,4 @@
example:
1.edit rtconfig.py to config toolchain and bsp
2.scons --app=basicapp
3.copy basicapp/build/$bsp/basicapp.so to filesystem
example:
1.edit rtconfig.py to config toolchain and bsp
2.scons --app=basicapp
3.copy basicapp/build/$bsp/basicapp.so to filesystem

View File

@ -1,73 +1,73 @@
import os
import sys
import SCons.cpp
import rtconfig
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.normpath(os.getcwd() + '/../..')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
from building import *
Export('RTT_ROOT')
# add target option
AddOption('--app',
dest='app',
nargs=1, type='string',
action='store',
metavar='DIR',
help='installation prefix')
# add target option
AddOption('--type',
dest='type',
nargs=1, type='string',
action='store',
metavar='DIR',
help='installation prefix')
app = GetOption('app')
if GetOption('type') == 'ext':
linkflags = rtconfig.LFLAGS + ' -e 0'
else:
linkflags = rtconfig.LFLAGS + ' -e main'
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
CXX = rtconfig.CXX,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = linkflags,
CPPPATH = [
RTT_ROOT + '/include',
RTT_ROOT + '/bsp/' + rtconfig.BSP,
RTT_ROOT + '/components/finsh',
RTT_ROOT + '/components/rtgui/include',
RTT_ROOT + '/components/rgtui/common',
RTT_ROOT + '/components/rtgui/server',
RTT_ROOT + '/components/rtgui/widgets',
RTT_ROOT + '/components/libdl',
RTT_ROOT + '/components/external/ftk/ftk/src/os/rt-thread',
RTT_ROOT + '/components/external/ftk/ftk/src/demos',
RTT_ROOT + '/components/external/ftk/ftk/apps/common',
RTT_ROOT + '/components/external/ftk/ftk/src',
RTT_ROOT + '/components/dfs',
RTT_ROOT + '/components/dfs/include',
RTT_ROOT + '/components/libc/newlib',
RTT_ROOT + '/components/external/cairo/cairo-1.10.2/src',
RTT_ROOT + '/components/external/cairo/'
])
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
PrepareModuleBuilding(env, RTT_ROOT)
dir = app + '/build/' + rtconfig.BSP
objs = SConscript(app + '/Sconscript', variant_dir=dir, duplicate=0)
TARGET = dir + '/' + app + '.' + rtconfig.TARGET_EXT
# build program
env.Program(TARGET, objs)
import os
import sys
import SCons.cpp
import rtconfig
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.normpath(os.getcwd() + '/../..')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
from building import *
Export('RTT_ROOT')
# add target option
AddOption('--app',
dest='app',
nargs=1, type='string',
action='store',
metavar='DIR',
help='installation prefix')
# add target option
AddOption('--type',
dest='type',
nargs=1, type='string',
action='store',
metavar='DIR',
help='installation prefix')
app = GetOption('app')
if GetOption('type') == 'ext':
linkflags = rtconfig.LFLAGS + ' -e 0'
else:
linkflags = rtconfig.LFLAGS + ' -e main'
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
CXX = rtconfig.CXX,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = linkflags,
CPPPATH = [
RTT_ROOT + '/include',
RTT_ROOT + '/bsp/' + rtconfig.BSP,
RTT_ROOT + '/components/finsh',
RTT_ROOT + '/components/rtgui/include',
RTT_ROOT + '/components/rgtui/common',
RTT_ROOT + '/components/rtgui/server',
RTT_ROOT + '/components/rtgui/widgets',
RTT_ROOT + '/components/libdl',
RTT_ROOT + '/components/external/ftk/ftk/src/os/rt-thread',
RTT_ROOT + '/components/external/ftk/ftk/src/demos',
RTT_ROOT + '/components/external/ftk/ftk/apps/common',
RTT_ROOT + '/components/external/ftk/ftk/src',
RTT_ROOT + '/components/dfs',
RTT_ROOT + '/components/dfs/include',
RTT_ROOT + '/components/libc/newlib',
RTT_ROOT + '/components/external/cairo/cairo-1.10.2/src',
RTT_ROOT + '/components/external/cairo/'
])
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
PrepareModuleBuilding(env, RTT_ROOT)
dir = app + '/build/' + rtconfig.BSP
objs = SConscript(app + '/Sconscript', variant_dir=dir, duplicate=0)
TARGET = dir + '/' + app + '.' + rtconfig.TARGET_EXT
# build program
env.Program(TARGET, objs)

View File

@ -1,7 +1,7 @@
import rtconfig
Import('RTT_ROOT')
from building import *
src = Glob('*.c')
group = DefineGroup('', src, depend = [''])
import rtconfig
Import('RTT_ROOT')
from building import *
src = Glob('*.c')
group = DefineGroup('', src, depend = [''])
Return('group')

View File

@ -1,7 +1,7 @@
import rtconfig
Import('RTT_ROOT')
from building import *
src = Glob('*.c')
group = DefineGroup('', src, depend = [''])
import rtconfig
Import('RTT_ROOT')
from building import *
src = Glob('*.c')
group = DefineGroup('', src, depend = [''])
Return('group')

View File

@ -1,23 +1,23 @@
# bsp name
BSP = 'mini2440'
# toolchains
EXEC_PATH = 'C:/Program Files/CodeSourcery/Sourcery G++ Lite/bin'
PREFIX = 'arm-none-eabi-'
CC = PREFIX + 'gcc'
CXX = PREFIX + 'g++'
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
LINK = PREFIX + 'gcc'
TARGET_EXT = 'so'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
DEVICE = ' -mcpu=arm920t'
CFLAGS = DEVICE + ' -O0 -fPIC -DFTK_AS_PLUGIN -DRT_THREAD '
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp'
LFLAGS = DEVICE + ' -Wl,-z,max-page-size=0x4 -shared -fPIC -nostdlib -s'
CPATH = ''
LPATH = ''
# bsp name
BSP = 'mini2440'
# toolchains
EXEC_PATH = 'C:/Program Files/CodeSourcery/Sourcery G++ Lite/bin'
PREFIX = 'arm-none-eabi-'
CC = PREFIX + 'gcc'
CXX = PREFIX + 'g++'
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
LINK = PREFIX + 'gcc'
TARGET_EXT = 'so'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
DEVICE = ' -mcpu=arm920t'
CFLAGS = DEVICE + ' -O0 -fPIC -DFTK_AS_PLUGIN -DRT_THREAD '
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp'
LFLAGS = DEVICE + ' -Wl,-z,max-page-size=0x4 -shared -fPIC -nostdlib -s'
CPATH = ''
LPATH = ''

View File

@ -1,23 +1,23 @@
# bsp name
BSP = 'lm3s8962'
# toolchains
EXEC_PATH = 'C:/Program Files/CodeSourcery/Sourcery G++ Lite/bin'
PREFIX = 'arm-none-eabi-'
CC = PREFIX + 'gcc'
CXX = PREFIX + 'g++'
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
LINK = PREFIX + 'gcc'
TARGET_EXT = 'so'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
DEVICE = ' -mcpu=cortex-m3'
CFLAGS = DEVICE + ' -mthumb -mlong-calls -Dsourcerygxx -O0 -fPIC'
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp'
LFLAGS = DEVICE + ' -mthumb -Wl,-z,max-page-size=0x4 -shared -fPIC -e main -nostdlib'
CPATH = ''
LPATH = ''
# bsp name
BSP = 'lm3s8962'
# toolchains
EXEC_PATH = 'C:/Program Files/CodeSourcery/Sourcery G++ Lite/bin'
PREFIX = 'arm-none-eabi-'
CC = PREFIX + 'gcc'
CXX = PREFIX + 'g++'
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
LINK = PREFIX + 'gcc'
TARGET_EXT = 'so'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
DEVICE = ' -mcpu=cortex-m3'
CFLAGS = DEVICE + ' -mthumb -mlong-calls -Dsourcerygxx -O0 -fPIC'
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp'
LFLAGS = DEVICE + ' -mthumb -Wl,-z,max-page-size=0x4 -shared -fPIC -e main -nostdlib'
CPATH = ''
LPATH = ''

View File

@ -1,7 +1,7 @@
import rtconfig
Import('RTT_ROOT')
from building import *
src = Glob('*.c')
group = DefineGroup('', src, depend = [''])
import rtconfig
Import('RTT_ROOT')
from building import *
src = Glob('*.c')
group = DefineGroup('', src, depend = [''])
Return('group')

View File

@ -1,61 +1,61 @@
/*
* File : tetris_modal.c
* This file is part of RTGUI 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-08-14 Yi.Qiu first version
*/
#include <rtthread.h>
struct rt_tetris;
typedef struct rt_tetris rt_tetris_t;
struct rt_tetris_view;
typedef struct rt_tetris_view rt_tetris_view_t;
typedef rt_err_t (*on_update)(rt_tetris_view_t* thiz, rt_tetris_t* tetris);
struct rt_tetris_view
{
rt_uint32_t width;
rt_uint32_t height;
on_update update;
on_update update_next_brick;
on_update update_level;
on_update update_score_and_lines;
void *private;
};
rt_tetris_t* rt_tetris_create(rt_uint32_t width, rt_uint32_t height);
rt_err_t rt_tetris_destory(rt_tetris_t* thiz);
rt_err_t rt_tetris_start(rt_tetris_t* thiz);
rt_err_t rt_tetris_pause(rt_tetris_t* thiz);
rt_uint32_t rt_tetris_width(rt_tetris_t* thiz);
rt_uint32_t* rt_tetris_next_brick(rt_tetris_t* thiz);
rt_uint32_t rt_tetris_level(rt_tetris_t* thiz);
rt_uint32_t rt_tetris_lines(rt_tetris_t* thiz);
rt_uint32_t rt_tetris_score(rt_tetris_t* thiz);
rt_uint32_t rt_tetris_height(rt_tetris_t* thiz);
rt_bool_t rt_tetris_status(rt_tetris_t* thiz);
rt_err_t rt_tetris_down(rt_tetris_t* thiz);
rt_err_t rt_tetris_left(rt_tetris_t* thiz);
rt_err_t rt_tetris_right(rt_tetris_t* thiz);
rt_err_t rt_tetris_drop(rt_tetris_t* thiz);
rt_err_t rt_tetris_rotate(rt_tetris_t* thiz, rt_bool_t direction);
rt_err_t rt_tetris_add_view(rt_tetris_t* thiz, rt_tetris_view_t* view);
rt_err_t rt_tetris_delete_view(rt_tetris_t* thiz, rt_tetris_view_t* view);
rt_err_t rt_tetris_check_collision(rt_tetris_t* thiz, rt_uint32_t block);
rt_tetris_view_t* rt_tetris_view_create(void* private);
rt_err_t rt_tetris_view_destroy(rt_tetris_view_t* thiz);
void tetris_ui_entry(void* parameter);
/*
* File : tetris_modal.c
* This file is part of RTGUI 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-08-14 Yi.Qiu first version
*/
#include <rtthread.h>
struct rt_tetris;
typedef struct rt_tetris rt_tetris_t;
struct rt_tetris_view;
typedef struct rt_tetris_view rt_tetris_view_t;
typedef rt_err_t (*on_update)(rt_tetris_view_t* thiz, rt_tetris_t* tetris);
struct rt_tetris_view
{
rt_uint32_t width;
rt_uint32_t height;
on_update update;
on_update update_next_brick;
on_update update_level;
on_update update_score_and_lines;
void *private;
};
rt_tetris_t* rt_tetris_create(rt_uint32_t width, rt_uint32_t height);
rt_err_t rt_tetris_destory(rt_tetris_t* thiz);
rt_err_t rt_tetris_start(rt_tetris_t* thiz);
rt_err_t rt_tetris_pause(rt_tetris_t* thiz);
rt_uint32_t rt_tetris_width(rt_tetris_t* thiz);
rt_uint32_t* rt_tetris_next_brick(rt_tetris_t* thiz);
rt_uint32_t rt_tetris_level(rt_tetris_t* thiz);
rt_uint32_t rt_tetris_lines(rt_tetris_t* thiz);
rt_uint32_t rt_tetris_score(rt_tetris_t* thiz);
rt_uint32_t rt_tetris_height(rt_tetris_t* thiz);
rt_bool_t rt_tetris_status(rt_tetris_t* thiz);
rt_err_t rt_tetris_down(rt_tetris_t* thiz);
rt_err_t rt_tetris_left(rt_tetris_t* thiz);
rt_err_t rt_tetris_right(rt_tetris_t* thiz);
rt_err_t rt_tetris_drop(rt_tetris_t* thiz);
rt_err_t rt_tetris_rotate(rt_tetris_t* thiz, rt_bool_t direction);
rt_err_t rt_tetris_add_view(rt_tetris_t* thiz, rt_tetris_view_t* view);
rt_err_t rt_tetris_delete_view(rt_tetris_t* thiz, rt_tetris_view_t* view);
rt_err_t rt_tetris_check_collision(rt_tetris_t* thiz, rt_uint32_t block);
rt_tetris_view_t* rt_tetris_view_create(void* private);
rt_err_t rt_tetris_view_destroy(rt_tetris_view_t* thiz);
void tetris_ui_entry(void* parameter);

File diff suppressed because it is too large Load Diff

View File

@ -1,239 +1,239 @@
/*
* File : tetris_ui.c
* This file is part of RTGUI 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-08-14 Yi.Qiu first version
*/
#include <rtgui/rtgui.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/widgets/view.h>
#include <rtgui/widgets/list_view.h>
#include <rtgui/widgets/label.h>
#include <rtgui/widgets/button.h>
#include <rtgui/widgets/window.h>
#include <rtgui/widgets/workbench.h>
#include <rtgui/dc.h>
#include "tetris.h"
struct app_info
{
rtgui_workbench_t* workbench;
rtgui_view_t* game_view;
rtgui_list_view_t* function_view;
rt_tetris_t * tetris;
rt_tetris_view_t* tetris_view;
rtgui_timer_t* _timer;
};
typedef struct app_info app_info;
static app_info g_app_info;
static void _game_over(void)
{
rtgui_timer_destory(g_app_info._timer);
rt_tetris_destory(g_app_info.tetris);
rt_tetris_view_destroy(g_app_info.tetris_view);
rt_kprintf("GAME OVER\n");
rtgui_view_show(g_app_info.function_view, RT_FALSE);
}
static rt_bool_t game_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
{
if (event->type == RTGUI_EVENT_PAINT)
{
struct rtgui_dc* dc;
rtgui_rect_t rect;
/* draw child */
rtgui_view_event_handler(widget, event);
dc = rtgui_dc_begin_drawing(widget);
if (dc == RT_NULL) return -RT_ERROR;
rect.x1 = 96;
rect.y1 = 0;
rect.x2 = 128;
rect.y2 = 16;
rtgui_dc_draw_text(dc, "next", &rect);
rect.y1 += 30;
rect.y2 = rect.y1 + 16;
rtgui_dc_draw_text(dc, "level", &rect);
rect.y1 += 22;
rect.y2 = rect.y1 + 16;
rtgui_dc_draw_text(dc, "lines", &rect);
rect.y1 += 22;
rect.y2 = rect.y1 + 16;
rtgui_dc_draw_text(dc, "score", &rect);
rtgui_dc_end_drawing(dc);
/* start tetris game, removed later */
rt_tetris_start(g_app_info.tetris);
return RT_FALSE;
}
else if ((event->type == RTGUI_EVENT_KBD))
{
struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
if (ekbd->type == RTGUI_KEYDOWN)
{
if (ekbd->key == RTGUIK_RIGHT)
{
rt_tetris_right(g_app_info.tetris);
}
else if (ekbd->key == RTGUIK_LEFT)
{
rt_tetris_left(g_app_info.tetris);
}
else if (ekbd->key == RTGUIK_UP)
{
rt_tetris_rotate(g_app_info.tetris, RT_EOK);
}
else if (ekbd->key == RTGUIK_DOWN)
{
if( rt_tetris_drop(g_app_info.tetris) == -RT_ETIMEOUT
&& rt_tetris_status(g_app_info.tetris) != RT_FALSE)
{
_game_over();
}
}
}
}
return rtgui_view_event_handler(widget, event);
}
static void _timer_timeout(rtgui_timer_t* timer, void* parameter)
{
if( rt_tetris_down(g_app_info.tetris) == -RT_ETIMEOUT)
{
_game_over();
}
}
static rt_bool_t workbench_event_handler(rtgui_widget_t *widget, rtgui_event_t *event)
{
if (event->type == RTGUI_EVENT_KBD)
{
struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
if (((ekbd->type == RTGUI_KEYUP) && ekbd->key == RTGUIK_HOME)
&& !RTGUI_WORKBENCH_IS_MODAL_MODE(g_app_info.workbench))
{
/* active home view */
if (g_app_info.workbench->current_view != g_app_info.game_view)
{
rtgui_view_show(g_app_info.game_view, RT_FALSE);
return RT_TRUE;
}
}
}
return rtgui_workbench_event_handler(widget, event);
}
static void listitem_action_return(void)
{
rtgui_view_destroy(g_app_info.game_view);
rtgui_list_view_destroy(g_app_info.function_view);
rtgui_workbench_close(g_app_info.workbench);
}
static void listitem_action_start(void)
{
/* create tetris modal instance */
g_app_info.tetris = rt_tetris_create(16, 17);
/* create tetris view instance */
g_app_info.tetris_view = rt_tetris_view_create(RTGUI_WIDGET(g_app_info.game_view));
/* register tetris view to tetris modal */
rt_tetris_add_view(g_app_info.tetris, g_app_info.tetris_view);
/* create timer */
g_app_info._timer = rtgui_timer_create(40, RT_TIMER_FLAG_PERIODIC, _timer_timeout, RT_NULL);
/* this view can be focused */
RTGUI_WIDGET(g_app_info.game_view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
/* set widget focus */
rtgui_widget_focus(RTGUI_WIDGET(g_app_info.game_view));
RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(g_app_info.game_view)) = RTGUI_RGB(0xff, 0xff, 0xff);
rtgui_view_show(g_app_info.game_view, RT_FALSE);
rtgui_timer_start(g_app_info._timer);
}
static void listitem_action_continue(void)
{
}
static void listitem_action_adjust(void)
{
}
static void listitem_action_description(void)
{
}
static const struct rtgui_list_item function_list[] =
{
{"新游戏", RT_NULL, listitem_action_start, RT_NULL},
{"继续", RT_NULL, listitem_action_continue, RT_NULL},
{"等级", RT_NULL, listitem_action_adjust, RT_NULL},
{"游戏说明", RT_NULL, listitem_action_description, RT_NULL},
{"退出游戏", RT_NULL, listitem_action_return, RT_NULL},
};
void main(void)
{
rt_mq_t mq;
rtgui_rect_t rect;
mq = rt_mq_create("tetris_ui", 256, 4, RT_IPC_FLAG_FIFO);
rtgui_thread_register(rt_thread_self(), mq);
g_app_info.workbench = rtgui_workbench_create("main", "tetris");
if (g_app_info.workbench == RT_NULL)
{
rt_kprintf("can't find panel 'main'\n");
rt_mq_delete(mq);
return;
}
rtgui_widget_set_event_handler(RTGUI_WIDGET(g_app_info.workbench), workbench_event_handler);
/* add function view */
rtgui_widget_get_rect(RTGUI_WIDGET(g_app_info.workbench), &rect);
g_app_info.function_view = rtgui_list_view_create(function_list,
sizeof(function_list) / sizeof(struct rtgui_list_item),
&rect,
RTGUI_LIST_VIEW_LIST);
rtgui_workbench_add_view(g_app_info.workbench, RTGUI_VIEW(g_app_info.function_view));
/* add home view */
g_app_info.game_view = rtgui_view_create("game");
rtgui_widget_set_event_handler(RTGUI_WIDGET(g_app_info.game_view), game_view_event_handler);
rtgui_workbench_add_view(g_app_info.workbench, g_app_info.game_view);
rtgui_view_show(RTGUI_VIEW(g_app_info.function_view), RT_FALSE);
rtgui_workbench_event_loop(g_app_info.workbench);
rtgui_workbench_destroy(g_app_info.workbench);
rtgui_thread_deregister(rt_thread_self());
rt_mq_delete(mq);
}
/*
* File : tetris_ui.c
* This file is part of RTGUI 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-08-14 Yi.Qiu first version
*/
#include <rtgui/rtgui.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/widgets/view.h>
#include <rtgui/widgets/list_view.h>
#include <rtgui/widgets/label.h>
#include <rtgui/widgets/button.h>
#include <rtgui/widgets/window.h>
#include <rtgui/widgets/workbench.h>
#include <rtgui/dc.h>
#include "tetris.h"
struct app_info
{
rtgui_workbench_t* workbench;
rtgui_view_t* game_view;
rtgui_list_view_t* function_view;
rt_tetris_t * tetris;
rt_tetris_view_t* tetris_view;
rtgui_timer_t* _timer;
};
typedef struct app_info app_info;
static app_info g_app_info;
static void _game_over(void)
{
rtgui_timer_destory(g_app_info._timer);
rt_tetris_destory(g_app_info.tetris);
rt_tetris_view_destroy(g_app_info.tetris_view);
rt_kprintf("GAME OVER\n");
rtgui_view_show(g_app_info.function_view, RT_FALSE);
}
static rt_bool_t game_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
{
if (event->type == RTGUI_EVENT_PAINT)
{
struct rtgui_dc* dc;
rtgui_rect_t rect;
/* draw child */
rtgui_view_event_handler(widget, event);
dc = rtgui_dc_begin_drawing(widget);
if (dc == RT_NULL) return -RT_ERROR;
rect.x1 = 96;
rect.y1 = 0;
rect.x2 = 128;
rect.y2 = 16;
rtgui_dc_draw_text(dc, "next", &rect);
rect.y1 += 30;
rect.y2 = rect.y1 + 16;
rtgui_dc_draw_text(dc, "level", &rect);
rect.y1 += 22;
rect.y2 = rect.y1 + 16;
rtgui_dc_draw_text(dc, "lines", &rect);
rect.y1 += 22;
rect.y2 = rect.y1 + 16;
rtgui_dc_draw_text(dc, "score", &rect);
rtgui_dc_end_drawing(dc);
/* start tetris game, removed later */
rt_tetris_start(g_app_info.tetris);
return RT_FALSE;
}
else if ((event->type == RTGUI_EVENT_KBD))
{
struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
if (ekbd->type == RTGUI_KEYDOWN)
{
if (ekbd->key == RTGUIK_RIGHT)
{
rt_tetris_right(g_app_info.tetris);
}
else if (ekbd->key == RTGUIK_LEFT)
{
rt_tetris_left(g_app_info.tetris);
}
else if (ekbd->key == RTGUIK_UP)
{
rt_tetris_rotate(g_app_info.tetris, RT_EOK);
}
else if (ekbd->key == RTGUIK_DOWN)
{
if( rt_tetris_drop(g_app_info.tetris) == -RT_ETIMEOUT
&& rt_tetris_status(g_app_info.tetris) != RT_FALSE)
{
_game_over();
}
}
}
}
return rtgui_view_event_handler(widget, event);
}
static void _timer_timeout(rtgui_timer_t* timer, void* parameter)
{
if( rt_tetris_down(g_app_info.tetris) == -RT_ETIMEOUT)
{
_game_over();
}
}
static rt_bool_t workbench_event_handler(rtgui_widget_t *widget, rtgui_event_t *event)
{
if (event->type == RTGUI_EVENT_KBD)
{
struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
if (((ekbd->type == RTGUI_KEYUP) && ekbd->key == RTGUIK_HOME)
&& !RTGUI_WORKBENCH_IS_MODAL_MODE(g_app_info.workbench))
{
/* active home view */
if (g_app_info.workbench->current_view != g_app_info.game_view)
{
rtgui_view_show(g_app_info.game_view, RT_FALSE);
return RT_TRUE;
}
}
}
return rtgui_workbench_event_handler(widget, event);
}
static void listitem_action_return(void)
{
rtgui_view_destroy(g_app_info.game_view);
rtgui_list_view_destroy(g_app_info.function_view);
rtgui_workbench_close(g_app_info.workbench);
}
static void listitem_action_start(void)
{
/* create tetris modal instance */
g_app_info.tetris = rt_tetris_create(16, 17);
/* create tetris view instance */
g_app_info.tetris_view = rt_tetris_view_create(RTGUI_WIDGET(g_app_info.game_view));
/* register tetris view to tetris modal */
rt_tetris_add_view(g_app_info.tetris, g_app_info.tetris_view);
/* create timer */
g_app_info._timer = rtgui_timer_create(40, RT_TIMER_FLAG_PERIODIC, _timer_timeout, RT_NULL);
/* this view can be focused */
RTGUI_WIDGET(g_app_info.game_view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
/* set widget focus */
rtgui_widget_focus(RTGUI_WIDGET(g_app_info.game_view));
RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(g_app_info.game_view)) = RTGUI_RGB(0xff, 0xff, 0xff);
rtgui_view_show(g_app_info.game_view, RT_FALSE);
rtgui_timer_start(g_app_info._timer);
}
static void listitem_action_continue(void)
{
}
static void listitem_action_adjust(void)
{
}
static void listitem_action_description(void)
{
}
static const struct rtgui_list_item function_list[] =
{
{"新游戏", RT_NULL, listitem_action_start, RT_NULL},
{"继续", RT_NULL, listitem_action_continue, RT_NULL},
{"等级", RT_NULL, listitem_action_adjust, RT_NULL},
{"游戏说明", RT_NULL, listitem_action_description, RT_NULL},
{"退出游戏", RT_NULL, listitem_action_return, RT_NULL},
};
void main(void)
{
rt_mq_t mq;
rtgui_rect_t rect;
mq = rt_mq_create("tetris_ui", 256, 4, RT_IPC_FLAG_FIFO);
rtgui_thread_register(rt_thread_self(), mq);
g_app_info.workbench = rtgui_workbench_create("main", "tetris");
if (g_app_info.workbench == RT_NULL)
{
rt_kprintf("can't find panel 'main'\n");
rt_mq_delete(mq);
return;
}
rtgui_widget_set_event_handler(RTGUI_WIDGET(g_app_info.workbench), workbench_event_handler);
/* add function view */
rtgui_widget_get_rect(RTGUI_WIDGET(g_app_info.workbench), &rect);
g_app_info.function_view = rtgui_list_view_create(function_list,
sizeof(function_list) / sizeof(struct rtgui_list_item),
&rect,
RTGUI_LIST_VIEW_LIST);
rtgui_workbench_add_view(g_app_info.workbench, RTGUI_VIEW(g_app_info.function_view));
/* add home view */
g_app_info.game_view = rtgui_view_create("game");
rtgui_widget_set_event_handler(RTGUI_WIDGET(g_app_info.game_view), game_view_event_handler);
rtgui_workbench_add_view(g_app_info.workbench, g_app_info.game_view);
rtgui_view_show(RTGUI_VIEW(g_app_info.function_view), RT_FALSE);
rtgui_workbench_event_loop(g_app_info.workbench);
rtgui_workbench_destroy(g_app_info.workbench);
rtgui_thread_deregister(rt_thread_self());
rt_mq_delete(mq);
}

View File

@ -1,218 +1,218 @@
/*
* File : tetris_view.c
* This file is part of RTGUI 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-08-14 Yi.Qiu first version
*/
#include <rtthread.h>
#include <rtgui/rtgui.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/widgets/view.h>
#include <rtgui/dc.h>
#include "tetris.h"
static rt_err_t _rt_tetris_view_update(rt_tetris_view_t* thiz, rt_tetris_t* tetris);
static rt_err_t _rt_tetris_view_update_next_brick(rt_tetris_view_t* thiz, rt_tetris_t* tetris);
static rt_err_t _rt_tetris_view_update_level(rt_tetris_view_t* thiz, rt_tetris_t* tetris);
static rt_err_t _rt_tetris_view_update_score_and_lines(rt_tetris_view_t* thiz, rt_tetris_t* tetris);
rt_tetris_view_t* rt_tetris_view_create(void* private)
{
rt_tetris_view_t* thiz;
RT_ASSERT(private != RT_NULL)
thiz = (rt_tetris_view_t*)rt_malloc(sizeof(rt_tetris_view_t));
thiz->width = 96;
thiz->height = 96;
thiz->update = _rt_tetris_view_update;
thiz->update_next_brick = _rt_tetris_view_update_next_brick;
thiz->update_level = _rt_tetris_view_update_level;
thiz->update_score_and_lines = _rt_tetris_view_update_score_and_lines;
thiz->private = private;
return thiz;
}
rt_err_t rt_tetris_view_destroy(rt_tetris_view_t* thiz)
{
RT_ASSERT(thiz != RT_NULL);
rt_free(thiz);
return RT_EOK;
}
static rt_err_t _rt_tetris_view_update_next_brick(rt_tetris_view_t* thiz, rt_tetris_t* tetris)
{
struct rtgui_dc* dc;
struct rtgui_rect rect;
rt_uint32_t width;
rt_uint32_t ppb, i;
rtgui_widget_t* widget;
rt_uint32_t* next_brick;
RT_ASSERT(thiz != RT_NULL);
RT_ASSERT(tetris != RT_NULL);
next_brick = rt_tetris_next_brick(tetris);
widget = (rtgui_widget_t*)thiz->private;
width = rt_tetris_width(tetris);
/* pixel per block */
ppb = thiz->width / width;
dc = rtgui_dc_begin_drawing(widget);
if (dc == RT_NULL) return -RT_ERROR;
rect.x1 = 100;
rect.x2 = rect.x1 + 4 * ppb;
rect.y1 = 16;
rect.y2 = rect.y1 + 2 * ppb;
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff);
rtgui_dc_fill_rect(dc, &rect);
for(i=0; i<4; i++)
{
rt_uint32_t y = next_brick[i] / width;
rt_uint32_t x = next_brick[i] % width;
rect.x1 = 100 + ppb * (x - 6);
rect.x2 = rect.x1 + ppb - 1;
rect.y1 = 16 + ppb * y ;
rect.y2 = rect.y1 + ppb - 1;
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00);
rtgui_dc_fill_rect(dc, &rect);
}
rtgui_dc_end_drawing(dc);
return RT_EOK;
}
static rt_err_t _rt_tetris_view_update_level(rt_tetris_view_t* thiz, rt_tetris_t* tetris)
{
struct rtgui_dc* dc;
struct rtgui_rect rect;
rtgui_widget_t* widget;
char text[4];
RT_ASSERT(thiz != RT_NULL);
RT_ASSERT(tetris != RT_NULL);
widget = (rtgui_widget_t*)thiz->private;
dc = rtgui_dc_begin_drawing(widget);
if (dc == RT_NULL) return -RT_ERROR;
rect.x1 = 96;
rect.y1 = 42;
rect.x2 = 128;
rect.y2 = rect.y1 + 10;
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff);
rtgui_dc_fill_rect(dc, &rect);
rt_sprintf(text, "%d", rt_tetris_level(tetris));
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00);
rtgui_dc_draw_text(dc, text, &rect);
/* Redraw panel */
rtgui_dc_end_drawing(dc);
return RT_EOK;
}
static rt_err_t _rt_tetris_view_update_score_and_lines(rt_tetris_view_t* thiz, rt_tetris_t* tetris)
{
struct rtgui_dc* dc;
struct rtgui_rect rect;
rtgui_widget_t* widget;
char text[4];
RT_ASSERT(thiz != RT_NULL);
RT_ASSERT(tetris != RT_NULL);
widget = (rtgui_widget_t*)thiz->private;
dc = rtgui_dc_begin_drawing(widget);
if (dc == RT_NULL) return -RT_ERROR;
rect.x1 = 96;
rect.y1 = 64;
rect.x2 = 128;
rect.y2 = rect.y1 + 10;
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff);
rtgui_dc_fill_rect(dc, &rect);
rt_sprintf(text, "%d", rt_tetris_lines(tetris));
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00);
rtgui_dc_draw_text(dc, text, &rect);
rect.y1 += 22;
rect.y2 = rect.y1 + 10;
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff);
rtgui_dc_fill_rect(dc, &rect);
rt_sprintf(text, "%d", rt_tetris_score(tetris));
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00);
rtgui_dc_draw_text(dc, text, &rect);
/* Redraw panel */
rtgui_dc_end_drawing(dc);
return RT_EOK;
}
static rt_err_t _rt_tetris_view_update(rt_tetris_view_t* thiz, rt_tetris_t* tetris)
{
struct rtgui_dc* dc;
struct rtgui_rect rect;
rt_uint32_t width, height;
rt_uint32_t j,k, ppb;
rtgui_widget_t* widget;
RT_ASSERT(thiz != RT_NULL);
RT_ASSERT(tetris != RT_NULL);
widget = (rtgui_widget_t*)thiz->private;
width = rt_tetris_width(tetris);
height = rt_tetris_height(tetris);
ppb = thiz->width / width;
dc = rtgui_dc_begin_drawing(widget);
if (dc == RT_NULL) return -RT_ERROR;
/* Redraw panel */
for(j=0; j<width; j++)
{
for(k=1; k<height; k++)
{
rect.x1 = ppb * j;
rect.x2 = ppb * (j + 1) - 1;
rect.y1 = ppb * (k - 1);
rect.y2 = ppb * k - 1;
if(rt_tetris_check_collision(tetris, k * width + j))
{
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff);
}
else
{
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00);
}
rtgui_dc_fill_rect(dc, &rect);
}
}
/* Redraw panel */
rtgui_dc_end_drawing(dc);
return RT_EOK;
}
/*
* File : tetris_view.c
* This file is part of RTGUI 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-08-14 Yi.Qiu first version
*/
#include <rtthread.h>
#include <rtgui/rtgui.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/widgets/view.h>
#include <rtgui/dc.h>
#include "tetris.h"
static rt_err_t _rt_tetris_view_update(rt_tetris_view_t* thiz, rt_tetris_t* tetris);
static rt_err_t _rt_tetris_view_update_next_brick(rt_tetris_view_t* thiz, rt_tetris_t* tetris);
static rt_err_t _rt_tetris_view_update_level(rt_tetris_view_t* thiz, rt_tetris_t* tetris);
static rt_err_t _rt_tetris_view_update_score_and_lines(rt_tetris_view_t* thiz, rt_tetris_t* tetris);
rt_tetris_view_t* rt_tetris_view_create(void* private)
{
rt_tetris_view_t* thiz;
RT_ASSERT(private != RT_NULL)
thiz = (rt_tetris_view_t*)rt_malloc(sizeof(rt_tetris_view_t));
thiz->width = 96;
thiz->height = 96;
thiz->update = _rt_tetris_view_update;
thiz->update_next_brick = _rt_tetris_view_update_next_brick;
thiz->update_level = _rt_tetris_view_update_level;
thiz->update_score_and_lines = _rt_tetris_view_update_score_and_lines;
thiz->private = private;
return thiz;
}
rt_err_t rt_tetris_view_destroy(rt_tetris_view_t* thiz)
{
RT_ASSERT(thiz != RT_NULL);
rt_free(thiz);
return RT_EOK;
}
static rt_err_t _rt_tetris_view_update_next_brick(rt_tetris_view_t* thiz, rt_tetris_t* tetris)
{
struct rtgui_dc* dc;
struct rtgui_rect rect;
rt_uint32_t width;
rt_uint32_t ppb, i;
rtgui_widget_t* widget;
rt_uint32_t* next_brick;
RT_ASSERT(thiz != RT_NULL);
RT_ASSERT(tetris != RT_NULL);
next_brick = rt_tetris_next_brick(tetris);
widget = (rtgui_widget_t*)thiz->private;
width = rt_tetris_width(tetris);
/* pixel per block */
ppb = thiz->width / width;
dc = rtgui_dc_begin_drawing(widget);
if (dc == RT_NULL) return -RT_ERROR;
rect.x1 = 100;
rect.x2 = rect.x1 + 4 * ppb;
rect.y1 = 16;
rect.y2 = rect.y1 + 2 * ppb;
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff);
rtgui_dc_fill_rect(dc, &rect);
for(i=0; i<4; i++)
{
rt_uint32_t y = next_brick[i] / width;
rt_uint32_t x = next_brick[i] % width;
rect.x1 = 100 + ppb * (x - 6);
rect.x2 = rect.x1 + ppb - 1;
rect.y1 = 16 + ppb * y ;
rect.y2 = rect.y1 + ppb - 1;
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00);
rtgui_dc_fill_rect(dc, &rect);
}
rtgui_dc_end_drawing(dc);
return RT_EOK;
}
static rt_err_t _rt_tetris_view_update_level(rt_tetris_view_t* thiz, rt_tetris_t* tetris)
{
struct rtgui_dc* dc;
struct rtgui_rect rect;
rtgui_widget_t* widget;
char text[4];
RT_ASSERT(thiz != RT_NULL);
RT_ASSERT(tetris != RT_NULL);
widget = (rtgui_widget_t*)thiz->private;
dc = rtgui_dc_begin_drawing(widget);
if (dc == RT_NULL) return -RT_ERROR;
rect.x1 = 96;
rect.y1 = 42;
rect.x2 = 128;
rect.y2 = rect.y1 + 10;
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff);
rtgui_dc_fill_rect(dc, &rect);
rt_sprintf(text, "%d", rt_tetris_level(tetris));
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00);
rtgui_dc_draw_text(dc, text, &rect);
/* Redraw panel */
rtgui_dc_end_drawing(dc);
return RT_EOK;
}
static rt_err_t _rt_tetris_view_update_score_and_lines(rt_tetris_view_t* thiz, rt_tetris_t* tetris)
{
struct rtgui_dc* dc;
struct rtgui_rect rect;
rtgui_widget_t* widget;
char text[4];
RT_ASSERT(thiz != RT_NULL);
RT_ASSERT(tetris != RT_NULL);
widget = (rtgui_widget_t*)thiz->private;
dc = rtgui_dc_begin_drawing(widget);
if (dc == RT_NULL) return -RT_ERROR;
rect.x1 = 96;
rect.y1 = 64;
rect.x2 = 128;
rect.y2 = rect.y1 + 10;
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff);
rtgui_dc_fill_rect(dc, &rect);
rt_sprintf(text, "%d", rt_tetris_lines(tetris));
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00);
rtgui_dc_draw_text(dc, text, &rect);
rect.y1 += 22;
rect.y2 = rect.y1 + 10;
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff);
rtgui_dc_fill_rect(dc, &rect);
rt_sprintf(text, "%d", rt_tetris_score(tetris));
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00);
rtgui_dc_draw_text(dc, text, &rect);
/* Redraw panel */
rtgui_dc_end_drawing(dc);
return RT_EOK;
}
static rt_err_t _rt_tetris_view_update(rt_tetris_view_t* thiz, rt_tetris_t* tetris)
{
struct rtgui_dc* dc;
struct rtgui_rect rect;
rt_uint32_t width, height;
rt_uint32_t j,k, ppb;
rtgui_widget_t* widget;
RT_ASSERT(thiz != RT_NULL);
RT_ASSERT(tetris != RT_NULL);
widget = (rtgui_widget_t*)thiz->private;
width = rt_tetris_width(tetris);
height = rt_tetris_height(tetris);
ppb = thiz->width / width;
dc = rtgui_dc_begin_drawing(widget);
if (dc == RT_NULL) return -RT_ERROR;
/* Redraw panel */
for(j=0; j<width; j++)
{
for(k=1; k<height; k++)
{
rect.x1 = ppb * j;
rect.x2 = ppb * (j + 1) - 1;
rect.y1 = ppb * (k - 1);
rect.y2 = ppb * k - 1;
if(rt_tetris_check_collision(tetris, k * width + j))
{
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0xff, 0xff);
}
else
{
RTGUI_DC_BC(dc) = RTGUI_RGB(0xff, 0x00, 0x00);
}
rtgui_dc_fill_rect(dc, &rect);
}
}
/* Redraw panel */
rtgui_dc_end_drawing(dc);
return RT_EOK;
}

View File

@ -1,98 +1,98 @@
#include <rtthread.h>
#include <lwip/netdb.h> /* 为了解析主机名需要包含netdb.h头文件 */
#include <lwip/sockets.h> /* 使用BSD socket需要包含sockets.h头文件 */
#define BUFSZ 1024
static const char send_data[] = "This is TCP Client from RT-Thread."; /* 发送用到的数据 */
void tcpclient(const char* url, int port)
{
char *recv_data;
struct hostent *host;
int sock, bytes_received;
struct sockaddr_in server_addr;
/* 通过函数入口参数url获得host地址如果是域名会做域名解析 */
host = gethostbyname(url);
/* 分配用于存放接收数据的缓冲 */
recv_data = rt_malloc(BUFSZ);
if (recv_data == RT_NULL)
{
rt_kprintf("No memory\n");
return;
}
/* 创建一个socket类型是SOCKET_STREAMTCP类型 */
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
/* 创建socket失败 */
rt_kprintf("Socket error\n");
/* 释放接收缓冲 */
rt_free(recv_data);
return;
}
/* 初始化预连接的服务端地址 */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
/* 连接到服务端 */
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
{
/* 连接失败 */
rt_kprintf("Connect fail!\n");
lwip_close(sock);
/*释放接收缓冲 */
rt_free(recv_data);
return;
}
while(1)
{
/* 从sock连接中接收最大BUFSZ - 1字节数据 */
bytes_received = recv(sock, recv_data, BUFSZ - 1, 0);
if (bytes_received <= 0)
{
/* 接收失败,关闭这个连接 */
lwip_close(sock);
/* 释放接收缓冲 */
rt_free(recv_data);
break;
}
/* 有接收到数据,把末端清零 */
recv_data[bytes_received] = '\0';
if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0)
{
/* 如果是首字母是q或Q关闭这个连接 */
lwip_close(sock);
/* 释放接收缓冲 */
rt_free(recv_data);
break;
}
else
{
/* 在控制终端显示收到的数据 */
rt_kprintf("\nRecieved data = %s " , recv_data);
}
/* 发送数据到sock连接 */
send(sock,send_data,strlen(send_data), 0);
}
return;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
/* 输出tcpclient函数到finsh shell中 */
FINSH_FUNCTION_EXPORT(tcpclient, startup tcp client);
#endif
#include <rtthread.h>
#include <lwip/netdb.h> /* 为了解析主机名需要包含netdb.h头文件 */
#include <lwip/sockets.h> /* 使用BSD socket需要包含sockets.h头文件 */
#define BUFSZ 1024
static const char send_data[] = "This is TCP Client from RT-Thread."; /* 发送用到的数据 */
void tcpclient(const char* url, int port)
{
char *recv_data;
struct hostent *host;
int sock, bytes_received;
struct sockaddr_in server_addr;
/* 通过函数入口参数url获得host地址如果是域名会做域名解析 */
host = gethostbyname(url);
/* 分配用于存放接收数据的缓冲 */
recv_data = rt_malloc(BUFSZ);
if (recv_data == RT_NULL)
{
rt_kprintf("No memory\n");
return;
}
/* 创建一个socket类型是SOCKET_STREAMTCP类型 */
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
/* 创建socket失败 */
rt_kprintf("Socket error\n");
/* 释放接收缓冲 */
rt_free(recv_data);
return;
}
/* 初始化预连接的服务端地址 */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
/* 连接到服务端 */
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
{
/* 连接失败 */
rt_kprintf("Connect fail!\n");
lwip_close(sock);
/*释放接收缓冲 */
rt_free(recv_data);
return;
}
while(1)
{
/* 从sock连接中接收最大BUFSZ - 1字节数据 */
bytes_received = recv(sock, recv_data, BUFSZ - 1, 0);
if (bytes_received <= 0)
{
/* 接收失败,关闭这个连接 */
lwip_close(sock);
/* 释放接收缓冲 */
rt_free(recv_data);
break;
}
/* 有接收到数据,把末端清零 */
recv_data[bytes_received] = '\0';
if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0)
{
/* 如果是首字母是q或Q关闭这个连接 */
lwip_close(sock);
/* 释放接收缓冲 */
rt_free(recv_data);
break;
}
else
{
/* 在控制终端显示收到的数据 */
rt_kprintf("\nRecieved data = %s " , recv_data);
}
/* 发送数据到sock连接 */
send(sock,send_data,strlen(send_data), 0);
}
return;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
/* 输出tcpclient函数到finsh shell中 */
FINSH_FUNCTION_EXPORT(tcpclient, startup tcp client);
#endif

View File

@ -1,63 +1,63 @@
#include <rtthread.h>
#include <lwip/netdb.h> /* 为了解析主机名需要包含netdb.h头文件 */
#include <lwip/sockets.h> /* 使用BSD socket需要包含sockets.h头文件 */
void tcp_senddata(const char* url, int port, int length)
{
struct hostent *host;
int sock, err, result, timeout, index;
struct sockaddr_in server_addr;
rt_uint8_t *buffer_ptr;
/* 通过函数入口参数url获得host地址如果是域名会做域名解析 */
host = gethostbyname(url);
/* 创建一个socket类型是SOCKET_STREAMTCP类型 */
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{
/* 创建socket失败 */
rt_kprintf("Socket error\n");
return;
}
/* 神奇内存 */
buffer_ptr = rt_malloc(length);
/* 构造发生数据 */
for (index = 0; index < length; index ++)
buffer_ptr[index] = index & 0xff;
timeout = 100;
/* 设置发送超时时间100ms */
lwip_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
/* 初始化预连接的服务端地址 */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
/* 连接到服务端 */
err = connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
rt_kprintf("TCP thread connect error code: %d\n", err);
while(1)
{
/* 发送数据到sock连接 */
result = send(sock, buffer_ptr, length, MSG_DONTWAIT);
if(result == -1) //数据发送错误处理
{
rt_kprintf("TCP thread send error: %d\n", result);
lwip_close(sock); //关闭连接,重新创建连接
rt_thread_delay(10);
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
rt_kprintf("TCP Socket error:%d\n",sock);
err = connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
rt_kprintf("TCP thread connect error code: %d\n", err);
}
}
}
#ifdef RT_USING_FINSH
#include <finsh.h>
/* 输出tcpclient函数到finsh shell中 */
FINSH_FUNCTION_EXPORT(tcp_senddata, send a packet through tcp connection);
#endif
#include <rtthread.h>
#include <lwip/netdb.h> /* 为了解析主机名需要包含netdb.h头文件 */
#include <lwip/sockets.h> /* 使用BSD socket需要包含sockets.h头文件 */
void tcp_senddata(const char* url, int port, int length)
{
struct hostent *host;
int sock, err, result, timeout, index;
struct sockaddr_in server_addr;
rt_uint8_t *buffer_ptr;
/* 通过函数入口参数url获得host地址如果是域名会做域名解析 */
host = gethostbyname(url);
/* 创建一个socket类型是SOCKET_STREAMTCP类型 */
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{
/* 创建socket失败 */
rt_kprintf("Socket error\n");
return;
}
/* 神奇内存 */
buffer_ptr = rt_malloc(length);
/* 构造发生数据 */
for (index = 0; index < length; index ++)
buffer_ptr[index] = index & 0xff;
timeout = 100;
/* 设置发送超时时间100ms */
lwip_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
/* 初始化预连接的服务端地址 */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
/* 连接到服务端 */
err = connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
rt_kprintf("TCP thread connect error code: %d\n", err);
while(1)
{
/* 发送数据到sock连接 */
result = send(sock, buffer_ptr, length, MSG_DONTWAIT);
if(result == -1) //数据发送错误处理
{
rt_kprintf("TCP thread send error: %d\n", result);
lwip_close(sock); //关闭连接,重新创建连接
rt_thread_delay(10);
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
rt_kprintf("TCP Socket error:%d\n",sock);
err = connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
rt_kprintf("TCP thread connect error code: %d\n", err);
}
}
}
#ifdef RT_USING_FINSH
#include <finsh.h>
/* 输出tcpclient函数到finsh shell中 */
FINSH_FUNCTION_EXPORT(tcp_senddata, send a packet through tcp connection);
#endif

View File

@ -1,122 +1,122 @@
#include <rtthread.h>
#include <lwip/sockets.h> /* 使用BSD Socket接口必须包含sockets.h这个头文件 */
static const char send_data[] = "This is TCP Server from RT-Thread."; /* 发送用到的数据 */
void tcpserv(void* parameter)
{
char *recv_data; /* 用于接收的指针,后面会做一次动态分配以请求可用内存 */
rt_uint32_t sin_size;
int sock, connected, bytes_received;
struct sockaddr_in server_addr, client_addr;
rt_bool_t stop = RT_FALSE; /* 停止标志 */
recv_data = rt_malloc(1024); /* 分配接收用的数据缓冲 */
if (recv_data == RT_NULL)
{
rt_kprintf("No memory\n");
return;
}
/* 一个socket在使用前需要预先创建出来指定SOCK_STREAM为TCP的socket */
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
/* 创建失败的错误处理 */
rt_kprintf("Socket error\n");
/* 释放已分配的接收缓冲 */
rt_free(recv_data);
return;
}
/* 初始化服务端地址 */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(5000); /* 服务端工作的端口 */
server_addr.sin_addr.s_addr = INADDR_ANY;
rt_memset(&(server_addr.sin_zero),8, sizeof(server_addr.sin_zero));
/* 绑定socket到服务端地址 */
if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
{
/* 绑定失败 */
rt_kprintf("Unable to bind\n");
/* 释放已分配的接收缓冲 */
rt_free(recv_data);
return;
}
/* 在socket上进行监听 */
if (listen(sock, 5) == -1)
{
rt_kprintf("Listen error\n");
/* release recv buffer */
rt_free(recv_data);
return;
}
rt_kprintf("\nTCPServer Waiting for client on port 5000...\n");
while(stop != RT_TRUE)
{
sin_size = sizeof(struct sockaddr_in);
/* 接受一个客户端连接socket的请求这个函数调用是阻塞式的 */
connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size);
/* 返回的是连接成功的socket */
/* 接受返回的client_addr指向了客户端的地址信息 */
rt_kprintf("I got a connection from (%s , %d)\n",
inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
/* 客户端连接的处理 */
while (1)
{
/* 发送数据到connected socket */
send(connected, send_data, strlen(send_data), 0);
/* 从connected socket中接收数据接收buffer是1024大小但并不一定能够收到1024大小的数据 */
bytes_received = recv(connected,recv_data, 1024, 0);
if (bytes_received <= 0)
{
/* 接收失败关闭这个connected socket */
lwip_close(connected);
break;
}
/* 有接收到数据,把末端清零 */
recv_data[bytes_received] = '\0';
if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0)
{
/* 如果是首字母是q或Q关闭这个连接 */
lwip_close(connected);
break;
}
else if (strcmp(recv_data, "exit") == 0)
{
/* 如果接收的是exit则关闭整个服务端 */
lwip_close(connected);
stop = RT_TRUE;
break;
}
else
{
/* 在控制终端显示收到的数据 */
rt_kprintf("RECIEVED DATA = %s \n" , recv_data);
}
}
}
/* 退出服务 */
lwip_close(sock);
/* 释放接收缓冲 */
rt_free(recv_data);
return ;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
/* 输出tcpserv函数到finsh shell中 */
FINSH_FUNCTION_EXPORT(tcpserv, startup tcp server);
#endif
#include <rtthread.h>
#include <lwip/sockets.h> /* 使用BSD Socket接口必须包含sockets.h这个头文件 */
static const char send_data[] = "This is TCP Server from RT-Thread."; /* 发送用到的数据 */
void tcpserv(void* parameter)
{
char *recv_data; /* 用于接收的指针,后面会做一次动态分配以请求可用内存 */
rt_uint32_t sin_size;
int sock, connected, bytes_received;
struct sockaddr_in server_addr, client_addr;
rt_bool_t stop = RT_FALSE; /* 停止标志 */
recv_data = rt_malloc(1024); /* 分配接收用的数据缓冲 */
if (recv_data == RT_NULL)
{
rt_kprintf("No memory\n");
return;
}
/* 一个socket在使用前需要预先创建出来指定SOCK_STREAM为TCP的socket */
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
/* 创建失败的错误处理 */
rt_kprintf("Socket error\n");
/* 释放已分配的接收缓冲 */
rt_free(recv_data);
return;
}
/* 初始化服务端地址 */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(5000); /* 服务端工作的端口 */
server_addr.sin_addr.s_addr = INADDR_ANY;
rt_memset(&(server_addr.sin_zero),8, sizeof(server_addr.sin_zero));
/* 绑定socket到服务端地址 */
if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
{
/* 绑定失败 */
rt_kprintf("Unable to bind\n");
/* 释放已分配的接收缓冲 */
rt_free(recv_data);
return;
}
/* 在socket上进行监听 */
if (listen(sock, 5) == -1)
{
rt_kprintf("Listen error\n");
/* release recv buffer */
rt_free(recv_data);
return;
}
rt_kprintf("\nTCPServer Waiting for client on port 5000...\n");
while(stop != RT_TRUE)
{
sin_size = sizeof(struct sockaddr_in);
/* 接受一个客户端连接socket的请求这个函数调用是阻塞式的 */
connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size);
/* 返回的是连接成功的socket */
/* 接受返回的client_addr指向了客户端的地址信息 */
rt_kprintf("I got a connection from (%s , %d)\n",
inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
/* 客户端连接的处理 */
while (1)
{
/* 发送数据到connected socket */
send(connected, send_data, strlen(send_data), 0);
/* 从connected socket中接收数据接收buffer是1024大小但并不一定能够收到1024大小的数据 */
bytes_received = recv(connected,recv_data, 1024, 0);
if (bytes_received <= 0)
{
/* 接收失败关闭这个connected socket */
lwip_close(connected);
break;
}
/* 有接收到数据,把末端清零 */
recv_data[bytes_received] = '\0';
if (strcmp(recv_data , "q") == 0 || strcmp(recv_data , "Q") == 0)
{
/* 如果是首字母是q或Q关闭这个连接 */
lwip_close(connected);
break;
}
else if (strcmp(recv_data, "exit") == 0)
{
/* 如果接收的是exit则关闭整个服务端 */
lwip_close(connected);
stop = RT_TRUE;
break;
}
else
{
/* 在控制终端显示收到的数据 */
rt_kprintf("RECIEVED DATA = %s \n" , recv_data);
}
}
}
/* 退出服务 */
lwip_close(sock);
/* 释放接收缓冲 */
rt_free(recv_data);
return ;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
/* 输出tcpserv函数到finsh shell中 */
FINSH_FUNCTION_EXPORT(tcpserv, startup tcp server);
#endif

View File

@ -1,50 +1,50 @@
#include <rtthread.h>
#include <lwip/netdb.h> /* 为了解析主机名需要包含netdb.h头文件 */
#include <lwip/sockets.h> /* 使用BSD socket需要包含sockets.h头文件 */
const char send_data[] = "This is UDP Client from RT-Thread.\n"; /* 发送用到的数据 */
void udpclient(const char* url, int port, int count)
{
int sock;
struct hostent *host;
struct sockaddr_in server_addr;
/* 通过函数入口参数url获得host地址如果是域名会做域名解析 */
host= (struct hostent *) gethostbyname(url);
/* 创建一个socket类型是SOCK_DGRAMUDP类型 */
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
rt_kprintf("Socket error\n");
return;
}
/* 初始化预连接的服务端地址 */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
/* 总计发送count次数据 */
while (count)
{
/* 发送数据到服务远端 */
sendto(sock, send_data, strlen(send_data), 0,
(struct sockaddr *)&server_addr, sizeof(struct sockaddr));
/* 线程休眠一段时间 */
rt_thread_delay(50);
/* 计数值减一 */
count --;
}
/* 关闭这个socket */
lwip_close(sock);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
/* 输出udpclient函数到finsh shell中 */
FINSH_FUNCTION_EXPORT(udpclient, startup udp client);
#endif
#include <rtthread.h>
#include <lwip/netdb.h> /* 为了解析主机名需要包含netdb.h头文件 */
#include <lwip/sockets.h> /* 使用BSD socket需要包含sockets.h头文件 */
const char send_data[] = "This is UDP Client from RT-Thread.\n"; /* 发送用到的数据 */
void udpclient(const char* url, int port, int count)
{
int sock;
struct hostent *host;
struct sockaddr_in server_addr;
/* 通过函数入口参数url获得host地址如果是域名会做域名解析 */
host= (struct hostent *) gethostbyname(url);
/* 创建一个socket类型是SOCK_DGRAMUDP类型 */
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
rt_kprintf("Socket error\n");
return;
}
/* 初始化预连接的服务端地址 */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
/* 总计发送count次数据 */
while (count)
{
/* 发送数据到服务远端 */
sendto(sock, send_data, strlen(send_data), 0,
(struct sockaddr *)&server_addr, sizeof(struct sockaddr));
/* 线程休眠一段时间 */
rt_thread_delay(50);
/* 计数值减一 */
count --;
}
/* 关闭这个socket */
lwip_close(sock);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
/* 输出udpclient函数到finsh shell中 */
FINSH_FUNCTION_EXPORT(udpclient, startup udp client);
#endif

View File

@ -1,86 +1,86 @@
#include <rtthread.h>
#include <lwip/sockets.h> /* 使用BSD socket需要包含sockets.h头文件 */
#define BUFSZ 1024
void udpserv(void* paramemter)
{
int sock;
int bytes_read;
char *recv_data;
rt_uint32_t addr_len;
struct sockaddr_in server_addr, client_addr;
/* 分配接收用的数据缓冲 */
recv_data = rt_malloc(BUFSZ);
if (recv_data == RT_NULL)
{
/* 分配内存失败,返回 */
rt_kprintf("No memory\n");
return;
}
/* 创建一个socket类型是SOCK_DGRAMUDP类型 */
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
rt_kprintf("Socket error\n");
/* 释放接收用的数据缓冲 */
rt_free(recv_data);
return;
}
/* 初始化服务端地址 */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(5000);
server_addr.sin_addr.s_addr = INADDR_ANY;
rt_memset(&(server_addr.sin_zero),0, sizeof(server_addr.sin_zero));
/* 绑定socket到服务端地址 */
if (bind(sock,(struct sockaddr *)&server_addr,
sizeof(struct sockaddr)) == -1)
{
/* 绑定地址失败 */
rt_kprintf("Bind error\n");
/* 释放接收用的数据缓冲 */
rt_free(recv_data);
return;
}
addr_len = sizeof(struct sockaddr);
rt_kprintf("UDPServer Waiting for client on port 5000...\n");
while (1)
{
/* 从sock中收取最大BUFSZ - 1字节数据 */
bytes_read = recvfrom(sock, recv_data, BUFSZ - 1, 0,
(struct sockaddr *)&client_addr, &addr_len);
/* UDP不同于TCP它基本不会出现收取的数据失败的情况除非设置了超时等待 */
recv_data[bytes_read] = '\0'; /* 把末端清零 */
/* 输出接收的数据 */
rt_kprintf("\n(%s , %d) said : ",inet_ntoa(client_addr.sin_addr),
ntohs(client_addr.sin_port));
rt_kprintf("%s", recv_data);
/* 如果接收数据是exit退出 */
if (strcmp(recv_data, "exit") == 0)
{
lwip_close(sock);
/* 释放接收用的数据缓冲 */
rt_free(recv_data);
break;
}
}
return;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
/* 输出udpserv函数到finsh shell中 */
FINSH_FUNCTION_EXPORT(udpserv, startup udp server);
#endif
#include <rtthread.h>
#include <lwip/sockets.h> /* 使用BSD socket需要包含sockets.h头文件 */
#define BUFSZ 1024
void udpserv(void* paramemter)
{
int sock;
int bytes_read;
char *recv_data;
rt_uint32_t addr_len;
struct sockaddr_in server_addr, client_addr;
/* 分配接收用的数据缓冲 */
recv_data = rt_malloc(BUFSZ);
if (recv_data == RT_NULL)
{
/* 分配内存失败,返回 */
rt_kprintf("No memory\n");
return;
}
/* 创建一个socket类型是SOCK_DGRAMUDP类型 */
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
rt_kprintf("Socket error\n");
/* 释放接收用的数据缓冲 */
rt_free(recv_data);
return;
}
/* 初始化服务端地址 */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(5000);
server_addr.sin_addr.s_addr = INADDR_ANY;
rt_memset(&(server_addr.sin_zero),0, sizeof(server_addr.sin_zero));
/* 绑定socket到服务端地址 */
if (bind(sock,(struct sockaddr *)&server_addr,
sizeof(struct sockaddr)) == -1)
{
/* 绑定地址失败 */
rt_kprintf("Bind error\n");
/* 释放接收用的数据缓冲 */
rt_free(recv_data);
return;
}
addr_len = sizeof(struct sockaddr);
rt_kprintf("UDPServer Waiting for client on port 5000...\n");
while (1)
{
/* 从sock中收取最大BUFSZ - 1字节数据 */
bytes_read = recvfrom(sock, recv_data, BUFSZ - 1, 0,
(struct sockaddr *)&client_addr, &addr_len);
/* UDP不同于TCP它基本不会出现收取的数据失败的情况除非设置了超时等待 */
recv_data[bytes_read] = '\0'; /* 把末端清零 */
/* 输出接收的数据 */
rt_kprintf("\n(%s , %d) said : ",inet_ntoa(client_addr.sin_addr),
ntohs(client_addr.sin_port));
rt_kprintf("%s", recv_data);
/* 如果接收数据是exit退出 */
if (strcmp(recv_data, "exit") == 0)
{
lwip_close(sock);
/* 释放接收用的数据缓冲 */
rt_free(recv_data);
break;
}
}
return;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
/* 输出udpserv函数到finsh shell中 */
FINSH_FUNCTION_EXPORT(udpserv, startup udp server);
#endif

View File

@ -1,412 +1,412 @@
/*
****************************************************************************
*
* "DHRYSTONE" Benchmark Program
* -----------------------------
*
* Version: C, Version 2.1
*
* File: dhry.h (part 1 of 3)
*
* Date: May 25, 1988
*
* Author: Reinhold P. Weicker
* Siemens AG, AUT E 51
* Postfach 3220
* 8520 Erlangen
* Germany (West)
* Phone: [+49]-9131-7-20330
* (8-17 Central European Time)
* Usenet: ..!mcsun!unido!estevax!weicker
*
* Original Version (in Ada) published in
* "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
* pp. 1013 - 1030, together with the statistics
* on which the distribution of statements etc. is based.
*
* In this C version, the following C library functions are used:
* - strcpy, strcmp (inside the measurement loop)
* - printf, scanf (outside the measurement loop)
* In addition, Berkeley UNIX system calls "times ()" or "time ()"
* are used for execution time measurement. For measurements
* on other systems, these calls have to be changed.
*
* Collection of Results:
* Reinhold Weicker (address see above) and
*
* Rick Richardson
* PC Research. Inc.
* 94 Apple Orchard Drive
* Tinton Falls, NJ 07724
* Phone: (201) 389-8963 (9-17 EST)
* Usenet: ...!uunet!pcrat!rick
*
* Please send results to Rick Richardson and/or Reinhold Weicker.
* Complete information should be given on hardware and software used.
* Hardware information includes: Machine type, CPU, type and size
* of caches; for microprocessors: clock frequency, memory speed
* (number of wait states).
* Software information includes: Compiler (and runtime library)
* manufacturer and version, compilation switches, OS version.
* The Operating System version may give an indication about the
* compiler; Dhrystone itself performs no OS calls in the measurement loop.
*
* The complete output generated by the program should be mailed
* such that at least some checks for correctness can be made.
*
***************************************************************************
*
* History: This version C/2.1 has been made for two reasons:
*
* 1) There is an obvious need for a common C version of
* Dhrystone, since C is at present the most popular system
* programming language for the class of processors
* (microcomputers, minicomputers) where Dhrystone is used most.
* There should be, as far as possible, only one C version of
* Dhrystone such that results can be compared without
* restrictions. In the past, the C versions distributed
* by Rick Richardson (Version 1.1) and by Reinhold Weicker
* had small (though not significant) differences.
*
* 2) As far as it is possible without changes to the Dhrystone
* statistics, optimizing compilers should be prevented from
* removing significant statements.
*
* This C version has been developed in cooperation with
* Rick Richardson (Tinton Falls, NJ), it incorporates many
* ideas from the "Version 1.1" distributed previously by
* him over the UNIX network Usenet.
* I also thank Chaim Benedelac (National Semiconductor),
* David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
* Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
* for their help with comments on earlier versions of the
* benchmark.
*
* Changes: In the initialization part, this version follows mostly
* Rick Richardson's version distributed via Usenet, not the
* version distributed earlier via floppy disk by Reinhold Weicker.
* As a concession to older compilers, names have been made
* unique within the first 8 characters.
* Inside the measurement loop, this version follows the
* version previously distributed by Reinhold Weicker.
*
* At several places in the benchmark, code has been added,
* but within the measurement loop only in branches that
* are not executed. The intention is that optimizing compilers
* should be prevented from moving code out of the measurement
* loop, or from removing code altogether. Since the statements
* that are executed within the measurement loop have NOT been
* changed, the numbers defining the "Dhrystone distribution"
* (distribution of statements, operand types and locality)
* still hold. Except for sophisticated optimizing compilers,
* execution times for this version should be the same as
* for previous versions.
*
* Since it has proven difficult to subtract the time for the
* measurement loop overhead in a correct way, the loop check
* has been made a part of the benchmark. This does have
* an impact - though a very minor one - on the distribution
* statistics which have been updated for this version.
*
* All changes within the measurement loop are described
* and discussed in the companion paper "Rationale for
* Dhrystone version 2".
*
* Because of the self-imposed limitation that the order and
* distribution of the executed statements should not be
* changed, there are still cases where optimizing compilers
* may not generate code for some statements. To a certain
* degree, this is unavoidable for small synthetic benchmarks.
* Users of the benchmark are advised to check code listings
* whether code is generated for all statements of Dhrystone.
*
* Version 2.1 is identical to version 2.0 distributed via
* the UNIX network Usenet in March 1988 except that it corrects
* some minor deficiencies that were found by users of version 2.0.
* The only change within the measurement loop is that a
* non-executed "else" part was added to the "if" statement in
* Func_3, and a non-executed "else" part removed from Proc_3.
*
***************************************************************************
*
* Defines: The following "Defines" are possible:
* -DREG=register (default: Not defined)
* As an approximation to what an average C programmer
* might do, the "register" storage class is applied
* (if enabled by -DREG=register)
* - for local variables, if they are used (dynamically)
* five or more times
* - for parameters if they are used (dynamically)
* six or more times
* Note that an optimal "register" strategy is
* compiler-dependent, and that "register" declarations
* do not necessarily lead to faster execution.
* -DNOSTRUCTASSIGN (default: Not defined)
* Define if the C compiler does not support
* assignment of structures.
* -DNOENUMS (default: Not defined)
* Define if the C compiler does not support
* enumeration types.
* -DTIMES (default)
* -DTIME
* The "times" function of UNIX (returning process times)
* or the "time" function (returning wallclock time)
* is used for measurement.
* For single user machines, "time ()" is adequate. For
* multi-user machines where you cannot get single-user
* access, use the "times ()" function. If you have
* neither, use a stopwatch in the dead of night.
* "printf"s are provided marking the points "Start Timer"
* and "Stop Timer". DO NOT use the UNIX "time(1)"
* command, as this will measure the total time to
* run this program, which will (erroneously) include
* the time to allocate storage (malloc) and to perform
* the initialization.
* -DHZ=nnn
* In Berkeley UNIX, the function "times" returns process
* time in 1/HZ seconds, with HZ = 60 for most systems.
* CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
* A VALUE.
*
***************************************************************************
*
* Compilation model and measurement (IMPORTANT):
*
* This C version of Dhrystone consists of three files:
* - dhry.h (this file, containing global definitions and comments)
* - dhry_1.c (containing the code corresponding to Ada package Pack_1)
* - dhry_2.c (containing the code corresponding to Ada package Pack_2)
*
* The following "ground rules" apply for measurements:
* - Separate compilation
* - No procedure merging
* - Otherwise, compiler optimizations are allowed but should be indicated
* - Default results are those without register declarations
* See the companion paper "Rationale for Dhrystone Version 2" for a more
* detailed discussion of these ground rules.
*
* For 16-Bit processors (e.g. 80186, 80286), times for all compilation
* models ("small", "medium", "large" etc.) should be given if possible,
* together with a definition of these models for the compiler system used.
*
**************************************************************************
*
* Dhrystone (C version) statistics:
*
* [Comment from the first distribution, updated for version 2.
* Note that because of language differences, the numbers are slightly
* different from the Ada version.]
*
* The following program contains statements of a high level programming
* language (here: C) in a distribution considered representative:
*
* assignments 52 (51.0 %)
* control statements 33 (32.4 %)
* procedure, function calls 17 (16.7 %)
*
* 103 statements are dynamically executed. The program is balanced with
* respect to the three aspects:
*
* - statement type
* - operand type
* - operand locality
* operand global, local, parameter, or constant.
*
* The combination of these three aspects is balanced only approximately.
*
* 1. Statement Type:
* ----------------- number
*
* V1 = V2 9
* (incl. V1 = F(..)
* V = Constant 12
* Assignment, 7
* with array element
* Assignment, 6
* with record component
* --
* 34 34
*
* X = Y +|-|"&&"|"|" Z 5
* X = Y +|-|"==" Constant 6
* X = X +|- 1 3
* X = Y *|/ Z 2
* X = Expression, 1
* two operators
* X = Expression, 1
* three operators
* --
* 18 18
*
* if .... 14
* with "else" 7
* without "else" 7
* executed 3
* not executed 4
* for ... 7 | counted every time
* while ... 4 | the loop condition
* do ... while 1 | is evaluated
* switch ... 1
* break 1
* declaration with 1
* initialization
* --
* 34 34
*
* P (...) procedure call 11
* user procedure 10
* library procedure 1
* X = F (...)
* function call 6
* user function 5
* library function 1
* --
* 17 17
* ---
* 103
*
* The average number of parameters in procedure or function calls
* is 1.82 (not counting the function values as implicit parameters).
*
*
* 2. Operators
* ------------
* number approximate
* percentage
*
* Arithmetic 32 50.8
*
* + 21 33.3
* - 7 11.1
* * 3 4.8
* / (int div) 1 1.6
*
* Comparison 27 42.8
*
* == 9 14.3
* /= 4 6.3
* > 1 1.6
* < 3 4.8
* >= 1 1.6
* <= 9 14.3
*
* Logic 4 6.3
*
* && (AND-THEN) 1 1.6
* | (OR) 1 1.6
* ! (NOT) 2 3.2
*
* -- -----
* 63 100.1
*
*
* 3. Operand Type (counted once per operand reference):
* ---------------
* number approximate
* percentage
*
* Integer 175 72.3 %
* Character 45 18.6 %
* Pointer 12 5.0 %
* String30 6 2.5 %
* Array 2 0.8 %
* Record 2 0.8 %
* --- -------
* 242 100.0 %
*
* When there is an access path leading to the final operand (e.g. a record
* component), only the final data type on the access path is counted.
*
*
* 4. Operand Locality:
* -------------------
* number approximate
* percentage
*
* local variable 114 47.1 %
* global variable 22 9.1 %
* parameter 45 18.6 %
* value 23 9.5 %
* reference 22 9.1 %
* function result 6 2.5 %
* constant 55 22.7 %
* --- -------
* 242 100.0 %
*
*
* The program does not compute anything meaningful, but it is syntactically
* and semantically correct. All variables have a value assigned to them
* before they are used as a source operand.
*
* There has been no explicit effort to account for the effects of a
* cache, or to balance the use of long or short displacements for code or
* data.
*
***************************************************************************
*/
/* Compiler and system dependent definitions: */
#define Mic_secs_Per_Second 1000000.0
/* Berkeley UNIX C returns process times in seconds/HZ */
#ifdef NOSTRUCTASSIGN
#define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
#else
#define structassign(d, s) d = s
#endif
#ifdef NOENUM
#define Ident_1 0
#define Ident_2 1
#define Ident_3 2
#define Ident_4 3
#define Ident_5 4
typedef int Enumeration;
#else
typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
Enumeration;
#endif
/* for boolean and enumeration types in Ada, Pascal */
/* General definitions: */
// #include <stdio.h>
/* for strcpy, strcmp */
#include <rtthread.h>
#define Null 0
/* Value of a Null pointer */
#define true 1
#define false 0
typedef int One_Thirty;
typedef int One_Fifty;
typedef char Capital_Letter;
typedef int Boolean;
typedef char Str_30 [31];
typedef int Arr_1_Dim [50];
typedef int Arr_2_Dim [50] [50];
typedef struct record
{
struct record *Ptr_Comp;
Enumeration Discr;
union {
struct {
Enumeration Enum_Comp;
int Int_Comp;
char Str_Comp [31];
} var_1;
struct {
Enumeration E_Comp_2;
char Str_2_Comp [31];
} var_2;
struct {
char Ch_1_Comp;
char Ch_2_Comp;
} var_3;
} variant;
} Rec_Type, *Rec_Pointer;
/*
****************************************************************************
*
* "DHRYSTONE" Benchmark Program
* -----------------------------
*
* Version: C, Version 2.1
*
* File: dhry.h (part 1 of 3)
*
* Date: May 25, 1988
*
* Author: Reinhold P. Weicker
* Siemens AG, AUT E 51
* Postfach 3220
* 8520 Erlangen
* Germany (West)
* Phone: [+49]-9131-7-20330
* (8-17 Central European Time)
* Usenet: ..!mcsun!unido!estevax!weicker
*
* Original Version (in Ada) published in
* "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
* pp. 1013 - 1030, together with the statistics
* on which the distribution of statements etc. is based.
*
* In this C version, the following C library functions are used:
* - strcpy, strcmp (inside the measurement loop)
* - printf, scanf (outside the measurement loop)
* In addition, Berkeley UNIX system calls "times ()" or "time ()"
* are used for execution time measurement. For measurements
* on other systems, these calls have to be changed.
*
* Collection of Results:
* Reinhold Weicker (address see above) and
*
* Rick Richardson
* PC Research. Inc.
* 94 Apple Orchard Drive
* Tinton Falls, NJ 07724
* Phone: (201) 389-8963 (9-17 EST)
* Usenet: ...!uunet!pcrat!rick
*
* Please send results to Rick Richardson and/or Reinhold Weicker.
* Complete information should be given on hardware and software used.
* Hardware information includes: Machine type, CPU, type and size
* of caches; for microprocessors: clock frequency, memory speed
* (number of wait states).
* Software information includes: Compiler (and runtime library)
* manufacturer and version, compilation switches, OS version.
* The Operating System version may give an indication about the
* compiler; Dhrystone itself performs no OS calls in the measurement loop.
*
* The complete output generated by the program should be mailed
* such that at least some checks for correctness can be made.
*
***************************************************************************
*
* History: This version C/2.1 has been made for two reasons:
*
* 1) There is an obvious need for a common C version of
* Dhrystone, since C is at present the most popular system
* programming language for the class of processors
* (microcomputers, minicomputers) where Dhrystone is used most.
* There should be, as far as possible, only one C version of
* Dhrystone such that results can be compared without
* restrictions. In the past, the C versions distributed
* by Rick Richardson (Version 1.1) and by Reinhold Weicker
* had small (though not significant) differences.
*
* 2) As far as it is possible without changes to the Dhrystone
* statistics, optimizing compilers should be prevented from
* removing significant statements.
*
* This C version has been developed in cooperation with
* Rick Richardson (Tinton Falls, NJ), it incorporates many
* ideas from the "Version 1.1" distributed previously by
* him over the UNIX network Usenet.
* I also thank Chaim Benedelac (National Semiconductor),
* David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
* Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
* for their help with comments on earlier versions of the
* benchmark.
*
* Changes: In the initialization part, this version follows mostly
* Rick Richardson's version distributed via Usenet, not the
* version distributed earlier via floppy disk by Reinhold Weicker.
* As a concession to older compilers, names have been made
* unique within the first 8 characters.
* Inside the measurement loop, this version follows the
* version previously distributed by Reinhold Weicker.
*
* At several places in the benchmark, code has been added,
* but within the measurement loop only in branches that
* are not executed. The intention is that optimizing compilers
* should be prevented from moving code out of the measurement
* loop, or from removing code altogether. Since the statements
* that are executed within the measurement loop have NOT been
* changed, the numbers defining the "Dhrystone distribution"
* (distribution of statements, operand types and locality)
* still hold. Except for sophisticated optimizing compilers,
* execution times for this version should be the same as
* for previous versions.
*
* Since it has proven difficult to subtract the time for the
* measurement loop overhead in a correct way, the loop check
* has been made a part of the benchmark. This does have
* an impact - though a very minor one - on the distribution
* statistics which have been updated for this version.
*
* All changes within the measurement loop are described
* and discussed in the companion paper "Rationale for
* Dhrystone version 2".
*
* Because of the self-imposed limitation that the order and
* distribution of the executed statements should not be
* changed, there are still cases where optimizing compilers
* may not generate code for some statements. To a certain
* degree, this is unavoidable for small synthetic benchmarks.
* Users of the benchmark are advised to check code listings
* whether code is generated for all statements of Dhrystone.
*
* Version 2.1 is identical to version 2.0 distributed via
* the UNIX network Usenet in March 1988 except that it corrects
* some minor deficiencies that were found by users of version 2.0.
* The only change within the measurement loop is that a
* non-executed "else" part was added to the "if" statement in
* Func_3, and a non-executed "else" part removed from Proc_3.
*
***************************************************************************
*
* Defines: The following "Defines" are possible:
* -DREG=register (default: Not defined)
* As an approximation to what an average C programmer
* might do, the "register" storage class is applied
* (if enabled by -DREG=register)
* - for local variables, if they are used (dynamically)
* five or more times
* - for parameters if they are used (dynamically)
* six or more times
* Note that an optimal "register" strategy is
* compiler-dependent, and that "register" declarations
* do not necessarily lead to faster execution.
* -DNOSTRUCTASSIGN (default: Not defined)
* Define if the C compiler does not support
* assignment of structures.
* -DNOENUMS (default: Not defined)
* Define if the C compiler does not support
* enumeration types.
* -DTIMES (default)
* -DTIME
* The "times" function of UNIX (returning process times)
* or the "time" function (returning wallclock time)
* is used for measurement.
* For single user machines, "time ()" is adequate. For
* multi-user machines where you cannot get single-user
* access, use the "times ()" function. If you have
* neither, use a stopwatch in the dead of night.
* "printf"s are provided marking the points "Start Timer"
* and "Stop Timer". DO NOT use the UNIX "time(1)"
* command, as this will measure the total time to
* run this program, which will (erroneously) include
* the time to allocate storage (malloc) and to perform
* the initialization.
* -DHZ=nnn
* In Berkeley UNIX, the function "times" returns process
* time in 1/HZ seconds, with HZ = 60 for most systems.
* CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
* A VALUE.
*
***************************************************************************
*
* Compilation model and measurement (IMPORTANT):
*
* This C version of Dhrystone consists of three files:
* - dhry.h (this file, containing global definitions and comments)
* - dhry_1.c (containing the code corresponding to Ada package Pack_1)
* - dhry_2.c (containing the code corresponding to Ada package Pack_2)
*
* The following "ground rules" apply for measurements:
* - Separate compilation
* - No procedure merging
* - Otherwise, compiler optimizations are allowed but should be indicated
* - Default results are those without register declarations
* See the companion paper "Rationale for Dhrystone Version 2" for a more
* detailed discussion of these ground rules.
*
* For 16-Bit processors (e.g. 80186, 80286), times for all compilation
* models ("small", "medium", "large" etc.) should be given if possible,
* together with a definition of these models for the compiler system used.
*
**************************************************************************
*
* Dhrystone (C version) statistics:
*
* [Comment from the first distribution, updated for version 2.
* Note that because of language differences, the numbers are slightly
* different from the Ada version.]
*
* The following program contains statements of a high level programming
* language (here: C) in a distribution considered representative:
*
* assignments 52 (51.0 %)
* control statements 33 (32.4 %)
* procedure, function calls 17 (16.7 %)
*
* 103 statements are dynamically executed. The program is balanced with
* respect to the three aspects:
*
* - statement type
* - operand type
* - operand locality
* operand global, local, parameter, or constant.
*
* The combination of these three aspects is balanced only approximately.
*
* 1. Statement Type:
* ----------------- number
*
* V1 = V2 9
* (incl. V1 = F(..)
* V = Constant 12
* Assignment, 7
* with array element
* Assignment, 6
* with record component
* --
* 34 34
*
* X = Y +|-|"&&"|"|" Z 5
* X = Y +|-|"==" Constant 6
* X = X +|- 1 3
* X = Y *|/ Z 2
* X = Expression, 1
* two operators
* X = Expression, 1
* three operators
* --
* 18 18
*
* if .... 14
* with "else" 7
* without "else" 7
* executed 3
* not executed 4
* for ... 7 | counted every time
* while ... 4 | the loop condition
* do ... while 1 | is evaluated
* switch ... 1
* break 1
* declaration with 1
* initialization
* --
* 34 34
*
* P (...) procedure call 11
* user procedure 10
* library procedure 1
* X = F (...)
* function call 6
* user function 5
* library function 1
* --
* 17 17
* ---
* 103
*
* The average number of parameters in procedure or function calls
* is 1.82 (not counting the function values as implicit parameters).
*
*
* 2. Operators
* ------------
* number approximate
* percentage
*
* Arithmetic 32 50.8
*
* + 21 33.3
* - 7 11.1
* * 3 4.8
* / (int div) 1 1.6
*
* Comparison 27 42.8
*
* == 9 14.3
* /= 4 6.3
* > 1 1.6
* < 3 4.8
* >= 1 1.6
* <= 9 14.3
*
* Logic 4 6.3
*
* && (AND-THEN) 1 1.6
* | (OR) 1 1.6
* ! (NOT) 2 3.2
*
* -- -----
* 63 100.1
*
*
* 3. Operand Type (counted once per operand reference):
* ---------------
* number approximate
* percentage
*
* Integer 175 72.3 %
* Character 45 18.6 %
* Pointer 12 5.0 %
* String30 6 2.5 %
* Array 2 0.8 %
* Record 2 0.8 %
* --- -------
* 242 100.0 %
*
* When there is an access path leading to the final operand (e.g. a record
* component), only the final data type on the access path is counted.
*
*
* 4. Operand Locality:
* -------------------
* number approximate
* percentage
*
* local variable 114 47.1 %
* global variable 22 9.1 %
* parameter 45 18.6 %
* value 23 9.5 %
* reference 22 9.1 %
* function result 6 2.5 %
* constant 55 22.7 %
* --- -------
* 242 100.0 %
*
*
* The program does not compute anything meaningful, but it is syntactically
* and semantically correct. All variables have a value assigned to them
* before they are used as a source operand.
*
* There has been no explicit effort to account for the effects of a
* cache, or to balance the use of long or short displacements for code or
* data.
*
***************************************************************************
*/
/* Compiler and system dependent definitions: */
#define Mic_secs_Per_Second 1000000.0
/* Berkeley UNIX C returns process times in seconds/HZ */
#ifdef NOSTRUCTASSIGN
#define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
#else
#define structassign(d, s) d = s
#endif
#ifdef NOENUM
#define Ident_1 0
#define Ident_2 1
#define Ident_3 2
#define Ident_4 3
#define Ident_5 4
typedef int Enumeration;
#else
typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
Enumeration;
#endif
/* for boolean and enumeration types in Ada, Pascal */
/* General definitions: */
// #include <stdio.h>
/* for strcpy, strcmp */
#include <rtthread.h>
#define Null 0
/* Value of a Null pointer */
#define true 1
#define false 0
typedef int One_Thirty;
typedef int One_Fifty;
typedef char Capital_Letter;
typedef int Boolean;
typedef char Str_30 [31];
typedef int Arr_1_Dim [50];
typedef int Arr_2_Dim [50] [50];
typedef struct record
{
struct record *Ptr_Comp;
Enumeration Discr;
union {
struct {
Enumeration Enum_Comp;
int Int_Comp;
char Str_Comp [31];
} var_1;
struct {
Enumeration E_Comp_2;
char Str_2_Comp [31];
} var_2;
struct {
char Ch_1_Comp;
char Ch_2_Comp;
} var_3;
} variant;
} Rec_Type, *Rec_Pointer;

View File

@ -1,349 +1,349 @@
/*
****************************************************************************
*
* "DHRYSTONE" Benchmark Program
* -----------------------------
*
* Version: C, Version 2.1
*
* File: dhry_1.c (part 2 of 3)
*
* Date: May 25, 1988
*
* Author: Reinhold P. Weicker
*
****************************************************************************
*/
#define NUMBER_OF_RUNS 1000000
#include "dhry.h"
#define printf rt_kprintf
/* Global Variables: */
Rec_Pointer Ptr_Glob,
Next_Ptr_Glob;
int Int_Glob;
Boolean Bool_Glob;
char Ch_1_Glob,
Ch_2_Glob;
int Arr_1_Glob [50];
int Arr_2_Glob [50] [50];
Enumeration Func_1 ();
/* forward declaration necessary since Enumeration may not simply be int */
#ifndef REG
Boolean Reg = false;
#define REG
/* REG becomes defined as empty */
/* i.e. no register variables */
#else
Boolean Reg = true;
#endif
/* variables for time measurement: */
float Begin_Time,
End_Time,
User_Time;
float Microseconds,
Dhrystones_Per_Second;
/* end of variables for time measurement */
void dhry_test(void)
/*****/
/* main program, corresponds to procedures */
/* Main and Proc_0 in the Ada version */
{
One_Fifty Int_1_Loc;
REG One_Fifty Int_2_Loc;
One_Fifty Int_3_Loc;
REG char Ch_Index;
Enumeration Enum_Loc;
Str_30 Str_1_Loc;
Str_30 Str_2_Loc;
REG int Run_Index;
REG int Number_Of_Runs;
/* Initializations */
Next_Ptr_Glob = (Rec_Pointer) rt_malloc (sizeof (Rec_Type));
Ptr_Glob = (Rec_Pointer) rt_malloc (sizeof (Rec_Type));
Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
Ptr_Glob->Discr = Ident_1;
Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
Ptr_Glob->variant.var_1.Int_Comp = 40;
rt_strncpy (Ptr_Glob->variant.var_1.Str_Comp,
"DHRYSTONE PROGRAM, SOME STRING", sizeof(Ptr_Glob->variant.var_1.Str_Comp));
rt_strncpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING", sizeof(Str_1_Loc));
Arr_2_Glob [8][7] = 10;
/* Was missing in published program. Without this statement, */
/* Arr_2_Glob [8][7] would have an undefined value. */
/* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
/* overflow may occur for this array element. */
printf ("\n");
printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
printf ("\n");
if (Reg)
{
printf ("Program compiled with 'register' attribute\n");
printf ("\n");
}
else
{
printf ("Program compiled without 'register' attribute\n");
printf ("\n");
}
printf ("Please give the number of runs through the benchmark: ");
Number_Of_Runs = NUMBER_OF_RUNS;
printf ("%d\n", Number_Of_Runs);
printf ("\n");
printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
/***************/
/* Start timer */
/***************/
// Add your timer initializing code here
Begin_Time = rt_tick_get(); /* get start tick */
for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
{
Proc_5();
Proc_4();
/* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
Int_1_Loc = 2;
Int_2_Loc = 3;
rt_strncpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING", sizeof(Str_2_Loc));
Enum_Loc = Ident_2;
Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
/* Bool_Glob == 1 */
while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
{
Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
/* Int_3_Loc == 7 */
Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
/* Int_3_Loc == 7 */
Int_1_Loc += 1;
} /* while */
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
/* Int_Glob == 5 */
Proc_1 (Ptr_Glob);
for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
/* loop body executed twice */
{
if (Enum_Loc == Func_1 (Ch_Index, 'C'))
/* then, not executed */
{
Proc_6 (Ident_1, &Enum_Loc);
rt_strncpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING", sizeof(Str_2_Loc));
Int_2_Loc = Run_Index;
Int_Glob = Run_Index;
}
}
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
Int_2_Loc = Int_2_Loc * Int_1_Loc;
Int_1_Loc = Int_2_Loc / Int_3_Loc;
Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
/* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
Proc_2 (&Int_1_Loc);
/* Int_1_Loc == 5 */
} /* loop "for Run_Index" */
/**************/
/* Stop timer */
/**************/
End_Time = rt_tick_get(); // Get end tick
printf ("Execution ends\n");
printf ("\n");
printf ("Final values of the variables used in the benchmark:\n");
printf ("\n");
printf ("Int_Glob: %d\n", Int_Glob);
printf (" should be: %d\n", 5);
printf ("Bool_Glob: %d\n", Bool_Glob);
printf (" should be: %d\n", 1);
printf ("Ch_1_Glob: %c\n", Ch_1_Glob);
printf (" should be: %c\n", 'A');
printf ("Ch_2_Glob: %c\n", Ch_2_Glob);
printf (" should be: %c\n", 'B');
printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
printf (" should be: %d\n", 7);
printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
printf (" should be: Number_Of_Runs + 10\n");
printf ("Ptr_Glob->\n");
printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp);
printf (" should be: (implementation-dependent)\n");
printf (" Discr: %d\n", Ptr_Glob->Discr);
printf (" should be: %d\n", 0);
printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
printf (" should be: %d\n", 2);
printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp);
printf (" should be: %d\n", 17);
printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp);
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
printf ("Next_Ptr_Glob->\n");
printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
printf (" should be: (implementation-dependent), same as above\n");
printf (" Discr: %d\n", Next_Ptr_Glob->Discr);
printf (" should be: %d\n", 0);
printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
printf (" should be: %d\n", 1);
printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
printf (" should be: %d\n", 18);
printf (" Str_Comp: %s\n",
Next_Ptr_Glob->variant.var_1.Str_Comp);
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
printf ("Int_1_Loc: %d\n", Int_1_Loc);
printf (" should be: %d\n", 5);
printf ("Int_2_Loc: %d\n", Int_2_Loc);
printf (" should be: %d\n", 13);
printf ("Int_3_Loc: %d\n", Int_3_Loc);
printf (" should be: %d\n", 7);
printf ("Enum_Loc: %d\n", Enum_Loc);
printf (" should be: %d\n", 1);
printf ("Str_1_Loc: %s\n", Str_1_Loc);
printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
printf ("Str_2_Loc: %s\n", Str_2_Loc);
printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
printf ("\n");
User_Time = (End_Time - Begin_Time) / RT_TICK_PER_SECOND;
Microseconds = (float) User_Time * Mic_secs_Per_Second
/ (float) Number_Of_Runs;
Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time;
printf ("Microseconds for one run through Dhrystone: ");
printf ("%6d \n", (int)Microseconds);
printf ("Dhrystones per Second: ");
printf ("%6d \n", (int)Dhrystones_Per_Second);
printf ("Dhrystones MIPS: ");
printf ("%6d \n", (int)(Dhrystones_Per_Second / 1757.0));
printf ("\n");
}
Proc_1 (Ptr_Val_Par)
/******************/
REG Rec_Pointer Ptr_Val_Par;
/* executed once */
{
REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
/* == Ptr_Glob_Next */
/* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
/* corresponds to "rename" in Ada, "with" in Pascal */
structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
Ptr_Val_Par->variant.var_1.Int_Comp = 5;
Next_Record->variant.var_1.Int_Comp
= Ptr_Val_Par->variant.var_1.Int_Comp;
Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
Proc_3 (&Next_Record->Ptr_Comp);
/* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
== Ptr_Glob->Ptr_Comp */
if (Next_Record->Discr == Ident_1)
/* then, executed */
{
Next_Record->variant.var_1.Int_Comp = 6;
Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
&Next_Record->variant.var_1.Enum_Comp);
Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
&Next_Record->variant.var_1.Int_Comp);
}
else /* not executed */
structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
} /* Proc_1 */
Proc_2 (Int_Par_Ref)
/******************/
/* executed once */
/* *Int_Par_Ref == 1, becomes 4 */
One_Fifty *Int_Par_Ref;
{
One_Fifty Int_Loc;
Enumeration Enum_Loc;
Int_Loc = *Int_Par_Ref + 10;
do /* executed once */
if (Ch_1_Glob == 'A')
/* then, executed */
{
Int_Loc -= 1;
*Int_Par_Ref = Int_Loc - Int_Glob;
Enum_Loc = Ident_1;
} /* if */
while (Enum_Loc != Ident_1); /* true */
} /* Proc_2 */
Proc_3 (Ptr_Ref_Par)
/******************/
/* executed once */
/* Ptr_Ref_Par becomes Ptr_Glob */
Rec_Pointer *Ptr_Ref_Par;
{
if (Ptr_Glob != Null)
/* then, executed */
*Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
} /* Proc_3 */
Proc_4 () /* without parameters */
/*******/
/* executed once */
{
Boolean Bool_Loc;
Bool_Loc = Ch_1_Glob == 'A';
Bool_Glob = Bool_Loc | Bool_Glob;
Ch_2_Glob = 'B';
} /* Proc_4 */
Proc_5 () /* without parameters */
/*******/
/* executed once */
{
Ch_1_Glob = 'A';
Bool_Glob = false;
} /* Proc_5 */
/* Procedure for the assignment of structures, */
/* if the C compiler doesn't support this feature */
#ifdef NOSTRUCTASSIGN
memcpy (d, s, l)
register char *d;
register char *s;
register int l;
{
while (l--) *d++ = *s++;
}
#endif
#include <finsh.h>
FINSH_FUNCTION_EXPORT(dhry_test, dhry test);
/*
****************************************************************************
*
* "DHRYSTONE" Benchmark Program
* -----------------------------
*
* Version: C, Version 2.1
*
* File: dhry_1.c (part 2 of 3)
*
* Date: May 25, 1988
*
* Author: Reinhold P. Weicker
*
****************************************************************************
*/
#define NUMBER_OF_RUNS 1000000
#include "dhry.h"
#define printf rt_kprintf
/* Global Variables: */
Rec_Pointer Ptr_Glob,
Next_Ptr_Glob;
int Int_Glob;
Boolean Bool_Glob;
char Ch_1_Glob,
Ch_2_Glob;
int Arr_1_Glob [50];
int Arr_2_Glob [50] [50];
Enumeration Func_1 ();
/* forward declaration necessary since Enumeration may not simply be int */
#ifndef REG
Boolean Reg = false;
#define REG
/* REG becomes defined as empty */
/* i.e. no register variables */
#else
Boolean Reg = true;
#endif
/* variables for time measurement: */
float Begin_Time,
End_Time,
User_Time;
float Microseconds,
Dhrystones_Per_Second;
/* end of variables for time measurement */
void dhry_test(void)
/*****/
/* main program, corresponds to procedures */
/* Main and Proc_0 in the Ada version */
{
One_Fifty Int_1_Loc;
REG One_Fifty Int_2_Loc;
One_Fifty Int_3_Loc;
REG char Ch_Index;
Enumeration Enum_Loc;
Str_30 Str_1_Loc;
Str_30 Str_2_Loc;
REG int Run_Index;
REG int Number_Of_Runs;
/* Initializations */
Next_Ptr_Glob = (Rec_Pointer) rt_malloc (sizeof (Rec_Type));
Ptr_Glob = (Rec_Pointer) rt_malloc (sizeof (Rec_Type));
Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
Ptr_Glob->Discr = Ident_1;
Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
Ptr_Glob->variant.var_1.Int_Comp = 40;
rt_strncpy (Ptr_Glob->variant.var_1.Str_Comp,
"DHRYSTONE PROGRAM, SOME STRING", sizeof(Ptr_Glob->variant.var_1.Str_Comp));
rt_strncpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING", sizeof(Str_1_Loc));
Arr_2_Glob [8][7] = 10;
/* Was missing in published program. Without this statement, */
/* Arr_2_Glob [8][7] would have an undefined value. */
/* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
/* overflow may occur for this array element. */
printf ("\n");
printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
printf ("\n");
if (Reg)
{
printf ("Program compiled with 'register' attribute\n");
printf ("\n");
}
else
{
printf ("Program compiled without 'register' attribute\n");
printf ("\n");
}
printf ("Please give the number of runs through the benchmark: ");
Number_Of_Runs = NUMBER_OF_RUNS;
printf ("%d\n", Number_Of_Runs);
printf ("\n");
printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
/***************/
/* Start timer */
/***************/
// Add your timer initializing code here
Begin_Time = rt_tick_get(); /* get start tick */
for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
{
Proc_5();
Proc_4();
/* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
Int_1_Loc = 2;
Int_2_Loc = 3;
rt_strncpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING", sizeof(Str_2_Loc));
Enum_Loc = Ident_2;
Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
/* Bool_Glob == 1 */
while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
{
Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
/* Int_3_Loc == 7 */
Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
/* Int_3_Loc == 7 */
Int_1_Loc += 1;
} /* while */
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
/* Int_Glob == 5 */
Proc_1 (Ptr_Glob);
for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
/* loop body executed twice */
{
if (Enum_Loc == Func_1 (Ch_Index, 'C'))
/* then, not executed */
{
Proc_6 (Ident_1, &Enum_Loc);
rt_strncpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING", sizeof(Str_2_Loc));
Int_2_Loc = Run_Index;
Int_Glob = Run_Index;
}
}
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
Int_2_Loc = Int_2_Loc * Int_1_Loc;
Int_1_Loc = Int_2_Loc / Int_3_Loc;
Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
/* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
Proc_2 (&Int_1_Loc);
/* Int_1_Loc == 5 */
} /* loop "for Run_Index" */
/**************/
/* Stop timer */
/**************/
End_Time = rt_tick_get(); // Get end tick
printf ("Execution ends\n");
printf ("\n");
printf ("Final values of the variables used in the benchmark:\n");
printf ("\n");
printf ("Int_Glob: %d\n", Int_Glob);
printf (" should be: %d\n", 5);
printf ("Bool_Glob: %d\n", Bool_Glob);
printf (" should be: %d\n", 1);
printf ("Ch_1_Glob: %c\n", Ch_1_Glob);
printf (" should be: %c\n", 'A');
printf ("Ch_2_Glob: %c\n", Ch_2_Glob);
printf (" should be: %c\n", 'B');
printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
printf (" should be: %d\n", 7);
printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
printf (" should be: Number_Of_Runs + 10\n");
printf ("Ptr_Glob->\n");
printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp);
printf (" should be: (implementation-dependent)\n");
printf (" Discr: %d\n", Ptr_Glob->Discr);
printf (" should be: %d\n", 0);
printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
printf (" should be: %d\n", 2);
printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp);
printf (" should be: %d\n", 17);
printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp);
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
printf ("Next_Ptr_Glob->\n");
printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
printf (" should be: (implementation-dependent), same as above\n");
printf (" Discr: %d\n", Next_Ptr_Glob->Discr);
printf (" should be: %d\n", 0);
printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
printf (" should be: %d\n", 1);
printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
printf (" should be: %d\n", 18);
printf (" Str_Comp: %s\n",
Next_Ptr_Glob->variant.var_1.Str_Comp);
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
printf ("Int_1_Loc: %d\n", Int_1_Loc);
printf (" should be: %d\n", 5);
printf ("Int_2_Loc: %d\n", Int_2_Loc);
printf (" should be: %d\n", 13);
printf ("Int_3_Loc: %d\n", Int_3_Loc);
printf (" should be: %d\n", 7);
printf ("Enum_Loc: %d\n", Enum_Loc);
printf (" should be: %d\n", 1);
printf ("Str_1_Loc: %s\n", Str_1_Loc);
printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
printf ("Str_2_Loc: %s\n", Str_2_Loc);
printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
printf ("\n");
User_Time = (End_Time - Begin_Time) / RT_TICK_PER_SECOND;
Microseconds = (float) User_Time * Mic_secs_Per_Second
/ (float) Number_Of_Runs;
Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time;
printf ("Microseconds for one run through Dhrystone: ");
printf ("%6d \n", (int)Microseconds);
printf ("Dhrystones per Second: ");
printf ("%6d \n", (int)Dhrystones_Per_Second);
printf ("Dhrystones MIPS: ");
printf ("%6d \n", (int)(Dhrystones_Per_Second / 1757.0));
printf ("\n");
}
Proc_1 (Ptr_Val_Par)
/******************/
REG Rec_Pointer Ptr_Val_Par;
/* executed once */
{
REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
/* == Ptr_Glob_Next */
/* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
/* corresponds to "rename" in Ada, "with" in Pascal */
structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
Ptr_Val_Par->variant.var_1.Int_Comp = 5;
Next_Record->variant.var_1.Int_Comp
= Ptr_Val_Par->variant.var_1.Int_Comp;
Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
Proc_3 (&Next_Record->Ptr_Comp);
/* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
== Ptr_Glob->Ptr_Comp */
if (Next_Record->Discr == Ident_1)
/* then, executed */
{
Next_Record->variant.var_1.Int_Comp = 6;
Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
&Next_Record->variant.var_1.Enum_Comp);
Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
&Next_Record->variant.var_1.Int_Comp);
}
else /* not executed */
structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
} /* Proc_1 */
Proc_2 (Int_Par_Ref)
/******************/
/* executed once */
/* *Int_Par_Ref == 1, becomes 4 */
One_Fifty *Int_Par_Ref;
{
One_Fifty Int_Loc;
Enumeration Enum_Loc;
Int_Loc = *Int_Par_Ref + 10;
do /* executed once */
if (Ch_1_Glob == 'A')
/* then, executed */
{
Int_Loc -= 1;
*Int_Par_Ref = Int_Loc - Int_Glob;
Enum_Loc = Ident_1;
} /* if */
while (Enum_Loc != Ident_1); /* true */
} /* Proc_2 */
Proc_3 (Ptr_Ref_Par)
/******************/
/* executed once */
/* Ptr_Ref_Par becomes Ptr_Glob */
Rec_Pointer *Ptr_Ref_Par;
{
if (Ptr_Glob != Null)
/* then, executed */
*Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
} /* Proc_3 */
Proc_4 () /* without parameters */
/*******/
/* executed once */
{
Boolean Bool_Loc;
Bool_Loc = Ch_1_Glob == 'A';
Bool_Glob = Bool_Loc | Bool_Glob;
Ch_2_Glob = 'B';
} /* Proc_4 */
Proc_5 () /* without parameters */
/*******/
/* executed once */
{
Ch_1_Glob = 'A';
Bool_Glob = false;
} /* Proc_5 */
/* Procedure for the assignment of structures, */
/* if the C compiler doesn't support this feature */
#ifdef NOSTRUCTASSIGN
memcpy (d, s, l)
register char *d;
register char *s;
register int l;
{
while (l--) *d++ = *s++;
}
#endif
#include <finsh.h>
FINSH_FUNCTION_EXPORT(dhry_test, dhry test);

View File

@ -1,297 +1,297 @@
/*
* File : fs_test.c
* This file is part of 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://openlab.rt-thread.com/license/LICENSE.
*
* Change Logs:
* Date Author Notes
* 2011-01-02 aozima the first version.
* 2011-03-17 aozima fix some bug.
* 2011-03-18 aozima to dynamic thread.
*/
#include <rtthread.h>
#include <dfs_posix.h>
static rt_uint32_t stop_flag = 0;
static rt_thread_t fsrw1_thread = RT_NULL;
static rt_thread_t fsrw2_thread = RT_NULL;
#define fsrw1_fn "/test1.dat"
#define fsrw1_data_len 120 /* Less than 256 */
static void fsrw1_thread_entry(void* parameter)
{
int fd;
int index,length;
rt_uint32_t round;
rt_uint32_t tick_start,tick_end,read_speed,write_speed;
static rt_uint8_t write_data1[fsrw1_data_len];
static rt_uint8_t read_data1[fsrw1_data_len];
round = 1;
while(1)
{
if( stop_flag )
{
rt_kprintf("thread fsrw2 error,thread fsrw1 quit!\r\n");
fsrw1_thread = RT_NULL;
stop_flag = 0;
return;
}
/* creat file */
fd = open(fsrw1_fn, O_WRONLY | O_CREAT | O_TRUNC, 0);
if (fd < 0)
{
rt_kprintf("fsrw1 open file for write failed\n");
stop_flag = 1;
fsrw1_thread = RT_NULL;
return;
}
/* plan write data */
for (index = 0; index < fsrw1_data_len; index ++)
{
write_data1[index] = index;
}
/* write 8000 times */
tick_start = rt_tick_get();
for(index=0; index<8000; index++)
{
length = write(fd, write_data1, fsrw1_data_len);
if (length != fsrw1_data_len)
{
rt_kprintf("fsrw1 write data failed\n");
close(fd);
fsrw1_thread = RT_NULL;
stop_flag = 1;
return;
}
}
tick_end = rt_tick_get();
write_speed = fsrw1_data_len*8000UL*RT_TICK_PER_SECOND/(tick_end-tick_start);
/* close file */
close(fd);
/* open file read only */
fd = open(fsrw1_fn, O_RDONLY, 0);
if (fd < 0)
{
rt_kprintf("fsrw1 open file for read failed\n");
stop_flag = 1;
fsrw1_thread = RT_NULL;
return;
}
/* verify data */
tick_start = rt_tick_get();
for(index=0; index<8000; index++)
{
rt_uint32_t i;
length = read(fd, read_data1, fsrw1_data_len);
if (length != fsrw1_data_len)
{
rt_kprintf("fsrw1 read file failed\r\n");
close(fd);
stop_flag = 1;
fsrw1_thread = RT_NULL;
return;
}
for(i=0; i<fsrw1_data_len; i++)
{
if( read_data1[i] != write_data1[i] )
{
rt_kprintf("fsrw1 data error!\r\n");
close(fd);
stop_flag = 1;
fsrw1_thread = RT_NULL;
return;
}
}
}
tick_end = rt_tick_get();
read_speed = fsrw1_data_len*8000UL*RT_TICK_PER_SECOND/(tick_end-tick_start);
rt_kprintf("thread fsrw1 round %d ",round++);
rt_kprintf("rd:%dbyte/s,wr:%dbyte/s\r\n",read_speed,write_speed);
/* close file */
close(fd);
}
}
#define fsrw2_fn "/test2.dat"
#define fsrw2_data_len 180 /* Less than 256 */
static void fsrw2_thread_entry(void* parameter)
{
int fd;
int index,length;
rt_uint32_t round;
rt_uint32_t tick_start,tick_end,read_speed,write_speed;
static rt_uint8_t write_data2[fsrw2_data_len];
static rt_uint8_t read_data2[fsrw2_data_len];
round = 1;
while(1)
{
if( stop_flag )
{
rt_kprintf("thread fsrw1 error,thread fsrw2 quit!\r\n");
fsrw2_thread = RT_NULL;
stop_flag = 0;
return;
}
/* creat file */
fd = open(fsrw2_fn, O_WRONLY | O_CREAT | O_TRUNC, 0);
if (fd < 0)
{
rt_kprintf("fsrw2 open file for write failed\n");
stop_flag = 1;
fsrw2_thread = RT_NULL;
return;
}
/* plan write data */
for (index = 0; index < fsrw2_data_len; index ++)
{
write_data2[index] = index;
}
/* write 5000 times */
tick_start = rt_tick_get();
for(index=0; index<5000; index++)
{
length = write(fd, write_data2, fsrw2_data_len);
if (length != fsrw2_data_len)
{
rt_kprintf("fsrw2 write data failed\n");
close(fd);
stop_flag = 1;
fsrw2_thread = RT_NULL;
return;
}
}
tick_end = rt_tick_get();
write_speed = fsrw2_data_len*5000UL*RT_TICK_PER_SECOND/(tick_end-tick_start);
/* close file */
close(fd);
/* open file read only */
fd = open(fsrw2_fn, O_RDONLY, 0);
if (fd < 0)
{
rt_kprintf("fsrw2 open file for read failed\n");
stop_flag = 1;
fsrw2_thread = RT_NULL;
return;
}
/* verify data */
tick_start = rt_tick_get();
for(index=0; index<5000; index++)
{
rt_uint32_t i;
length = read(fd, read_data2, fsrw2_data_len);
if (length != fsrw2_data_len)
{
rt_kprintf("fsrw2 read file failed\r\n");
close(fd);
stop_flag = 1;
fsrw2_thread = RT_NULL;
return;
}
for(i=0; i<fsrw2_data_len; i++)
{
if( read_data2[i] != write_data2[i] )
{
rt_kprintf("fsrw2 data error!\r\n");
close(fd);
stop_flag = 1;
fsrw2_thread = RT_NULL;
return;
}
}
}
tick_end = rt_tick_get();
read_speed = fsrw2_data_len*5000UL*RT_TICK_PER_SECOND/(tick_end-tick_start);
rt_kprintf("thread fsrw2 round %d ",round++);
rt_kprintf("rd:%dbyte/s,wr:%dbyte/s\r\n",read_speed,write_speed);
/* close file */
close(fd);
}
}
/** \brief startup filesystem read/write test(multi thread).
*
* \param arg rt_uint32_t [0]startup thread1,[1]startup thread2.
* \return void
*
*/
void fs_test(rt_uint32_t arg)
{
rt_kprintf("arg is : 0x%02X ",arg);
if(arg & 0x01)
{
if( fsrw1_thread != RT_NULL )
{
rt_kprintf("fsrw1_thread already exists!\r\n");
}
else
{
fsrw1_thread = rt_thread_create( "fsrw1",
fsrw1_thread_entry,
RT_NULL,
2048,
RT_THREAD_PRIORITY_MAX-2,
1);
if ( fsrw1_thread != RT_NULL)
{
rt_thread_startup(fsrw1_thread);
}
}
}
if( arg & 0x02)
{
if( fsrw2_thread != RT_NULL )
{
rt_kprintf("fsrw2_thread already exists!\r\n");
}
else
{
fsrw2_thread = rt_thread_create( "fsrw2",
fsrw2_thread_entry,
RT_NULL,
2048,
RT_THREAD_PRIORITY_MAX-2,
1);
if ( fsrw2_thread != RT_NULL)
{
rt_thread_startup(fsrw2_thread);
}
}
}
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(fs_test, file system R/W test. e.g: fs_test(3));
#endif
/*
* File : fs_test.c
* This file is part of 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://openlab.rt-thread.com/license/LICENSE.
*
* Change Logs:
* Date Author Notes
* 2011-01-02 aozima the first version.
* 2011-03-17 aozima fix some bug.
* 2011-03-18 aozima to dynamic thread.
*/
#include <rtthread.h>
#include <dfs_posix.h>
static rt_uint32_t stop_flag = 0;
static rt_thread_t fsrw1_thread = RT_NULL;
static rt_thread_t fsrw2_thread = RT_NULL;
#define fsrw1_fn "/test1.dat"
#define fsrw1_data_len 120 /* Less than 256 */
static void fsrw1_thread_entry(void* parameter)
{
int fd;
int index,length;
rt_uint32_t round;
rt_uint32_t tick_start,tick_end,read_speed,write_speed;
static rt_uint8_t write_data1[fsrw1_data_len];
static rt_uint8_t read_data1[fsrw1_data_len];
round = 1;
while(1)
{
if( stop_flag )
{
rt_kprintf("thread fsrw2 error,thread fsrw1 quit!\r\n");
fsrw1_thread = RT_NULL;
stop_flag = 0;
return;
}
/* creat file */
fd = open(fsrw1_fn, O_WRONLY | O_CREAT | O_TRUNC, 0);
if (fd < 0)
{
rt_kprintf("fsrw1 open file for write failed\n");
stop_flag = 1;
fsrw1_thread = RT_NULL;
return;
}
/* plan write data */
for (index = 0; index < fsrw1_data_len; index ++)
{
write_data1[index] = index;
}
/* write 8000 times */
tick_start = rt_tick_get();
for(index=0; index<8000; index++)
{
length = write(fd, write_data1, fsrw1_data_len);
if (length != fsrw1_data_len)
{
rt_kprintf("fsrw1 write data failed\n");
close(fd);
fsrw1_thread = RT_NULL;
stop_flag = 1;
return;
}
}
tick_end = rt_tick_get();
write_speed = fsrw1_data_len*8000UL*RT_TICK_PER_SECOND/(tick_end-tick_start);
/* close file */
close(fd);
/* open file read only */
fd = open(fsrw1_fn, O_RDONLY, 0);
if (fd < 0)
{
rt_kprintf("fsrw1 open file for read failed\n");
stop_flag = 1;
fsrw1_thread = RT_NULL;
return;
}
/* verify data */
tick_start = rt_tick_get();
for(index=0; index<8000; index++)
{
rt_uint32_t i;
length = read(fd, read_data1, fsrw1_data_len);
if (length != fsrw1_data_len)
{
rt_kprintf("fsrw1 read file failed\r\n");
close(fd);
stop_flag = 1;
fsrw1_thread = RT_NULL;
return;
}
for(i=0; i<fsrw1_data_len; i++)
{
if( read_data1[i] != write_data1[i] )
{
rt_kprintf("fsrw1 data error!\r\n");
close(fd);
stop_flag = 1;
fsrw1_thread = RT_NULL;
return;
}
}
}
tick_end = rt_tick_get();
read_speed = fsrw1_data_len*8000UL*RT_TICK_PER_SECOND/(tick_end-tick_start);
rt_kprintf("thread fsrw1 round %d ",round++);
rt_kprintf("rd:%dbyte/s,wr:%dbyte/s\r\n",read_speed,write_speed);
/* close file */
close(fd);
}
}
#define fsrw2_fn "/test2.dat"
#define fsrw2_data_len 180 /* Less than 256 */
static void fsrw2_thread_entry(void* parameter)
{
int fd;
int index,length;
rt_uint32_t round;
rt_uint32_t tick_start,tick_end,read_speed,write_speed;
static rt_uint8_t write_data2[fsrw2_data_len];
static rt_uint8_t read_data2[fsrw2_data_len];
round = 1;
while(1)
{
if( stop_flag )
{
rt_kprintf("thread fsrw1 error,thread fsrw2 quit!\r\n");
fsrw2_thread = RT_NULL;
stop_flag = 0;
return;
}
/* creat file */
fd = open(fsrw2_fn, O_WRONLY | O_CREAT | O_TRUNC, 0);
if (fd < 0)
{
rt_kprintf("fsrw2 open file for write failed\n");
stop_flag = 1;
fsrw2_thread = RT_NULL;
return;
}
/* plan write data */
for (index = 0; index < fsrw2_data_len; index ++)
{
write_data2[index] = index;
}
/* write 5000 times */
tick_start = rt_tick_get();
for(index=0; index<5000; index++)
{
length = write(fd, write_data2, fsrw2_data_len);
if (length != fsrw2_data_len)
{
rt_kprintf("fsrw2 write data failed\n");
close(fd);
stop_flag = 1;
fsrw2_thread = RT_NULL;
return;
}
}
tick_end = rt_tick_get();
write_speed = fsrw2_data_len*5000UL*RT_TICK_PER_SECOND/(tick_end-tick_start);
/* close file */
close(fd);
/* open file read only */
fd = open(fsrw2_fn, O_RDONLY, 0);
if (fd < 0)
{
rt_kprintf("fsrw2 open file for read failed\n");
stop_flag = 1;
fsrw2_thread = RT_NULL;
return;
}
/* verify data */
tick_start = rt_tick_get();
for(index=0; index<5000; index++)
{
rt_uint32_t i;
length = read(fd, read_data2, fsrw2_data_len);
if (length != fsrw2_data_len)
{
rt_kprintf("fsrw2 read file failed\r\n");
close(fd);
stop_flag = 1;
fsrw2_thread = RT_NULL;
return;
}
for(i=0; i<fsrw2_data_len; i++)
{
if( read_data2[i] != write_data2[i] )
{
rt_kprintf("fsrw2 data error!\r\n");
close(fd);
stop_flag = 1;
fsrw2_thread = RT_NULL;
return;
}
}
}
tick_end = rt_tick_get();
read_speed = fsrw2_data_len*5000UL*RT_TICK_PER_SECOND/(tick_end-tick_start);
rt_kprintf("thread fsrw2 round %d ",round++);
rt_kprintf("rd:%dbyte/s,wr:%dbyte/s\r\n",read_speed,write_speed);
/* close file */
close(fd);
}
}
/** \brief startup filesystem read/write test(multi thread).
*
* \param arg rt_uint32_t [0]startup thread1,[1]startup thread2.
* \return void
*
*/
void fs_test(rt_uint32_t arg)
{
rt_kprintf("arg is : 0x%02X ",arg);
if(arg & 0x01)
{
if( fsrw1_thread != RT_NULL )
{
rt_kprintf("fsrw1_thread already exists!\r\n");
}
else
{
fsrw1_thread = rt_thread_create( "fsrw1",
fsrw1_thread_entry,
RT_NULL,
2048,
RT_THREAD_PRIORITY_MAX-2,
1);
if ( fsrw1_thread != RT_NULL)
{
rt_thread_startup(fsrw1_thread);
}
}
}
if( arg & 0x02)
{
if( fsrw2_thread != RT_NULL )
{
rt_kprintf("fsrw2_thread already exists!\r\n");
}
else
{
fsrw2_thread = rt_thread_create( "fsrw2",
fsrw2_thread_entry,
RT_NULL,
2048,
RT_THREAD_PRIORITY_MAX-2,
1);
if ( fsrw2_thread != RT_NULL)
{
rt_thread_startup(fsrw2_thread);
}
}
}
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(fs_test, file system R/W test. e.g: fs_test(3));
#endif

View File

@ -1,105 +1,105 @@
#include <stdint.h>
#include <rthw.h>
#include <rtthread.h>
#define printf rt_kprintf
void mem_test(uint32_t address, uint32_t size )
{
uint32_t i;
printf("memtest,address: 0x%08X size: 0x%08X\r\n", address, size);
/**< 8bit test */
{
uint8_t * p_uint8_t = (uint8_t *)address;
for(i=0; i<size/sizeof(uint8_t); i++)
{
*p_uint8_t++ = (uint8_t)i;
}
p_uint8_t = (uint8_t *)address;
for(i=0; i<size/sizeof(uint8_t); i++)
{
if( *p_uint8_t != (uint8_t)i )
{
printf("8bit test fail @ 0x%08X\r\nsystem halt!!!!!",(uint32_t)p_uint8_t);
while(1);
}
p_uint8_t++;
}
printf("8bit test pass!!\r\n");
}
/**< 16bit test */
{
uint16_t * p_uint16_t = (uint16_t *)address;
for(i=0; i<size/sizeof(uint16_t); i++)
{
*p_uint16_t++ = (uint16_t)i;
}
p_uint16_t = (uint16_t *)address;
for(i=0; i<size/sizeof(uint16_t); i++)
{
if( *p_uint16_t != (uint16_t)i )
{
printf("16bit test fail @ 0x%08X\r\nsystem halt!!!!!",(uint32_t)p_uint16_t);
while(1);
}
p_uint16_t++;
}
printf("16bit test pass!!\r\n");
}
/**< 32bit test */
{
uint32_t * p_uint32_t = (uint32_t *)address;
for(i=0; i<size/sizeof(uint32_t); i++)
{
*p_uint32_t++ = (uint32_t)i;
}
p_uint32_t = (uint32_t *)address;
for(i=0; i<size/sizeof(uint32_t); i++)
{
if( *p_uint32_t != (uint32_t)i )
{
printf("32bit test fail @ 0x%08X\r\nsystem halt!!!!!",(uint32_t)p_uint32_t);
while(1);
}
p_uint32_t++;
}
printf("32bit test pass!!\r\n");
}
/**< 32bit Loopback test */
{
uint32_t * p_uint32_t = (uint32_t *)address;
for(i=0; i<size/sizeof(uint32_t); i++)
{
*p_uint32_t = (uint32_t)p_uint32_t;
*p_uint32_t++;
}
p_uint32_t = (uint32_t *)address;
for(i=0; i<size/sizeof(uint32_t); i++)
{
if( *p_uint32_t != (uint32_t)p_uint32_t )
{
printf("32bit Loopback test fail @ 0x%08X", (uint32_t)p_uint32_t);
printf(" data:0x%08X \r\n", (uint32_t)*p_uint32_t);
printf("system halt!!!!!",(uint32_t)p_uint32_t);
while(1);
}
p_uint32_t++;
}
printf("32bit Loopback test pass!!\r\n");
}
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(mem_test, mem_test(0xA0000000, 0x00100000) );
#endif
#include <stdint.h>
#include <rthw.h>
#include <rtthread.h>
#define printf rt_kprintf
void mem_test(uint32_t address, uint32_t size )
{
uint32_t i;
printf("memtest,address: 0x%08X size: 0x%08X\r\n", address, size);
/**< 8bit test */
{
uint8_t * p_uint8_t = (uint8_t *)address;
for(i=0; i<size/sizeof(uint8_t); i++)
{
*p_uint8_t++ = (uint8_t)i;
}
p_uint8_t = (uint8_t *)address;
for(i=0; i<size/sizeof(uint8_t); i++)
{
if( *p_uint8_t != (uint8_t)i )
{
printf("8bit test fail @ 0x%08X\r\nsystem halt!!!!!",(uint32_t)p_uint8_t);
while(1);
}
p_uint8_t++;
}
printf("8bit test pass!!\r\n");
}
/**< 16bit test */
{
uint16_t * p_uint16_t = (uint16_t *)address;
for(i=0; i<size/sizeof(uint16_t); i++)
{
*p_uint16_t++ = (uint16_t)i;
}
p_uint16_t = (uint16_t *)address;
for(i=0; i<size/sizeof(uint16_t); i++)
{
if( *p_uint16_t != (uint16_t)i )
{
printf("16bit test fail @ 0x%08X\r\nsystem halt!!!!!",(uint32_t)p_uint16_t);
while(1);
}
p_uint16_t++;
}
printf("16bit test pass!!\r\n");
}
/**< 32bit test */
{
uint32_t * p_uint32_t = (uint32_t *)address;
for(i=0; i<size/sizeof(uint32_t); i++)
{
*p_uint32_t++ = (uint32_t)i;
}
p_uint32_t = (uint32_t *)address;
for(i=0; i<size/sizeof(uint32_t); i++)
{
if( *p_uint32_t != (uint32_t)i )
{
printf("32bit test fail @ 0x%08X\r\nsystem halt!!!!!",(uint32_t)p_uint32_t);
while(1);
}
p_uint32_t++;
}
printf("32bit test pass!!\r\n");
}
/**< 32bit Loopback test */
{
uint32_t * p_uint32_t = (uint32_t *)address;
for(i=0; i<size/sizeof(uint32_t); i++)
{
*p_uint32_t = (uint32_t)p_uint32_t;
*p_uint32_t++;
}
p_uint32_t = (uint32_t *)address;
for(i=0; i<size/sizeof(uint32_t); i++)
{
if( *p_uint32_t != (uint32_t)p_uint32_t )
{
printf("32bit Loopback test fail @ 0x%08X", (uint32_t)p_uint32_t);
printf(" data:0x%08X \r\n", (uint32_t)*p_uint32_t);
printf("system halt!!!!!",(uint32_t)p_uint32_t);
while(1);
}
p_uint32_t++;
}
printf("32bit Loopback test pass!!\r\n");
}
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(mem_test, mem_test(0xA0000000, 0x00100000) );
#endif

View File

@ -1,282 +1,282 @@
/*
* Net Test Utilities for RT-Thread
*/
#include <rtthread.h>
#include <finsh.h>
#include <lwip/api.h>
#include <lwip/sockets.h>
/*
* UDP echo server
*/
#define UDP_ECHO_PORT 7
rt_thread_t udpecho_tid = RT_NULL;
void udpecho_entry(void *parameter)
{
struct netconn *conn;
struct netbuf *buf;
struct ip_addr *addr;
unsigned short port;
conn = netconn_new(NETCONN_UDP);
netconn_bind(conn, IP_ADDR_ANY, 7);
while(1)
{
/* received data to buffer */
buf = netconn_recv(conn);
addr = netbuf_fromaddr(buf);
port = netbuf_fromport(buf);
/* send the data to buffer */
netconn_connect(conn, addr, port);
/* reset address, and send to client */
buf->addr = RT_NULL;
netconn_send(conn, buf);
/* release buffer */
netbuf_delete(buf);
}
}
/*
* UDP socket echo server
*/
#define UDP_SOCKET_ECHO_PORT 700
#define UDP_SOCKET_BUFFER_SIZE 4096
rt_thread_t udpecho_socket_tid = RT_NULL;
void udpecho_socket_entry(void *parameter)
{
int sock;
int bytes_read;
char *recv_data;
rt_uint32_t addr_len;
struct sockaddr_in server_addr, client_addr;
/* allocate the data buffer */
recv_data = rt_malloc(UDP_SOCKET_BUFFER_SIZE);
if (recv_data == RT_NULL)
{
/* no memory yet */
rt_kprintf("no memory\n");
goto _exit;
}
/* create a UDP socket */
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
rt_kprintf("create socket error\n");
goto _exit;
}
/* initialize server address */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(UDP_SOCKET_ECHO_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
rt_memset(&(server_addr.sin_zero),0, sizeof(server_addr.sin_zero));
/* bind socket to server address */
if (bind(sock,(struct sockaddr *)&server_addr,
sizeof(struct sockaddr)) == -1)
{
/* bind failed */
rt_kprintf("bind error\n");
goto _exit;
}
addr_len = sizeof(struct sockaddr);
while (1)
{
/* try to receive from UDP socket */
bytes_read = recvfrom(sock, recv_data, UDP_SOCKET_BUFFER_SIZE, 0,
(struct sockaddr *)&client_addr, &addr_len);
/* send back */
sendto(sock, recv_data, bytes_read, 0,
(struct sockaddr *)&client_addr, addr_len);
}
_exit:
rt_free(recv_data);
return;
}
/*
* TCP echo server
*/
#define TCP_ECHO_PORT 7
rt_thread_t tcpecho_tid = RT_NULL;
void tcpecho_entry(void *parameter)
{
struct netconn *conn, *newconn;
err_t err;
/* Create a new connection identifier. */
conn = netconn_new(NETCONN_TCP);
/* Bind connection to well known port number 7. */
netconn_bind(conn, NULL, TCP_ECHO_PORT);
/* Tell connection to go into listening mode. */
netconn_listen(conn);
while(1)
{
/* Grab new connection. */
newconn = netconn_accept(conn);
/* Process the new connection. */
if(newconn != NULL)
{
struct netbuf *buf;
void *data;
u16_t len;
while((buf = netconn_recv(newconn)) != NULL)
{
do
{
netbuf_data(buf, &data, &len);
err = netconn_write(newconn, data, len, NETCONN_COPY);
if(err != ERR_OK){}
}
while(netbuf_next(buf) >= 0);
netbuf_delete(buf);
}
/* Close connection and discard connection identifier. */
netconn_delete(newconn);
}
}
}
/*
* TCP socket echo server
*/
#define TCP_SOCKET_ECHO_PORT 700
#define TCP_SOCKET_BUFFER_SIZE 4096
rt_thread_t tcpecho_socket_tid = RT_NULL;
void tcpecho_socket_entry(void *parameter)
{
char *recv_data;
rt_uint32_t sin_size;
int sock = -1, connected, bytes_received;
struct sockaddr_in server_addr, client_addr;
recv_data = rt_malloc(TCP_SOCKET_BUFFER_SIZE);
if (recv_data == RT_NULL)
{
rt_kprintf("no memory\n");
goto _exit;
}
/* create a TCP socket */
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
rt_kprintf("create socket error\n");
goto _exit;
}
/* initialize server address */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(TCP_SOCKET_ECHO_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
rt_memset(&(server_addr.sin_zero),8, sizeof(server_addr.sin_zero));
/* bind to server address */
if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
{
rt_kprintf("bind address failed\n");
goto _exit;
}
/* listen */
if (listen(sock, 5) == -1)
{
rt_kprintf("listen error\n");
goto _exit;
}
sin_size = sizeof(struct sockaddr_in);
while(1)
{
/* accept client connected */
connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size);
if (connected > 0)
{
int timeout;
/* set timeout option */
timeout = 5000; /* 5second */
setsockopt(connected, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
/* handle this client */
while (1)
{
/* receive data from this connection */
bytes_received = recv(connected,recv_data, TCP_SOCKET_BUFFER_SIZE, 0);
if (bytes_received <= 0)
{
rt_kprintf("close client connection, errno: %d, socket error: %d\n",
rt_get_errno(),
lwip_get_error());
/* connection closed. */
lwip_close(connected);
break;
}
/* send data to client */
send(connected, recv_data, bytes_received, 0);
}
}
}
_exit:
/* close socket */
if (sock != -1) lwip_close(sock);
rt_free(recv_data);
return ;
}
/*
* NetIO TCP server
*/
/* network test utilities entry */
void net_test(void)
{
/* start UDP echo server */
if (udpecho_tid == RT_NULL)
{
udpecho_tid = rt_thread_create("uecho",
udpecho_entry, RT_NULL,
512, RT_THREAD_PRIORITY_MAX/2, 5);
if (udpecho_tid != RT_NULL)
rt_thread_startup(udpecho_tid);
}
if (udpecho_socket_tid == RT_NULL)
{
udpecho_socket_tid = rt_thread_create("uecho_s",
udpecho_socket_entry, RT_NULL,
512, RT_THREAD_PRIORITY_MAX/2 + 1, 5);
if (udpecho_socket_tid != RT_NULL)
rt_thread_startup(udpecho_socket_tid);
}
if (tcpecho_tid == RT_NULL)
{
tcpecho_tid = rt_thread_create("techo",
tcpecho_entry, RT_NULL,
512, RT_THREAD_PRIORITY_MAX/2 + 2, 5);
if (tcpecho_tid != RT_NULL)
rt_thread_startup(tcpecho_tid);
}
if (tcpecho_socket_tid == RT_NULL)
{
tcpecho_socket_tid = rt_thread_create("techo_s",
tcpecho_socket_entry, RT_NULL,
512, RT_THREAD_PRIORITY_MAX/2 + 3, 5);
if (tcpecho_socket_tid != RT_NULL)
rt_thread_startup(tcpecho_socket_tid);
}
}
FINSH_FUNCTION_EXPORT(net_test, network test);
/*
* Net Test Utilities for RT-Thread
*/
#include <rtthread.h>
#include <finsh.h>
#include <lwip/api.h>
#include <lwip/sockets.h>
/*
* UDP echo server
*/
#define UDP_ECHO_PORT 7
rt_thread_t udpecho_tid = RT_NULL;
void udpecho_entry(void *parameter)
{
struct netconn *conn;
struct netbuf *buf;
struct ip_addr *addr;
unsigned short port;
conn = netconn_new(NETCONN_UDP);
netconn_bind(conn, IP_ADDR_ANY, 7);
while(1)
{
/* received data to buffer */
buf = netconn_recv(conn);
addr = netbuf_fromaddr(buf);
port = netbuf_fromport(buf);
/* send the data to buffer */
netconn_connect(conn, addr, port);
/* reset address, and send to client */
buf->addr = RT_NULL;
netconn_send(conn, buf);
/* release buffer */
netbuf_delete(buf);
}
}
/*
* UDP socket echo server
*/
#define UDP_SOCKET_ECHO_PORT 700
#define UDP_SOCKET_BUFFER_SIZE 4096
rt_thread_t udpecho_socket_tid = RT_NULL;
void udpecho_socket_entry(void *parameter)
{
int sock;
int bytes_read;
char *recv_data;
rt_uint32_t addr_len;
struct sockaddr_in server_addr, client_addr;
/* allocate the data buffer */
recv_data = rt_malloc(UDP_SOCKET_BUFFER_SIZE);
if (recv_data == RT_NULL)
{
/* no memory yet */
rt_kprintf("no memory\n");
goto _exit;
}
/* create a UDP socket */
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
rt_kprintf("create socket error\n");
goto _exit;
}
/* initialize server address */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(UDP_SOCKET_ECHO_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
rt_memset(&(server_addr.sin_zero),0, sizeof(server_addr.sin_zero));
/* bind socket to server address */
if (bind(sock,(struct sockaddr *)&server_addr,
sizeof(struct sockaddr)) == -1)
{
/* bind failed */
rt_kprintf("bind error\n");
goto _exit;
}
addr_len = sizeof(struct sockaddr);
while (1)
{
/* try to receive from UDP socket */
bytes_read = recvfrom(sock, recv_data, UDP_SOCKET_BUFFER_SIZE, 0,
(struct sockaddr *)&client_addr, &addr_len);
/* send back */
sendto(sock, recv_data, bytes_read, 0,
(struct sockaddr *)&client_addr, addr_len);
}
_exit:
rt_free(recv_data);
return;
}
/*
* TCP echo server
*/
#define TCP_ECHO_PORT 7
rt_thread_t tcpecho_tid = RT_NULL;
void tcpecho_entry(void *parameter)
{
struct netconn *conn, *newconn;
err_t err;
/* Create a new connection identifier. */
conn = netconn_new(NETCONN_TCP);
/* Bind connection to well known port number 7. */
netconn_bind(conn, NULL, TCP_ECHO_PORT);
/* Tell connection to go into listening mode. */
netconn_listen(conn);
while(1)
{
/* Grab new connection. */
newconn = netconn_accept(conn);
/* Process the new connection. */
if(newconn != NULL)
{
struct netbuf *buf;
void *data;
u16_t len;
while((buf = netconn_recv(newconn)) != NULL)
{
do
{
netbuf_data(buf, &data, &len);
err = netconn_write(newconn, data, len, NETCONN_COPY);
if(err != ERR_OK){}
}
while(netbuf_next(buf) >= 0);
netbuf_delete(buf);
}
/* Close connection and discard connection identifier. */
netconn_delete(newconn);
}
}
}
/*
* TCP socket echo server
*/
#define TCP_SOCKET_ECHO_PORT 700
#define TCP_SOCKET_BUFFER_SIZE 4096
rt_thread_t tcpecho_socket_tid = RT_NULL;
void tcpecho_socket_entry(void *parameter)
{
char *recv_data;
rt_uint32_t sin_size;
int sock = -1, connected, bytes_received;
struct sockaddr_in server_addr, client_addr;
recv_data = rt_malloc(TCP_SOCKET_BUFFER_SIZE);
if (recv_data == RT_NULL)
{
rt_kprintf("no memory\n");
goto _exit;
}
/* create a TCP socket */
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
rt_kprintf("create socket error\n");
goto _exit;
}
/* initialize server address */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(TCP_SOCKET_ECHO_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
rt_memset(&(server_addr.sin_zero),8, sizeof(server_addr.sin_zero));
/* bind to server address */
if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
{
rt_kprintf("bind address failed\n");
goto _exit;
}
/* listen */
if (listen(sock, 5) == -1)
{
rt_kprintf("listen error\n");
goto _exit;
}
sin_size = sizeof(struct sockaddr_in);
while(1)
{
/* accept client connected */
connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size);
if (connected > 0)
{
int timeout;
/* set timeout option */
timeout = 5000; /* 5second */
setsockopt(connected, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
/* handle this client */
while (1)
{
/* receive data from this connection */
bytes_received = recv(connected,recv_data, TCP_SOCKET_BUFFER_SIZE, 0);
if (bytes_received <= 0)
{
rt_kprintf("close client connection, errno: %d, socket error: %d\n",
rt_get_errno(),
lwip_get_error());
/* connection closed. */
lwip_close(connected);
break;
}
/* send data to client */
send(connected, recv_data, bytes_received, 0);
}
}
}
_exit:
/* close socket */
if (sock != -1) lwip_close(sock);
rt_free(recv_data);
return ;
}
/*
* NetIO TCP server
*/
/* network test utilities entry */
void net_test(void)
{
/* start UDP echo server */
if (udpecho_tid == RT_NULL)
{
udpecho_tid = rt_thread_create("uecho",
udpecho_entry, RT_NULL,
512, RT_THREAD_PRIORITY_MAX/2, 5);
if (udpecho_tid != RT_NULL)
rt_thread_startup(udpecho_tid);
}
if (udpecho_socket_tid == RT_NULL)
{
udpecho_socket_tid = rt_thread_create("uecho_s",
udpecho_socket_entry, RT_NULL,
512, RT_THREAD_PRIORITY_MAX/2 + 1, 5);
if (udpecho_socket_tid != RT_NULL)
rt_thread_startup(udpecho_socket_tid);
}
if (tcpecho_tid == RT_NULL)
{
tcpecho_tid = rt_thread_create("techo",
tcpecho_entry, RT_NULL,
512, RT_THREAD_PRIORITY_MAX/2 + 2, 5);
if (tcpecho_tid != RT_NULL)
rt_thread_startup(tcpecho_tid);
}
if (tcpecho_socket_tid == RT_NULL)
{
tcpecho_socket_tid = rt_thread_create("techo_s",
tcpecho_socket_entry, RT_NULL,
512, RT_THREAD_PRIORITY_MAX/2 + 3, 5);
if (tcpecho_socket_tid != RT_NULL)
rt_thread_startup(tcpecho_socket_tid);
}
}
FINSH_FUNCTION_EXPORT(net_test, network test);

View File

@ -57,11 +57,11 @@ extern "C" {
#define AT91C_TC2_IER (AT91_REG(0xFFFA00A4)) /* TC2 Interrupt Enable Register */
#define AT91C_TC2_SR (AT91_REG(0xFFFA00A0)) /* TC2 Status Register */
/* ========== Register definition for PITC peripheral ========== */
#define AT91C_PITC_PIVR (AT91_REG(0xFFFFFD38)) /* PITC Period Interval Value Register */
#define AT91C_PITC_PISR (AT91_REG(0xFFFFFD34)) /* PITC Period Interval Status Register */
#define AT91C_PITC_PIIR (AT91_REG(0xFFFFFD3C)) /* PITC Period Interval Image Register */
#define AT91C_PITC_PIMR (AT91_REG(0xFFFFFD30)) /* PITC Period Interval Mode Register */
/* ========== Register definition for PITC peripheral ========== */
#define AT91C_PITC_PIVR (AT91_REG(0xFFFFFD38)) /* PITC Period Interval Value Register */
#define AT91C_PITC_PISR (AT91_REG(0xFFFFFD34)) /* PITC Period Interval Status Register */
#define AT91C_PITC_PIIR (AT91_REG(0xFFFFFD3C)) /* PITC Period Interval Image Register */
#define AT91C_PITC_PIMR (AT91_REG(0xFFFFFD30)) /* PITC Period Interval Mode Register */
/* ========== Register definition for UDP peripheral ========== */
#define AT91C_UDP_NUM (AT91_REG(0xFFFB0000)) /* UDP Frame Number Register */
@ -241,42 +241,42 @@ extern "C" {
#define AT91C_PMC_SR (AT91_REG(0xFFFFFC68)) /* PMC Status Register */
#define AT91C_PMC_IMR (AT91_REG(0xFFFFFC6C)) /* PMC Interrupt Mask Register */
/******************************************************************************/
/* PERIPHERAL ID DEFINITIONS FOR AT91SAM7S64 */
/******************************************************************************/
#define AT91C_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */
#define AT91C_ID_SYS 1 /* System Peripheral */
#define AT91C_ID_PIOA 2 /* Parallel IO Controller A */
/******************************************************************************/
/* PERIPHERAL ID DEFINITIONS FOR AT91SAM7S64 */
/******************************************************************************/
#define AT91C_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */
#define AT91C_ID_SYS 1 /* System Peripheral */
#define AT91C_ID_PIOA 2 /* Parallel IO Controller A */
#define AT91C_ID_PIOB 3 /* Parallel IO Controller B */
#define AT91C_ID_ADC 4 /* Analog-to-Digital Converter */
#define AT91C_ID_SPI 5 /* Serial Peripheral Interface */
#define AT91C_ID_US0 6 /* USART 0 */
#define AT91C_ID_US1 7 /* USART 1 */
#define AT91C_ID_SSC 8 /* Serial Synchronous Controller */
#define AT91C_ID_TWI 9 /* Two-Wire Interface */
#define AT91C_ID_PWMC 10 /* PWM Controller */
#define AT91C_ID_UDP 11 /* USB Device Port */
#define AT91C_ID_TC0 12 /* Timer Counter 0 */
#define AT91C_ID_TC1 13 /* Timer Counter 1 */
#define AT91C_ID_TC2 14 /* Timer Counter 2 */
#define AT91C_ID_15 15 /* Reserved */
#define AT91C_ID_16 16 /* Reserved */
#define AT91C_ID_17 17 /* Reserved */
#define AT91C_ID_18 18 /* Reserved */
#define AT91C_ID_19 19 /* Reserved */
#define AT91C_ID_20 20 /* Reserved */
#define AT91C_ID_21 21 /* Reserved */
#define AT91C_ID_22 22 /* Reserved */
#define AT91C_ID_23 23 /* Reserved */
#define AT91C_ID_24 24 /* Reserved */
#define AT91C_ID_25 25 /* Reserved */
#define AT91C_ID_26 26 /* Reserved */
#define AT91C_ID_27 27 /* Reserved */
#define AT91C_ID_28 28 /* Reserved */
#define AT91C_ID_29 29 /* Reserved */
#define AT91C_ID_IRQ0 30 /* Advanced Interrupt Controller (IRQ0) */
#define AT91C_ID_IRQ1 31 /* Advanced Interrupt Controller (IRQ1) */
#define AT91C_ALL_INT 0xC0007FF7 /* ALL VALID INTERRUPTS */
#define AT91C_ID_ADC 4 /* Analog-to-Digital Converter */
#define AT91C_ID_SPI 5 /* Serial Peripheral Interface */
#define AT91C_ID_US0 6 /* USART 0 */
#define AT91C_ID_US1 7 /* USART 1 */
#define AT91C_ID_SSC 8 /* Serial Synchronous Controller */
#define AT91C_ID_TWI 9 /* Two-Wire Interface */
#define AT91C_ID_PWMC 10 /* PWM Controller */
#define AT91C_ID_UDP 11 /* USB Device Port */
#define AT91C_ID_TC0 12 /* Timer Counter 0 */
#define AT91C_ID_TC1 13 /* Timer Counter 1 */
#define AT91C_ID_TC2 14 /* Timer Counter 2 */
#define AT91C_ID_15 15 /* Reserved */
#define AT91C_ID_16 16 /* Reserved */
#define AT91C_ID_17 17 /* Reserved */
#define AT91C_ID_18 18 /* Reserved */
#define AT91C_ID_19 19 /* Reserved */
#define AT91C_ID_20 20 /* Reserved */
#define AT91C_ID_21 21 /* Reserved */
#define AT91C_ID_22 22 /* Reserved */
#define AT91C_ID_23 23 /* Reserved */
#define AT91C_ID_24 24 /* Reserved */
#define AT91C_ID_25 25 /* Reserved */
#define AT91C_ID_26 26 /* Reserved */
#define AT91C_ID_27 27 /* Reserved */
#define AT91C_ID_28 28 /* Reserved */
#define AT91C_ID_29 29 /* Reserved */
#define AT91C_ID_IRQ0 30 /* Advanced Interrupt Controller (IRQ0) */
#define AT91C_ID_IRQ1 31 /* Advanced Interrupt Controller (IRQ1) */
#define AT91C_ALL_INT 0xC0007FF7 /* ALL VALID INTERRUPTS */
/*****************************/
/* CPU Mode */

View File

@ -12,12 +12,12 @@
; * 2009-01-20 Bernard first version
; */
NOINT EQU 0xc0 ; disable interrupt in psr
NOINT EQU 0xc0 ; disable interrupt in psr
AREA |.text|, CODE, READONLY, ALIGN=2
ARM
REQUIRE8
PRESERVE8
AREA |.text|, CODE, READONLY, ALIGN=2
ARM
REQUIRE8
PRESERVE8
;/*
; * rt_base_t rt_hw_interrupt_disable();
@ -26,16 +26,16 @@ rt_hw_interrupt_disable PROC
EXPORT rt_hw_interrupt_disable
MRS r0, cpsr
ORR r1, r0, #NOINT
MSR cpsr_c, r1
MSR cpsr_c, r1
BX lr
ENDP
ENDP
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
rt_hw_interrupt_enable PROC
EXPORT rt_hw_interrupt_enable
MSR cpsr_c, r0
MSR cpsr_c, r0
BX lr
ENDP
@ -63,7 +63,7 @@ rt_hw_context_switch PROC
MSR cpsr_cxsf, r4
LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
ENDP
ENDP
;/*
; * void rt_hw_context_switch_to(rt_uint32 to);
@ -79,14 +79,14 @@ rt_hw_context_switch_to PROC
MSR cpsr_cxsf, r4
LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
ENDP
ENDP
;/*
; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
; */
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
IMPORT rt_interrupt_to_thread
rt_hw_context_switch_interrupt PROC
EXPORT rt_hw_context_switch_interrupt
@ -100,8 +100,8 @@ rt_hw_context_switch_interrupt PROC
STR r0, [r2]
_reswitch
LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
STR r1, [r2]
STR r1, [r2]
BX lr
ENDP
ENDP
END

View File

@ -56,11 +56,11 @@ void rt_hw_interrupt_init()
* @param vector the interrupt number
*/
void rt_hw_interrupt_mask(int vector)
{
{
/* disable interrupt */
AT91C_AIC_IDCR = 1 << vector;
/* clear interrupt */
AT91C_AIC_IDCR = 1 << vector;
/* clear interrupt */
AT91C_AIC_ICCR = 1 << vector;
}

View File

@ -9,7 +9,7 @@
*
* Change Logs:
* Date Author Notes
* 2006-08-23 Bernard first version
* 2006-08-23 Bernard first version
* 2009-05-14 Bernard add RT-THread device interface
*/
@ -17,142 +17,142 @@
#include <rtthread.h>
#include "AT91SAM7S.h"
#include "serial.h"
#include "serial.h"
/**
* @addtogroup AT91SAM7
*/
/*@{*/
typedef volatile rt_uint32_t REG32;
struct rt_at91serial_hw
{
REG32 US_CR; // Control Register
REG32 US_MR; // Mode Register
REG32 US_IER; // Interrupt Enable Register
REG32 US_IDR; // Interrupt Disable Register
REG32 US_IMR; // Interrupt Mask Register
REG32 US_CSR; // Channel Status Register
REG32 US_RHR; // Receiver Holding Register
REG32 US_THR; // Transmitter Holding Register
REG32 US_BRGR; // Baud Rate Generator Register
REG32 US_RTOR; // Receiver Time-out Register
REG32 US_TTGR; // Transmitter Time-guard Register
REG32 Reserved0[5]; //
REG32 US_FIDI; // FI_DI_Ratio Register
REG32 US_NER; // Nb Errors Register
REG32 Reserved1[1]; //
REG32 US_IF; // IRDA_FILTER Register
REG32 Reserved2[44]; //
REG32 US_RPR; // Receive Pointer Register
REG32 US_RCR; // Receive Counter Register
REG32 US_TPR; // Transmit Pointer Register
REG32 US_TCR; // Transmit Counter Register
REG32 US_RNPR; // Receive Next Pointer Register
REG32 US_RNCR; // Receive Next Counter Register
REG32 US_TNPR; // Transmit Next Pointer Register
REG32 US_TNCR; // Transmit Next Counter Register
REG32 US_PTCR; // PDC Transfer Control Register
REG32 US_PTSR; // PDC Transfer Status Register
};
struct rt_at91serial
{
struct rt_device parent;
struct rt_at91serial_hw* hw_base;
rt_uint16_t peripheral_id;
rt_uint32_t baudrate;
/* reception field */
rt_uint16_t save_index, read_index;
rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
};
#ifdef RT_USING_UART1
struct rt_at91serial serial1;
#endif
#ifdef RT_USING_UART2
struct rt_at91serial serial2;
#endif
static void rt_hw_serial_isr(int irqno)
{
rt_base_t level;
struct rt_device* device;
struct rt_at91serial* serial = RT_NULL;
if (irqno == AT91C_ID_US0)
{
#ifdef RT_USING_UART1
/* serial 1 */
serial = &serial1;
#endif
}
else if (irqno == AT91C_ID_US1)
{
#ifdef RT_USING_UART2
/* serial 2 */
serial = &serial2;
#endif
}
RT_ASSERT(serial != RT_NULL);
/* get generic device object */
device = (rt_device_t)serial;
/* disable interrupt */
level = rt_hw_interrupt_disable();
/* get received character */
serial->rx_buffer[serial->save_index] = serial->hw_base->US_RHR;
/* move to next position */
serial->save_index ++;
if (serial->save_index >= RT_UART_RX_BUFFER_SIZE)
serial->save_index = 0;
/* if the next position is read index, discard this 'read char' */
if (serial->save_index == serial->read_index)
{
serial->read_index ++;
if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
serial->read_index = 0;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
/* indicate to upper layer application */
if (device->rx_indicate != RT_NULL)
device->rx_indicate(device, 1);
/* ack interrupt */
AT91C_AIC_EOICR = 1;
}
static rt_err_t rt_serial_init (rt_device_t dev)
{
rt_uint32_t bd;
struct rt_at91serial* serial = (struct rt_at91serial*) dev;
RT_ASSERT(serial != RT_NULL);
/* must be US0 or US1 */
RT_ASSERT(((serial->peripheral_id == AT91C_ID_US0) ||
(serial->peripheral_id == AT91C_ID_US1)));
/* Enable Clock for USART */
AT91C_PMC_PCER = 1 << serial->peripheral_id;
/*@{*/
typedef volatile rt_uint32_t REG32;
struct rt_at91serial_hw
{
REG32 US_CR; // Control Register
REG32 US_MR; // Mode Register
REG32 US_IER; // Interrupt Enable Register
REG32 US_IDR; // Interrupt Disable Register
REG32 US_IMR; // Interrupt Mask Register
REG32 US_CSR; // Channel Status Register
REG32 US_RHR; // Receiver Holding Register
REG32 US_THR; // Transmitter Holding Register
REG32 US_BRGR; // Baud Rate Generator Register
REG32 US_RTOR; // Receiver Time-out Register
REG32 US_TTGR; // Transmitter Time-guard Register
REG32 Reserved0[5]; //
REG32 US_FIDI; // FI_DI_Ratio Register
REG32 US_NER; // Nb Errors Register
REG32 Reserved1[1]; //
REG32 US_IF; // IRDA_FILTER Register
REG32 Reserved2[44]; //
REG32 US_RPR; // Receive Pointer Register
REG32 US_RCR; // Receive Counter Register
REG32 US_TPR; // Transmit Pointer Register
REG32 US_TCR; // Transmit Counter Register
REG32 US_RNPR; // Receive Next Pointer Register
REG32 US_RNCR; // Receive Next Counter Register
REG32 US_TNPR; // Transmit Next Pointer Register
REG32 US_TNCR; // Transmit Next Counter Register
REG32 US_PTCR; // PDC Transfer Control Register
REG32 US_PTSR; // PDC Transfer Status Register
};
struct rt_at91serial
{
struct rt_device parent;
struct rt_at91serial_hw* hw_base;
rt_uint16_t peripheral_id;
rt_uint32_t baudrate;
/* reception field */
rt_uint16_t save_index, read_index;
rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
};
#ifdef RT_USING_UART1
struct rt_at91serial serial1;
#endif
#ifdef RT_USING_UART2
struct rt_at91serial serial2;
#endif
static void rt_hw_serial_isr(int irqno)
{
rt_base_t level;
struct rt_device* device;
struct rt_at91serial* serial = RT_NULL;
if (irqno == AT91C_ID_US0)
{
#ifdef RT_USING_UART1
/* serial 1 */
serial = &serial1;
#endif
}
else if (irqno == AT91C_ID_US1)
{
#ifdef RT_USING_UART2
/* serial 2 */
serial = &serial2;
#endif
}
RT_ASSERT(serial != RT_NULL);
/* get generic device object */
device = (rt_device_t)serial;
/* disable interrupt */
level = rt_hw_interrupt_disable();
/* get received character */
serial->rx_buffer[serial->save_index] = serial->hw_base->US_RHR;
/* move to next position */
serial->save_index ++;
if (serial->save_index >= RT_UART_RX_BUFFER_SIZE)
serial->save_index = 0;
/* if the next position is read index, discard this 'read char' */
if (serial->save_index == serial->read_index)
{
serial->read_index ++;
if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
serial->read_index = 0;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
/* indicate to upper layer application */
if (device->rx_indicate != RT_NULL)
device->rx_indicate(device, 1);
/* ack interrupt */
AT91C_AIC_EOICR = 1;
}
static rt_err_t rt_serial_init (rt_device_t dev)
{
rt_uint32_t bd;
struct rt_at91serial* serial = (struct rt_at91serial*) dev;
RT_ASSERT(serial != RT_NULL);
/* must be US0 or US1 */
RT_ASSERT(((serial->peripheral_id == AT91C_ID_US0) ||
(serial->peripheral_id == AT91C_ID_US1)));
/* Enable Clock for USART */
AT91C_PMC_PCER = 1 << serial->peripheral_id;
/* Enable RxD0 and TxDO Pin */
if (serial->peripheral_id == AT91C_ID_US0)
{
if (serial->peripheral_id == AT91C_ID_US0)
{
/* set pinmux */
AT91C_PIO_PDR = (1 << 5) | (1 << 6);
}
else if (serial->peripheral_id == AT91C_ID_US1)
{
AT91C_PIO_PDR = (1 << 5) | (1 << 6);
}
else if (serial->peripheral_id == AT91C_ID_US1)
{
/* set pinmux */
AT91C_PIO_PDR = (1 << 21) | (1 << 22);
}
AT91C_PIO_PDR = (1 << 21) | (1 << 22);
}
serial->hw_base->US_CR = AT91C_US_RSTRX | /* Reset Receiver */
AT91C_US_RSTTX | /* Reset Transmitter */
@ -165,143 +165,143 @@ static rt_err_t rt_serial_init (rt_device_t dev)
AT91C_US_PAR_NONE | /* No Parity */
AT91C_US_NBSTOP_1_BIT; /* 1 Stop Bit */
/* set baud rate divisor */
bd = ((MCK*10)/(serial->baudrate * 16));
if ((bd % 10) >= 5) bd = (bd / 10) + 1;
else bd /= 10;
serial->hw_base->US_BRGR = bd;
serial->hw_base->US_CR = AT91C_US_RXEN | /* Receiver Enable */
AT91C_US_TXEN; /* Transmitter Enable */
/* reset rx index */
serial->save_index = 0;
serial->read_index = 0;
/* reset rx buffer */
rt_memset(serial->rx_buffer, 0, RT_UART_RX_BUFFER_SIZE);
return RT_EOK;
}
static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
{
struct rt_at91serial *serial = (struct rt_at91serial*)dev;
RT_ASSERT(serial != RT_NULL);
/* set baud rate divisor */
bd = ((MCK*10)/(serial->baudrate * 16));
if ((bd % 10) >= 5) bd = (bd / 10) + 1;
else bd /= 10;
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
/* enable UART rx interrupt */
serial->hw_base->US_IER = 1 << 0; /* RxReady interrupt */
serial->hw_base->US_IMR |= 1 << 0; /* umask RxReady interrupt */
/* install UART handler */
rt_hw_interrupt_install(serial->peripheral_id, rt_hw_serial_isr, RT_NULL);
AT91C_AIC_SMR(serial->peripheral_id) = 5 | (0x01 << 5);
rt_hw_interrupt_umask(serial->peripheral_id);
}
return RT_EOK;
}
static rt_err_t rt_serial_close(rt_device_t dev)
{
struct rt_at91serial *serial = (struct rt_at91serial*)dev;
RT_ASSERT(serial != RT_NULL);
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
/* disable interrupt */
serial->hw_base->US_IDR = 1 << 0; /* RxReady interrupt */
serial->hw_base->US_IMR &= ~(1 << 0); /* mask RxReady interrupt */
}
serial->hw_base->US_BRGR = bd;
serial->hw_base->US_CR = AT91C_US_RXEN | /* Receiver Enable */
AT91C_US_TXEN; /* Transmitter Enable */
/* reset rx index */
serial->save_index = 0;
serial->read_index = 0;
/* reset rx buffer */
rt_memset(serial->rx_buffer, 0, RT_UART_RX_BUFFER_SIZE);
return RT_EOK;
}
static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
rt_uint8_t* ptr;
struct rt_at91serial *serial = (struct rt_at91serial*)dev;
RT_ASSERT(serial != RT_NULL);
/* point to buffer */
ptr = (rt_uint8_t*) buffer;
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
while (size)
{
/* interrupt receive */
rt_base_t level;
/* disable interrupt */
level = rt_hw_interrupt_disable();
if (serial->read_index != serial->save_index)
{
*ptr = serial->rx_buffer[serial->read_index];
serial->read_index ++;
if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
serial->read_index = 0;
}
else
{
/* no data in rx buffer */
/* enable interrupt */
rt_hw_interrupt_enable(level);
break;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
ptr ++; size --;
}
return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
}
else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
{
/* not support right now */
RT_ASSERT(0);
}
else
{
/* poll mode */
while (size)
{
}
static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
{
struct rt_at91serial *serial = (struct rt_at91serial*)dev;
RT_ASSERT(serial != RT_NULL);
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
/* enable UART rx interrupt */
serial->hw_base->US_IER = 1 << 0; /* RxReady interrupt */
serial->hw_base->US_IMR |= 1 << 0; /* umask RxReady interrupt */
/* install UART handler */
rt_hw_interrupt_install(serial->peripheral_id, rt_hw_serial_isr, RT_NULL);
AT91C_AIC_SMR(serial->peripheral_id) = 5 | (0x01 << 5);
rt_hw_interrupt_umask(serial->peripheral_id);
}
return RT_EOK;
}
static rt_err_t rt_serial_close(rt_device_t dev)
{
struct rt_at91serial *serial = (struct rt_at91serial*)dev;
RT_ASSERT(serial != RT_NULL);
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
/* disable interrupt */
serial->hw_base->US_IDR = 1 << 0; /* RxReady interrupt */
serial->hw_base->US_IMR &= ~(1 << 0); /* mask RxReady interrupt */
}
return RT_EOK;
}
static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
rt_uint8_t* ptr;
struct rt_at91serial *serial = (struct rt_at91serial*)dev;
RT_ASSERT(serial != RT_NULL);
/* point to buffer */
ptr = (rt_uint8_t*) buffer;
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
while (size)
{
/* interrupt receive */
rt_base_t level;
/* disable interrupt */
level = rt_hw_interrupt_disable();
if (serial->read_index != serial->save_index)
{
*ptr = serial->rx_buffer[serial->read_index];
serial->read_index ++;
if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
serial->read_index = 0;
}
else
{
/* no data in rx buffer */
/* enable interrupt */
rt_hw_interrupt_enable(level);
break;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
ptr ++; size --;
}
return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
}
else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
{
/* not support right now */
RT_ASSERT(0);
}
else
{
/* poll mode */
while (size)
{
/* Wait for Full Rx Buffer */
while (!(serial->hw_base->US_CSR & AT91C_US_RXRDY));
/* Read Character */
*ptr = serial->hw_base->US_RHR;
ptr ++;
*ptr = serial->hw_base->US_RHR;
ptr ++;
size --;
}
return (rt_size_t)ptr - (rt_size_t)buffer;
}
return 0;
}
static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
{
rt_uint8_t* ptr;
struct rt_at91serial *serial = (struct rt_at91serial*)dev;
RT_ASSERT(serial != RT_NULL);
ptr = (rt_uint8_t*) buffer;
if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY)
{
if (dev->flag & RT_DEVICE_FLAG_STREAM)
{
/* it's a stream mode device */
while (size)
{
/* stream mode */
}
return (rt_size_t)ptr - (rt_size_t)buffer;
}
return 0;
}
static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
{
rt_uint8_t* ptr;
struct rt_at91serial *serial = (struct rt_at91serial*)dev;
RT_ASSERT(serial != RT_NULL);
ptr = (rt_uint8_t*) buffer;
if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY)
{
if (dev->flag & RT_DEVICE_FLAG_STREAM)
{
/* it's a stream mode device */
while (size)
{
/* stream mode */
if (*ptr == '\n')
{
while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
@ -312,76 +312,76 @@ static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buf
while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
/* Transmit Character */
serial->hw_base->US_THR = *ptr;
serial->hw_base->US_THR = *ptr;
ptr ++; size --;
}
}
else
{
while (size)
{
}
}
else
{
while (size)
{
/* Wait for Empty Tx Buffer */
while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
/* Transmit Character */
serial->hw_base->US_THR = *ptr;
ptr ++; size --;
}
}
}
return (rt_size_t)ptr - (rt_size_t)buffer;
}
static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
{
return RT_EOK;
}
rt_err_t rt_hw_serial_init()
{
rt_device_t device;
#ifdef RT_USING_UART1
device = (rt_device_t) &serial1;
/* init serial device private data */
serial1.hw_base = (struct rt_at91serial_hw*)AT91C_BASE_US0;
serial1.peripheral_id = AT91C_ID_US0;
serial1.baudrate = 115200;
/* set device virtual interface */
device->init = rt_serial_init;
device->open = rt_serial_open;
device->close = rt_serial_close;
device->read = rt_serial_read;
device->write = rt_serial_write;
device->control = rt_serial_control;
/* register uart1 on device subsystem */
rt_device_register(device, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
#endif
#ifdef RT_USING_UART2
device = (rt_device_t) &serial2;
serial2.hw_base = (struct rt_at91serial_hw*)AT91C_BASE_US1;
serial2.peripheral_id = AT91C_ID_US1;
serial2.baudrate = 115200;
/* set device virtual interface */
device->init = rt_serial_init;
device->open = rt_serial_open;
device->close = rt_serial_close;
device->read = rt_serial_read;
device->write = rt_serial_write;
device->control = rt_serial_control;
/* register uart2 on device subsystem */
rt_device_register(device, "uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
#endif
return RT_EOK;
}
serial->hw_base->US_THR = *ptr;
ptr ++; size --;
}
}
}
return (rt_size_t)ptr - (rt_size_t)buffer;
}
static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
{
return RT_EOK;
}
rt_err_t rt_hw_serial_init()
{
rt_device_t device;
#ifdef RT_USING_UART1
device = (rt_device_t) &serial1;
/* init serial device private data */
serial1.hw_base = (struct rt_at91serial_hw*)AT91C_BASE_US0;
serial1.peripheral_id = AT91C_ID_US0;
serial1.baudrate = 115200;
/* set device virtual interface */
device->init = rt_serial_init;
device->open = rt_serial_open;
device->close = rt_serial_close;
device->read = rt_serial_read;
device->write = rt_serial_write;
device->control = rt_serial_control;
/* register uart1 on device subsystem */
rt_device_register(device, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
#endif
#ifdef RT_USING_UART2
device = (rt_device_t) &serial2;
serial2.hw_base = (struct rt_at91serial_hw*)AT91C_BASE_US1;
serial2.peripheral_id = AT91C_ID_US1;
serial2.baudrate = 115200;
/* set device virtual interface */
device->init = rt_serial_init;
device->open = rt_serial_open;
device->close = rt_serial_close;
device->read = rt_serial_read;
device->write = rt_serial_write;
device->control = rt_serial_control;
/* register uart2 on device subsystem */
rt_device_register(device, "uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
#endif
return RT_EOK;
}
/*@}*/

View File

@ -1,14 +1,14 @@
#ifndef __RT_SERIAL_H__
#define __RT_SERIAL_H__
#ifndef AT91C_BASE_US0
#define AT91C_BASE_US0 (0xFFFC0000) // (US0) Base Address
#endif
#ifndef AT91C_BASE_US1
#define AT91C_BASE_US1 (0xFFFC4000) // (US1) Base Address
#endif
#ifndef __RT_SERIAL_H__
#define __RT_SERIAL_H__
#ifndef AT91C_BASE_US0
#define AT91C_BASE_US0 (0xFFFC0000) // (US0) Base Address
#endif
#ifndef AT91C_BASE_US1
#define AT91C_BASE_US1 (0xFFFC4000) // (US1) Base Address
#endif
#define AT91C_US_RXRDY ((unsigned int) 0x1 << 0) /* US RXRDY Interrupt */
#define AT91C_US_TXRDY ((unsigned int) 0x1 << 1) /* US TXRDY Interrupt */
#define AT91C_US_RSTRX ((unsigned int) 0x1 << 2) /* US Reset Receiver */
@ -52,5 +52,5 @@
#define MCK 48054857
#define BR 115200 /* Baud Rate */
#define BRD (MCK/16/BR) /* Baud Rate Divisor */
#endif
#endif

View File

@ -1,499 +1,499 @@
;/*****************************************************************************/
;/* SAM7.S: Startup file for Atmel AT91SAM7 device series */
;/*****************************************************************************/
;/* <<< Use Configuration Wizard in Context Menu >>> */
;/*****************************************************************************/
;/* This file is part of the uVision/ARM development tools. */
;/* Copyright (c) 2005-2006 Keil Software. All rights reserved. */
;/* This software may only be used under the terms of a valid, current, */
;/* end user licence from KEIL for a compatible version of KEIL software */
;/* development tools. Nothing else gives you the right to use this software. */
;/*****************************************************************************/
;/*
; * The SAM7.S code is executed after CPU Reset. This file may be
; * translated with the following SET symbols. In uVision these SET
; * symbols are entered under Options - ASM - Define.
; *
; * REMAP: when set the startup code remaps exception vectors from
; * on-chip RAM to address 0.
; *
; * RAM_INTVEC: when set the startup code copies exception vectors
; * from on-chip Flash to on-chip RAM.
; */
; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
Mode_USR EQU 0x10
Mode_FIQ EQU 0x11
Mode_IRQ EQU 0x12
Mode_SVC EQU 0x13
Mode_ABT EQU 0x17
Mode_UND EQU 0x1B
Mode_SYS EQU 0x1F
I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
; Internal Memory Base Addresses
FLASH_BASE EQU 0x00100000
RAM_BASE EQU 0x00200000
;// <h> Stack Configuration (Stack Sizes in Bytes)
;// <o0> Undefined Mode <0x0-0xFFFFFFFF:8>
;// <o1> Supervisor Mode <0x0-0xFFFFFFFF:8>
;// <o2> Abort Mode <0x0-0xFFFFFFFF:8>
;// <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
;// <o4> Interrupt Mode <0x0-0xFFFFFFFF:8>
;// <o5> User/System Mode <0x0-0xFFFFFFFF:8>
;// </h>
UND_Stack_Size EQU 0x00000000
SVC_Stack_Size EQU 0x00000100
ABT_Stack_Size EQU 0x00000000
FIQ_Stack_Size EQU 0x00000000
IRQ_Stack_Size EQU 0x00000100
USR_Stack_Size EQU 0x00000100
ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
FIQ_Stack_Size + IRQ_Stack_Size)
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE USR_Stack_Size
__initial_sp SPACE ISR_Stack_Size
Stack_Top
;// <h> Heap Configuration
;// <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF>
;// </h>
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
; Reset Controller (RSTC) definitions
RSTC_BASE EQU 0xFFFFFD00 ; RSTC Base Address
RSTC_MR EQU 0x08 ; RSTC_MR Offset
;/*
;// <e> Reset Controller (RSTC)
;// <o1.0> URSTEN: User Reset Enable
;// <i> Enables NRST Pin to generate Reset
;// <o1.8..11> ERSTL: External Reset Length <0-15>
;// <i> External Reset Time in 2^(ERSTL+1) Slow Clock Cycles
;// </e>
;*/
RSTC_SETUP EQU 1
RSTC_MR_Val EQU 0xA5000401
; Embedded Flash Controller (EFC) definitions
EFC_BASE EQU 0xFFFFFF00 ; EFC Base Address
EFC0_FMR EQU 0x60 ; EFC0_FMR Offset
EFC1_FMR EQU 0x70 ; EFC1_FMR Offset
;// <e> Embedded Flash Controller 0 (EFC0)
;// <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
;// <i> Number of Master Clock Cycles in 1us
;// <o1.8..9> FWS: Flash Wait State
;// <0=> Read: 1 cycle / Write: 2 cycles
;// <1=> Read: 2 cycle / Write: 3 cycles
;// <2=> Read: 3 cycle / Write: 4 cycles
;// <3=> Read: 4 cycle / Write: 4 cycles
;// </e>
EFC0_SETUP EQU 1
EFC0_FMR_Val EQU 0x00320100
;// <e> Embedded Flash Controller 1 (EFC1)
;// <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
;// <i> Number of Master Clock Cycles in 1us
;// <o1.8..9> FWS: Flash Wait State
;// <0=> Read: 1 cycle / Write: 2 cycles
;// <1=> Read: 2 cycle / Write: 3 cycles
;// <2=> Read: 3 cycle / Write: 4 cycles
;// <3=> Read: 4 cycle / Write: 4 cycles
;// </e>
EFC1_SETUP EQU 0
EFC1_FMR_Val EQU 0x00320100
; Watchdog Timer (WDT) definitions
WDT_BASE EQU 0xFFFFFD40 ; WDT Base Address
WDT_MR EQU 0x04 ; WDT_MR Offset
;// <e> Watchdog Timer (WDT)
;// <o1.0..11> WDV: Watchdog Counter Value <0-4095>
;// <o1.16..27> WDD: Watchdog Delta Value <0-4095>
;// <o1.12> WDFIEN: Watchdog Fault Interrupt Enable
;// <o1.13> WDRSTEN: Watchdog Reset Enable
;// <o1.14> WDRPROC: Watchdog Reset Processor
;// <o1.28> WDDBGHLT: Watchdog Debug Halt
;// <o1.29> WDIDLEHLT: Watchdog Idle Halt
;// <o1.15> WDDIS: Watchdog Disable
;// </e>
WDT_SETUP EQU 1
WDT_MR_Val EQU 0x00008000
; Power Mangement Controller (PMC) definitions
PMC_BASE EQU 0xFFFFFC00 ; PMC Base Address
PMC_MOR EQU 0x20 ; PMC_MOR Offset
PMC_MCFR EQU 0x24 ; PMC_MCFR Offset
PMC_PLLR EQU 0x2C ; PMC_PLLR Offset
PMC_MCKR EQU 0x30 ; PMC_MCKR Offset
PMC_SR EQU 0x68 ; PMC_SR Offset
PMC_MOSCEN EQU (1<<0) ; Main Oscillator Enable
PMC_OSCBYPASS EQU (1<<1) ; Main Oscillator Bypass
PMC_OSCOUNT EQU (0xFF<<8) ; Main OScillator Start-up Time
PMC_DIV EQU (0xFF<<0) ; PLL Divider
PMC_PLLCOUNT EQU (0x3F<<8) ; PLL Lock Counter
PMC_OUT EQU (0x03<<14) ; PLL Clock Frequency Range
PMC_MUL EQU (0x7FF<<16) ; PLL Multiplier
PMC_USBDIV EQU (0x03<<28) ; USB Clock Divider
PMC_CSS EQU (3<<0) ; Clock Source Selection
PMC_PRES EQU (7<<2) ; Prescaler Selection
PMC_MOSCS EQU (1<<0) ; Main Oscillator Stable
PMC_LOCK EQU (1<<2) ; PLL Lock Status
PMC_MCKRDY EQU (1<<3) ; Master Clock Status
;// <e> Power Mangement Controller (PMC)
;// <h> Main Oscillator
;// <o1.0> MOSCEN: Main Oscillator Enable
;// <o1.1> OSCBYPASS: Oscillator Bypass
;// <o1.8..15> OSCCOUNT: Main Oscillator Startup Time <0-255>
;// </h>
;// <h> Phase Locked Loop (PLL)
;// <o2.0..7> DIV: PLL Divider <0-255>
;// <o2.16..26> MUL: PLL Multiplier <0-2047>
;// <i> PLL Output is multiplied by MUL+1
;// <o2.14..15> OUT: PLL Clock Frequency Range
;// <0=> 80..160MHz <1=> Reserved
;// <2=> 150..220MHz <3=> Reserved
;// <o2.8..13> PLLCOUNT: PLL Lock Counter <0-63>
;// <o2.28..29> USBDIV: USB Clock Divider
;// <0=> None <1=> 2 <2=> 4 <3=> Reserved
;// </h>
;// <o3.0..1> CSS: Clock Source Selection
;// <0=> Slow Clock
;// <1=> Main Clock
;// <2=> Reserved
;// <3=> PLL Clock
;// <o3.2..4> PRES: Prescaler
;// <0=> None
;// <1=> Clock / 2 <2=> Clock / 4
;// <3=> Clock / 8 <4=> Clock / 16
;// <5=> Clock / 32 <6=> Clock / 64
;// <7=> Reserved
;// </e>
PMC_SETUP EQU 1
PMC_MOR_Val EQU 0x00000601
PMC_PLLR_Val EQU 0x00191C05
PMC_MCKR_Val EQU 0x00000007
PRESERVE8
; Area Definition and Entry Point
; Startup Code must be linked first at Address at which it expects to run.
AREA RESET, CODE, READONLY
ARM
; Exception Vectors
; Mapped to Address 0.
; Absolute addressing mode must be used.
; Dummy Handlers are implemented as infinite loops which can be modified.
Vectors LDR PC,Reset_Addr
LDR PC,Undef_Addr
LDR PC,SWI_Addr
LDR PC,PAbt_Addr
LDR PC,DAbt_Addr
NOP ; Reserved Vector
LDR PC,IRQ_Addr
LDR PC,FIQ_Addr
Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
SWI_Addr DCD SWI_Handler
PAbt_Addr DCD PAbt_Handler
DAbt_Addr DCD DAbt_Handler
DCD 0 ; Reserved Address
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler
Undef_Handler B Undef_Handler
SWI_Handler B SWI_Handler
PAbt_Handler B PAbt_Handler
DAbt_Handler B DAbt_Handler
FIQ_Handler B FIQ_Handler
; Reset Handler
EXPORT Reset_Handler
Reset_Handler
; Setup RSTC
IF RSTC_SETUP != 0
LDR R0, =RSTC_BASE
LDR R1, =RSTC_MR_Val
STR R1, [R0, #RSTC_MR]
ENDIF
; Setup EFC0
IF EFC0_SETUP != 0
LDR R0, =EFC_BASE
LDR R1, =EFC0_FMR_Val
STR R1, [R0, #EFC0_FMR]
ENDIF
; Setup EFC1
IF EFC1_SETUP != 0
LDR R0, =EFC_BASE
LDR R1, =EFC1_FMR_Val
STR R1, [R0, #EFC1_FMR]
ENDIF
; Setup WDT
IF WDT_SETUP != 0
LDR R0, =WDT_BASE
LDR R1, =WDT_MR_Val
STR R1, [R0, #WDT_MR]
ENDIF
; Setup PMC
IF PMC_SETUP != 0
LDR R0, =PMC_BASE
; Setup Main Oscillator
LDR R1, =PMC_MOR_Val
STR R1, [R0, #PMC_MOR]
; Wait until Main Oscillator is stablilized
IF (PMC_MOR_Val:AND:PMC_MOSCEN) != 0
MOSCS_Loop LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_MOSCS
BEQ MOSCS_Loop
ENDIF
; Setup the PLL
IF (PMC_PLLR_Val:AND:PMC_MUL) != 0
LDR R1, =PMC_PLLR_Val
STR R1, [R0, #PMC_PLLR]
; Wait until PLL is stabilized
PLL_Loop LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_LOCK
BEQ PLL_Loop
ENDIF
; Select Clock
IF (PMC_MCKR_Val:AND:PMC_CSS) == 1 ; Main Clock Selected
LDR R1, =PMC_MCKR_Val
AND R1, #PMC_CSS
STR R1, [R0, #PMC_MCKR]
WAIT_Rdy1 LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_MCKRDY
BEQ WAIT_Rdy1
LDR R1, =PMC_MCKR_Val
STR R1, [R0, #PMC_MCKR]
WAIT_Rdy2 LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_MCKRDY
BEQ WAIT_Rdy2
ELIF (PMC_MCKR_Val:AND:PMC_CSS) == 3 ; PLL Clock Selected
LDR R1, =PMC_MCKR_Val
AND R1, #PMC_PRES
STR R1, [R0, #PMC_MCKR]
WAIT_Rdy1 LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_MCKRDY
BEQ WAIT_Rdy1
LDR R1, =PMC_MCKR_Val
STR R1, [R0, #PMC_MCKR]
WAIT_Rdy2 LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_MCKRDY
BEQ WAIT_Rdy2
ENDIF ; Select Clock
ENDIF ; PMC_SETUP
; Copy Exception Vectors to Internal RAM
IF :DEF:RAM_INTVEC
ADR R8, Vectors ; Source
LDR R9, =RAM_BASE ; Destination
LDMIA R8!, {R0-R7} ; Load Vectors
STMIA R9!, {R0-R7} ; Store Vectors
LDMIA R8!, {R0-R7} ; Load Handler Addresses
STMIA R9!, {R0-R7} ; Store Handler Addresses
ENDIF
; Remap on-chip RAM to address 0
MC_BASE EQU 0xFFFFFF00 ; MC Base Address
MC_RCR EQU 0x00 ; MC_RCR Offset
IF :DEF:REMAP
LDR R0, =MC_BASE
MOV R1, #1
STR R1, [R0, #MC_RCR] ; Remap
ENDIF
; Setup Stack for each mode
LDR R0, =Stack_Top
; Enter Undefined Instruction Mode and set its Stack Pointer
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #UND_Stack_Size
; Enter Abort Mode and set its Stack Pointer
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size
; Enter FIQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size
; Enter IRQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size
; Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size
; Enter User Mode and set its Stack Pointer
; MSR CPSR_c, #Mode_USR
IF :DEF:__MICROLIB
EXPORT __initial_sp
ELSE
; No usr mode stack here.
;MOV SP, R0
;SUB SL, SP, #USR_Stack_Size
ENDIF
; Enter the C code
IMPORT __main
LDR R0, =__main
BX R0
IMPORT rt_interrupt_enter
IMPORT rt_interrupt_leave
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
IMPORT rt_hw_trap_irq
IRQ_Handler PROC
EXPORT IRQ_Handler
STMFD sp!, {r0-r12,lr}
BL rt_interrupt_enter
BL rt_hw_trap_irq
BL rt_interrupt_leave
; if rt_thread_switch_interrupt_flag set, jump to
; rt_hw_context_switch_interrupt_do and don't return
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CMP r1, #1
BEQ rt_hw_context_switch_interrupt_do
LDMFD sp!, {r0-r12,lr}
SUBS pc, lr, #4
ENDP
; /*
; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
; */
rt_hw_context_switch_interrupt_do PROC
EXPORT rt_hw_context_switch_interrupt_do
MOV r1, #0 ; clear flag
STR r1, [r0]
LDMFD sp!, {r0-r12,lr}; reload saved registers
STMFD sp!, {r0-r3} ; save r0-r3
MOV r1, sp
ADD sp, sp, #16 ; restore sp
SUB r2, lr, #4 ; save old task's pc to r2
MRS r3, spsr ; get cpsr of interrupt thread
; switch to SVC mode and no interrupt
MSR cpsr_c, #I_Bit|F_Bit|Mode_SVC
STMFD sp!, {r2} ; push old task's pc
STMFD sp!, {r4-r12,lr}; push old task's lr,r12-r4
MOV r4, r1 ; Special optimised code below
MOV r5, r3
LDMFD r4!, {r0-r3}
STMFD sp!, {r0-r3} ; push old task's r3-r0
STMFD sp!, {r5} ; push old task's cpsr
MRS r4, spsr
STMFD sp!, {r4} ; push old task's spsr
LDR r4, =rt_interrupt_from_thread
LDR r5, [r4]
STR sp, [r5] ; store sp in preempted tasks's TCB
LDR r6, =rt_interrupt_to_thread
LDR r6, [r6]
LDR sp, [r6] ; get new task's stack pointer
LDMFD sp!, {r4} ; pop new task's spsr
MSR spsr_cxsf, r4
LDMFD sp!, {r4} ; pop new task's psr
MSR cpsr_cxsf, r4
LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc
ENDP
IF :DEF:__MICROLIB
EXPORT __heap_base
EXPORT __heap_limit
ELSE
; User Initial Stack & Heap
AREA |.text|, CODE, READONLY
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, = (Stack_Mem + IRQ_Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ENDIF
END
;/*****************************************************************************/
;/* SAM7.S: Startup file for Atmel AT91SAM7 device series */
;/*****************************************************************************/
;/* <<< Use Configuration Wizard in Context Menu >>> */
;/*****************************************************************************/
;/* This file is part of the uVision/ARM development tools. */
;/* Copyright (c) 2005-2006 Keil Software. All rights reserved. */
;/* This software may only be used under the terms of a valid, current, */
;/* end user licence from KEIL for a compatible version of KEIL software */
;/* development tools. Nothing else gives you the right to use this software. */
;/*****************************************************************************/
;/*
; * The SAM7.S code is executed after CPU Reset. This file may be
; * translated with the following SET symbols. In uVision these SET
; * symbols are entered under Options - ASM - Define.
; *
; * REMAP: when set the startup code remaps exception vectors from
; * on-chip RAM to address 0.
; *
; * RAM_INTVEC: when set the startup code copies exception vectors
; * from on-chip Flash to on-chip RAM.
; */
; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
Mode_USR EQU 0x10
Mode_FIQ EQU 0x11
Mode_IRQ EQU 0x12
Mode_SVC EQU 0x13
Mode_ABT EQU 0x17
Mode_UND EQU 0x1B
Mode_SYS EQU 0x1F
I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
; Internal Memory Base Addresses
FLASH_BASE EQU 0x00100000
RAM_BASE EQU 0x00200000
;// <h> Stack Configuration (Stack Sizes in Bytes)
;// <o0> Undefined Mode <0x0-0xFFFFFFFF:8>
;// <o1> Supervisor Mode <0x0-0xFFFFFFFF:8>
;// <o2> Abort Mode <0x0-0xFFFFFFFF:8>
;// <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
;// <o4> Interrupt Mode <0x0-0xFFFFFFFF:8>
;// <o5> User/System Mode <0x0-0xFFFFFFFF:8>
;// </h>
UND_Stack_Size EQU 0x00000000
SVC_Stack_Size EQU 0x00000100
ABT_Stack_Size EQU 0x00000000
FIQ_Stack_Size EQU 0x00000000
IRQ_Stack_Size EQU 0x00000100
USR_Stack_Size EQU 0x00000100
ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
FIQ_Stack_Size + IRQ_Stack_Size)
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE USR_Stack_Size
__initial_sp SPACE ISR_Stack_Size
Stack_Top
;// <h> Heap Configuration
;// <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF>
;// </h>
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
; Reset Controller (RSTC) definitions
RSTC_BASE EQU 0xFFFFFD00 ; RSTC Base Address
RSTC_MR EQU 0x08 ; RSTC_MR Offset
;/*
;// <e> Reset Controller (RSTC)
;// <o1.0> URSTEN: User Reset Enable
;// <i> Enables NRST Pin to generate Reset
;// <o1.8..11> ERSTL: External Reset Length <0-15>
;// <i> External Reset Time in 2^(ERSTL+1) Slow Clock Cycles
;// </e>
;*/
RSTC_SETUP EQU 1
RSTC_MR_Val EQU 0xA5000401
; Embedded Flash Controller (EFC) definitions
EFC_BASE EQU 0xFFFFFF00 ; EFC Base Address
EFC0_FMR EQU 0x60 ; EFC0_FMR Offset
EFC1_FMR EQU 0x70 ; EFC1_FMR Offset
;// <e> Embedded Flash Controller 0 (EFC0)
;// <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
;// <i> Number of Master Clock Cycles in 1us
;// <o1.8..9> FWS: Flash Wait State
;// <0=> Read: 1 cycle / Write: 2 cycles
;// <1=> Read: 2 cycle / Write: 3 cycles
;// <2=> Read: 3 cycle / Write: 4 cycles
;// <3=> Read: 4 cycle / Write: 4 cycles
;// </e>
EFC0_SETUP EQU 1
EFC0_FMR_Val EQU 0x00320100
;// <e> Embedded Flash Controller 1 (EFC1)
;// <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
;// <i> Number of Master Clock Cycles in 1us
;// <o1.8..9> FWS: Flash Wait State
;// <0=> Read: 1 cycle / Write: 2 cycles
;// <1=> Read: 2 cycle / Write: 3 cycles
;// <2=> Read: 3 cycle / Write: 4 cycles
;// <3=> Read: 4 cycle / Write: 4 cycles
;// </e>
EFC1_SETUP EQU 0
EFC1_FMR_Val EQU 0x00320100
; Watchdog Timer (WDT) definitions
WDT_BASE EQU 0xFFFFFD40 ; WDT Base Address
WDT_MR EQU 0x04 ; WDT_MR Offset
;// <e> Watchdog Timer (WDT)
;// <o1.0..11> WDV: Watchdog Counter Value <0-4095>
;// <o1.16..27> WDD: Watchdog Delta Value <0-4095>
;// <o1.12> WDFIEN: Watchdog Fault Interrupt Enable
;// <o1.13> WDRSTEN: Watchdog Reset Enable
;// <o1.14> WDRPROC: Watchdog Reset Processor
;// <o1.28> WDDBGHLT: Watchdog Debug Halt
;// <o1.29> WDIDLEHLT: Watchdog Idle Halt
;// <o1.15> WDDIS: Watchdog Disable
;// </e>
WDT_SETUP EQU 1
WDT_MR_Val EQU 0x00008000
; Power Mangement Controller (PMC) definitions
PMC_BASE EQU 0xFFFFFC00 ; PMC Base Address
PMC_MOR EQU 0x20 ; PMC_MOR Offset
PMC_MCFR EQU 0x24 ; PMC_MCFR Offset
PMC_PLLR EQU 0x2C ; PMC_PLLR Offset
PMC_MCKR EQU 0x30 ; PMC_MCKR Offset
PMC_SR EQU 0x68 ; PMC_SR Offset
PMC_MOSCEN EQU (1<<0) ; Main Oscillator Enable
PMC_OSCBYPASS EQU (1<<1) ; Main Oscillator Bypass
PMC_OSCOUNT EQU (0xFF<<8) ; Main OScillator Start-up Time
PMC_DIV EQU (0xFF<<0) ; PLL Divider
PMC_PLLCOUNT EQU (0x3F<<8) ; PLL Lock Counter
PMC_OUT EQU (0x03<<14) ; PLL Clock Frequency Range
PMC_MUL EQU (0x7FF<<16) ; PLL Multiplier
PMC_USBDIV EQU (0x03<<28) ; USB Clock Divider
PMC_CSS EQU (3<<0) ; Clock Source Selection
PMC_PRES EQU (7<<2) ; Prescaler Selection
PMC_MOSCS EQU (1<<0) ; Main Oscillator Stable
PMC_LOCK EQU (1<<2) ; PLL Lock Status
PMC_MCKRDY EQU (1<<3) ; Master Clock Status
;// <e> Power Mangement Controller (PMC)
;// <h> Main Oscillator
;// <o1.0> MOSCEN: Main Oscillator Enable
;// <o1.1> OSCBYPASS: Oscillator Bypass
;// <o1.8..15> OSCCOUNT: Main Oscillator Startup Time <0-255>
;// </h>
;// <h> Phase Locked Loop (PLL)
;// <o2.0..7> DIV: PLL Divider <0-255>
;// <o2.16..26> MUL: PLL Multiplier <0-2047>
;// <i> PLL Output is multiplied by MUL+1
;// <o2.14..15> OUT: PLL Clock Frequency Range
;// <0=> 80..160MHz <1=> Reserved
;// <2=> 150..220MHz <3=> Reserved
;// <o2.8..13> PLLCOUNT: PLL Lock Counter <0-63>
;// <o2.28..29> USBDIV: USB Clock Divider
;// <0=> None <1=> 2 <2=> 4 <3=> Reserved
;// </h>
;// <o3.0..1> CSS: Clock Source Selection
;// <0=> Slow Clock
;// <1=> Main Clock
;// <2=> Reserved
;// <3=> PLL Clock
;// <o3.2..4> PRES: Prescaler
;// <0=> None
;// <1=> Clock / 2 <2=> Clock / 4
;// <3=> Clock / 8 <4=> Clock / 16
;// <5=> Clock / 32 <6=> Clock / 64
;// <7=> Reserved
;// </e>
PMC_SETUP EQU 1
PMC_MOR_Val EQU 0x00000601
PMC_PLLR_Val EQU 0x00191C05
PMC_MCKR_Val EQU 0x00000007
PRESERVE8
; Area Definition and Entry Point
; Startup Code must be linked first at Address at which it expects to run.
AREA RESET, CODE, READONLY
ARM
; Exception Vectors
; Mapped to Address 0.
; Absolute addressing mode must be used.
; Dummy Handlers are implemented as infinite loops which can be modified.
Vectors LDR PC,Reset_Addr
LDR PC,Undef_Addr
LDR PC,SWI_Addr
LDR PC,PAbt_Addr
LDR PC,DAbt_Addr
NOP ; Reserved Vector
LDR PC,IRQ_Addr
LDR PC,FIQ_Addr
Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
SWI_Addr DCD SWI_Handler
PAbt_Addr DCD PAbt_Handler
DAbt_Addr DCD DAbt_Handler
DCD 0 ; Reserved Address
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler
Undef_Handler B Undef_Handler
SWI_Handler B SWI_Handler
PAbt_Handler B PAbt_Handler
DAbt_Handler B DAbt_Handler
FIQ_Handler B FIQ_Handler
; Reset Handler
EXPORT Reset_Handler
Reset_Handler
; Setup RSTC
IF RSTC_SETUP != 0
LDR R0, =RSTC_BASE
LDR R1, =RSTC_MR_Val
STR R1, [R0, #RSTC_MR]
ENDIF
; Setup EFC0
IF EFC0_SETUP != 0
LDR R0, =EFC_BASE
LDR R1, =EFC0_FMR_Val
STR R1, [R0, #EFC0_FMR]
ENDIF
; Setup EFC1
IF EFC1_SETUP != 0
LDR R0, =EFC_BASE
LDR R1, =EFC1_FMR_Val
STR R1, [R0, #EFC1_FMR]
ENDIF
; Setup WDT
IF WDT_SETUP != 0
LDR R0, =WDT_BASE
LDR R1, =WDT_MR_Val
STR R1, [R0, #WDT_MR]
ENDIF
; Setup PMC
IF PMC_SETUP != 0
LDR R0, =PMC_BASE
; Setup Main Oscillator
LDR R1, =PMC_MOR_Val
STR R1, [R0, #PMC_MOR]
; Wait until Main Oscillator is stablilized
IF (PMC_MOR_Val:AND:PMC_MOSCEN) != 0
MOSCS_Loop LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_MOSCS
BEQ MOSCS_Loop
ENDIF
; Setup the PLL
IF (PMC_PLLR_Val:AND:PMC_MUL) != 0
LDR R1, =PMC_PLLR_Val
STR R1, [R0, #PMC_PLLR]
; Wait until PLL is stabilized
PLL_Loop LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_LOCK
BEQ PLL_Loop
ENDIF
; Select Clock
IF (PMC_MCKR_Val:AND:PMC_CSS) == 1 ; Main Clock Selected
LDR R1, =PMC_MCKR_Val
AND R1, #PMC_CSS
STR R1, [R0, #PMC_MCKR]
WAIT_Rdy1 LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_MCKRDY
BEQ WAIT_Rdy1
LDR R1, =PMC_MCKR_Val
STR R1, [R0, #PMC_MCKR]
WAIT_Rdy2 LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_MCKRDY
BEQ WAIT_Rdy2
ELIF (PMC_MCKR_Val:AND:PMC_CSS) == 3 ; PLL Clock Selected
LDR R1, =PMC_MCKR_Val
AND R1, #PMC_PRES
STR R1, [R0, #PMC_MCKR]
WAIT_Rdy1 LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_MCKRDY
BEQ WAIT_Rdy1
LDR R1, =PMC_MCKR_Val
STR R1, [R0, #PMC_MCKR]
WAIT_Rdy2 LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_MCKRDY
BEQ WAIT_Rdy2
ENDIF ; Select Clock
ENDIF ; PMC_SETUP
; Copy Exception Vectors to Internal RAM
IF :DEF:RAM_INTVEC
ADR R8, Vectors ; Source
LDR R9, =RAM_BASE ; Destination
LDMIA R8!, {R0-R7} ; Load Vectors
STMIA R9!, {R0-R7} ; Store Vectors
LDMIA R8!, {R0-R7} ; Load Handler Addresses
STMIA R9!, {R0-R7} ; Store Handler Addresses
ENDIF
; Remap on-chip RAM to address 0
MC_BASE EQU 0xFFFFFF00 ; MC Base Address
MC_RCR EQU 0x00 ; MC_RCR Offset
IF :DEF:REMAP
LDR R0, =MC_BASE
MOV R1, #1
STR R1, [R0, #MC_RCR] ; Remap
ENDIF
; Setup Stack for each mode
LDR R0, =Stack_Top
; Enter Undefined Instruction Mode and set its Stack Pointer
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #UND_Stack_Size
; Enter Abort Mode and set its Stack Pointer
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size
; Enter FIQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size
; Enter IRQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size
; Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size
; Enter User Mode and set its Stack Pointer
; MSR CPSR_c, #Mode_USR
IF :DEF:__MICROLIB
EXPORT __initial_sp
ELSE
; No usr mode stack here.
;MOV SP, R0
;SUB SL, SP, #USR_Stack_Size
ENDIF
; Enter the C code
IMPORT __main
LDR R0, =__main
BX R0
IMPORT rt_interrupt_enter
IMPORT rt_interrupt_leave
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
IMPORT rt_hw_trap_irq
IRQ_Handler PROC
EXPORT IRQ_Handler
STMFD sp!, {r0-r12,lr}
BL rt_interrupt_enter
BL rt_hw_trap_irq
BL rt_interrupt_leave
; if rt_thread_switch_interrupt_flag set, jump to
; rt_hw_context_switch_interrupt_do and don't return
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CMP r1, #1
BEQ rt_hw_context_switch_interrupt_do
LDMFD sp!, {r0-r12,lr}
SUBS pc, lr, #4
ENDP
; /*
; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
; */
rt_hw_context_switch_interrupt_do PROC
EXPORT rt_hw_context_switch_interrupt_do
MOV r1, #0 ; clear flag
STR r1, [r0]
LDMFD sp!, {r0-r12,lr}; reload saved registers
STMFD sp!, {r0-r3} ; save r0-r3
MOV r1, sp
ADD sp, sp, #16 ; restore sp
SUB r2, lr, #4 ; save old task's pc to r2
MRS r3, spsr ; get cpsr of interrupt thread
; switch to SVC mode and no interrupt
MSR cpsr_c, #I_Bit|F_Bit|Mode_SVC
STMFD sp!, {r2} ; push old task's pc
STMFD sp!, {r4-r12,lr}; push old task's lr,r12-r4
MOV r4, r1 ; Special optimised code below
MOV r5, r3
LDMFD r4!, {r0-r3}
STMFD sp!, {r0-r3} ; push old task's r3-r0
STMFD sp!, {r5} ; push old task's cpsr
MRS r4, spsr
STMFD sp!, {r4} ; push old task's spsr
LDR r4, =rt_interrupt_from_thread
LDR r5, [r4]
STR sp, [r5] ; store sp in preempted tasks's TCB
LDR r6, =rt_interrupt_to_thread
LDR r6, [r6]
LDR sp, [r6] ; get new task's stack pointer
LDMFD sp!, {r4} ; pop new task's spsr
MSR spsr_cxsf, r4
LDMFD sp!, {r4} ; pop new task's psr
MSR cpsr_cxsf, r4
LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc
ENDP
IF :DEF:__MICROLIB
EXPORT __heap_base
EXPORT __heap_limit
ELSE
; User Initial Stack & Heap
AREA |.text|, CODE, READONLY
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, = (Stack_Mem + IRQ_Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ENDIF
END

File diff suppressed because it is too large Load Diff

View File

@ -36,12 +36,12 @@ void rt_hw_trap_fiq()
{
rt_kprintf("fast interrupt request\n");
}
extern struct rt_thread* rt_current_thread;
void rt_hw_trap_abort()
{
rt_kprintf("Abort occured!!! Thread [%s] suspended.\n",rt_current_thread->name);
rt_thread_suspend(rt_current_thread);
{
rt_kprintf("Abort occured!!! Thread [%s] suspended.\n",rt_current_thread->name);
rt_thread_suspend(rt_current_thread);
rt_schedule();
}

View File

@ -1,193 +1,193 @@
/*
* File : cpu.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Develop Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://openlab.rt-thread.com/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2011-01-13 weety modified from mini2440
*/
#include <rthw.h>
#include <rtthread.h>
#include "at91sam926x.h"
/**
* @addtogroup AT91SAM926X
*/
/*@{*/
#define ICACHE_MASK (rt_uint32_t)(1 << 12)
#define DCACHE_MASK (rt_uint32_t)(1 << 2)
#ifdef __GNUC__
rt_inline rt_uint32_t cp15_rd(void)
{
rt_uint32_t i;
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
return i;
}
rt_inline void cache_enable(rt_uint32_t bit)
{
__asm__ __volatile__( \
"mrc p15,0,r0,c1,c0,0\n\t" \
"orr r0,r0,%0\n\t" \
"mcr p15,0,r0,c1,c0,0" \
: \
:"r" (bit) \
:"memory");
}
rt_inline void cache_disable(rt_uint32_t bit)
{
__asm__ __volatile__( \
"mrc p15,0,r0,c1,c0,0\n\t" \
"bic r0,r0,%0\n\t" \
"mcr p15,0,r0,c1,c0,0" \
: \
:"r" (bit) \
:"memory");
}
#endif
#ifdef __CC_ARM
rt_inline rt_uint32_t cp15_rd(void)
{
rt_uint32_t i;
__asm
{
mrc p15, 0, i, c1, c0, 0
}
return i;
}
rt_inline void cache_enable(rt_uint32_t bit)
{
rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
orr value, value, bit
mcr p15, 0, value, c1, c0, 0
}
}
rt_inline void cache_disable(rt_uint32_t bit)
{
rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
bic value, value, bit
mcr p15, 0, value, c1, c0, 0
}
}
#endif
/**
* enable I-Cache
*
*/
void rt_hw_cpu_icache_enable()
{
cache_enable(ICACHE_MASK);
}
/**
* disable I-Cache
*
*/
void rt_hw_cpu_icache_disable()
{
cache_disable(ICACHE_MASK);
}
/**
* return the status of I-Cache
*
*/
rt_base_t rt_hw_cpu_icache_status()
{
return (cp15_rd() & ICACHE_MASK);
}
/**
* enable D-Cache
*
*/
void rt_hw_cpu_dcache_enable()
{
cache_enable(DCACHE_MASK);
}
/**
* disable D-Cache
*
*/
void rt_hw_cpu_dcache_disable()
{
cache_disable(DCACHE_MASK);
}
/**
* return the status of D-Cache
*
*/
rt_base_t rt_hw_cpu_dcache_status()
{
return (cp15_rd() & DCACHE_MASK);
}
static void at91sam9260_reset(void)
{
at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
}
static void at91sam9260_poweroff(void)
{
at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
}
/**
* reset cpu by dog's time-out
*
*/
void rt_hw_cpu_reset()
{
rt_kprintf("Restarting system...\n");
at91sam9260_reset();
while(1); /* loop forever and wait for reset to happen */
/* NEVER REACHED */
}
/**
* shutdown CPU
*
*/
void rt_hw_cpu_shutdown()
{
rt_uint32_t level;
rt_kprintf("shutdown...\n");
level = rt_hw_interrupt_disable();
at91sam9260_poweroff();
while (level)
{
RT_ASSERT(0);
}
}
/*@}*/
/*
* File : cpu.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Develop Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://openlab.rt-thread.com/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2011-01-13 weety modified from mini2440
*/
#include <rthw.h>
#include <rtthread.h>
#include "at91sam926x.h"
/**
* @addtogroup AT91SAM926X
*/
/*@{*/
#define ICACHE_MASK (rt_uint32_t)(1 << 12)
#define DCACHE_MASK (rt_uint32_t)(1 << 2)
#ifdef __GNUC__
rt_inline rt_uint32_t cp15_rd(void)
{
rt_uint32_t i;
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
return i;
}
rt_inline void cache_enable(rt_uint32_t bit)
{
__asm__ __volatile__( \
"mrc p15,0,r0,c1,c0,0\n\t" \
"orr r0,r0,%0\n\t" \
"mcr p15,0,r0,c1,c0,0" \
: \
:"r" (bit) \
:"memory");
}
rt_inline void cache_disable(rt_uint32_t bit)
{
__asm__ __volatile__( \
"mrc p15,0,r0,c1,c0,0\n\t" \
"bic r0,r0,%0\n\t" \
"mcr p15,0,r0,c1,c0,0" \
: \
:"r" (bit) \
:"memory");
}
#endif
#ifdef __CC_ARM
rt_inline rt_uint32_t cp15_rd(void)
{
rt_uint32_t i;
__asm
{
mrc p15, 0, i, c1, c0, 0
}
return i;
}
rt_inline void cache_enable(rt_uint32_t bit)
{
rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
orr value, value, bit
mcr p15, 0, value, c1, c0, 0
}
}
rt_inline void cache_disable(rt_uint32_t bit)
{
rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
bic value, value, bit
mcr p15, 0, value, c1, c0, 0
}
}
#endif
/**
* enable I-Cache
*
*/
void rt_hw_cpu_icache_enable()
{
cache_enable(ICACHE_MASK);
}
/**
* disable I-Cache
*
*/
void rt_hw_cpu_icache_disable()
{
cache_disable(ICACHE_MASK);
}
/**
* return the status of I-Cache
*
*/
rt_base_t rt_hw_cpu_icache_status()
{
return (cp15_rd() & ICACHE_MASK);
}
/**
* enable D-Cache
*
*/
void rt_hw_cpu_dcache_enable()
{
cache_enable(DCACHE_MASK);
}
/**
* disable D-Cache
*
*/
void rt_hw_cpu_dcache_disable()
{
cache_disable(DCACHE_MASK);
}
/**
* return the status of D-Cache
*
*/
rt_base_t rt_hw_cpu_dcache_status()
{
return (cp15_rd() & DCACHE_MASK);
}
static void at91sam9260_reset(void)
{
at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
}
static void at91sam9260_poweroff(void)
{
at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
}
/**
* reset cpu by dog's time-out
*
*/
void rt_hw_cpu_reset()
{
rt_kprintf("Restarting system...\n");
at91sam9260_reset();
while(1); /* loop forever and wait for reset to happen */
/* NEVER REACHED */
}
/**
* shutdown CPU
*
*/
void rt_hw_cpu_shutdown()
{
rt_uint32_t level;
rt_kprintf("shutdown...\n");
level = rt_hw_interrupt_disable();
at91sam9260_poweroff();
while (level)
{
RT_ASSERT(0);
}
}
/*@}*/

View File

@ -1,395 +1,395 @@
/*
* File : mmu.c
* 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
* 2011-01-13 weety modified from mini2440
*/
#include <rtthread.h>
#include "at91sam926x.h"
#define _MMUTT_STARTADDRESS 0x33FF0000
#define DESC_SEC (0x2|(1<<4))
#define CB (3<<2) //cache_on, write_back
#define CNB (2<<2) //cache_on, write_through
#define NCB (1<<2) //cache_off,WR_BUF on
#define NCNB (0<<2) //cache_off,WR_BUF off
#define AP_RW (3<<10) //supervisor=RW, user=RW
#define AP_RO (2<<10) //supervisor=RW, user=RO
#define DOMAIN_FAULT (0x0)
#define DOMAIN_CHK (0x1)
#define DOMAIN_NOTCHK (0x3)
#define DOMAIN0 (0x0<<5)
#define DOMAIN1 (0x1<<5)
#define DOMAIN0_ATTR (DOMAIN_CHK<<0)
#define DOMAIN1_ATTR (DOMAIN_FAULT<<2)
#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC)
#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC)
#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC)
#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC)
#ifdef __GNUC__
void mmu_setttbase(register rt_uint32_t i)
{
asm ("mcr p15, 0, %0, c2, c0, 0": :"r" (i));
}
void mmu_set_domain(register rt_uint32_t i)
{
asm ("mcr p15,0, %0, c3, c0, 0": :"r" (i));
}
void mmu_enable()
{
register rt_uint32_t i;
/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i |= 0x1;
/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
void mmu_disable()
{
register rt_uint32_t i;
/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i &= ~0x1;
/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
void mmu_enable_icache()
{
register rt_uint32_t i;
/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i |= (1 << 12);
/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
void mmu_enable_dcache()
{
register rt_uint32_t i;
/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i |= (1 << 2);
/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
void mmu_disable_icache()
{
register rt_uint32_t i;
/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i &= ~(1 << 12);
/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
void mmu_disable_dcache()
{
register rt_uint32_t i;
/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i &= ~(1 << 2);
/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
void mmu_enable_alignfault()
{
register rt_uint32_t i;
/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i |= (1 << 1);
/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
void mmu_disable_alignfault()
{
register rt_uint32_t i;
/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i &= ~(1 << 1);
/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
void mmu_clean_invalidated_cache_index(int index)
{
asm ("mcr p15, 0, %0, c7, c14, 2": :"r" (index));
}
void mmu_invalidate_tlb()
{
asm ("mcr p15, 0, %0, c8, c7, 0": :"r" (0));
}
void mmu_invalidate_icache()
{
asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
}
#endif
#ifdef __CC_ARM
void mmu_setttbase(rt_uint32_t i)
{
__asm
{
mcr p15, 0, i, c2, c0, 0
}
}
void mmu_set_domain(rt_uint32_t i)
{
__asm
{
mcr p15,0, i, c3, c0, 0
}
}
void mmu_enable()
{
register rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
orr value, value, #0x01
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_disable()
{
register rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
bic value, value, #0x01
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_enable_icache()
{
register rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
orr value, value, #0x1000
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_enable_dcache()
{
register rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
orr value, value, #0x04
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_disable_icache()
{
register rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
bic value, value, #0x1000
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_disable_dcache()
{
register rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
bic value, value, #0x04
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_enable_alignfault()
{
register rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
orr value, value, #0x02
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_disable_alignfault()
{
register rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
bic value, value, #0x02
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_clean_invalidated_cache_index(int index)
{
__asm
{
mcr p15, 0, index, c7, c14, 2
}
}
void mmu_invalidate_tlb()
{
register rt_uint32_t value;
value = 0;
__asm
{
mcr p15, 0, value, c8, c7, 0
}
}
void mmu_invalidate_icache()
{
register rt_uint32_t value;
value = 0;
__asm
{
mcr p15, 0, value, c7, c5, 0
}
}
#endif
void mmu_setmtt(int vaddrStart,int vaddrEnd,int paddrStart,int attr)
{
volatile rt_uint32_t *pTT;
volatile int i,nSec;
pTT=(rt_uint32_t *)_MMUTT_STARTADDRESS+(vaddrStart>>20);
nSec=(vaddrEnd>>20)-(vaddrStart>>20);
for(i=0;i<=nSec;i++)
{
*pTT = attr |(((paddrStart>>20)+i)<<20);
pTT++;
}
}
void rt_hw_mmu_init(void)
{
#if 0
int i,j;
//========================== IMPORTANT NOTE =========================
//The current stack and code area can't be re-mapped in this routine.
//If you want memory map mapped freely, your own sophiscated mmu
//initialization code is needed.
//===================================================================
mmu_disable_dcache();
mmu_disable_icache();
//If write-back is used,the DCache should be cleared.
for(i=0;i<64;i++)
for(j=0;j<8;j++)
mmu_clean_invalidated_cache_index((i<<26)|(j<<5));
mmu_invalidate_icache();
//To complete mmu_Init() fast, Icache may be turned on here.
mmu_enable_icache();
mmu_disable();
mmu_invalidate_tlb();
//mmu_setmtt(int vaddrStart,int vaddrEnd,int paddrStart,int attr);
mmu_setmtt(0x00000000,0x07f00000,0x00000000,RW_CNB); //bank0
mmu_setmtt(0x00000000,0x03f00000,(int)0x30000000,RW_CB); //bank0
mmu_setmtt(0x04000000,0x07f00000,0,RW_NCNB); //bank0
mmu_setmtt(0x08000000,0x0ff00000,0x08000000,RW_CNB); //bank1
mmu_setmtt(0x10000000,0x17f00000,0x10000000,RW_NCNB); //bank2
mmu_setmtt(0x18000000,0x1ff00000,0x18000000,RW_NCNB); //bank3
//mmu_setmtt(0x20000000,0x27f00000,0x20000000,RW_CB); //bank4
mmu_setmtt(0x20000000,0x27f00000,0x20000000,RW_NCNB); //bank4 for DM9000
mmu_setmtt(0x28000000,0x2ff00000,0x28000000,RW_NCNB); //bank5
//30f00000->30100000, 31000000->30200000
mmu_setmtt(0x30000000,0x30100000,0x30000000,RW_CB); //bank6-1
mmu_setmtt(0x30200000,0x33e00000,0x30200000,RW_CB); //bank6-2
mmu_setmtt(0x33f00000,0x34000000,0x33f00000,RW_NCNB); //bank6-3
mmu_setmtt(0x38000000,0x3ff00000,0x38000000,RW_NCNB); //bank7
mmu_setmtt(0x40000000,0x47f00000,0x40000000,RW_NCNB); //SFR
mmu_setmtt(0x48000000,0x5af00000,0x48000000,RW_NCNB); //SFR
mmu_setmtt(0x5b000000,0x5b000000,0x5b000000,RW_NCNB); //SFR
mmu_setmtt(0x5b100000,0xfff00000,0x5b100000,RW_FAULT);//not used
mmu_setmtt(0x60000000,0x67f00000,0x60000000,RW_NCNB); //SFR
mmu_setttbase(_MMUTT_STARTADDRESS);
/* DOMAIN1: no_access, DOMAIN0,2~15=client(AP is checked) */
mmu_set_domain(0x55555550|DOMAIN1_ATTR|DOMAIN0_ATTR);
mmu_enable_alignfault();
mmu_enable();
/* ICache enable */
mmu_enable_icache();
/* DCache should be turned on after mmu is turned on. */
mmu_enable_dcache();
#endif
}
/*
* File : mmu.c
* 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
* 2011-01-13 weety modified from mini2440
*/
#include <rtthread.h>
#include "at91sam926x.h"
#define _MMUTT_STARTADDRESS 0x33FF0000
#define DESC_SEC (0x2|(1<<4))
#define CB (3<<2) //cache_on, write_back
#define CNB (2<<2) //cache_on, write_through
#define NCB (1<<2) //cache_off,WR_BUF on
#define NCNB (0<<2) //cache_off,WR_BUF off
#define AP_RW (3<<10) //supervisor=RW, user=RW
#define AP_RO (2<<10) //supervisor=RW, user=RO
#define DOMAIN_FAULT (0x0)
#define DOMAIN_CHK (0x1)
#define DOMAIN_NOTCHK (0x3)
#define DOMAIN0 (0x0<<5)
#define DOMAIN1 (0x1<<5)
#define DOMAIN0_ATTR (DOMAIN_CHK<<0)
#define DOMAIN1_ATTR (DOMAIN_FAULT<<2)
#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC)
#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC)
#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC)
#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC)
#ifdef __GNUC__
void mmu_setttbase(register rt_uint32_t i)
{
asm ("mcr p15, 0, %0, c2, c0, 0": :"r" (i));
}
void mmu_set_domain(register rt_uint32_t i)
{
asm ("mcr p15,0, %0, c3, c0, 0": :"r" (i));
}
void mmu_enable()
{
register rt_uint32_t i;
/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i |= 0x1;
/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
void mmu_disable()
{
register rt_uint32_t i;
/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i &= ~0x1;
/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
void mmu_enable_icache()
{
register rt_uint32_t i;
/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i |= (1 << 12);
/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
void mmu_enable_dcache()
{
register rt_uint32_t i;
/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i |= (1 << 2);
/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
void mmu_disable_icache()
{
register rt_uint32_t i;
/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i &= ~(1 << 12);
/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
void mmu_disable_dcache()
{
register rt_uint32_t i;
/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i &= ~(1 << 2);
/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
void mmu_enable_alignfault()
{
register rt_uint32_t i;
/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i |= (1 << 1);
/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
void mmu_disable_alignfault()
{
register rt_uint32_t i;
/* read control register */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i &= ~(1 << 1);
/* write back to control register */
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
}
void mmu_clean_invalidated_cache_index(int index)
{
asm ("mcr p15, 0, %0, c7, c14, 2": :"r" (index));
}
void mmu_invalidate_tlb()
{
asm ("mcr p15, 0, %0, c8, c7, 0": :"r" (0));
}
void mmu_invalidate_icache()
{
asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
}
#endif
#ifdef __CC_ARM
void mmu_setttbase(rt_uint32_t i)
{
__asm
{
mcr p15, 0, i, c2, c0, 0
}
}
void mmu_set_domain(rt_uint32_t i)
{
__asm
{
mcr p15,0, i, c3, c0, 0
}
}
void mmu_enable()
{
register rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
orr value, value, #0x01
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_disable()
{
register rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
bic value, value, #0x01
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_enable_icache()
{
register rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
orr value, value, #0x1000
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_enable_dcache()
{
register rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
orr value, value, #0x04
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_disable_icache()
{
register rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
bic value, value, #0x1000
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_disable_dcache()
{
register rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
bic value, value, #0x04
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_enable_alignfault()
{
register rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
orr value, value, #0x02
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_disable_alignfault()
{
register rt_uint32_t value;
__asm
{
mrc p15, 0, value, c1, c0, 0
bic value, value, #0x02
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_clean_invalidated_cache_index(int index)
{
__asm
{
mcr p15, 0, index, c7, c14, 2
}
}
void mmu_invalidate_tlb()
{
register rt_uint32_t value;
value = 0;
__asm
{
mcr p15, 0, value, c8, c7, 0
}
}
void mmu_invalidate_icache()
{
register rt_uint32_t value;
value = 0;
__asm
{
mcr p15, 0, value, c7, c5, 0
}
}
#endif
void mmu_setmtt(int vaddrStart,int vaddrEnd,int paddrStart,int attr)
{
volatile rt_uint32_t *pTT;
volatile int i,nSec;
pTT=(rt_uint32_t *)_MMUTT_STARTADDRESS+(vaddrStart>>20);
nSec=(vaddrEnd>>20)-(vaddrStart>>20);
for(i=0;i<=nSec;i++)
{
*pTT = attr |(((paddrStart>>20)+i)<<20);
pTT++;
}
}
void rt_hw_mmu_init(void)
{
#if 0
int i,j;
//========================== IMPORTANT NOTE =========================
//The current stack and code area can't be re-mapped in this routine.
//If you want memory map mapped freely, your own sophiscated mmu
//initialization code is needed.
//===================================================================
mmu_disable_dcache();
mmu_disable_icache();
//If write-back is used,the DCache should be cleared.
for(i=0;i<64;i++)
for(j=0;j<8;j++)
mmu_clean_invalidated_cache_index((i<<26)|(j<<5));
mmu_invalidate_icache();
//To complete mmu_Init() fast, Icache may be turned on here.
mmu_enable_icache();
mmu_disable();
mmu_invalidate_tlb();
//mmu_setmtt(int vaddrStart,int vaddrEnd,int paddrStart,int attr);
mmu_setmtt(0x00000000,0x07f00000,0x00000000,RW_CNB); //bank0
mmu_setmtt(0x00000000,0x03f00000,(int)0x30000000,RW_CB); //bank0
mmu_setmtt(0x04000000,0x07f00000,0,RW_NCNB); //bank0
mmu_setmtt(0x08000000,0x0ff00000,0x08000000,RW_CNB); //bank1
mmu_setmtt(0x10000000,0x17f00000,0x10000000,RW_NCNB); //bank2
mmu_setmtt(0x18000000,0x1ff00000,0x18000000,RW_NCNB); //bank3
//mmu_setmtt(0x20000000,0x27f00000,0x20000000,RW_CB); //bank4
mmu_setmtt(0x20000000,0x27f00000,0x20000000,RW_NCNB); //bank4 for DM9000
mmu_setmtt(0x28000000,0x2ff00000,0x28000000,RW_NCNB); //bank5
//30f00000->30100000, 31000000->30200000
mmu_setmtt(0x30000000,0x30100000,0x30000000,RW_CB); //bank6-1
mmu_setmtt(0x30200000,0x33e00000,0x30200000,RW_CB); //bank6-2
mmu_setmtt(0x33f00000,0x34000000,0x33f00000,RW_NCNB); //bank6-3
mmu_setmtt(0x38000000,0x3ff00000,0x38000000,RW_NCNB); //bank7
mmu_setmtt(0x40000000,0x47f00000,0x40000000,RW_NCNB); //SFR
mmu_setmtt(0x48000000,0x5af00000,0x48000000,RW_NCNB); //SFR
mmu_setmtt(0x5b000000,0x5b000000,0x5b000000,RW_NCNB); //SFR
mmu_setmtt(0x5b100000,0xfff00000,0x5b100000,RW_FAULT);//not used
mmu_setmtt(0x60000000,0x67f00000,0x60000000,RW_NCNB); //SFR
mmu_setttbase(_MMUTT_STARTADDRESS);
/* DOMAIN1: no_access, DOMAIN0,2~15=client(AP is checked) */
mmu_set_domain(0x55555550|DOMAIN1_ATTR|DOMAIN0_ATTR);
mmu_enable_alignfault();
mmu_enable();
/* ICache enable */
mmu_enable_icache();
/* DCache should be turned on after mmu is turned on. */
mmu_enable_dcache();
#endif
}

View File

@ -1,76 +1,76 @@
#ifndef __RT_HW_SERIAL_H__
#define __RT_HW_SERIAL_H__
#include <rthw.h>
#include <rtthread.h>
#include "at91sam926x.h"
#define RXRDY 0x01
#define TXRDY (1 << 1)
#define BPS 115200 /* serial baudrate */
#define UART_RX_BUFFER_SIZE 64
#define UART_TX_BUFFER_SIZE 64
struct serial_int_rx
{
rt_uint8_t rx_buffer[UART_RX_BUFFER_SIZE];
rt_uint32_t read_index, save_index;
};
struct serial_int_tx
{
rt_uint8_t tx_buffer[UART_TX_BUFFER_SIZE];
rt_uint32_t write_index, save_index;
};
typedef struct uartport
{
/* USART register offsets */
volatile rt_uint32_t USART_CR;
volatile rt_uint32_t USART_MR;
volatile rt_uint32_t USART_IER;
volatile rt_uint32_t USART_IDR;
volatile rt_uint32_t USART_IMR;
volatile rt_uint32_t USART_CSR;
volatile rt_uint32_t USART_RHR;
volatile rt_uint32_t USART_THR;
volatile rt_uint32_t USART_BRGR;
volatile rt_uint32_t USART_RTOR;
volatile rt_uint32_t USART_TTGR;
volatile rt_uint32_t reseverd0[5];
volatile rt_uint32_t USART_FIDI;
volatile rt_uint32_t USART_NER;
volatile rt_uint32_t USART_XXR;
volatile rt_uint32_t USART_IFR;
volatile rt_uint32_t reserved1[44];
volatile rt_uint32_t USART_RPR;
volatile rt_uint32_t USART_RCR;
volatile rt_uint32_t USART_TPR;
volatile rt_uint32_t USART_TCR;
volatile rt_uint32_t USART_RNPR;
volatile rt_uint32_t USART_RNCR;
volatile rt_uint32_t USART_TNPR;
volatile rt_uint32_t USART_TNCR;
volatile rt_uint32_t USART_PTCR;
volatile rt_uint32_t USART_PTSR;
}uartport;
struct serial_device
{
uartport* uart_device;
/* rx structure */
struct serial_int_rx* int_rx;
/* tx structure */
struct serial_int_tx* int_tx;
};
rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct serial_device *serial);
void rt_hw_serial_isr(rt_device_t device);
#endif
#ifndef __RT_HW_SERIAL_H__
#define __RT_HW_SERIAL_H__
#include <rthw.h>
#include <rtthread.h>
#include "at91sam926x.h"
#define RXRDY 0x01
#define TXRDY (1 << 1)
#define BPS 115200 /* serial baudrate */
#define UART_RX_BUFFER_SIZE 64
#define UART_TX_BUFFER_SIZE 64
struct serial_int_rx
{
rt_uint8_t rx_buffer[UART_RX_BUFFER_SIZE];
rt_uint32_t read_index, save_index;
};
struct serial_int_tx
{
rt_uint8_t tx_buffer[UART_TX_BUFFER_SIZE];
rt_uint32_t write_index, save_index;
};
typedef struct uartport
{
/* USART register offsets */
volatile rt_uint32_t USART_CR;
volatile rt_uint32_t USART_MR;
volatile rt_uint32_t USART_IER;
volatile rt_uint32_t USART_IDR;
volatile rt_uint32_t USART_IMR;
volatile rt_uint32_t USART_CSR;
volatile rt_uint32_t USART_RHR;
volatile rt_uint32_t USART_THR;
volatile rt_uint32_t USART_BRGR;
volatile rt_uint32_t USART_RTOR;
volatile rt_uint32_t USART_TTGR;
volatile rt_uint32_t reseverd0[5];
volatile rt_uint32_t USART_FIDI;
volatile rt_uint32_t USART_NER;
volatile rt_uint32_t USART_XXR;
volatile rt_uint32_t USART_IFR;
volatile rt_uint32_t reserved1[44];
volatile rt_uint32_t USART_RPR;
volatile rt_uint32_t USART_RCR;
volatile rt_uint32_t USART_TPR;
volatile rt_uint32_t USART_TCR;
volatile rt_uint32_t USART_RNPR;
volatile rt_uint32_t USART_RNCR;
volatile rt_uint32_t USART_TNPR;
volatile rt_uint32_t USART_TNCR;
volatile rt_uint32_t USART_PTCR;
volatile rt_uint32_t USART_PTSR;
}uartport;
struct serial_device
{
uartport* uart_device;
/* rx structure */
struct serial_int_rx* int_rx;
/* tx structure */
struct serial_int_tx* int_tx;
};
rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct serial_device *serial);
void rt_hw_serial_isr(rt_device_t device);
#endif

View File

@ -1,315 +1,315 @@
;/*
; * File : start_rvds.S
; * 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
; * 2011-08-14 weety first version
; */
; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
Mode_USR EQU 0x10
Mode_FIQ EQU 0x11
Mode_IRQ EQU 0x12
Mode_SVC EQU 0x13
Mode_ABT EQU 0x17
Mode_UND EQU 0x1B
Mode_SYS EQU 0x1F
SVCMODE EQU 0x13
MODEMASK EQU 0x1f
I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
;----------------------- Stack and Heap Definitions ----------------------------
;// <h> Stack Configuration (Stack Sizes in Bytes)
;// <o0> Undefined Mode <0x0-0xFFFFFFFF:8>
;// <o1> Supervisor Mode <0x0-0xFFFFFFFF:8>
;// <o2> Abort Mode <0x0-0xFFFFFFFF:8>
;// <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
;// <o4> Interrupt Mode <0x0-0xFFFFFFFF:8>
;// <o5> User/System Mode <0x0-0xFFFFFFFF:8>
;// </h>
UND_Stack_Size EQU 512
SVC_Stack_Size EQU 4096
ABT_Stack_Size EQU 512
FIQ_Stack_Size EQU 1024
IRQ_Stack_Size EQU 1024
USR_Stack_Size EQU 512
ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
FIQ_Stack_Size + IRQ_Stack_Size)
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE USR_Stack_Size
__initial_sp SPACE ISR_Stack_Size
Stack_Top
;// <h> Heap Configuration
;// <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF>
;// </h>
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
;----------------------- Memory Definitions ------------------------------------
AT91_MATRIX_BASE EQU 0xffffee00
AT91_MATRIX_MRCR EQU (AT91_MATRIX_BASE + 0x100)
AT91_MATRIX_RCB0 EQU 0x00000001
AT91_MATRIX_RCB1 EQU 0x00000002
AT91_AIC_BASE EQU 0xfffff000
AT91_AIC_IDCR EQU 0x124
AT91_AIC_ICCR EQU 0x128
;----------------------- CODE --------------------------------------------------
PRESERVE8
; Area Definition and Entry Point
; Startup Code must be linked first at Address at which it expects to run.
AREA RESET, CODE, READONLY
ARM
; Exception Vectors
; Mapped to Address 0.
; Absolute addressing mode must be used.
; Dummy Handlers are implemented as infinite loops which can be modified.
EXPORT Entry_Point
Entry_Point
Vectors LDR PC, Reset_Addr
LDR PC, Undef_Addr
LDR PC, SWI_Addr
LDR PC, PAbt_Addr
LDR PC, DAbt_Addr
NOP
LDR PC, IRQ_Addr
LDR PC, FIQ_Addr
Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
SWI_Addr DCD SWI_Handler
PAbt_Addr DCD PAbt_Handler
DAbt_Addr DCD DAbt_Handler
DCD 0 ; Reserved Address
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler
Undef_Handler B Undef_Handler
SWI_Handler B SWI_Handler
PAbt_Handler B PAbt_Handler
;DAbt_Handler B DAbt_Handler
FIQ_Handler B FIQ_Handler
;*
;*************************************************************************
;*
;* Interrupt handling
;*
;*************************************************************************
;*
; DAbt Handler
DAbt_Handler
IMPORT rt_hw_trap_dabt
sub sp, sp, #72
stmia sp, {r0 - r12} ;/* Calling r0-r12 */
add r8, sp, #60
stmdb r8, {sp, lr} ;/* Calling SP, LR */
str lr, [r8, #0] ;/* Save calling PC */
mrs r6, spsr
str r6, [r8, #4] ;/* Save CPSR */
str r0, [r8, #8] ;/* Save OLD_R0 */
mov r0, sp
bl rt_hw_trap_dabt
;##########################################
; Reset Handler
EXPORT Reset_Handler
Reset_Handler
; set the cpu to SVC32 mode-----------------------------------------------------
MRS R0,CPSR
BIC R0,R0,#MODEMASK
ORR R0,R0,#SVCMODE
MSR CPSR_cxsf,R0
LDR R1, =AT91_AIC_BASE
LDR R0, =0xffffffff
STR R0, [R1, #AT91_AIC_IDCR]
STR R0, [R1, #AT91_AIC_ICCR]
; remap internal ram to 0x00000000 address
LDR R0, =AT91_MATRIX_MRCR
LDR R1, =(AT91_MATRIX_RCB0|AT91_MATRIX_RCB1)
STR R1, [R0]
; Copy Exception Vectors to Internal RAM ---------------------------------------
ADR R8, Vectors ; Source
LDR R9, =0x00 ; Destination
LDMIA R8!, {R0-R7} ; Load Vectors
STMIA R9!, {R0-R7} ; Store Vectors
LDMIA R8!, {R0-R7} ; Load Handler Addresses
STMIA R9!, {R0-R7} ; Store Handler Addresses
; Setup Stack for each mode ----------------------------------------------------
LDR R0, =Stack_Top
; Enter Undefined Instruction Mode and set its Stack Pointer
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #UND_Stack_Size
; Enter Abort Mode and set its Stack Pointer
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size
; Enter FIQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size
; Enter IRQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size
; Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size
; Enter User Mode and set its Stack Pointer
; MSR CPSR_c, #Mode_USR
MOV SP, R0
SUB SL, SP, #USR_Stack_Size
; Enter the C code -------------------------------------------------------------
IMPORT __main
LDR R0, =__main
BX R0
IMPORT rt_interrupt_enter
IMPORT rt_interrupt_leave
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
IMPORT rt_hw_trap_irq
IRQ_Handler PROC
EXPORT IRQ_Handler
STMFD sp!, {r0-r12,lr}
BL rt_interrupt_enter
BL rt_hw_trap_irq
BL rt_interrupt_leave
; if rt_thread_switch_interrupt_flag set, jump to
; rt_hw_context_switch_interrupt_do and don't return
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CMP r1, #1
BEQ rt_hw_context_switch_interrupt_do
LDMFD sp!, {r0-r12,lr}
SUBS pc, lr, #4
ENDP
; /*
; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
; */
rt_hw_context_switch_interrupt_do PROC
EXPORT rt_hw_context_switch_interrupt_do
MOV r1, #0 ; clear flag
STR r1, [r0]
LDMFD sp!, {r0-r12,lr}; reload saved registers
STMFD sp!, {r0-r3} ; save r0-r3
MOV r1, sp
ADD sp, sp, #16 ; restore sp
SUB r2, lr, #4 ; save old task's pc to r2
MRS r3, spsr ; get cpsr of interrupt thread
; switch to SVC mode and no interrupt
MSR cpsr_c, #I_Bit:OR:F_Bit:OR:Mode_SVC
STMFD sp!, {r2} ; push old task's pc
STMFD sp!, {r4-r12,lr}; push old task's lr,r12-r4
MOV r4, r1 ; Special optimised code below
MOV r5, r3
LDMFD r4!, {r0-r3}
STMFD sp!, {r0-r3} ; push old task's r3-r0
STMFD sp!, {r5} ; push old task's cpsr
MRS r4, spsr
STMFD sp!, {r4} ; push old task's spsr
LDR r4, =rt_interrupt_from_thread
LDR r5, [r4]
STR sp, [r5] ; store sp in preempted tasks's TCB
LDR r6, =rt_interrupt_to_thread
LDR r6, [r6]
LDR sp, [r6] ; get new task's stack pointer
LDMFD sp!, {r4} ; pop new task's spsr
MSR spsr_cxsf, r4
LDMFD sp!, {r4} ; pop new task's psr
MSR cpsr_cxsf, r4
LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc
ENDP
IF :DEF:__MICROLIB
EXPORT __heap_base
EXPORT __heap_limit
ELSE
; User Initial Stack & Heap
AREA |.text|, CODE, READONLY
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + USR_Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ENDIF
END
;/*
; * File : start_rvds.S
; * 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
; * 2011-08-14 weety first version
; */
; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
Mode_USR EQU 0x10
Mode_FIQ EQU 0x11
Mode_IRQ EQU 0x12
Mode_SVC EQU 0x13
Mode_ABT EQU 0x17
Mode_UND EQU 0x1B
Mode_SYS EQU 0x1F
SVCMODE EQU 0x13
MODEMASK EQU 0x1f
I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
;----------------------- Stack and Heap Definitions ----------------------------
;// <h> Stack Configuration (Stack Sizes in Bytes)
;// <o0> Undefined Mode <0x0-0xFFFFFFFF:8>
;// <o1> Supervisor Mode <0x0-0xFFFFFFFF:8>
;// <o2> Abort Mode <0x0-0xFFFFFFFF:8>
;// <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
;// <o4> Interrupt Mode <0x0-0xFFFFFFFF:8>
;// <o5> User/System Mode <0x0-0xFFFFFFFF:8>
;// </h>
UND_Stack_Size EQU 512
SVC_Stack_Size EQU 4096
ABT_Stack_Size EQU 512
FIQ_Stack_Size EQU 1024
IRQ_Stack_Size EQU 1024
USR_Stack_Size EQU 512
ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
FIQ_Stack_Size + IRQ_Stack_Size)
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE USR_Stack_Size
__initial_sp SPACE ISR_Stack_Size
Stack_Top
;// <h> Heap Configuration
;// <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF>
;// </h>
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
;----------------------- Memory Definitions ------------------------------------
AT91_MATRIX_BASE EQU 0xffffee00
AT91_MATRIX_MRCR EQU (AT91_MATRIX_BASE + 0x100)
AT91_MATRIX_RCB0 EQU 0x00000001
AT91_MATRIX_RCB1 EQU 0x00000002
AT91_AIC_BASE EQU 0xfffff000
AT91_AIC_IDCR EQU 0x124
AT91_AIC_ICCR EQU 0x128
;----------------------- CODE --------------------------------------------------
PRESERVE8
; Area Definition and Entry Point
; Startup Code must be linked first at Address at which it expects to run.
AREA RESET, CODE, READONLY
ARM
; Exception Vectors
; Mapped to Address 0.
; Absolute addressing mode must be used.
; Dummy Handlers are implemented as infinite loops which can be modified.
EXPORT Entry_Point
Entry_Point
Vectors LDR PC, Reset_Addr
LDR PC, Undef_Addr
LDR PC, SWI_Addr
LDR PC, PAbt_Addr
LDR PC, DAbt_Addr
NOP
LDR PC, IRQ_Addr
LDR PC, FIQ_Addr
Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
SWI_Addr DCD SWI_Handler
PAbt_Addr DCD PAbt_Handler
DAbt_Addr DCD DAbt_Handler
DCD 0 ; Reserved Address
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler
Undef_Handler B Undef_Handler
SWI_Handler B SWI_Handler
PAbt_Handler B PAbt_Handler
;DAbt_Handler B DAbt_Handler
FIQ_Handler B FIQ_Handler
;*
;*************************************************************************
;*
;* Interrupt handling
;*
;*************************************************************************
;*
; DAbt Handler
DAbt_Handler
IMPORT rt_hw_trap_dabt
sub sp, sp, #72
stmia sp, {r0 - r12} ;/* Calling r0-r12 */
add r8, sp, #60
stmdb r8, {sp, lr} ;/* Calling SP, LR */
str lr, [r8, #0] ;/* Save calling PC */
mrs r6, spsr
str r6, [r8, #4] ;/* Save CPSR */
str r0, [r8, #8] ;/* Save OLD_R0 */
mov r0, sp
bl rt_hw_trap_dabt
;##########################################
; Reset Handler
EXPORT Reset_Handler
Reset_Handler
; set the cpu to SVC32 mode-----------------------------------------------------
MRS R0,CPSR
BIC R0,R0,#MODEMASK
ORR R0,R0,#SVCMODE
MSR CPSR_cxsf,R0
LDR R1, =AT91_AIC_BASE
LDR R0, =0xffffffff
STR R0, [R1, #AT91_AIC_IDCR]
STR R0, [R1, #AT91_AIC_ICCR]
; remap internal ram to 0x00000000 address
LDR R0, =AT91_MATRIX_MRCR
LDR R1, =(AT91_MATRIX_RCB0|AT91_MATRIX_RCB1)
STR R1, [R0]
; Copy Exception Vectors to Internal RAM ---------------------------------------
ADR R8, Vectors ; Source
LDR R9, =0x00 ; Destination
LDMIA R8!, {R0-R7} ; Load Vectors
STMIA R9!, {R0-R7} ; Store Vectors
LDMIA R8!, {R0-R7} ; Load Handler Addresses
STMIA R9!, {R0-R7} ; Store Handler Addresses
; Setup Stack for each mode ----------------------------------------------------
LDR R0, =Stack_Top
; Enter Undefined Instruction Mode and set its Stack Pointer
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #UND_Stack_Size
; Enter Abort Mode and set its Stack Pointer
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size
; Enter FIQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size
; Enter IRQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size
; Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size
; Enter User Mode and set its Stack Pointer
; MSR CPSR_c, #Mode_USR
MOV SP, R0
SUB SL, SP, #USR_Stack_Size
; Enter the C code -------------------------------------------------------------
IMPORT __main
LDR R0, =__main
BX R0
IMPORT rt_interrupt_enter
IMPORT rt_interrupt_leave
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
IMPORT rt_hw_trap_irq
IRQ_Handler PROC
EXPORT IRQ_Handler
STMFD sp!, {r0-r12,lr}
BL rt_interrupt_enter
BL rt_hw_trap_irq
BL rt_interrupt_leave
; if rt_thread_switch_interrupt_flag set, jump to
; rt_hw_context_switch_interrupt_do and don't return
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CMP r1, #1
BEQ rt_hw_context_switch_interrupt_do
LDMFD sp!, {r0-r12,lr}
SUBS pc, lr, #4
ENDP
; /*
; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
; */
rt_hw_context_switch_interrupt_do PROC
EXPORT rt_hw_context_switch_interrupt_do
MOV r1, #0 ; clear flag
STR r1, [r0]
LDMFD sp!, {r0-r12,lr}; reload saved registers
STMFD sp!, {r0-r3} ; save r0-r3
MOV r1, sp
ADD sp, sp, #16 ; restore sp
SUB r2, lr, #4 ; save old task's pc to r2
MRS r3, spsr ; get cpsr of interrupt thread
; switch to SVC mode and no interrupt
MSR cpsr_c, #I_Bit:OR:F_Bit:OR:Mode_SVC
STMFD sp!, {r2} ; push old task's pc
STMFD sp!, {r4-r12,lr}; push old task's lr,r12-r4
MOV r4, r1 ; Special optimised code below
MOV r5, r3
LDMFD r4!, {r0-r3}
STMFD sp!, {r0-r3} ; push old task's r3-r0
STMFD sp!, {r5} ; push old task's cpsr
MRS r4, spsr
STMFD sp!, {r4} ; push old task's spsr
LDR r4, =rt_interrupt_from_thread
LDR r5, [r4]
STR sp, [r5] ; store sp in preempted tasks's TCB
LDR r6, =rt_interrupt_to_thread
LDR r6, [r6]
LDR sp, [r6] ; get new task's stack pointer
LDMFD sp!, {r4} ; pop new task's spsr
MSR spsr_cxsf, r4
LDMFD sp!, {r4} ; pop new task's psr
MSR cpsr_cxsf, r4
LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc
ENDP
IF :DEF:__MICROLIB
EXPORT __heap_base
EXPORT __heap_limit
ELSE
; User Initial Stack & Heap
AREA |.text|, CODE, READONLY
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + USR_Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ENDIF
END

View File

@ -1,294 +1,294 @@
/*
* File : clock.c
* 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://openlab.rt-thread.com/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2011-01-13 weety first version
*/
#include <rtthread.h>
#include "at91sam926x.h"
static rt_list_t clocks;
struct clk {
char name[32];
rt_uint32_t rate_hz;
struct clk *parent;
rt_list_t node;
};
static struct clk clk32k = {
"clk32k",
AT91_SLOW_CLOCK,
RT_NULL,
{RT_NULL, RT_NULL},
};
static struct clk main_clk = {
"main",
0,
RT_NULL,
{RT_NULL, RT_NULL},
};
static struct clk plla = {
"plla",
0,
RT_NULL,
{RT_NULL, RT_NULL},
};
static struct clk mck = {
"mck",
0,
RT_NULL,
{RT_NULL, RT_NULL},
};
static struct clk uhpck = {
"uhpck",
0,
RT_NULL,
{RT_NULL, RT_NULL},
};
static struct clk pllb = {
"pllb",
0,
&main_clk,
{RT_NULL, RT_NULL},
};
static struct clk udpck = {
"udpck",
0,
&pllb,
{RT_NULL, RT_NULL},
};
static struct clk *const standard_pmc_clocks[] = {
/* four primary clocks */
&clk32k,
&main_clk,
&plla,
/* MCK */
&mck
};
/* clocks cannot be de-registered no refcounting necessary */
struct clk *clk_get(const char *id)
{
struct clk *clk;
rt_list_t *list;
for (list = (&clocks)->next; list != &clocks; list = list->next)
{
clk = (struct clk *)rt_list_entry(list, struct clk, node);
if (rt_strcmp(id, clk->name) == 0)
return clk;
}
return RT_NULL;
}
rt_uint32_t clk_get_rate(struct clk *clk)
{
rt_uint32_t flags;
rt_uint32_t rate;
for (;;) {
rate = clk->rate_hz;
if (rate || !clk->parent)
break;
clk = clk->parent;
}
return rate;
}
static rt_uint32_t at91_pll_rate(struct clk *pll, rt_uint32_t freq, rt_uint32_t reg)
{
unsigned mul, div;
div = reg & 0xff;
mul = (reg >> 16) & 0x7ff;
if (div && mul) {
freq /= div;
freq *= mul + 1;
} else
freq = 0;
return freq;
}
static unsigned at91_pll_calc(unsigned main_freq, unsigned out_freq)
{
unsigned i, div = 0, mul = 0, diff = 1 << 30;
unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00;
/* PLL output max 240 MHz (or 180 MHz per errata) */
if (out_freq > 240000000)
goto fail;
for (i = 1; i < 256; i++) {
int diff1;
unsigned input, mul1;
/*
* PLL input between 1MHz and 32MHz per spec, but lower
* frequences seem necessary in some cases so allow 100K.
* Warning: some newer products need 2MHz min.
*/
input = main_freq / i;
if (input < 100000)
continue;
if (input > 32000000)
continue;
mul1 = out_freq / input;
if (mul1 > 2048)
continue;
if (mul1 < 2)
goto fail;
diff1 = out_freq - input * mul1;
if (diff1 < 0)
diff1 = -diff1;
if (diff > diff1) {
diff = diff1;
div = i;
mul = mul1;
if (diff == 0)
break;
}
}
if (i == 256 && diff > (out_freq >> 5))
goto fail;
return ret | ((mul - 1) << 16) | div;
fail:
return 0;
}
static rt_uint32_t at91_usb_rate(struct clk *pll, rt_uint32_t freq, rt_uint32_t reg)
{
if (pll == &pllb && (reg & AT91_PMC_USB96M))
return freq / 2;
else
return freq;
}
/* PLLB generated USB full speed clock init */
static void at91_pllb_usbfs_clock_init(rt_uint32_t main_clock)
{
rt_uint32_t at91_pllb_usb_init;
/*
* USB clock init: choose 48 MHz PLLB value,
* disable 48MHz clock during usb peripheral suspend.
*
* REVISIT: assumes MCK doesn't derive from PLLB!
*/
uhpck.parent = &pllb;
at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M;
pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init);
at91_sys_write(AT91_CKGR_PLLBR, 0);
udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
}
static struct clk *at91_css_to_clk(unsigned long css)
{
switch (css) {
case AT91_PMC_CSS_SLOW:
return &clk32k;
case AT91_PMC_CSS_MAIN:
return &main_clk;
case AT91_PMC_CSS_PLLA:
return &plla;
case AT91_PMC_CSS_PLLB:
return &pllb;
}
return RT_NULL;
}
#define false 0
#define true 1
int at91_clock_init(rt_uint32_t main_clock)
{
unsigned tmp, freq, mckr;
int i;
int pll_overclock = false;
/*
* When the bootloader initialized the main oscillator correctly,
* there's no problem using the cycle counter. But if it didn't,
* or when using oscillator bypass mode, we must be told the speed
* of the main clock.
*/
if (!main_clock) {
do {
tmp = at91_sys_read(AT91_CKGR_MCFR);
} while (!(tmp & AT91_PMC_MAINRDY));
main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16);
}
main_clk.rate_hz = main_clock;
/* report if PLLA is more than mildly overclocked */
plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR));
if (plla.rate_hz > 209000000)
pll_overclock = true;
if (pll_overclock)
;//rt_kprintf("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
at91_pllb_usbfs_clock_init(main_clock);
/*
* MCK and CPU derive from one of those primary clocks.
* For now, assume this parentage won't change.
*/
mckr = at91_sys_read(AT91_PMC_MCKR);
mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
freq = mck.parent->rate_hz;
freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2)); /* prescale */
mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
/* Register the PMC's standard clocks */
rt_list_init(&clocks);
for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
rt_list_insert_after(&clocks, &standard_pmc_clocks[i]->node);
rt_list_insert_after(&clocks, &pllb.node);
rt_list_insert_after(&clocks, &uhpck.node);
rt_list_insert_after(&clocks, &udpck.node);
/* MCK and CPU clock are "always on" */
//clk_enable(&mck);
/*rt_kprintf("Clocks: CPU %u MHz, master %u MHz, main %u.%03u MHz\n",
freq / 1000000, (unsigned) mck.rate_hz / 1000000,
(unsigned) main_clock / 1000000,
((unsigned) main_clock % 1000000) / 1000);*///cause blocked
return 0;
}
/**
* @brief System Clock Configuration
*/
void rt_hw_clock_init(void)
{
at91_clock_init(18432000);
}
/*
* File : clock.c
* 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://openlab.rt-thread.com/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2011-01-13 weety first version
*/
#include <rtthread.h>
#include "at91sam926x.h"
static rt_list_t clocks;
struct clk {
char name[32];
rt_uint32_t rate_hz;
struct clk *parent;
rt_list_t node;
};
static struct clk clk32k = {
"clk32k",
AT91_SLOW_CLOCK,
RT_NULL,
{RT_NULL, RT_NULL},
};
static struct clk main_clk = {
"main",
0,
RT_NULL,
{RT_NULL, RT_NULL},
};
static struct clk plla = {
"plla",
0,
RT_NULL,
{RT_NULL, RT_NULL},
};
static struct clk mck = {
"mck",
0,
RT_NULL,
{RT_NULL, RT_NULL},
};
static struct clk uhpck = {
"uhpck",
0,
RT_NULL,
{RT_NULL, RT_NULL},
};
static struct clk pllb = {
"pllb",
0,
&main_clk,
{RT_NULL, RT_NULL},
};
static struct clk udpck = {
"udpck",
0,
&pllb,
{RT_NULL, RT_NULL},
};
static struct clk *const standard_pmc_clocks[] = {
/* four primary clocks */
&clk32k,
&main_clk,
&plla,
/* MCK */
&mck
};
/* clocks cannot be de-registered no refcounting necessary */
struct clk *clk_get(const char *id)
{
struct clk *clk;
rt_list_t *list;
for (list = (&clocks)->next; list != &clocks; list = list->next)
{
clk = (struct clk *)rt_list_entry(list, struct clk, node);
if (rt_strcmp(id, clk->name) == 0)
return clk;
}
return RT_NULL;
}
rt_uint32_t clk_get_rate(struct clk *clk)
{
rt_uint32_t flags;
rt_uint32_t rate;
for (;;) {
rate = clk->rate_hz;
if (rate || !clk->parent)
break;
clk = clk->parent;
}
return rate;
}
static rt_uint32_t at91_pll_rate(struct clk *pll, rt_uint32_t freq, rt_uint32_t reg)
{
unsigned mul, div;
div = reg & 0xff;
mul = (reg >> 16) & 0x7ff;
if (div && mul) {
freq /= div;
freq *= mul + 1;
} else
freq = 0;
return freq;
}
static unsigned at91_pll_calc(unsigned main_freq, unsigned out_freq)
{
unsigned i, div = 0, mul = 0, diff = 1 << 30;
unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00;
/* PLL output max 240 MHz (or 180 MHz per errata) */
if (out_freq > 240000000)
goto fail;
for (i = 1; i < 256; i++) {
int diff1;
unsigned input, mul1;
/*
* PLL input between 1MHz and 32MHz per spec, but lower
* frequences seem necessary in some cases so allow 100K.
* Warning: some newer products need 2MHz min.
*/
input = main_freq / i;
if (input < 100000)
continue;
if (input > 32000000)
continue;
mul1 = out_freq / input;
if (mul1 > 2048)
continue;
if (mul1 < 2)
goto fail;
diff1 = out_freq - input * mul1;
if (diff1 < 0)
diff1 = -diff1;
if (diff > diff1) {
diff = diff1;
div = i;
mul = mul1;
if (diff == 0)
break;
}
}
if (i == 256 && diff > (out_freq >> 5))
goto fail;
return ret | ((mul - 1) << 16) | div;
fail:
return 0;
}
static rt_uint32_t at91_usb_rate(struct clk *pll, rt_uint32_t freq, rt_uint32_t reg)
{
if (pll == &pllb && (reg & AT91_PMC_USB96M))
return freq / 2;
else
return freq;
}
/* PLLB generated USB full speed clock init */
static void at91_pllb_usbfs_clock_init(rt_uint32_t main_clock)
{
rt_uint32_t at91_pllb_usb_init;
/*
* USB clock init: choose 48 MHz PLLB value,
* disable 48MHz clock during usb peripheral suspend.
*
* REVISIT: assumes MCK doesn't derive from PLLB!
*/
uhpck.parent = &pllb;
at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M;
pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init);
at91_sys_write(AT91_CKGR_PLLBR, 0);
udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
}
static struct clk *at91_css_to_clk(unsigned long css)
{
switch (css) {
case AT91_PMC_CSS_SLOW:
return &clk32k;
case AT91_PMC_CSS_MAIN:
return &main_clk;
case AT91_PMC_CSS_PLLA:
return &plla;
case AT91_PMC_CSS_PLLB:
return &pllb;
}
return RT_NULL;
}
#define false 0
#define true 1
int at91_clock_init(rt_uint32_t main_clock)
{
unsigned tmp, freq, mckr;
int i;
int pll_overclock = false;
/*
* When the bootloader initialized the main oscillator correctly,
* there's no problem using the cycle counter. But if it didn't,
* or when using oscillator bypass mode, we must be told the speed
* of the main clock.
*/
if (!main_clock) {
do {
tmp = at91_sys_read(AT91_CKGR_MCFR);
} while (!(tmp & AT91_PMC_MAINRDY));
main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16);
}
main_clk.rate_hz = main_clock;
/* report if PLLA is more than mildly overclocked */
plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR));
if (plla.rate_hz > 209000000)
pll_overclock = true;
if (pll_overclock)
;//rt_kprintf("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
at91_pllb_usbfs_clock_init(main_clock);
/*
* MCK and CPU derive from one of those primary clocks.
* For now, assume this parentage won't change.
*/
mckr = at91_sys_read(AT91_PMC_MCKR);
mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
freq = mck.parent->rate_hz;
freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2)); /* prescale */
mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
/* Register the PMC's standard clocks */
rt_list_init(&clocks);
for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
rt_list_insert_after(&clocks, &standard_pmc_clocks[i]->node);
rt_list_insert_after(&clocks, &pllb.node);
rt_list_insert_after(&clocks, &uhpck.node);
rt_list_insert_after(&clocks, &udpck.node);
/* MCK and CPU clock are "always on" */
//clk_enable(&mck);
/*rt_kprintf("Clocks: CPU %u MHz, master %u MHz, main %u.%03u MHz\n",
freq / 1000000, (unsigned) mck.rate_hz / 1000000,
(unsigned) main_clock / 1000000,
((unsigned) main_clock % 1000000) / 1000);*///cause blocked
return 0;
}
/**
* @brief System Clock Configuration
*/
void rt_hw_clock_init(void)
{
at91_clock_init(18432000);
}

View File

@ -1,67 +1,67 @@
/*
* File : backtrace.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, 2008 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://openlab.rt-thread.com/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2008-07-29 Bernard first version from QiuYi implementation
*/
#include <rtthread.h>
#ifdef __GNUC__
/*
-->High Address,Stack Top
PC<-----|
LR |
IP |
FP |
...... |
PC<-| |
LR | |
IP | |
FP---|-- |
...... |
PC |
LR |
IP |
FP---
-->Low Address,Stack Bottom
*/
void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry)
{
rt_uint32_t i, pc, func_entry;
pc = *fp;
rt_kprintf("[0x%x]\n", pc-0xC);
for(i=0; i<10; i++)
{
fp = (rt_uint32_t *)*(fp - 3);
pc = *fp ;
func_entry = pc - 0xC;
if(func_entry <= 0x30000000) break;
if((func_entry == thread_entry))
{
rt_kprintf("EntryPoint:0x%x\n", func_entry);
break;
}
rt_kprintf("[0x%x]\n", func_entry);
}
}
#else
void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry)
{
/* old compiler implementation */
}
#endif
/*
* File : backtrace.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, 2008 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://openlab.rt-thread.com/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2008-07-29 Bernard first version from QiuYi implementation
*/
#include <rtthread.h>
#ifdef __GNUC__
/*
-->High Address,Stack Top
PC<-----|
LR |
IP |
FP |
...... |
PC<-| |
LR | |
IP | |
FP---|-- |
...... |
PC |
LR |
IP |
FP---
-->Low Address,Stack Bottom
*/
void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry)
{
rt_uint32_t i, pc, func_entry;
pc = *fp;
rt_kprintf("[0x%x]\n", pc-0xC);
for(i=0; i<10; i++)
{
fp = (rt_uint32_t *)*(fp - 3);
pc = *fp ;
func_entry = pc - 0xC;
if(func_entry <= 0x30000000) break;
if((func_entry == thread_entry))
{
rt_kprintf("EntryPoint:0x%x\n", func_entry);
break;
}
rt_kprintf("[0x%x]\n", func_entry);
}
}
#else
void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry)
{
/* old compiler implementation */
}
#endif

View File

@ -1,42 +1,42 @@
/*
* File : showmem.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, 2008 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://openlab.rt-thread.com/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2008-07-29 Bernard first version from QiuYi implementation
*/
#include <rtthread.h>
void rt_hw_show_memory(rt_uint32_t addr, rt_uint32_t size)
{
int i = 0, j =0;
RT_ASSERT(addr);
addr = addr & ~0xF;
size = 4*((size + 3)/4);
while(i < size)
{
rt_kprintf("0x%08x: ", addr );
for(j=0; j<4; j++)
{
rt_kprintf("0x%08x ", *(rt_uint32_t *)addr);
addr += 4;
i++;
}
rt_kprintf("\n");
}
return;
}
/*
* File : showmem.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, 2008 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://openlab.rt-thread.com/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2008-07-29 Bernard first version from QiuYi implementation
*/
#include <rtthread.h>
void rt_hw_show_memory(rt_uint32_t addr, rt_uint32_t size)
{
int i = 0, j =0;
RT_ASSERT(addr);
addr = addr & ~0xF;
size = 4*((size + 3)/4);
while(i < size)
{
rt_kprintf("0x%08x: ", addr );
for(j=0; j<4; j++)
{
rt_kprintf("0x%08x ", *(rt_uint32_t *)addr);
addr += 4;
i++;
}
rt_kprintf("\n");
}
return;
}

View File

@ -1,201 +1,201 @@
;/*
; * File : context_iar.S
; * This file is part of RT-Thread RTOS
; * COPYRIGHT (C) 2009, 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-01-25 Bernard first version
; * 2012-06-01 aozima set pendsv priority to 0xFF.
; * 2012-08-17 aozima fixed bug: store r8 - r11.
; */
;/**
; * @addtogroup CORTEX-M0
; */
;/*@{*/
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2)
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
SECTION .text:CODE(2)
THUMB
REQUIRE8
PRESERVE8
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
EXPORT rt_hw_interrupt_disable
rt_hw_interrupt_disable:
MRS r0, PRIMASK
CPSID I
BX LR
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
EXPORT rt_hw_interrupt_enable
rt_hw_interrupt_enable:
MSR PRIMASK, r0
BX LR
;/*
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
; * r0 --> from
; * r1 --> to
; */
EXPORT rt_hw_context_switch_interrupt
EXPORT rt_hw_context_switch
rt_hw_context_switch_interrupt:
rt_hw_context_switch:
; set rt_thread_switch_interrupt_flag to 1
LDR r2, =rt_thread_switch_interrupt_flag
LDR r3, [r2]
CMP r3, #1
BEQ _reswitch
MOVS r3, #0x1
STR r3, [r2]
LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
STR r0, [r2]
_reswitch
LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
STR r1, [r2]
LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
BX LR
; r0 --> swith from thread stack
; r1 --> swith to thread stack
; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
EXPORT PendSV_Handler
PendSV_Handler:
; disable interrupt to protect context switch
MRS r2, PRIMASK
CPSID I
; get rt_thread_switch_interrupt_flag
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CMP r1, #0x00
BEQ pendsv_exit ; pendsv already handled
; clear rt_thread_switch_interrupt_flag to 0
MOVS r1, #0x00
STR r1, [r0]
LDR r0, =rt_interrupt_from_thread
LDR r1, [r0]
CMP r1, #0x00
BEQ swtich_to_thread ; skip register save at the first time
MRS r1, psp ; get from thread stack pointer
SUBS r1, r1, #0x20 ; space for {r4 - r7} and {r8 - r11}
LDR r0, [r0]
STR r1, [r0] ; update from thread stack pointer
STMIA r1!, {r4 - r7} ; push thread {r4 - r7} register to thread stack
MOV r4, r8 ; mov thread {r8 - r11} to {r4 - r7}
MOV r5, r9
MOV r6, r10
MOV r7, r11
STMIA r1!, {r4 - r7} ; push thread {r8 - r11} high register to thread stack
swtich_to_thread
LDR r1, =rt_interrupt_to_thread
LDR r1, [r1]
LDR r1, [r1] ; load thread stack pointer
LDMIA r1!, {r4 - r7} ; pop thread {r4 - r7} register from thread stack
PUSH {r4 - r7} ; push {r4 - r7} to MSP for copy {r8 - r11}
LDMIA r1!, {r4 - r7} ; pop thread {r8 - r11} high register from thread stack to {r4 - r7}
MOV r8, r4 ; mov {r4 - r7} to {r8 - r11}
MOV r9, r5
MOV r10, r6
MOV r11, r7
POP {r4 - r7} ; pop {r4 - r7} from MSP
MSR psp, r1 ; update stack pointer
pendsv_exit
; restore interrupt
MSR PRIMASK, r2
MOVS r0, #0x04
RSBS r0, r0, #0x00
BX r0
;/*
; * void rt_hw_context_switch_to(rt_uint32 to);
; * r0 --> to
; * this fucntion is used to perform the first thread switch
; */
EXPORT rt_hw_context_switch_to
rt_hw_context_switch_to:
; set to thread
LDR r1, =rt_interrupt_to_thread
STR r0, [r1]
; set from thread to 0
LDR r1, =rt_interrupt_from_thread
MOVS r0, #0x0
STR r0, [r1]
; set interrupt flag to 1
LDR r1, =rt_thread_switch_interrupt_flag
MOVS r0, #1
STR r0, [r1]
; set the PendSV exception priority
LDR r0, =NVIC_SHPR3
LDR r1, =NVIC_PENDSV_PRI
LDR r2, [r0,#0x00] ; read
ORRS r1,r1,r2 ; modify
STR r1, [r0] ; write-back
; trigger the PendSV exception (causes context switch)
LDR r0, =NVIC_INT_CTRL
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
NOP
; enable interrupts at processor level
CPSIE I
; never reach here!
; compatible with old version
EXPORT rt_hw_interrupt_thread_switch
rt_hw_interrupt_thread_switch:
BX lr
IMPORT rt_hw_hard_fault_exception
EXPORT HardFault_Handler
HardFault_Handler:
; get current context
MRS r0, psp ; get fault thread stack pointer
PUSH {lr}
BL rt_hw_hard_fault_exception
POP {pc}
END
;/*
; * File : context_iar.S
; * This file is part of RT-Thread RTOS
; * COPYRIGHT (C) 2009, 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-01-25 Bernard first version
; * 2012-06-01 aozima set pendsv priority to 0xFF.
; * 2012-08-17 aozima fixed bug: store r8 - r11.
; */
;/**
; * @addtogroup CORTEX-M0
; */
;/*@{*/
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2)
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
SECTION .text:CODE(2)
THUMB
REQUIRE8
PRESERVE8
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
EXPORT rt_hw_interrupt_disable
rt_hw_interrupt_disable:
MRS r0, PRIMASK
CPSID I
BX LR
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
EXPORT rt_hw_interrupt_enable
rt_hw_interrupt_enable:
MSR PRIMASK, r0
BX LR
;/*
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
; * r0 --> from
; * r1 --> to
; */
EXPORT rt_hw_context_switch_interrupt
EXPORT rt_hw_context_switch
rt_hw_context_switch_interrupt:
rt_hw_context_switch:
; set rt_thread_switch_interrupt_flag to 1
LDR r2, =rt_thread_switch_interrupt_flag
LDR r3, [r2]
CMP r3, #1
BEQ _reswitch
MOVS r3, #0x1
STR r3, [r2]
LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
STR r0, [r2]
_reswitch
LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
STR r1, [r2]
LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
BX LR
; r0 --> swith from thread stack
; r1 --> swith to thread stack
; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
EXPORT PendSV_Handler
PendSV_Handler:
; disable interrupt to protect context switch
MRS r2, PRIMASK
CPSID I
; get rt_thread_switch_interrupt_flag
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CMP r1, #0x00
BEQ pendsv_exit ; pendsv already handled
; clear rt_thread_switch_interrupt_flag to 0
MOVS r1, #0x00
STR r1, [r0]
LDR r0, =rt_interrupt_from_thread
LDR r1, [r0]
CMP r1, #0x00
BEQ swtich_to_thread ; skip register save at the first time
MRS r1, psp ; get from thread stack pointer
SUBS r1, r1, #0x20 ; space for {r4 - r7} and {r8 - r11}
LDR r0, [r0]
STR r1, [r0] ; update from thread stack pointer
STMIA r1!, {r4 - r7} ; push thread {r4 - r7} register to thread stack
MOV r4, r8 ; mov thread {r8 - r11} to {r4 - r7}
MOV r5, r9
MOV r6, r10
MOV r7, r11
STMIA r1!, {r4 - r7} ; push thread {r8 - r11} high register to thread stack
swtich_to_thread
LDR r1, =rt_interrupt_to_thread
LDR r1, [r1]
LDR r1, [r1] ; load thread stack pointer
LDMIA r1!, {r4 - r7} ; pop thread {r4 - r7} register from thread stack
PUSH {r4 - r7} ; push {r4 - r7} to MSP for copy {r8 - r11}
LDMIA r1!, {r4 - r7} ; pop thread {r8 - r11} high register from thread stack to {r4 - r7}
MOV r8, r4 ; mov {r4 - r7} to {r8 - r11}
MOV r9, r5
MOV r10, r6
MOV r11, r7
POP {r4 - r7} ; pop {r4 - r7} from MSP
MSR psp, r1 ; update stack pointer
pendsv_exit
; restore interrupt
MSR PRIMASK, r2
MOVS r0, #0x04
RSBS r0, r0, #0x00
BX r0
;/*
; * void rt_hw_context_switch_to(rt_uint32 to);
; * r0 --> to
; * this fucntion is used to perform the first thread switch
; */
EXPORT rt_hw_context_switch_to
rt_hw_context_switch_to:
; set to thread
LDR r1, =rt_interrupt_to_thread
STR r0, [r1]
; set from thread to 0
LDR r1, =rt_interrupt_from_thread
MOVS r0, #0x0
STR r0, [r1]
; set interrupt flag to 1
LDR r1, =rt_thread_switch_interrupt_flag
MOVS r0, #1
STR r0, [r1]
; set the PendSV exception priority
LDR r0, =NVIC_SHPR3
LDR r1, =NVIC_PENDSV_PRI
LDR r2, [r0,#0x00] ; read
ORRS r1,r1,r2 ; modify
STR r1, [r0] ; write-back
; trigger the PendSV exception (causes context switch)
LDR r0, =NVIC_INT_CTRL
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
NOP
; enable interrupts at processor level
CPSIE I
; never reach here!
; compatible with old version
EXPORT rt_hw_interrupt_thread_switch
rt_hw_interrupt_thread_switch:
BX lr
IMPORT rt_hw_hard_fault_exception
EXPORT HardFault_Handler
HardFault_Handler:
; get current context
MRS r0, psp ; get fault thread stack pointer
PUSH {lr}
BL rt_hw_hard_fault_exception
POP {pc}
END

View File

@ -1,210 +1,210 @@
;/*
; * File : context_rvds.S
; * This file is part of RT-Thread RTOS
; * COPYRIGHT (C) 2009, 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-01-25 Bernard first version
; * 2012-06-01 aozima set pendsv priority to 0xFF.
; * 2012-08-17 aozima fixed bug: store r8 - r11.
; */
;/**
; * @addtogroup CORTEX-M0
; */
;/*@{*/
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2)
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
AREA |.text|, CODE, READONLY, ALIGN=2
THUMB
REQUIRE8
PRESERVE8
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
rt_hw_interrupt_disable PROC
EXPORT rt_hw_interrupt_disable
MRS r0, PRIMASK
CPSID I
BX LR
ENDP
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
rt_hw_interrupt_enable PROC
EXPORT rt_hw_interrupt_enable
MSR PRIMASK, r0
BX LR
ENDP
;/*
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
; * r0 --> from
; * r1 --> to
; */
rt_hw_context_switch_interrupt
EXPORT rt_hw_context_switch_interrupt
rt_hw_context_switch PROC
EXPORT rt_hw_context_switch
; set rt_thread_switch_interrupt_flag to 1
LDR r2, =rt_thread_switch_interrupt_flag
LDR r3, [r2]
CMP r3, #1
BEQ _reswitch
MOVS r3, #0x01
STR r3, [r2]
LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
STR r0, [r2]
_reswitch
LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
STR r1, [r2]
LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
BX LR
ENDP
; r0 --> swith from thread stack
; r1 --> swith to thread stack
; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
PendSV_Handler PROC
EXPORT PendSV_Handler
; disable interrupt to protect context switch
MRS r2, PRIMASK
CPSID I
; get rt_thread_switch_interrupt_flag
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CMP r1, #0x00
BEQ pendsv_exit ; pendsv already handled
; clear rt_thread_switch_interrupt_flag to 0
MOVS r1, #0x00
STR r1, [r0]
LDR r0, =rt_interrupt_from_thread
LDR r1, [r0]
CMP r1, #0x00
BEQ swtich_to_thread ; skip register save at the first time
MRS r1, psp ; get from thread stack pointer
SUBS r1, r1, #0x20 ; space for {r4 - r7} and {r8 - r11}
LDR r0, [r0]
STR r1, [r0] ; update from thread stack pointer
STMIA r1!, {r4 - r7} ; push thread {r4 - r7} register to thread stack
MOV r4, r8 ; mov thread {r8 - r11} to {r4 - r7}
MOV r5, r9
MOV r6, r10
MOV r7, r11
STMIA r1!, {r4 - r7} ; push thread {r8 - r11} high register to thread stack
swtich_to_thread
LDR r1, =rt_interrupt_to_thread
LDR r1, [r1]
LDR r1, [r1] ; load thread stack pointer
LDMIA r1!, {r4 - r7} ; pop thread {r4 - r7} register from thread stack
PUSH {r4 - r7} ; push {r4 - r7} to MSP for copy {r8 - r11}
LDMIA r1!, {r4 - r7} ; pop thread {r8 - r11} high register from thread stack to {r4 - r7}
MOV r8, r4 ; mov {r4 - r7} to {r8 - r11}
MOV r9, r5
MOV r10, r6
MOV r11, r7
POP {r4 - r7} ; pop {r4 - r7} from MSP
MSR psp, r1 ; update stack pointer
pendsv_exit
; restore interrupt
MSR PRIMASK, r2
MOVS r0, #0x04
RSBS r0, r0, #0x00
BX r0
ENDP
;/*
; * void rt_hw_context_switch_to(rt_uint32 to);
; * r0 --> to
; * this fucntion is used to perform the first thread switch
; */
rt_hw_context_switch_to PROC
EXPORT rt_hw_context_switch_to
; set to thread
LDR r1, =rt_interrupt_to_thread
STR r0, [r1]
; set from thread to 0
LDR r1, =rt_interrupt_from_thread
MOVS r0, #0x0
STR r0, [r1]
; set interrupt flag to 1
LDR r1, =rt_thread_switch_interrupt_flag
MOVS r0, #1
STR r0, [r1]
; set the PendSV exception priority
LDR r0, =NVIC_SHPR3
LDR r1, =NVIC_PENDSV_PRI
LDR r2, [r0,#0x00] ; read
ORRS r1,r1,r2 ; modify
STR r1, [r0] ; write-back
; trigger the PendSV exception (causes context switch)
LDR r0, =NVIC_INT_CTRL
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
NOP
; enable interrupts at processor level
CPSIE I
; never reach here!
ENDP
; compatible with old version
rt_hw_interrupt_thread_switch PROC
EXPORT rt_hw_interrupt_thread_switch
BX lr
ENDP
IMPORT rt_hw_hard_fault_exception
HardFault_Handler PROC
EXPORT HardFault_Handler
; get current context
MRS r0, psp ; get fault thread stack pointer
PUSH {lr}
BL rt_hw_hard_fault_exception
POP {pc}
ENDP
END
;/*
; * File : context_rvds.S
; * This file is part of RT-Thread RTOS
; * COPYRIGHT (C) 2009, 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-01-25 Bernard first version
; * 2012-06-01 aozima set pendsv priority to 0xFF.
; * 2012-08-17 aozima fixed bug: store r8 - r11.
; */
;/**
; * @addtogroup CORTEX-M0
; */
;/*@{*/
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2)
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
AREA |.text|, CODE, READONLY, ALIGN=2
THUMB
REQUIRE8
PRESERVE8
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
rt_hw_interrupt_disable PROC
EXPORT rt_hw_interrupt_disable
MRS r0, PRIMASK
CPSID I
BX LR
ENDP
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
rt_hw_interrupt_enable PROC
EXPORT rt_hw_interrupt_enable
MSR PRIMASK, r0
BX LR
ENDP
;/*
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
; * r0 --> from
; * r1 --> to
; */
rt_hw_context_switch_interrupt
EXPORT rt_hw_context_switch_interrupt
rt_hw_context_switch PROC
EXPORT rt_hw_context_switch
; set rt_thread_switch_interrupt_flag to 1
LDR r2, =rt_thread_switch_interrupt_flag
LDR r3, [r2]
CMP r3, #1
BEQ _reswitch
MOVS r3, #0x01
STR r3, [r2]
LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
STR r0, [r2]
_reswitch
LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
STR r1, [r2]
LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
BX LR
ENDP
; r0 --> swith from thread stack
; r1 --> swith to thread stack
; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
PendSV_Handler PROC
EXPORT PendSV_Handler
; disable interrupt to protect context switch
MRS r2, PRIMASK
CPSID I
; get rt_thread_switch_interrupt_flag
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CMP r1, #0x00
BEQ pendsv_exit ; pendsv already handled
; clear rt_thread_switch_interrupt_flag to 0
MOVS r1, #0x00
STR r1, [r0]
LDR r0, =rt_interrupt_from_thread
LDR r1, [r0]
CMP r1, #0x00
BEQ swtich_to_thread ; skip register save at the first time
MRS r1, psp ; get from thread stack pointer
SUBS r1, r1, #0x20 ; space for {r4 - r7} and {r8 - r11}
LDR r0, [r0]
STR r1, [r0] ; update from thread stack pointer
STMIA r1!, {r4 - r7} ; push thread {r4 - r7} register to thread stack
MOV r4, r8 ; mov thread {r8 - r11} to {r4 - r7}
MOV r5, r9
MOV r6, r10
MOV r7, r11
STMIA r1!, {r4 - r7} ; push thread {r8 - r11} high register to thread stack
swtich_to_thread
LDR r1, =rt_interrupt_to_thread
LDR r1, [r1]
LDR r1, [r1] ; load thread stack pointer
LDMIA r1!, {r4 - r7} ; pop thread {r4 - r7} register from thread stack
PUSH {r4 - r7} ; push {r4 - r7} to MSP for copy {r8 - r11}
LDMIA r1!, {r4 - r7} ; pop thread {r8 - r11} high register from thread stack to {r4 - r7}
MOV r8, r4 ; mov {r4 - r7} to {r8 - r11}
MOV r9, r5
MOV r10, r6
MOV r11, r7
POP {r4 - r7} ; pop {r4 - r7} from MSP
MSR psp, r1 ; update stack pointer
pendsv_exit
; restore interrupt
MSR PRIMASK, r2
MOVS r0, #0x04
RSBS r0, r0, #0x00
BX r0
ENDP
;/*
; * void rt_hw_context_switch_to(rt_uint32 to);
; * r0 --> to
; * this fucntion is used to perform the first thread switch
; */
rt_hw_context_switch_to PROC
EXPORT rt_hw_context_switch_to
; set to thread
LDR r1, =rt_interrupt_to_thread
STR r0, [r1]
; set from thread to 0
LDR r1, =rt_interrupt_from_thread
MOVS r0, #0x0
STR r0, [r1]
; set interrupt flag to 1
LDR r1, =rt_thread_switch_interrupt_flag
MOVS r0, #1
STR r0, [r1]
; set the PendSV exception priority
LDR r0, =NVIC_SHPR3
LDR r1, =NVIC_PENDSV_PRI
LDR r2, [r0,#0x00] ; read
ORRS r1,r1,r2 ; modify
STR r1, [r0] ; write-back
; trigger the PendSV exception (causes context switch)
LDR r0, =NVIC_INT_CTRL
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
NOP
; enable interrupts at processor level
CPSIE I
; never reach here!
ENDP
; compatible with old version
rt_hw_interrupt_thread_switch PROC
EXPORT rt_hw_interrupt_thread_switch
BX lr
ENDP
IMPORT rt_hw_hard_fault_exception
HardFault_Handler PROC
EXPORT HardFault_Handler
; get current context
MRS r0, psp ; get fault thread stack pointer
PUSH {lr}
BL rt_hw_hard_fault_exception
POP {pc}
ENDP
END

View File

@ -1,186 +1,186 @@
/*
* File : context_gcc.S
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009 - 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
* 2009-10-11 Bernard First version
* 2010-12-29 onelife Modify for EFM32
* 2011-06-17 onelife Merge all of the assembly source code into context_gcc.S
* 2011-07-12 onelife Add interrupt context check function
*/
.cpu cortex-m3
.fpu softvfp
.syntax unified
.thumb
.text
.equ ICSR, 0xE000ED04 /* interrupt control state register */
.equ PENDSVSET_BIT, 0x10000000 /* value to trigger PendSV exception */
.equ SHPR3, 0xE000ED20 /* system priority register (3) */
.equ PENDSV_PRI_LOWEST, 0x00FF0000 /* PendSV priority value (lowest) */
/*
* rt_base_t rt_hw_interrupt_disable();
*/
.global rt_hw_interrupt_disable
.type rt_hw_interrupt_disable, %function
rt_hw_interrupt_disable:
MRS R0, PRIMASK
CPSID I
BX LR
/*
* void rt_hw_interrupt_enable(rt_base_t level);
*/
.global rt_hw_interrupt_enable
.type rt_hw_interrupt_enable, %function
rt_hw_interrupt_enable:
MSR PRIMASK, R0
BX LR
/*
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
* R0 --> from
* R1 --> to
*/
.global rt_hw_context_switch_interrupt
.type rt_hw_context_switch_interrupt, %function
.global rt_hw_context_switch
.type rt_hw_context_switch, %function
rt_hw_context_switch_interrupt:
rt_hw_context_switch:
/* set rt_thread_switch_interrupt_flag to 1 */
LDR R2, =rt_thread_switch_interrupt_flag
LDR R3, [R2]
CMP R3, #1
BEQ _reswitch
MOV R3, #1
STR R3, [R2]
LDR R2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread */
STR R0, [R2]
_reswitch:
LDR R2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread */
STR R1, [R2]
LDR R0, =ICSR /* trigger the PendSV exception (causes context switch) */
LDR R1, =PENDSVSET_BIT
STR R1, [R0]
BX LR
/* R0 --> swith from thread stack
* R1 --> swith to thread stack
* psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack
*/
.global PendSV_Handler
.type PendSV_Handler, %function
PendSV_Handler:
/* disable interrupt to protect context switch */
MRS R2, PRIMASK
CPSID I
/* get rt_thread_switch_interrupt_flag */
LDR R0, =rt_thread_switch_interrupt_flag
LDR R1, [R0]
CBZ R1, pendsv_exit /* pendsv aLReady handled */
/* clear rt_thread_switch_interrupt_flag to 0 */
MOV R1, #0
STR R1, [R0]
LDR R0, =rt_interrupt_from_thread
LDR R1, [R0]
CBZ R1, swtich_to_thread /* skip register save at the first time */
MRS R1, PSP /* get from thread stack pointer */
STMFD R1!, {R4 - R11} /* push R4 - R11 register */
LDR R0, [R0]
STR R1, [R0] /* update from thread stack pointer */
swtich_to_thread:
LDR R1, =rt_interrupt_to_thread
LDR R1, [R1]
LDR R1, [R1] /* load thread stack pointer */
LDMFD R1!, {R4 - R11} /* pop R4 - R11 register */
MSR PSP, R1 /* update stack pointer */
pendsv_exit:
/* restore interrupt */
MSR PRIMASK, R2
ORR LR, LR, #0x04
BX LR
/*
* void rt_hw_context_switch_to(rt_uint32 to);
* R0 --> to
*/
.global rt_hw_context_switch_to
.type rt_hw_context_switch_to, %function
rt_hw_context_switch_to:
LDR R1, =rt_interrupt_to_thread
STR R0, [R1]
/* set from thread to 0 */
LDR R1, =rt_interrupt_from_thread
MOV R0, #0
STR R0, [R1]
/* set interrupt flag to 1 */
LDR R1, =rt_thread_switch_interrupt_flag
MOV R0, #1
STR R0, [R1]
/* set the PendSV exception priority */
LDR R0, =SHPR3
LDR R1, =PENDSV_PRI_LOWEST
LDR.W R2, [R0,#0] /* read */
ORR R1, R1, R2 /* modify */
STR R1, [R0] /* write-back */
LDR R0, =ICSR /* trigger the PendSV exception (causes context switch) */
LDR R1, =PENDSVSET_BIT
STR R1, [R0]
CPSIE I /* enable interrupts at processor level */
/* never reach here! */
/* compatible with old version */
.global rt_hw_interrupt_thread_switch
.type rt_hw_interrupt_thread_switch, %function
rt_hw_interrupt_thread_switch:
BX LR
NOP
.global HardFault_Handler
.type HardFault_Handler, %function
HardFault_Handler:
/* get current context */
MRS R0, PSP /* get fault thread stack pointer */
PUSH {LR}
BL rt_hw_hard_fault_exception
POP {LR}
ORR LR, LR, #0x04
BX LR
/*
* rt_uint32_t rt_hw_interrupt_check(void);
* R0 --> state
*/
.global rt_hw_interrupt_check
.type rt_hw_interrupt_check, %function
rt_hw_interrupt_check:
MRS R0, IPSR
BX LR
/*
* File : context_gcc.S
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009 - 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
* 2009-10-11 Bernard First version
* 2010-12-29 onelife Modify for EFM32
* 2011-06-17 onelife Merge all of the assembly source code into context_gcc.S
* 2011-07-12 onelife Add interrupt context check function
*/
.cpu cortex-m3
.fpu softvfp
.syntax unified
.thumb
.text
.equ ICSR, 0xE000ED04 /* interrupt control state register */
.equ PENDSVSET_BIT, 0x10000000 /* value to trigger PendSV exception */
.equ SHPR3, 0xE000ED20 /* system priority register (3) */
.equ PENDSV_PRI_LOWEST, 0x00FF0000 /* PendSV priority value (lowest) */
/*
* rt_base_t rt_hw_interrupt_disable();
*/
.global rt_hw_interrupt_disable
.type rt_hw_interrupt_disable, %function
rt_hw_interrupt_disable:
MRS R0, PRIMASK
CPSID I
BX LR
/*
* void rt_hw_interrupt_enable(rt_base_t level);
*/
.global rt_hw_interrupt_enable
.type rt_hw_interrupt_enable, %function
rt_hw_interrupt_enable:
MSR PRIMASK, R0
BX LR
/*
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
* R0 --> from
* R1 --> to
*/
.global rt_hw_context_switch_interrupt
.type rt_hw_context_switch_interrupt, %function
.global rt_hw_context_switch
.type rt_hw_context_switch, %function
rt_hw_context_switch_interrupt:
rt_hw_context_switch:
/* set rt_thread_switch_interrupt_flag to 1 */
LDR R2, =rt_thread_switch_interrupt_flag
LDR R3, [R2]
CMP R3, #1
BEQ _reswitch
MOV R3, #1
STR R3, [R2]
LDR R2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread */
STR R0, [R2]
_reswitch:
LDR R2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread */
STR R1, [R2]
LDR R0, =ICSR /* trigger the PendSV exception (causes context switch) */
LDR R1, =PENDSVSET_BIT
STR R1, [R0]
BX LR
/* R0 --> swith from thread stack
* R1 --> swith to thread stack
* psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack
*/
.global PendSV_Handler
.type PendSV_Handler, %function
PendSV_Handler:
/* disable interrupt to protect context switch */
MRS R2, PRIMASK
CPSID I
/* get rt_thread_switch_interrupt_flag */
LDR R0, =rt_thread_switch_interrupt_flag
LDR R1, [R0]
CBZ R1, pendsv_exit /* pendsv aLReady handled */
/* clear rt_thread_switch_interrupt_flag to 0 */
MOV R1, #0
STR R1, [R0]
LDR R0, =rt_interrupt_from_thread
LDR R1, [R0]
CBZ R1, swtich_to_thread /* skip register save at the first time */
MRS R1, PSP /* get from thread stack pointer */
STMFD R1!, {R4 - R11} /* push R4 - R11 register */
LDR R0, [R0]
STR R1, [R0] /* update from thread stack pointer */
swtich_to_thread:
LDR R1, =rt_interrupt_to_thread
LDR R1, [R1]
LDR R1, [R1] /* load thread stack pointer */
LDMFD R1!, {R4 - R11} /* pop R4 - R11 register */
MSR PSP, R1 /* update stack pointer */
pendsv_exit:
/* restore interrupt */
MSR PRIMASK, R2
ORR LR, LR, #0x04
BX LR
/*
* void rt_hw_context_switch_to(rt_uint32 to);
* R0 --> to
*/
.global rt_hw_context_switch_to
.type rt_hw_context_switch_to, %function
rt_hw_context_switch_to:
LDR R1, =rt_interrupt_to_thread
STR R0, [R1]
/* set from thread to 0 */
LDR R1, =rt_interrupt_from_thread
MOV R0, #0
STR R0, [R1]
/* set interrupt flag to 1 */
LDR R1, =rt_thread_switch_interrupt_flag
MOV R0, #1
STR R0, [R1]
/* set the PendSV exception priority */
LDR R0, =SHPR3
LDR R1, =PENDSV_PRI_LOWEST
LDR.W R2, [R0,#0] /* read */
ORR R1, R1, R2 /* modify */
STR R1, [R0] /* write-back */
LDR R0, =ICSR /* trigger the PendSV exception (causes context switch) */
LDR R1, =PENDSVSET_BIT
STR R1, [R0]
CPSIE I /* enable interrupts at processor level */
/* never reach here! */
/* compatible with old version */
.global rt_hw_interrupt_thread_switch
.type rt_hw_interrupt_thread_switch, %function
rt_hw_interrupt_thread_switch:
BX LR
NOP
.global HardFault_Handler
.type HardFault_Handler, %function
HardFault_Handler:
/* get current context */
MRS R0, PSP /* get fault thread stack pointer */
PUSH {LR}
BL rt_hw_hard_fault_exception
POP {LR}
ORR LR, LR, #0x04
BX LR
/*
* rt_uint32_t rt_hw_interrupt_check(void);
* R0 --> state
*/
.global rt_hw_interrupt_check
.type rt_hw_interrupt_check, %function
rt_hw_interrupt_check:
MRS R0, IPSR
BX LR

View File

@ -1,188 +1,188 @@
;/*
; * File : context_rvds.S
; * This file is part of RT-Thread RTOS
; * COPYRIGHT (C) 2009, 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
; * 2009-01-17 Bernard first version
; */
;/**
; * @addtogroup CORTEX-M3
; */
;/*@{*/
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
AREA |.text|, CODE, READONLY, ALIGN=2
THUMB
REQUIRE8
PRESERVE8
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
rt_hw_interrupt_disable PROC
EXPORT rt_hw_interrupt_disable
MRS r0, PRIMASK
CPSID I
BX LR
ENDP
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
rt_hw_interrupt_enable PROC
EXPORT rt_hw_interrupt_enable
MSR PRIMASK, r0
BX LR
ENDP
;/*
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
; * r0 --> from
; * r1 --> to
; */
rt_hw_context_switch_interrupt
EXPORT rt_hw_context_switch_interrupt
rt_hw_context_switch PROC
EXPORT rt_hw_context_switch
; set rt_thread_switch_interrupt_flag to 1
LDR r2, =rt_thread_switch_interrupt_flag
LDR r3, [r2]
CMP r3, #1
BEQ _reswitch
MOV r3, #1
STR r3, [r2]
LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
STR r0, [r2]
_reswitch
LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
STR r1, [r2]
LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
BX LR
ENDP
; r0 --> swith from thread stack
; r1 --> swith to thread stack
; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
PendSV_Handler PROC
EXPORT PendSV_Handler
; disable interrupt to protect context switch
MRS r2, PRIMASK
CPSID I
; get rt_thread_switch_interrupt_flag
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CBZ r1, pendsv_exit ; pendsv already handled
; clear rt_thread_switch_interrupt_flag to 0
MOV r1, #0x00
STR r1, [r0]
LDR r0, =rt_interrupt_from_thread
LDR r1, [r0]
CBZ r1, swtich_to_thread ; skip register save at the first time
MRS r1, psp ; get from thread stack pointer
STMFD r1!, {r4 - r11} ; push r4 - r11 register
LDR r0, [r0]
STR r1, [r0] ; update from thread stack pointer
swtich_to_thread
LDR r1, =rt_interrupt_to_thread
LDR r1, [r1]
LDR r1, [r1] ; load thread stack pointer
LDMFD r1!, {r4 - r11} ; pop r4 - r11 register
MSR psp, r1 ; update stack pointer
pendsv_exit
; restore interrupt
MSR PRIMASK, r2
ORR lr, lr, #0x04
BX lr
ENDP
;/*
; * void rt_hw_context_switch_to(rt_uint32 to);
; * r0 --> to
; * this fucntion is used to perform the first thread switch
; */
rt_hw_context_switch_to PROC
EXPORT rt_hw_context_switch_to
; set to thread
LDR r1, =rt_interrupt_to_thread
STR r0, [r1]
; set from thread to 0
LDR r1, =rt_interrupt_from_thread
MOV r0, #0x0
STR r0, [r1]
; set interrupt flag to 1
LDR r1, =rt_thread_switch_interrupt_flag
MOV r0, #1
STR r0, [r1]
; set the PendSV exception priority
LDR r0, =NVIC_SYSPRI2
LDR r1, =NVIC_PENDSV_PRI
LDR.W r2, [r0,#0x00] ; read
ORR r1,r1,r2 ; modify
STR r1, [r0] ; write-back
; trigger the PendSV exception (causes context switch)
LDR r0, =NVIC_INT_CTRL
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
; enable interrupts at processor level
CPSIE I
; never reach here!
ENDP
; compatible with old version
rt_hw_interrupt_thread_switch PROC
EXPORT rt_hw_interrupt_thread_switch
BX lr
NOP
ENDP
IMPORT rt_hw_hard_fault_exception
EXPORT HardFault_Handler
HardFault_Handler PROC
; get current context
MRS r0, psp ; get fault thread stack pointer
PUSH {lr}
BL rt_hw_hard_fault_exception
POP {lr}
ORR lr, lr, #0x04
BX lr
ENDP
END
;/*
; * File : context_rvds.S
; * This file is part of RT-Thread RTOS
; * COPYRIGHT (C) 2009, 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
; * 2009-01-17 Bernard first version
; */
;/**
; * @addtogroup CORTEX-M3
; */
;/*@{*/
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
AREA |.text|, CODE, READONLY, ALIGN=2
THUMB
REQUIRE8
PRESERVE8
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
rt_hw_interrupt_disable PROC
EXPORT rt_hw_interrupt_disable
MRS r0, PRIMASK
CPSID I
BX LR
ENDP
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
rt_hw_interrupt_enable PROC
EXPORT rt_hw_interrupt_enable
MSR PRIMASK, r0
BX LR
ENDP
;/*
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
; * r0 --> from
; * r1 --> to
; */
rt_hw_context_switch_interrupt
EXPORT rt_hw_context_switch_interrupt
rt_hw_context_switch PROC
EXPORT rt_hw_context_switch
; set rt_thread_switch_interrupt_flag to 1
LDR r2, =rt_thread_switch_interrupt_flag
LDR r3, [r2]
CMP r3, #1
BEQ _reswitch
MOV r3, #1
STR r3, [r2]
LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
STR r0, [r2]
_reswitch
LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
STR r1, [r2]
LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
BX LR
ENDP
; r0 --> swith from thread stack
; r1 --> swith to thread stack
; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
PendSV_Handler PROC
EXPORT PendSV_Handler
; disable interrupt to protect context switch
MRS r2, PRIMASK
CPSID I
; get rt_thread_switch_interrupt_flag
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CBZ r1, pendsv_exit ; pendsv already handled
; clear rt_thread_switch_interrupt_flag to 0
MOV r1, #0x00
STR r1, [r0]
LDR r0, =rt_interrupt_from_thread
LDR r1, [r0]
CBZ r1, swtich_to_thread ; skip register save at the first time
MRS r1, psp ; get from thread stack pointer
STMFD r1!, {r4 - r11} ; push r4 - r11 register
LDR r0, [r0]
STR r1, [r0] ; update from thread stack pointer
swtich_to_thread
LDR r1, =rt_interrupt_to_thread
LDR r1, [r1]
LDR r1, [r1] ; load thread stack pointer
LDMFD r1!, {r4 - r11} ; pop r4 - r11 register
MSR psp, r1 ; update stack pointer
pendsv_exit
; restore interrupt
MSR PRIMASK, r2
ORR lr, lr, #0x04
BX lr
ENDP
;/*
; * void rt_hw_context_switch_to(rt_uint32 to);
; * r0 --> to
; * this fucntion is used to perform the first thread switch
; */
rt_hw_context_switch_to PROC
EXPORT rt_hw_context_switch_to
; set to thread
LDR r1, =rt_interrupt_to_thread
STR r0, [r1]
; set from thread to 0
LDR r1, =rt_interrupt_from_thread
MOV r0, #0x0
STR r0, [r1]
; set interrupt flag to 1
LDR r1, =rt_thread_switch_interrupt_flag
MOV r0, #1
STR r0, [r1]
; set the PendSV exception priority
LDR r0, =NVIC_SYSPRI2
LDR r1, =NVIC_PENDSV_PRI
LDR.W r2, [r0,#0x00] ; read
ORR r1,r1,r2 ; modify
STR r1, [r0] ; write-back
; trigger the PendSV exception (causes context switch)
LDR r0, =NVIC_INT_CTRL
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
; enable interrupts at processor level
CPSIE I
; never reach here!
ENDP
; compatible with old version
rt_hw_interrupt_thread_switch PROC
EXPORT rt_hw_interrupt_thread_switch
BX lr
NOP
ENDP
IMPORT rt_hw_hard_fault_exception
EXPORT HardFault_Handler
HardFault_Handler PROC
; get current context
MRS r0, psp ; get fault thread stack pointer
PUSH {lr}
BL rt_hw_hard_fault_exception
POP {lr}
ORR lr, lr, #0x04
BX lr
ENDP
END

View File

@ -1,188 +1,188 @@
/*
* File : context_gcc.S
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009, 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
* 2009-10-11 Bernard first version
* 2012-01-01 aozima support context switch load/store FPU register.
*/
/**
* @addtogroup STM32
*/
/*@{*/
.cpu cortex-m4
.syntax unified
.thumb
.text
.equ NVIC_INT_CTRL, 0xE000ED04 /* interrupt control state register */
.equ NVIC_SYSPRI2, 0xE000ED20 /* system priority register (2) */
.equ NVIC_PENDSV_PRI, 0x00FF0000 /* PendSV priority value (lowest) */
.equ NVIC_PENDSVSET, 0x10000000 /* value to trigger PendSV exception */
/*
* rt_base_t rt_hw_interrupt_disable();
*/
.global rt_hw_interrupt_disable
.type rt_hw_interrupt_disable, %function
rt_hw_interrupt_disable:
MRS r0, PRIMASK
CPSID I
BX LR
/*
* void rt_hw_interrupt_enable(rt_base_t level);
*/
.global rt_hw_interrupt_enable
.type rt_hw_interrupt_enable, %function
rt_hw_interrupt_enable:
MSR PRIMASK, r0
BX LR
/*
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
* r0 --> from
* r1 --> to
*/
.global rt_hw_context_switch_interrupt
.type rt_hw_context_switch_interrupt, %function
.global rt_hw_context_switch
.type rt_hw_context_switch, %function
rt_hw_context_switch_interrupt:
rt_hw_context_switch:
/* set rt_thread_switch_interrupt_flag to 1 */
LDR r2, =rt_thread_switch_interrupt_flag
LDR r3, [r2]
CMP r3, #1
BEQ _reswitch
MOV r3, #1
STR r3, [r2]
LDR r2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread */
STR r0, [r2]
_reswitch:
LDR r2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread */
STR r1, [r2]
LDR r0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
BX LR
/* r0 --> swith from thread stack
* r1 --> swith to thread stack
* psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
*/
.global PendSV_Handler
.type PendSV_Handler, %function
PendSV_Handler:
/* disable interrupt to protect context switch */
MRS r2, PRIMASK
CPSID I
/* get rt_thread_switch_interrupt_flag */
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CBZ r1, pendsv_exit /* pendsv already handled */
/* clear rt_thread_switch_interrupt_flag to 0 */
MOV r1, #0x00
STR r1, [r0]
LDR r0, =rt_interrupt_from_thread
LDR r1, [r0]
CBZ r1, swtich_to_thread /* skip register save at the first time */
MRS r1, psp /* get from thread stack pointer */
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
VSTMDB r1!, {d8 - d15} /* push FPU register s16~s31 */
#endif
STMFD r1!, {r4 - r11} /* push r4 - r11 register */
LDR r0, [r0]
STR r1, [r0] /* update from thread stack pointer */
swtich_to_thread:
LDR r1, =rt_interrupt_to_thread
LDR r1, [r1]
LDR r1, [r1] /* load thread stack pointer */
LDMFD r1!, {r4 - r11} /* pop r4 - r11 register */
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
VLDMIA r1!, {d8 - d15} /* pop FPU register s16~s31 */
#endif
MSR psp, r1 /* update stack pointer */
pendsv_exit:
/* restore interrupt */
MSR PRIMASK, r2
ORR lr, lr, #0x04
BX lr
/*
* void rt_hw_context_switch_to(rt_uint32 to);
* r0 --> to
*/
.global rt_hw_context_switch_to
.type rt_hw_context_switch_to, %function
rt_hw_context_switch_to:
LDR r1, =rt_interrupt_to_thread
STR r0, [r1]
/* set from thread to 0 */
LDR r1, =rt_interrupt_from_thread
MOV r0, #0x0
STR r0, [r1]
/* set interrupt flag to 1 */
LDR r1, =rt_thread_switch_interrupt_flag
MOV r0, #1
STR r0, [r1]
/* set the PendSV exception priority */
LDR r0, =NVIC_SYSPRI2
LDR r1, =NVIC_PENDSV_PRI
LDR.W r2, [r0,#0x00] /* read */
ORR r1,r1,r2 /* modify */
STR r1, [r0] /* write-back */
LDR r0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
CPSIE I /* enable interrupts at processor level */
/* never reach here! */
/* compatible with old version */
.global rt_hw_interrupt_thread_switch
.type rt_hw_interrupt_thread_switch, %function
rt_hw_interrupt_thread_switch:
BX lr
NOP
.global HardFault_Handler
.type HardFault_Handler, %function
HardFault_Handler:
/* get current context */
MRS r0, psp /* get fault thread stack pointer */
PUSH {lr}
BL rt_hw_hard_fault_exception
POP {lr}
ORR lr, lr, #0x04
BX lr
/*
* File : context_gcc.S
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009, 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
* 2009-10-11 Bernard first version
* 2012-01-01 aozima support context switch load/store FPU register.
*/
/**
* @addtogroup STM32
*/
/*@{*/
.cpu cortex-m4
.syntax unified
.thumb
.text
.equ NVIC_INT_CTRL, 0xE000ED04 /* interrupt control state register */
.equ NVIC_SYSPRI2, 0xE000ED20 /* system priority register (2) */
.equ NVIC_PENDSV_PRI, 0x00FF0000 /* PendSV priority value (lowest) */
.equ NVIC_PENDSVSET, 0x10000000 /* value to trigger PendSV exception */
/*
* rt_base_t rt_hw_interrupt_disable();
*/
.global rt_hw_interrupt_disable
.type rt_hw_interrupt_disable, %function
rt_hw_interrupt_disable:
MRS r0, PRIMASK
CPSID I
BX LR
/*
* void rt_hw_interrupt_enable(rt_base_t level);
*/
.global rt_hw_interrupt_enable
.type rt_hw_interrupt_enable, %function
rt_hw_interrupt_enable:
MSR PRIMASK, r0
BX LR
/*
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
* r0 --> from
* r1 --> to
*/
.global rt_hw_context_switch_interrupt
.type rt_hw_context_switch_interrupt, %function
.global rt_hw_context_switch
.type rt_hw_context_switch, %function
rt_hw_context_switch_interrupt:
rt_hw_context_switch:
/* set rt_thread_switch_interrupt_flag to 1 */
LDR r2, =rt_thread_switch_interrupt_flag
LDR r3, [r2]
CMP r3, #1
BEQ _reswitch
MOV r3, #1
STR r3, [r2]
LDR r2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread */
STR r0, [r2]
_reswitch:
LDR r2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread */
STR r1, [r2]
LDR r0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
BX LR
/* r0 --> swith from thread stack
* r1 --> swith to thread stack
* psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
*/
.global PendSV_Handler
.type PendSV_Handler, %function
PendSV_Handler:
/* disable interrupt to protect context switch */
MRS r2, PRIMASK
CPSID I
/* get rt_thread_switch_interrupt_flag */
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CBZ r1, pendsv_exit /* pendsv already handled */
/* clear rt_thread_switch_interrupt_flag to 0 */
MOV r1, #0x00
STR r1, [r0]
LDR r0, =rt_interrupt_from_thread
LDR r1, [r0]
CBZ r1, swtich_to_thread /* skip register save at the first time */
MRS r1, psp /* get from thread stack pointer */
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
VSTMDB r1!, {d8 - d15} /* push FPU register s16~s31 */
#endif
STMFD r1!, {r4 - r11} /* push r4 - r11 register */
LDR r0, [r0]
STR r1, [r0] /* update from thread stack pointer */
swtich_to_thread:
LDR r1, =rt_interrupt_to_thread
LDR r1, [r1]
LDR r1, [r1] /* load thread stack pointer */
LDMFD r1!, {r4 - r11} /* pop r4 - r11 register */
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
VLDMIA r1!, {d8 - d15} /* pop FPU register s16~s31 */
#endif
MSR psp, r1 /* update stack pointer */
pendsv_exit:
/* restore interrupt */
MSR PRIMASK, r2
ORR lr, lr, #0x04
BX lr
/*
* void rt_hw_context_switch_to(rt_uint32 to);
* r0 --> to
*/
.global rt_hw_context_switch_to
.type rt_hw_context_switch_to, %function
rt_hw_context_switch_to:
LDR r1, =rt_interrupt_to_thread
STR r0, [r1]
/* set from thread to 0 */
LDR r1, =rt_interrupt_from_thread
MOV r0, #0x0
STR r0, [r1]
/* set interrupt flag to 1 */
LDR r1, =rt_thread_switch_interrupt_flag
MOV r0, #1
STR r0, [r1]
/* set the PendSV exception priority */
LDR r0, =NVIC_SYSPRI2
LDR r1, =NVIC_PENDSV_PRI
LDR.W r2, [r0,#0x00] /* read */
ORR r1,r1,r2 /* modify */
STR r1, [r0] /* write-back */
LDR r0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
CPSIE I /* enable interrupts at processor level */
/* never reach here! */
/* compatible with old version */
.global rt_hw_interrupt_thread_switch
.type rt_hw_interrupt_thread_switch, %function
rt_hw_interrupt_thread_switch:
BX lr
NOP
.global HardFault_Handler
.type HardFault_Handler, %function
HardFault_Handler:
/* get current context */
MRS r0, psp /* get fault thread stack pointer */
PUSH {lr}
BL rt_hw_hard_fault_exception
POP {lr}
ORR lr, lr, #0x04
BX lr

View File

@ -1,187 +1,187 @@
;/*
; * File : context_iar.S
; * This file is part of RT-Thread RTOS
; * COPYRIGHT (C) 2009, 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
; * 2009-01-17 Bernard first version
; * 2009-09-27 Bernard add protect when contex switch occurs
; * 2012-01-01 aozima support context switch load/store FPU register.
; */
;/**
; * @addtogroup STM32
; */
;/*@{*/
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
SECTION .text:CODE(2)
THUMB
REQUIRE8
PRESERVE8
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
EXPORT rt_hw_interrupt_disable
rt_hw_interrupt_disable:
MRS r0, PRIMASK
CPSID I
BX LR
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
EXPORT rt_hw_interrupt_enable
rt_hw_interrupt_enable:
MSR PRIMASK, r0
BX LR
;/*
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
; * r0 --> from
; * r1 --> to
; */
EXPORT rt_hw_context_switch_interrupt
EXPORT rt_hw_context_switch
rt_hw_context_switch_interrupt:
rt_hw_context_switch:
; set rt_thread_switch_interrupt_flag to 1
LDR r2, =rt_thread_switch_interrupt_flag
LDR r3, [r2]
CMP r3, #1
BEQ _reswitch
MOV r3, #1
STR r3, [r2]
LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
STR r0, [r2]
_reswitch
LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
STR r1, [r2]
LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
BX LR
; r0 --> swith from thread stack
; r1 --> swith to thread stack
; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
EXPORT PendSV_Handler
PendSV_Handler:
; disable interrupt to protect context switch
MRS r2, PRIMASK
CPSID I
; get rt_thread_switch_interrupt_flag
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CBZ r1, pendsv_exit ; pendsv already handled
; clear rt_thread_switch_interrupt_flag to 0
MOV r1, #0x00
STR r1, [r0]
LDR r0, =rt_interrupt_from_thread
LDR r1, [r0]
CBZ r1, swtich_to_thread ; skip register save at the first time
MRS r1, psp ; get from thread stack pointer
#if defined ( __ARMVFP__ )
VSTMDB r1!, {d8 - d15} ; push FPU register s16~s31
#endif
STMFD r1!, {r4 - r11} ; push r4 - r11 register
LDR r0, [r0]
STR r1, [r0] ; update from thread stack pointer
swtich_to_thread
LDR r1, =rt_interrupt_to_thread
LDR r1, [r1]
LDR r1, [r1] ; load thread stack pointer
LDMFD r1!, {r4 - r11} ; pop r4 - r11 register
#if defined ( __ARMVFP__ )
VLDMIA r1!, {d8 - d15} ; pop FPU register s16~s31
#endif
MSR psp, r1 ; update stack pointer
pendsv_exit
; restore interrupt
MSR PRIMASK, r2
ORR lr, lr, #0x04
BX lr
;/*
; * void rt_hw_context_switch_to(rt_uint32 to);
; * r0 --> to
; */
EXPORT rt_hw_context_switch_to
rt_hw_context_switch_to:
LDR r1, =rt_interrupt_to_thread
STR r0, [r1]
; set from thread to 0
LDR r1, =rt_interrupt_from_thread
MOV r0, #0x0
STR r0, [r1]
; set interrupt flag to 1
LDR r1, =rt_thread_switch_interrupt_flag
MOV r0, #1
STR r0, [r1]
; set the PendSV exception priority
LDR r0, =NVIC_SYSPRI2
LDR r1, =NVIC_PENDSV_PRI
LDR.W r2, [r0,#0x00] ; read
ORR r1,r1,r2 ; modify
STR r1, [r0] ; write-back
LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
CPSIE I ; enable interrupts at processor level
; never reach here!
; compatible with old version
EXPORT rt_hw_interrupt_thread_switch
rt_hw_interrupt_thread_switch:
BX lr
IMPORT rt_hw_hard_fault_exception
EXPORT HardFault_Handler
HardFault_Handler:
; get current context
MRS r0, psp ; get fault thread stack pointer
PUSH {lr}
BL rt_hw_hard_fault_exception
POP {lr}
ORR lr, lr, #0x04
BX lr
END
;/*
; * File : context_iar.S
; * This file is part of RT-Thread RTOS
; * COPYRIGHT (C) 2009, 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
; * 2009-01-17 Bernard first version
; * 2009-09-27 Bernard add protect when contex switch occurs
; * 2012-01-01 aozima support context switch load/store FPU register.
; */
;/**
; * @addtogroup STM32
; */
;/*@{*/
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
SECTION .text:CODE(2)
THUMB
REQUIRE8
PRESERVE8
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
EXPORT rt_hw_interrupt_disable
rt_hw_interrupt_disable:
MRS r0, PRIMASK
CPSID I
BX LR
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
EXPORT rt_hw_interrupt_enable
rt_hw_interrupt_enable:
MSR PRIMASK, r0
BX LR
;/*
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
; * r0 --> from
; * r1 --> to
; */
EXPORT rt_hw_context_switch_interrupt
EXPORT rt_hw_context_switch
rt_hw_context_switch_interrupt:
rt_hw_context_switch:
; set rt_thread_switch_interrupt_flag to 1
LDR r2, =rt_thread_switch_interrupt_flag
LDR r3, [r2]
CMP r3, #1
BEQ _reswitch
MOV r3, #1
STR r3, [r2]
LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
STR r0, [r2]
_reswitch
LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
STR r1, [r2]
LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
BX LR
; r0 --> swith from thread stack
; r1 --> swith to thread stack
; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
EXPORT PendSV_Handler
PendSV_Handler:
; disable interrupt to protect context switch
MRS r2, PRIMASK
CPSID I
; get rt_thread_switch_interrupt_flag
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CBZ r1, pendsv_exit ; pendsv already handled
; clear rt_thread_switch_interrupt_flag to 0
MOV r1, #0x00
STR r1, [r0]
LDR r0, =rt_interrupt_from_thread
LDR r1, [r0]
CBZ r1, swtich_to_thread ; skip register save at the first time
MRS r1, psp ; get from thread stack pointer
#if defined ( __ARMVFP__ )
VSTMDB r1!, {d8 - d15} ; push FPU register s16~s31
#endif
STMFD r1!, {r4 - r11} ; push r4 - r11 register
LDR r0, [r0]
STR r1, [r0] ; update from thread stack pointer
swtich_to_thread
LDR r1, =rt_interrupt_to_thread
LDR r1, [r1]
LDR r1, [r1] ; load thread stack pointer
LDMFD r1!, {r4 - r11} ; pop r4 - r11 register
#if defined ( __ARMVFP__ )
VLDMIA r1!, {d8 - d15} ; pop FPU register s16~s31
#endif
MSR psp, r1 ; update stack pointer
pendsv_exit
; restore interrupt
MSR PRIMASK, r2
ORR lr, lr, #0x04
BX lr
;/*
; * void rt_hw_context_switch_to(rt_uint32 to);
; * r0 --> to
; */
EXPORT rt_hw_context_switch_to
rt_hw_context_switch_to:
LDR r1, =rt_interrupt_to_thread
STR r0, [r1]
; set from thread to 0
LDR r1, =rt_interrupt_from_thread
MOV r0, #0x0
STR r0, [r1]
; set interrupt flag to 1
LDR r1, =rt_thread_switch_interrupt_flag
MOV r0, #1
STR r0, [r1]
; set the PendSV exception priority
LDR r0, =NVIC_SYSPRI2
LDR r1, =NVIC_PENDSV_PRI
LDR.W r2, [r0,#0x00] ; read
ORR r1,r1,r2 ; modify
STR r1, [r0] ; write-back
LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
CPSIE I ; enable interrupts at processor level
; never reach here!
; compatible with old version
EXPORT rt_hw_interrupt_thread_switch
rt_hw_interrupt_thread_switch:
BX lr
IMPORT rt_hw_hard_fault_exception
EXPORT HardFault_Handler
HardFault_Handler:
; get current context
MRS r0, psp ; get fault thread stack pointer
PUSH {lr}
BL rt_hw_hard_fault_exception
POP {lr}
ORR lr, lr, #0x04
BX lr
END

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