/* * @brief Prints formatted output to the remote terminal * * Processes the input string into an output string rone understands. * If the input string is too large, rprintfOverRunError is set to TRUE. * * @returns void */ void rprintf(char *format, ...) { va_list arguments; va_start(arguments, format); int32 potentialChars; char* charPtr; if (rprintfOSInit) { // // wait until the callback function clears the flag, or the buffer times out // if (rprintfBufferCallbackLock) { // if (osTaskGetTickCount() > (rprintfRemoteRequestTime + RPRINTF_HOST_RESPONSE_TIMEOUT)) { // // the previous radio request has timed out. release the buffer lock // rprintfBufferCallbackLock = FALSE; // } else { // // wait a bit for the callback function to release the lock // osTaskDelay(1); // } // } // Not needed since we are now double buffered // get the mutex to write to the rprintf flags and buffer osSemaphoreTake(rprintfMutex, portMAX_DELAY); // since we are writing new data, the buffer is not ready to be accessed by the rprintf thread // rprintfRadioBufferDataReady = FALSE; // Not needed since we are now double buffered /* Process the input string and store the output in the 'outStringFormatted' */ /* note that vsnprintf returns the number of characters that would have been * written to the buffer if it were large enough. */ potentialChars = vsnprintf(rprintfBufferPtr, RPRINTF_TEXT_STRING_SIZE - 1, format, arguments); if (potentialChars >= (RPRINTF_TEXT_STRING_SIZE - 1)) { error("rprintf buffer overflow"); } charPtr = rprintfBufferPtr; while (*charPtr != '\0') { // buffer the char on the radio buffer //if((!rprintfBufferCallbackLock) && (rprintfRadioBufferPtr < (rprintfRadioBuffer + RPRINTF_TEXT_STRING_SIZE - 1))) { if(rprintfRadioBufferPtr < (rprintfRadioBuffer + RPRINTF_TEXT_STRING_SIZE - 1)) { *rprintfRadioBufferPtr++ = *charPtr; } if (*charPtr == '\n') { //if(!rprintfBufferCallbackLock) { // the radio buffer is ready for xmit *rprintfRadioBufferPtr = '\0'; rprintfRadioBufferDataReady = TRUE; rprintfRadioBufferPtr = rprintfRadioBuffer; //TODO replace these fake battery values and radio signal quality with real numbers cprintf("rtd, %d, ", roneID); cprintf(rprintfRadioBuffer); //} } charPtr++; } osSemaphoreGive(rprintfMutex); } // clean up the argument list va_end(arguments); }
void serial_send_string_mutex(const char* string) { osSemaphoreTake(xMutex, MAX_DELAY); { cprintf("%s\n", string); } osSemaphoreGive(xMutex); }
/* * @brief Serves the same purpose as formatted output string for the robot. * * Processes the input string into an output string rone understands. * If the input string is too large, cfprintfOverRunError is set to TRUE. * * @returns void */ void cprintf(char *format, ...) { va_list arguments; va_start(arguments, format); int32 potentialChars; boolean cfprintfOverRunError = FALSE; char* charPtr; if (cprintfOSInit) { osSemaphoreTake(cprintfMutex, portMAX_DELAY); } /* Process the input string and store the output in the 'outStringFormatted' */ /* note that vsnprintf returns the number of characters that would have been * written to the buffer if it were large enough. */ potentialChars = vsnprintf(cfprintfBufferPtr, CPRINTF_TEXT_STRING_SIZE - 1, format, arguments); if (potentialChars >= (CPRINTF_TEXT_STRING_SIZE - 1)) { cfprintfOverRunError = TRUE; } charPtr = cfprintfBufferPtr; while (*charPtr != '\0') { if (*charPtr == '\n') { // change '\n' into the current CRLF mode switch (CRLFMode) { case CPRINTF_CRLF_CR: sputchar('\r'); break; case CPRINTF_CRLF_CRLF: sputchar('\r'); sputchar('\n'); break; case CPRINTF_CRLF_LFCR: sputchar('\n'); sputchar('\r'); break; case CPRINTF_CRLF_LF: default: sputchar('\n'); break; } } else { sputchar(*charPtr); } charPtr++; } sputcharFlush(); if (cprintfOSInit) { osSemaphoreGive(cprintfMutex); } // clean up the argument list va_end(arguments); }
static void serialCommandTask(void* parameters) { // osSemaphoreTake(serialCommandSemaphore, portMAX_DELAY); while(TRUE) { // wait for a potential crlf osSemaphoreTake(serialCommandSemaphore, portMAX_DELAY); // process the serial data. Is there a command in here? if (serialStringUpdate()) { serialCmdCall(serialCommandString); } } }
/** * Sets a status variable's value * * @param indxVar Variable to set @sa DAT_CubesatVar * @param value Value to set */ void dat_setCubesatVar(DAT_CubesatVar indxVar, int value) { osSemaphoreTake(&repoDataSem, portMAX_DELAY); #if SCH_STATUSCH_STATUS_REPO_MODE == 0 //Uses internal memory DAT_CUBESAT_VAR_BUFF[indxVar] = value; #else //Uses external memory #if __linux__ printf("writeIntEEPROM1\n"); #else writeIntEEPROM1( (unsigned char)indxVar, value); #endif #endif osSemaphoreGiven(&repoDataSem); }
/** * Returns a status variable's value * * @param indxVar Variable to set @sa DAT_CubesatVar * @return Variable value */ int dat_getCubesatVar(DAT_CubesatVar indxVar) { int value = 0; osSemaphoreTake(&repoDataSem, portMAX_DELAY); #if SCH_STATUSCH_STATUS_REPO_MODE == 0 //Uses internal memory value = DAT_CUBESAT_VAR_BUFF[indxVar]; #else //Uses external memory #if __linux__ printf("readIntEEPROM1\n"); value = 0; #else value = readIntEEPROM1( (unsigned char)indxVar ); #endif #endif osSemaphoreGiven(&repoDataSem); return value; }
/* * When a robot receives a radio query, it transmits * the contents of its rprintf buffer back. * * msgPtr is the pointer to the radio message containing * the callback request. */ static void rprintfRemoteCallback(RadioCmd* radioCmdPtr, RadioMessage* msgPtr) { uint8 destinationRobotID, length, requestedBits, requestedBitsToXmit; uint8 packetNum, packetNumMax; RadioMessage radioResponseMsg; // We are remote. Respond to the host with the contents of the rprintf buffer. // Parse the request. requestedBits = msgPtr->command.data[RPRINTF_MSG_PACKET_REQ_BITS_IDX]; requestedBitsToXmit = requestedBits; rprintfRemoteRequestTime = osTaskGetTickCount(); if (requestedBits == 0x00) { // This is a new data request. requestedBitsToXmit = 0xFF; } // Lock the radio buffer to check if there is something to transmit. osSemaphoreTake(rprintfMutex, portMAX_DELAY); // If the buffer is ready, determine the length of the message. if (rprintfRadioBufferDataReady) { length = strlen(rprintfRadioBuffer); strncpy(rprintfRadioBufferSend, rprintfRadioBuffer, length); //rprintfBufferCallbackLock = TRUE; rprintfRadioBufferDataReady = FALSE; //Robot is being asked if it has a message //cprintf("*"); } else { length = 0; } osSemaphoreGive(rprintfMutex); // Build the response and request a retransmit if needed. packetNumMax = computeNumPackets(length); radioResponseMsg.command.data[RPRINTF_MSG_BUFFER_LENGTH_IDX] = length; // do we have anything to transmit at all? //TODO data race! split the writer buffer and the sender buffer if (packetNumMax == 0) { // You have nothing new to transmit. Send an ack back to the host. radioCommandXmit(&radioCmdRprintfRemoteToHost, ROBOT_ID_ALL, &radioResponseMsg); //rprintfBufferCallbackLock = FALSE; } // Transmit the message. for (packetNum = 0; packetNum < packetNumMax; packetNum++) { if (requestedBitsToXmit & 0x01) { radioResponseMsg.command.data[RPRINTF_MSG_PACKET_IDX] = packetNum; uint16 packetIdx; uint16 msgIdx = packetNum * RPRINTF_MSG_DATA_PAYLOAD_LENGTH; char c; for (packetIdx = 0; packetIdx < RPRINTF_MSG_DATA_PAYLOAD_LENGTH; packetIdx++) { if (msgIdx < RPRINTF_TEXT_STRING_SIZE) { //c = rprintfRadioBuffer[msgIdx++]; c = rprintfRadioBufferSend[msgIdx++]; } else { c = 0; } radioResponseMsg.command.data[RPRINTF_MSG_DATA_PAYLOAD_START + packetIdx] = c; } radioCommandXmit(&radioCmdRprintfRemoteToHost, ROBOT_ID_ALL, &radioResponseMsg); //TODO this delay is here because there is a bug in the radio drivers //systemDelay(5000); //osTaskDelay(1); } requestedBitsToXmit >>= 1; } }