示例#1
0
//-----------------------------------------------------------------------------
// Test binary data transmission.
// Format in:
//  <byte size>:<mode>
// Format out:
//  <4 bytes binary checksum><#size bytes data>
// If echo mode, also:
//    Format in:
//     <#size bytes data>
//    Format out:
//     OK/ER - according to CRC match on incomin data
// Format in:
//  DONE
//
// To Do:
//  o Add mode/flag specifying 5-8 bit transfer.
//     Test that 0xff gets masked off accordingly when transfered.
//     (This should be an INFO result if failing)
//  o Clean up the DUPLEX_ECHO implementation. Currently it's an ugly hack
//    that doesn't match the arguments / behavior of the two other modes.
void
CeCosTestSerialFilter::CMD_TestBinary(CeCosSerial &pSer, char* args)
{
    int size;
    cyg_mode_t mode;
    unsigned char *data_out, *data_in;
    int i;
    int crc;

    int loop_count = 0;

    INIT_VALUE(args);

    SET_VALUE(int, size);
    SET_VALUE(cyg_mode_t, mode);

    // Change behavior for DUPLEX mode.
    if (MODE_DUPLEX_ECHO == mode) {
        loop_count = size;
        size = 1024;                    // must be at least 4*block_size
    }

    // Generate data.
    data_out = (unsigned char*) malloc(size);
    if (!data_out) {
        fprintf(stderr, "Could not allocate %d byte buffer for data!\n", size);
        throw "data_out malloc failed";
    }
    data_in = (unsigned char*) malloc(size);
    if (!data_in) {
        fprintf(stderr, "Could not allocate %d byte buffer for data!\n", size);
        throw "data_in malloc failed";
    }
    int count = 0;
    for (i = 0; i < size; i++) {
        // Output 255 chars, not 256 so that we aren't a multiple/factor of the
        // likely buffer sizes in the system, this can mask problems as I've
        // found to my cost!
        unsigned char c = (unsigned char) (count++ % 255);
        // don't allow $s and @s in the data, nor 0x03 (GDB C-c), nor flow
        // control chars
        if ('$' == c || '@' == c || 0x03 == c || 0x11 == c || 0x13 == c)
            c = (unsigned char) '*';
        data_out[i] = c;
    }

    // Do checksum.
    crc = DoCRC(data_out, size);

    // Send checksum to target.
    SendChecksum(pSer, crc);

    // Give the target 1/10th of a sec to digest it
    CeCosThreadUtils::Sleep(100);

    switch (mode) {
    case MODE_NO_ECHO:
    {
        // Simple transmit. Don't expect target to echo data back.
        TargetWrite(pSer, data_out, size);
        ReceiveDone(pSer, NULL, 0);
    }
    break;
    case MODE_EOP_ECHO:
    {
        int in_crc;

        TargetWrite(pSer, data_out, size);
        Trace("Finished write, waiting for target echo.\n");

        // Expect target to echo the data
        TargetRead(pSer, data_in, size);

        // Check echoed data, and reply OK/ER accordingly.
        in_crc = DoCRC(data_in, size);
        SendStatus(pSer, (in_crc == crc));


        // Dump seen/expected on console.
        if (in_crc != crc) {
            Trace("Data seen:\n");
            PrintHex(data_in, size);
            Trace("<end>\n");
            Trace("Data expected:\n");
            PrintHex(data_out, size);
            Trace("<end>\n");
        }

        ReceiveDone(pSer, data_in, size);

    }
    break;
    case MODE_DUPLEX_ECHO:
    {
        int block_size = 64;
        int fail, j;

        // This is a simple implementation (maybe too simple).
        // Host sends 4 packets with the same size (64 bytes atm).
        // Target echoes in this way:
        //  packet1 -> packet1
        //  packet2 -> packet2, packet2
        //  packet3 -> packet3
        //  packet4 -> /dev/null
        //
        // The reads/writes are interleaved in a way that should ensure
        // the target out buffer to be full before the target starts to read
        // packet3. That is, the target should be both receiving (packet3)
        // and sending (packet2) at the same time.

        // This code needs restructuring. It's not very obvious what's
        // happening: The same block of data is output several times,
        // the target echoes the data back (one of the blocks is
        // echoed twice). Then the echoed data is compared agains the
        // outgoing data block.

        fail = 0;
        while (loop_count--) {
            int i;
            for (i = 0; i < block_size*4; i++)
                data_in[i] = 0;

            // out1: block_size -> block_size
            TargetWrite(pSer, data_out, block_size);

            // out2: block_size -> 2 x block_size
            TargetWrite(pSer, data_out, block_size);

            // in1:
            TargetRead(pSer, data_in, block_size);

            // out3: block_size -> block_size
            TargetWrite(pSer, data_out, block_size);
        
            // in2:
            TargetRead(pSer, &data_in[block_size], 2*block_size);

            // out4: block_size -> 0
            TargetWrite(pSer, data_out, block_size);
        
            // in3:
            TargetRead(pSer, &data_in[block_size*3], block_size);

            if (0 == loop_count % 10)
                Trace("%d loops to go\n", loop_count);

            // Verify data.
            if (!fail) {
                for (j = 0; j < 4 && !fail; j++) {
                    for (i = 0; i < block_size && !fail; i++) {
                        if (data_out[i] != data_in[j*block_size + i]) {
                            fail = 1;
                            Trace("Failed at byte %d\n", j*block_size + i);
                            
                            Trace("Data seen:\n");
                            PrintHex(&data_in[j*block_size], 
                                           block_size);
                            Trace("<end>\n");
                            Trace("Data expected:\n");
                            PrintHex(data_out, block_size);
                            Trace("<end>\n");
                        }
                    }
                }
            }
        }
        // Check echoed data, and reply OK/ER accordingly.
        SendStatus(pSer, (!fail));
        ReceiveDone(pSer, data_in, block_size*4);
    }
    break;
    default:
        Trace("Unknown mode. Ignoring.\n");
    }

    // Free buffer.
    free(data_in);
    free(data_out);
}
示例#2
0
// TODO: Refactor this with some of the timer changes
// TODO: Write unit tests
BootloaderState BootloaderFSM(BootloaderState state)
{
	BootloaderState next_state; // Leave like this for static analysis to catch or set to set state?
	char comByte;

	switch(state)
	{
	case Check:
		// Check that the program has been programmed correctly. If so, go to Boot. Otherwise, go to Not Loaded.

		if(*header == HEADER_CONSTANT)
		{
			// We want to read from the header, so let's set a pointer to it that we can advance
			uint32_t* read_header = header;
			// We should be pointing to start now
			read_header++;

			// Read start address, length, version, and footer address
			start = (uint32_t*)*read_header++;
			length = *read_header++;
			version = *read_header++;
			footer = (uint32_t*)*read_header++;

			crc = *(footer + 1);

			// TODO: Validate data

			if(*footer == FOOTER_CONSTANT)
			{
				uint32_t crc = DoCRC(start, length);

				if(crc == crc)
				{
					next_state = Booting;
				}
				else
				{
					SetError(error, "CrcFaild");
					next_state = NotLoaded;
				}
			}
			else
			{
				SetError(error, "BadFootr");
				next_state = NotLoaded;
			}
		}
		else
		{
			SetError(error, "BadHeadr");
			next_state = NotLoaded;
		}
		break;
	case NotLoaded:
		// Wait for 5 seconds. If no communication during that time, then power down

		if(power_down_time == 0)
		{
			power_down_time = *timer + FIVE_SECONDS;
			next_state = NotLoaded;
		}

		// Check for a message to push us into communicate
		comByte = Rs232GetByte();
		if(IsBootCommand(comByte))
		{
			next_state = Communicate;
		}
		else
		{
			// Otherwise, check if we need to power down
			if(*timer > power_down_time)
			{
				// 5 seconds have passed, power the device down
				next_state = PowerDown;
			}
			else
			{
				// Keep waiting.
				// TODO: Wait here?
				next_state = NotLoaded;
			}
		}

		break;
	case Booting:
		// Wait for 0.5 ms. If no communication during that time, boot our program.
		if(boot_time == 0)
		{
			boot_time = *timer + FIVE_HUNDRED_MS;
		}

		// Check if a service tool wants to communicate
		comByte = Rs232GetByte();
		if(IsBootCommand(comByte))
		{
			// Move to communicate state if so
			next_state = Communicate;
		}
		else
		{
			// Otherwise, check if it's time to boot
			if(boot_time > *timer)
			{
				// Point of No Return
				// Boot();
			}
			else
			{
				// Keep waiting
				// TODO: Wait here?
				next_state = Booting;
			}
		}

		break;
	case PowerDown:
		// PowerDown();

		// Once we come out of sleep, then go to check
		next_state = Check;

		break;
	case Communicate:
		DoProtocol();
		next_state = Check;

		break;
	}

	return next_state;
}
////////////////////////////////////////////////////////////////////////////
// Parameter:
// 1, CFile&  : hex file preference, to be read
// 2, char*  : a memory pointer, has been allocate in heep, it's a valid memory space.
// 3, int      :  specify parameter 2, memory space's size.
// return:
// int			: it's the truely length of the used buffer, also useful byte number after hex file been parsed.
// 读扩展线性地址记录的hex file-最大32位的地址空间
BOOL CHexFileParser::ReadExtLinearHexFile(CFile& hexfile, char* pBuf, int nBufLen)
{
	//CArchive ar(&m_hex_file,CArchive::load);
	//ASSERT(nBufLen >= 0xFFFF);
	if (pBuf)
	{
		delete[] pBuf;
		pBuf = NULL;
	}

	pBuf = new char[c_nHexFileBufLen];
		
	CString strGetData;
	int nBufCount = 0;
//*****************inspect the file*********************
	unsigned int nLineNumErr=0;

	DWORD dwHiAddr = 0; // 高位地址
	char a[256];
	ZeroMemory(a, 256);
	
	//while(NULL!=ar.ReadString(strGetData))	//循环读取文件,直到文件结束
	while(ReadLineFromFile(hexfile, a))
	{
		// 取得高位地址,可能不止一处扩展
		if( a[8] == '4')
		{
			CString strTemp(a);
			dwHiAddr = GetHighAddrFromFile(strTemp);
			dwHiAddr <<= 16;

			if( nBufCount != 0)
			{
				m_szFlags.push_back(nBufCount);
			}
			// do CRC
			continue;
		}

		//get a line from the file,check "crc" for total file
		nLineNumErr++;	//the line number that the wrong hex file;
		TS_UC get_hex[128]={0};//get hex data,it is get from the line char
		//the number is (i-1)
		//int nLen = strGetData.GetLength();
		for(UINT i=0; i<strlen(a); i++) // 去掉冒号
		{
			a[i]=a[i+1];
		}

		int nLen = strlen(a)-2; // 不算回车换行的长度
		if(strlen(a)%2==0)
			turn_hex_file_line_to_unsigned_char(a);//turn every char to int 
		else
		{
			wchar_t p_c_temp[74]={'\0'};
			swprintf_s(p_c_temp,_T("Error: the hex file had error at %d line!"),nLineNumErr);
			
			//AddStringToOutPuts(p_c_temp);
			nBufCount = 0;
			AfxMessageBox(p_c_temp);
			//close_com();
			goto END;
			return 0;
		}
		turn_int_to_unsigned_char(a,nLen,get_hex);//turn to hex 
		if(get_hex[3]==1)	//for to seektobegin() function,because to end of the file
			break;


		if(!DoCRC( get_hex, nLen/2))
		{
			wchar_t p_c_temp[74]={'\0'};
			swprintf_s(p_c_temp,_T("Error: the hex file had error at %d line!"),nLineNumErr);
			//AddStringToOutPuts(p_c_temp);	
			nBufCount = 0;	
			AfxMessageBox(p_c_temp, MB_OK);
			
			//close_com();
			goto END;
			return 0;
		}

	//	if(get_hex[1]==0 && get_hex[2]==0)
	//		get_hex[4]=255;//for the 0000 register to write 255
	    int temp;
		char temp_buf[32];
		
		if (nLineNumErr==9)
		{

		    for (int i=0;i<32;i++)
		    {
			  temp_buf[i]=a[i+8];
		    }
			for (int i=0;i<20;i++)
			{   
			    temp=temp_buf[2*i]*16+temp_buf[2*i+1];
				m_DeviceInfor[i]=temp;
			}
			
			//m_softwareRev = (temp_buf[30] + temp_buf[31]*256)/10.0;


			//m_ProductModel=m_DeviceInfor[0];
			m_softwareRev= ((a[38]*16+a[39]) + (a[40]*16 + a[41])*256)/10.0;
			m_ProductName.Empty();
			for (int i=0;i<10;i++)
			{
				CString temp1;
				temp1.Format(_T("%C"),m_DeviceInfor[5+i]);
				m_ProductName = m_ProductName + temp1;
			}
		}



		unsigned int ltemp;
		ltemp=get_hex[1]*256+get_hex[2] + dwHiAddr;
//         if (m_IsRAM)
//         {
//             ltemp-=0x00008000; 
//         }
		for(int j=0;j<get_hex[0];j++)
			pBuf[ltemp+j]=get_hex[4+j];//get the data
		if((UINT)nBufCount<(ltemp+get_hex[0]))
			nBufCount=ltemp+get_hex[0];


		ZeroMemory(a, 256);
	}//end while
	
	m_szFlags.push_back(nBufCount);
	

END:
	hexfile.Close();//close the file

	return nBufCount;
	//return 0 ;
}