📄 client.c
字号:
// client.cpp : functions for monitor download and communication.//#include <stdio.h>#include <stdlib.h>#include "scalar_types.h" // (U)INT8/16/32#include "Uart.h" // platform abstraction for UART#include "minimon.h" // protocol of my little monitor// do the baudrate configuration for the Playerint ConfigFirstlevelPlayer (tUartHandle serial_handle){ UINT32 result_nbr; if(!UartConfig(serial_handle, 4800, eMARKPARITY, eTWOSTOPBITS, 8)) { UINT32 dwErr = GET_LAST_ERR(); printf("Error %d setting up COM params for baudrate byte\n", dwErr); exit(1); } // this will read as 0x19 when viewed with 2300 baud like the player does result_nbr = UartWrite(serial_handle, (UINT8*)"\x86\xC0", 2); if (result_nbr != 2) { UINT32 dwErr = GET_LAST_ERR(); printf("Error %d setting up COM params for baudrate byte\n", dwErr); } SLEEP(100); // wait for the chars to be sent, is there a better way? // the read 0x19 means 14423 baud with 12 MHz if(!UartConfig(serial_handle, 14400, eNOPARITY, eONESTOPBIT, 8)) { printf("Error setting up COM params for 1st level loader\n"); exit(1); } return 0;}// do the baudrate configuration for the Recoder/FMint ConfigFirstlevelRecorder (tUartHandle serial_handle){ UINT32 result_nbr; if(!UartConfig(serial_handle, 4800, eNOPARITY, eTWOSTOPBITS, 8)) { UINT32 dwErr = GET_LAST_ERR(); printf("Error %d setting up COM params for baudrate byte\n", dwErr); exit(1); } // this will read as 0x08 when viewed with 2120 baud like the recorder does result_nbr = UartWrite(serial_handle, (UINT8*)"\x00\x00", 2); if(result_nbr != 2) { printf("Error transmitting baudrate byte\n"); exit(1); } SLEEP(100); // wait for the chars to be sent, is there a better way? // the read 0x08 means 38400 baud with 11.0592 MHz if(!UartConfig(serial_handle, 38400, eNOPARITY, eONESTOPBIT, 8)) { UINT32 dwErr = GET_LAST_ERR(); printf("Error %d setting up COM params for 1st level loader\n", dwErr); exit(1); } return 0;}// transfer a byte for the monitor download, with or without acknowledgeint DownloadByte(tUartHandle serial_handle, unsigned char byte, bool bAck){ unsigned char received; bool bRecorder = true; // false for player while (1) { UartWrite(serial_handle, &byte, 1); if (bAck) { UartRead(serial_handle, &received, 1); if (received == byte) { UartWrite(serial_handle, (UINT8*)"\x01", 1); // ack success break; // exit the loop } else { printf("Error transmitting monitor byte 0x%02X, got 0x%0X\n", byte, received); UartWrite(serial_handle, (UINT8*)"\x00", 1); // ack fail, try again } } else break; // no loop } return 1;}// download our little monitor, the box must have been just freshly switched on for this to workint DownloadMonitor(tUartHandle serial_handle, bool bRecorder, char* szFilename){ FILE* pFile; size_t filesize; UINT8 byte; unsigned i; // hard-coded parameters bool bAck = true; // configure if acknowledged download (without useful for remote pin boot) UINT32 TargetLoad = 0x0FFFF000; // target load address pFile = fopen(szFilename, "rb"); if (pFile == NULL) { printf("\nMonitor file %s not found, exiting\n", szFilename); exit(1); } // determine file size fseek(pFile, 0, SEEK_END); filesize = ftell(pFile); fseek(pFile, 0, SEEK_SET); // This is _really_ tricky! The box expects a BRR value in a nonstandard baudrate, // which a PC can't generate. I'm using a higher one with some wild settings // to generate a pulse series that: // 1) looks like a stable byte when sampled with the nonstandard baudrate // 2) gives a BRR value to the box which results in a baudrate the PC can also use if (bRecorder) { ConfigFirstlevelRecorder(serial_handle); } else { ConfigFirstlevelPlayer(serial_handle); } UartWrite(serial_handle, bAck ? (UINT8*)"\x01" : (UINT8*)"\x00", 1); // ACK mode // transmit the size, little endian DownloadByte(serial_handle, (UINT8)( filesize & 0xFF), bAck); DownloadByte(serial_handle, (UINT8)((filesize>>8) & 0xFF), bAck); DownloadByte(serial_handle, (UINT8)((filesize>>16) & 0xFF), bAck); DownloadByte(serial_handle, (UINT8)((filesize>>24) & 0xFF), bAck); // transmit the load address, little endian DownloadByte(serial_handle, (UINT8)( TargetLoad & 0xFF), bAck); DownloadByte(serial_handle, (UINT8)((TargetLoad>>8) & 0xFF), bAck); DownloadByte(serial_handle, (UINT8)((TargetLoad>>16) & 0xFF), bAck); DownloadByte(serial_handle, (UINT8)((TargetLoad>>24) & 0xFF), bAck); // transmit the command byte DownloadByte(serial_handle, 0xFF, bAck); // 0xFF means execute the transferred image // transmit the image for (i=0; i<filesize; i++) { fread(&byte, 1, 1, pFile); DownloadByte(serial_handle, byte, bAck); } fclose (pFile); // now the image should have been started, red LED off return 0;}// wait for a fixed string to be received (no foolproof algorithm,// may overlook if the searched string contains repeatitions)int WaitForString(tUartHandle serial_handle, char* pszWait){ int i = 0; unsigned char received; while(pszWait[i] != '\0') { UartRead(serial_handle, &received, 1); printf("%c", received); // debug if (received == pszWait[i]) i++; // continue else i=0; // mismatch, start over } return 0;}// send a sting and check the echoint SendWithEcho(tUartHandle serial_handle, char* pszSend){ int i = 0; unsigned char received; while(pszSend[i] != '\0') { UartWrite(serial_handle, (unsigned char*)(pszSend + i), 1); // send char do { UartRead(serial_handle, &received, 1); // receive echo printf("%c", received); // debug } while (received != pszSend[i]); // should normally be equal i++; // next char } return 0;}// rarely used variant: download our monitor using the built-in Archos monitorint DownloadArchosMonitor(tUartHandle serial_handle, char* szFilename){ FILE* pFile; size_t filesize; UINT8 byte; UINT16 checksum = 0; unsigned i; // the onboard monitor uses 115200 baud if(!UartConfig(serial_handle, 115200, eNOPARITY, eONESTOPBIT, 8)) { UINT32 dwErr = GET_LAST_ERR(); printf("Error %d setting up COM params for baudrate %d\n", dwErr, 115200); exit(1); } // wait for receiving "#SERIAL#" WaitForString(serial_handle, "#SERIAL#"); // send magic "SRL" command to get interactive mode SendWithEcho(serial_handle, "SRL\r"); // wait for menu completion: "ROOT>" at the end WaitForString(serial_handle, "ROOT>"); // send upload command "UP" SendWithEcho(serial_handle, "UP\r"); pFile = fopen(szFilename, "rb"); if (pFile == NULL) { printf("\nMonitor file %s not found, exiting\n", szFilename); exit(1); } // determine file size fseek(pFile, 0, SEEK_END); filesize = ftell(pFile); fseek(pFile, 0, SEEK_SET); // calculate checksum for (i=0; i<filesize; i++) { fread(&byte, 1, 1, pFile); checksum += byte; } fseek(pFile, 0, SEEK_SET); // send header // size as 32 bit little endian byte = (UINT8)( filesize & 0xFF); UartWrite(serial_handle, &byte, 1); byte = (UINT8)((filesize>>8) & 0xFF); UartWrite(serial_handle, &byte, 1); byte = (UINT8)((filesize>>16) & 0xFF); UartWrite(serial_handle, &byte, 1); byte = (UINT8)((filesize>>24) & 0xFF); UartWrite(serial_handle, &byte, 1); // checksum as 16 bit little endian byte = (UINT8)( checksum & 0xFF); UartWrite(serial_handle, &byte, 1); byte = (UINT8)((checksum>>8) & 0xFF); UartWrite(serial_handle, &byte, 1); UartWrite(serial_handle, (unsigned char*)"\x00", 1); // kind (3 means flash) UartWrite(serial_handle, (unsigned char*)"\x00", 1); // ignored byte // wait for monitor to accept data WaitForString(serial_handle, "#OKCTRL#"); // transmit the image for (i=0; i<filesize; i++) { fread(&byte, 1, 1, pFile); UartWrite(serial_handle, &byte, 1); // payload } fclose (pFile); UartWrite(serial_handle, (unsigned char*)"\x00", 1); // ignored byte // wait for menu completion: "ROOT>" at the end WaitForString(serial_handle, "ROOT>"); // send start program command "SPRO" SendWithEcho(serial_handle, "SPRO\r"); SLEEP(100); // wait a little while for startup return 0;}/********** Target functions using the Monitor Protocol **********/// read a byte using the target monitorUINT8 ReadByte(tUartHandle serial_handle, UINT32 addr){ UINT8 send; UINT8 received; // send the address command send = ADDRESS; UartWrite(serial_handle, &send, 1); // transmit the address, big endian send = (UINT8)((addr>>24) & 0xFF); UartWrite(serial_handle, &send, 1); send = (UINT8)((addr>>16) & 0xFF); UartWrite(serial_handle, &send, 1); send = (UINT8)((addr>>8) & 0xFF); UartWrite(serial_handle, &send, 1); send = (UINT8)(addr & 0xFF); UartWrite(serial_handle, &send, 1); UartRead(serial_handle, &received, 1); // response if (received != ADDRESS) { printf("Protocol error!\n"); return 1; } // send the read command send = BYTE_READ; UartWrite(serial_handle, &send, 1); UartRead(serial_handle, &received, 1); // response return received;}// write a byte using the target monitorint WriteByte(tUartHandle serial_handle, UINT32 addr, UINT8 byte){ UINT8 send; UINT8 received; // send the address command send = ADDRESS; UartWrite(serial_handle, &send, 1); // transmit the address, big endian send = (UINT8)((addr>>24) & 0xFF); UartWrite(serial_handle, &send, 1); send = (UINT8)((addr>>16) & 0xFF); UartWrite(serial_handle, &send, 1); send = (UINT8)((addr>>8) & 0xFF); UartWrite(serial_handle, &send, 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -