Compile C as C and C++ as C++

02 Jul 2012

You could have noticed a common pattern among all the officially supported mbed libraries:

  • mbed SDK
  • mbed IP networking
  • mbed RTOS

Their bulk is written in C and then a C++ "sugar coating" is providing a nice and friendly object oriented API.

Having to deal with a large bulk of C code the offline mbed build system has always compiled C source files as C syntax, and C++ source files as C++ syntax.

On the other hand, considering that the majority of the C syntax is a subset of the C++ syntax, as a simplification for the mbed community the online build system was compiling both C and C++ files as C++ syntax.

One of the goals the mbed team is aiming to is the open sourcing of all the officially supported mbed libraries.

For this reason, we are aiming at unifying the offline and online build system. As a first step, starting from the release 40 of the mbed library we have started compiling C files as C syntax and C++ files as C++ syntax.

These are some of the immediate outcomes of these changes:

  • We can now provide the source code of the mbed RTOS library
  • We can now provide the source code of the mbed IP networking library
  • The ".c" files are compiled as C syntax, not C++ syntax

If this change is breaking your existing code, you have a quick and simple fix: rename your ".c" file to ".cpp".

Cheers, Emilio

25 Jul 2012

By renaming all my .c files to .cpp that seems to work now. Thanks Emilio. Regards Tim

28 Aug 2012

This is great news for mixing c with cpp without having to re-write c to comply with cpp standards. Awesome!

31 Dec 2018
  1. include "mbed.h"
  2. include "MSCFileSystem.h"
  3. include "EthernetInterface.h"
  4. include "TextLCD.h"
  5. include "rtos.h"
  1. define SERVER_PORT 20
  2. define FSNAME "msc"

Temperature Structure typedef struct { float tempC; float tempF; float timeStamp; float avgC; average change in celsius per second float avgF; average change in farenheit per second } Temperature;

/* Defines all Analog/Digital devices connected to microcontroller*/ MSCFileSystem myUSBPort(FSNAME); DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); TextLCD lcd(p10, p12, p15, p16, p29, p30, TextLCD::LCD20x4); rs, e, d0-d3 AnalogIn tempSensor(p17); Temeperature sensor PwmOut Speaker(p21);

Mail<Temperature, 16> mail_box; allocatable queue - very similar to FIFO Timer t; timer FILE *fp; temperature logging File bool cont = true, pause = false; boolean for stopping and pausing application int numOfReadings = 0; total number of temperatures read float totalC = 0, totalF = 0; total temp read int TimeToRun = 0, timeInterval = 0; how long the application runs given by JAVA application TCPSocketConnection client; client connecting to JAVA app int pauseFlag = 5;

/** This function takes the pointer to mail and shared buffer to calculate and store temperature from sensor */ void calcTemp(Temperature *mail, void const *args){ Temperature* myTemp = (Temperature*)args; float holdC, holdF; conversion to degrees C holdC = myTemp->tempC; holdF = myTemp->tempF;

mail->tempC = ((tempSensor*3.3)-0.600)*100.0; myTemp->tempC = ((tempSensor*3.3)-0.600)*100.0; convert to degrees F mail->tempF = (9.0*mail->tempC)/5.0 + 32.0; myTemp->tempF = (9.0*mail->tempC)/5.0 + 32.0; storing time mail->timeStamp = t.read(); myTemp->timeStamp = t.read(); computing average change in temperature printf("%.1f + %.1f - %.1f = ", myTemp->avgF, myTemp->tempF, holdF); mail->avgC = mail->avgC + (mail->tempC - holdC); myTemp->avgC = myTemp->avgC + (myTemp->tempC - holdC); mail->avgF = mail->avgF + (mail->tempF - holdF); myTemp->avgF = myTemp->avgF + (myTemp->tempF - holdF); printf("%.1f\n", myTemp->avgF);

numOfReadings++; increase total number of readings totalC += myTemp->tempC; increase total temperature read in C totalF += myTemp->tempF; increase total temperature read in F

}

