where can I find an almost complete implementation (float, width, etc.) suitable for embedded systems (few nested funtction call, low stack and ram usage, no heap, mo syscall)
Have you checked out ChibiOS's implementation of chvprintf? It's Apache-licensed and float-support (costly) is a compile-time option via define.
It's built with microcontrollers in mind. The macros are all pretty much only calls to a function pointer in the supplied BaseSequentialStream struct and you can replace them as you see fit. The var-args list is your regular stdarg.h implementation.
For transmitting on the serial port, the quickest thing is:
int32_t printfDebugSerial(const char *format, ...)
{
if (strlen(format) >200) return -1;
char tempBuff[256]; memset(tempBuff, 0, sizeof tempBuff);
va_list arg;
int32_t done;
va_start (arg, format);
done = (int32_t)vsprintf(tempBuff,format, arg);
va_end (arg);
pushMsgOnSerial((uint8_t*)tempBuff, done);
return done;
}
where pushMsgOnSerial() will be your board specific function for sending bytes on the serial port.
Related
I reguarly check lwIP, a free TCP/IP stack with Coverity.
As a network stack, we have untrusted data coming in from the network which is stored in struct pbuf (some members omitted for clarity):
struct pbuf {
void *payload;
u16_t len;
u16_t ref;
};
My questions are:
1) I want to model that "void* payload" of struct pbuf ALWAYS points to tainted data, every access to it must be untrusted. How can I do this?
2) We use refcounting (u16_t ref). Is there any way to model refcounting in Coverity?
I need help with the uart communication I am trying to implement on my Proteus simulation. I use a PIC18f4520 and I want to display on the virtual terminal the values that have been calculated by the microcontroller.
Here a snap of my design on Proteus
Right now, this is how my UART code looks like :
#define _XTAL_FREQ 20000000
#define _BAUDRATE 9600
void Configuration_ISR(void) {
IPR1bits.TMR1IP = 1; // TMR1 Overflow Interrupt Priority - High
PIE1bits.TMR1IE = 1; // TMR1 Overflow Interrupt Enable
PIR1bits.TMR1IF = 0; // TMR1 Overflow Interrupt Flag
// 0 = TMR1 register did not overflow
// 1 = TMR1 register overflowed (must be cleared in software)
RCONbits.IPEN = 1; // Interrupt Priority High level
INTCONbits.PEIE = 1; // Enables all low-priority peripheral interrupts
//INTCONbits.GIE = 1; // Enables all high-priority interrupts
}
void Configuration_UART(void) {
TRISCbits.TRISC6 = 0;
TRISCbits.TRISC7 = 1;
SPBRG = ((_XTAL_FREQ/16)/_BAUDRATE)-1;
//RCSTA REG
RCSTAbits.SPEN = 1; // enable serial port pins
RCSTAbits.RX9 = 0;
//TXSTA REG
TXSTAbits.BRGH = 1; // fast baudrate
TXSTAbits.SYNC = 0; // asynchronous
TXSTAbits.TX9 = 0; // 8-bit transmission
TXSTAbits.TXEN = 1; // enble transmitter
}
void WriteByte_UART(unsigned char ch) {
while(!PIR1bits.TXIF); // Wait for TXIF flag Set which indicates
// TXREG register is empty
TXREG = ch; // Transmitt data to UART
}
void WriteString_UART(char *data) {
while(*data){
WriteByte_UART(*data++);
}
}
unsigned char ReceiveByte_UART(void) {
if(RCSTAbits.OERR) {
RCSTAbits.CREN = 0;
RCSTAbits.CREN = 1;
}
while(!PIR1bits.RCIF); //Wait for a byte
return RCREG;
}
And in the main loop :
while(1) {
WriteByte_UART('a'); // This works. I can see the As in the terminal
WriteString_UART("Hello World !"); //Nothing displayed :(
}//end while(1)
I have tried different solution for WriteString_UART but none has worked so far.
I don't want to use printf cause it impacts other operations I'm doing with the PIC by adding delay.
So I really want to make it work with WriteString_UART.
In the end I would like to have someting like "Error rate is : [a value]%" on the terminal.
Thanks for your help, and please tell me if something isn't clear.
In your WriteByte_UART() function, try polling the TRMT bit. In particular, change:
while(!PIR1bits.TXIF);
to
while(!TXSTA1bits.TRMT);
I don't know if this is your particular issue, but there exists a race-condition due to the fact that TXIF is not immediately cleared upon loading TXREG. Another option would be to try:
...
Nop();
while(!PIR1bits.TXIF);
...
EDIT BASED ON COMMENTS
The issue is due to the fact that the PIC18 utilizes two different pointer types based on data memory and program memory. Try changing your declaration to void WriteString_UART(const rom char * data) and see what happens. You will need to change your WriteByte_UART() declaration as well, to void WriteByte_UART(const unsigned char ch).
Add delay of few miliseconds after line
TXREG = ch;
verify that pointer *data of WriteString_UART(char *data) actually point to
string "Hello World !".
It seems you found a solution, but the reason why it wasn't working in the first place is still not clear. What compiler are you using?
I learned the hard way that C18 and XC8 are used differently regarding memory spaces. With both compilers, a string declared literally like char string[]="Hello!", will be stored in ROM (program memory). They differ in the way functions use strings.
C18 string functions will have variants to access strings either in RAM or ROM (for example strcpypgm2ram, strcpyram2pgm, etc.). XC8 on the other hand, does the job for you and you will not need to use specific functions to choose which memory you want to access.
If you are using C18, I would highly recommend you switch to XC8, which is more recent and easier to work with. If you still want to use C18 or another compiler which requires you to deal with program/data memory spaces, then here below are two solutions you may want to try. The C18 datasheet says that putsUSART prints a string from data memory to USART. The function putrsUSART will print a string from program memory. So you can simply use putrsUSART to print your string.
You may also want to try the following, which consists in copying your string from program memory to data memory (it may be a waste of memory if your application is tight on memory though) :
char pgmstring[] = "Hello";
char datstring[16];
strcpypgm2ram(datstring, pgmstring);
putsUSART(datstring);
In this example, the pointers pgmstring and datstring will be stored in data memory. The string "Hello" will be stored in program memory. So even if the pointer pgmstring itself is in data memory, it initially points to a memory address (the address of "Hello"). The only way to point to this same string in data memory is to create a copy of it in data memory. This is because a function accepting a string stored in data memory (such as putsUSART) can NOT be used directly with a string stored in program memory.
I hope this could help you understand a bit better how to work with Harvard microprocessors, where program and data memories are separated.
I have some straight C code in my Objective-C project. In one of the APIs I'm using, I can register for a callback with a function that takes an 32-bit integer parameter:
void Callback(Packet* packet, int32_t port);
I want to be able to send my callback two 16-bit ports instead of one 32-bit port. Naturally, I could just use bitwise operations, but I'd prefer something more explicit.
Here's my current solution with a union:
typedef struct {
int16_t port1;
int16_t port2;
} MultiPortStruct;
typedef union {
int32_t port;
MultiPortStruct portStruct;
} MultiPortAdaptor;
In the sender:
void registerCallback(int16_t port1, int16_t port2) {
MultiPortAdaptor adaptor;
adaptor.portStruct.port1 = port1;
adaptor.portStruct.port2 = port2;
int32_t port = adaptor.port
RegisterAPICallback(&myCallback, port);
}
In the callback:
void myCallback(Packet* packet, int32_t port) {
MultiPortAdaptor adaptor;
adaptor.port = port;
int16_t port1 = adaptor.portStruct.port1;
int16_t port2 = adaptor.portStruct.port2;
// do stuff
}
Is this approach correct or are there problems with it? (For example: should I zero out the adaptor unions? Is it OK to access different members of the same union?) Is there a simpler way?
UPDATE:
OK, I'm convinced: even if doing this is possible, it's probably not a great idea. I've decided to simply use a set of functions to do the bitwise operations for me:
int32_t SubPortsToPort(int16_t port1, int16_t port2)
int16_t PortToSubPort1(int32_t port)
int16_t PortToSubPort2(int32_t port)
So now all I have to do is this:
void registerCallback(int16_t port1, int16_t port2) {
int32_t port = SubPortsToPort(port1, port2);
RegisterAPICallback(&myCallback, port);
}
And in the callback:
void myCallback(Packet* packet, int32_t port) {
int16_t port1 = PortToSubPort1(port);
int16_t port2 = PortToSubPort2(port);
// do stuff
}
Less code, less worries!
First it is OK to store into one member and read from another member of the same union provided you only read bytes you have written - any others have unspecified values.
The issue with what you are doing is the possible introduction by the compiler of padding between fields, which would destroy your carefully arranged overlap. With current compilers & cpu architectures you will probably be OK, but there is no need to leave it to chance as there are a number of ways to fix the alignment of fields.
The simplest, though compiler dependent, method is to use the packed attribute:
typedef struct __attribute((packed))
{
int16_t port1;
int16_t port2;
} MultiPortStruct;
This simply instructs the compiler not to add any padding, so the above will always be 32-bits even on architectures which use, say, 4-byte alignment for 2-byte values.
This attribute is supported by Clang, GCC & LLVM (maybe not all versions?) - the compiler will tell you if it doesn't. If you are using a compiler which does not support the attribute (or an equivalent one) then you can look into using the C language _Alignof and _Alignas features.
HTH
With the "struct in a union trick" you have to take care, because the structure members can be padded:
There may be unnamed padding within a structure object, but not at its
beginning.
ISO/IEC 9899:TC3, 6.7.2.1 – 13
Therefore, …
typedef struct {
int16_t port1;
int16_t port2;
} MultiPortStruct;
… can have a layout as …
typedef struct {
int32_t port1;
int32_t port2;
} MultiPortStruct;
… if the implementation likes that.
So the overlay in the union will not work, even this is not very likely.
It would be similar with bitfields:
typedef struct {
int port1:16;
int port2:16;
} MultiPortStruct;
This is, because the compiler has to put the following bitfield into the same unit, if it fits, but can chose the unit.
An implementation may allocate any addressable storage unit large enough to hold a bit- field. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit.
ibidem, 6.7.2.1 – 10
Therefore, it is theoretically possible, that an implementation choses int16 as allocation unit and places padding between the fields, even this makes no sense and is very unlikely.
As mentioned in the comment, there is nothing wrong with bitfields.
As others said, a struct might have padding (though unlikely). Another approach that would at least not have internal padding would be
typedef struct {
int16_t port[2];
} MultiPortStruct;
arrays never have internal padding and the first field of a struct is always at its start. Now theoretically this still could have padding at the end, so you should check with something like
_Static_assert(sizeof(MultiPortStruct)==2*sizeof(int16_t));
I should use Objective-C to read some slowly growing file (under Mac OS X).
"Slowly" means that I read to EOF before it grows bigger.
In means of POSIX code in plain syncronous C I can do it as following:
while(1)
{
res = select(fd+1,&fdset,NULL,&fdset,some_timeout);
if(res > 0)
{
len = read(fd,buf,sizeof(buf));
if (len>0)
{
printf("Could read %u bytes. Continue.\n", len);
}
else
{
sleep(some_timeout_in_sec);
}
}
}
Now I want to re-write this in some asynchronous manner, using NSInputSource or some other async Objective-C technique.
The problem with NSInputSource: If I use scheduleInRunLoop: method then once I get NSStreamEventEndEncountered event, I stop receiving any events.
Can I still use NSInputSource or should I pass to using NSFileHandle somehow or what would you recommend ?
I see a few problems.
1) some_Timeout, for select() needs to be a struct timeval *.
2) for sleep() some_timeout needs to be an integer number of seconds.
3) the value in some_timeout is decremented via select() (which is why the last parameter is a pointer to the struct timeval*. And that struct needs to be re-initialized before each call to select().
4) the parameters to select() are highest fd of interest+1, then three separate struct fd_set * objects. The first is for input files, the second is for output files, the third is for exceptions, however, the posted code is using the same struct fd_set for both the inputs and the exceptions, This probably will not be what is needed.
When the above problems are corrected, the code should work.
I think that the wrapper framework in valgrind is pretty nice. I am trying to track differences between different code paths (as to why one works and another does not). Instead of trying to look at a difference of an strace output (which will not give me all details I need because I want to trace lib and sys calls I decided to use wrappers around a handful of functions.
The one function that got me scratching my head is fcntl.
The fcntl manpage declares it as follows
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
However as this is C and overloading does not come naturally to C, it is prototyped as follows in fcntl.h
extern int fcntl (int __fd, int __cmd, ...);
The end-user wrapping facility in valgrind supports N number of WORD arguments, but carries a warning about using the wrong number of args and I did not see a mention of any varargs.
A more classical varargs function like printf is typically implemented with a lower fixed args function vprintf which takes va_list as a single parameter. In such a case I would have wrapped vprintf rather than printf, but alas AFAIK fcntl does not have such an intermediate function.
My question is - what would a "safe" wrapper for fcntl look like?
For example, the following seems to work, but is it safe:
int I_WRAP_SONAME_FNNAME_ZU(libcZdsoZa,fcntl)(int fd, int cmd, ...)
{
int result;
OrigFn fn;
void* arg;
va_list argp;
va_start(argp, cmd);
arg=va_arg(argp, void*);
VALGRIND_GET_ORIG_FN(fn);
printf("##fcntl wrapper: args fd=%d, cmd=%d, arg=%p ... ", fd, cmd, arg);
CALL_FN_W_WWW(result, fn, fd, cmd, arg);
printf("##fcntl wrapper: result %d\n", result);
return result;
}
Look syswrappers for sys_ioctl in valgrind sources in file coregrind/m_syswrap/syswrap-linux.c.
Look at http://valgrind.org/docs/manual/dist.readme-missing.html for details.
Maybe you will need to rebuild valgrind with your changes for syswrappers.