void TextLCD(void const *args){ Temperature* myTemp = (Temperature*)args; char buffer[20];

while(cont) { loop to update LCD interface lcd.cls(); lcd.locate(0,0); lcd.printf("Temperature Logger"); lcd.locate(0,1); lcd.printf(" Time = %.1f", t.read()); lcd.locate(0,2); lcd.printf("C = %.1f F = %.1f", myTemp->tempC, myTemp->tempF); lcd.locate(0,3); lcd.printf("C/s= %.1f F/s= %.1f", (myTemp->avgC/t.read()), (myTemp->avgF/t.read()));

Thread::wait(50); wait 0.5ns to reduce the number of double sent times if (t.read() >= TimeToRun) break loop if time to end cont = false;

} snprintf(buffer, sizeof(buffer), ",#,%.1f,%.1f,%.1f, \n", (float)totalF/numOfReadings, (myTemp->avgF/t.read()), t.read()); puts final data to application in buffer client.send_all(buffer, sizeof(buffer));sends final data to application lcd.cls();

/* Display all final data on LCD*/ lcd.locate(0,0); lcd.printf("COMPLETE"); lcd.locate(0,1); lcd.printf("AvgC= %.1f", (float)totalC/numOfReadings); lcd.locate(0,2); lcd.printf("AvgF= %.1f", (float)totalF/numOfReadings); lcd.locate(0,3); lcd.printf("C/s= %.1f F/s= %.1f", (myTemp->avgC/t.read()), (myTemp->avgF/t.read()));

/* Play final noise on speaker**/ Speaker.period(1.0/500.0); 500hz period Speaker =0.01; 50% duty cycle - max volume Thread::wait(1500); wait 1.5s Speaker=0.0; turn off audio led1 = 1; led2 = 1; led3 = 1; led4 = 1; cont = false;

}

write temp from analalog port 17 to shared buffer args This is a real-time task and will only execute every given interval from application void readTemp(void const *args){ if (pause == true){ while(1){ if ((int)t.read()%timeInterval == 0 && pause == false){ break; } } } turn on LED's when reading temp led1 = 1; led2 = 1; led3 = 1; led4 = 1;

Temperature *mail = mail_box.alloc(); allocate mailbox to memory

calcTemp(mail, args);

mail_box.put(mail); put it on the mailbox mail_box.free(mail);

}

Speaker/LED thread - will play noise and flash LED everytime temp is read void speaker(void const *args) { while(cont) { if(led1 == 1){ use LED as a flag

Speaker.period(1.0/1000.0); 500hz period Speaker =0.05; 50% duty cycle - max volume Thread::wait(1); short wait Speaker=0.0; turn off audio Thread::wait(500); wait 0.5s led1 = 0; led2 = 0; led3 = 0; led4 = 0; } } }

void Pause(void const *args) will await message from application for pausing/resume { char buffer[5]; while(cont) { client.receive(buffer, sizeof(buffer)); will wait until info recieved printf("%s\n", buffer); if (strcmp(buffer, "Pause") == 0){ pauses all except for temp reader (stops timer) t.stop(); pause = true; } else if (strcmp(buffer, "Resum") == 0){ resumes all threads t.start(); pause = false; } else if (strcmp(buffer, "Stopn") == 0){ stops all threads cont = false; break; } memset(&buffer, 0, sizeof(buffer)); clear buffer } }

/** Thread responsible for writing to the USB Flash Drive**/ void USBWrite(void const *args) { FILE *fp = fopen( "/" FSNAME "/Temperature_Log.txt", "w"); open file on flash drive if ( fp == NULL ) if error { error("Could not open file for write\n"); } else printf("File opened successfuly\n");

while(cont){ if (pause == false){

osEvent evt = mail_box.get(); this will wait until something is put onto the mailbox if (evt.status == osEventMail && pause == false && cont == true) { if there is mail and application is not paused or stopped Temperature *mail = (Temperature*)evt.value.p; fprintf(fp, "Timestamp(s): | %.1f Temperature(C) = %.1f Average Change = %.1f | ", mail->timeStamp, mail->tempC, (mail->avgC/t.read())); printf("Timestamp: %.1f Temperature(C) = %.1f Average Change = %.1f | ", mail->timeStamp, mail->tempC, (mail->avgC/t.read())); fprintf(fp, "%.1f Temperature(F) = %.1f Average Change = %.1f\r\n", mail->tempF, (mail->avgF/t.read())); printf("Temperature(F) = %.1f Average Change = %.1f\n", mail->tempF, (mail->avgF/t.read())); mail_box.free(mail); }

} } fclose(fp); closes file }

int main() {

Temperature myTemp; myTemp.avgF = 0; myTemp.avgC = 0; myTemp.tempC = ((tempSensor*3.3)-0.600)*100.0; myTemp.tempF = (9.0*myTemp.tempC)/5.0 + 32.0;

led1 = 0; led2 = 0; led3 = 0; led4 = 0; DIR *d; struct dirent *p; char* runtime; char* interval; int n = 0; char buffer[15];

d = opendir("/" FSNAME);

/* Display all files on the flash drive */ printf("\nList of files on the flash drive:\n"); if ( d != NULL ) { while ( (p = readdir(d)) != NULL ) { printf(" - %s\n", p->d_name); } } else { error("Could not open directory!"); }

EthernetInterface eth; eth.init(); Use DHCP eth.connect(); printf("\nIP Address is %s\n", eth.getIPAddress()); print IP of MBED

lcd.locate(0,0); lcd.printf("Wait for connection...");

TCPSocketServer server; server.bind(SERVER_PORT); server.listen();

printf("\nWait for new connection...\n"); server.accept(client); wait and accept new client client.set_blocking(true, 1500); Set to blocking printf("Connection from: %s\n", client.get_address()); print JAVA IP on COM port

/* Print Ethernet Info on LCD Interface / lcd.cls(); lcd.locate(0,0); lcd.printf("My IP: %s", eth.getIPAddress()); lcd.locate(0,1); lcd.printf("Wait for info from"); lcd.locate(0,2); lcd.printf("%s", client.get_address());

n = client.receive(buffer, sizeof(buffer)); will wait until info recieved frin JAVA application for runtime and interval if (n == 0) if error receiving printf("Error recieving data"); runtime = strtok(buffer, " "); tokenize buffer interval = strtok(NULL, " ");

TimeToRun = atoi(runtime); timeInterval = atoi(interval);

/** Start all threads ****/ printf("Runtime %d Interval %d\n", TimeToRun, timeInterval); Thread writeToLog(USBWrite); Thread speakerThread(speaker); Thread pauseThread(Pause); lcd.cls(); Thread LCD_thread(TextLCD, &myTemp); RtosTimer tempReader(readTemp, osTimerPeriodic, &myTemp); /***********/ t.start(); start timer tempReader.start(timeInterval*1000); setup real time task with period of 5 seconds memset(&buffer, 0, sizeof(buffer)); Preclear buffer while(cont){ if (pause == true){ tempReader.stop(); pauseFlag = 0; }

if ((int)t.read()%timeInterval == 0 && pauseFlag == 0){ tempReader.start(timeInterval*1000); setup real time task with period of 5 seconds led1 = 1; led2 = 1; led3 = 1; led4 = 1;

Temperature *mail = mail_box.alloc(); allocate mailbox to memory calcTemp(mail, &myTemp); mail_box.put(mail); put it on the mailbox

pauseFlag = 1; } snprintf(buffer, sizeof(buffer), ",%d,%.1f\n", (int)t.read(), myTemp.tempF); put information in char* buffer for TCP transmit printf("Sent through socket: %s\n", buffer); Verify on COM port client.send_all(buffer, sizeof(buffer)); Send buffer over TCP Thread::wait(500); wait 0.5ns to reduce the number of double sent times if (n == 0) If failed printf("Error sending to client"); memset(&buffer, 0, sizeof(buffer)); Clear buffer

} tempReader.stop(); client.close(); close tcp connection Thread::wait(osWaitForever);

}

Please log in to post a reply.