Storing int values in an uint8_t array in code composer studio vs 5.4 - embedded

I have a string in a uint8_t str[] array and I am trying to store the positions of characters within the str in another variable called uint8_t pos[]. The code is written in Code Composer Studio vs 5.4
I tried using sprintf(), type casting as well as changing the type of uint8_t pos[] to int pos[] as well as unsigned int pos[]. None of these work.
The code breaks at the sprintf statement and comes to a halt by reaching an undefined memory location. When I run in assembly after reaching sprintf statement, it gives an error saying that a source code for sprint.c cannot be found in location.
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "tm4c123gh6pm.h"
#include <stdio.h>
void initHw()
{
.
.
}
int main(void)
{
// Initialize hardware
initHw();
char strRx[80];
int count =0;
int count_enter=0;
uint8_t posStr[80];
uint8_t typeStr[80];
int pos=0;
int len;
unsigned int j=0, argCount=0;
while(1)
{
if(count == 0)
{
putsUart0("Enter characters for the string\r\n");
}
if(count <= 80)
{
char c = getcUart0();
if(c=='\b')
if(count>0)
count--;
else
break;
if(c>=' ')
{
strRx[count]=c;
count++;
}
if(count==80 || c==13)//'\r')
{
count_enter++;
if(count_enter==1) //count==80 before carriage return
{
len = count;
strRx[count]='\0';
while(count!=80)
strRx[count++]='\0';
count_enter=0;
putsUart0("\r\nEntered string is:\r\n");
putsUart0(strRx);
putsUart0("\r\n");
}
j=0;
//char a[10];
for(pos=0; pos!=len; pos++)// strRx[pos]!='\0'; pos++)
{
char a[80];
if((strRx[pos]>='A' && strRx[pos]<='Z') || (strRx[pos]>='a' && strRx[pos]<='z'))
{
typeStr[j]='a';
//posStr[j]=pos;
a[j]=pos;
sprintf(a,"%u",pos); //source not found
//a[j]=pos;
//posStr[j]=sprintf("%c",a);
//posStr[j]=(uint8_t)a;//a;
while(strRx[pos]!='\0'&&((strRx[pos]>='A' && strRx[pos]<='Z') || (strRx[pos]>='a' && strRx[pos]<='z')))
{
pos++;
}
pos--;
j++;
}
else if(strRx[pos]>='0' && strRx[pos]<='9')
{
typeStr[j]='n';
a[j]=pos;
sprintf(a,"%u",pos);
//posStr[j]=pos;//a;
while(strRx[pos]!='\0'&&((strRx[pos]>='0' && strRx[pos]<='9')))
{
pos++;
}
pos--;
j++;
}
else
{
while(strRx[pos]!='\0'&&((strRx[pos]<'A' && strRx[pos]>'Z') && (strRx[pos]<'a' && strRx[pos]>'z') && (strRx[pos+1]<'0' && strRx[pos+1]>'9')))
pos++;
}
}
argCount=j;
while(j!=80)
{
typeStr[j++]='\0';
posStr[j++]='\0';
}
count = 0;
}//if(count==80 || c==13)//'\r')
}//if count<=80
}//while(1)
}//main

The "unable to locate sprintf.c" error probably just means that the debugger cannot locate the source file, which means it cannot show the source code in the debugger window. It's possible that you don't have the source code for sprintf.c and all you have is the precompiled library. Or maybe you do have the source code and the debugger is simply looking in the wrong path. If you have the source code then there may be a way to tell the debugger which path to find it.
But that is just a debugger display issue -- It is not what is causing your program to crash. The problem may be in your code but you'd have to share your code for us to identify that. Or the problem may be a couple other issues that can occur with the printf related routines.
1) printf routines can use a relatively large amount of stack space. So check for a stack overflow and increase the stack size if necessary.
2) Some embedded libraries provide multiple implementations of the printf routines such as "small", "no-float", and "full". The limited implementations use less code space but don't support all of the format specifiers. So make sure the implementation of sprintf that you've linked with supports all the format specifiers that you're actually using. Look through the project settings under linker or libraries for an option to select which version of printf is used.

Related

how to get (segment offset) each different plane (IODeviceTree, IOService ....) to make a dump?

I want to read analyze a plane (IODeviceTree IOUSB IOService IOACPIPlane)
without using ioreg, by creating a pointer (segment offset) in memory, my question is how to get the address of a plane, that in C or Objective C. Thank you for your answers.
First of all, I'm not sure what you mean by "segment offset" in this context, but the rest of the question makes sense, so I'll just ignore that part for my answer.
Second, the source code for ioreg is available here so you can see exactly how that does it.
A quick summary of how I would do it:
The main function you need to call is IORegistryCreateIterator().
Do not set the options argument to kIORegistryIterateRecursively - otherwise it will be difficult to find the graph structure.
For the plane argument, specify e.g. kIOServicePlane.
Keep calling IOIteratorNext(), and every time you get a registry entry back, try to recurse using IORegistryIteratorEnterEntry() and every time you get IO_OBJECT_NULL back, step one level back out using IORegistryIteratorExitEntry().
Working example code:
#include <stdio.h>
#include <IOKit/IOKitLib.h>
int main(int argc, const char * argv[])
{
io_iterator_t iter = IO_OBJECT_NULL;
unsigned recursion_level = 0;
kern_return_t result = IORegistryCreateIterator(kIOMasterPortDefault, kIOServicePlane, 0, &iter);
if (result == 0 && iter != IO_OBJECT_NULL)
{
while (true)
{
io_object_t entry = IOIteratorNext(iter);
if (entry != IO_OBJECT_NULL)
{
io_name_t name = "";
IORegistryEntryGetName(entry, name);
printf("%*s+ %s\n", recursion_level * 2, "", name);
++recursion_level;
result = IORegistryIteratorEnterEntry(iter);
assert(result == KERN_SUCCESS);
}
else
{
if (recursion_level == 0)
break;
result = IORegistryIteratorExitEntry(iter);
assert(result == KERN_SUCCESS);
--recursion_level;
}
}
}
return 0;
}
(Make sure to link against the IOKit.framework)
Of course, you can do much more interesting things than call IORegistryEntryGetName() on each registry entry.

How to get selected adapter's MAC address in WinPcap?

For example, when program runs, I entered 1 as input and wanted to get MAC address of that interface in here. How can I do that?
I did a lot of work trying to figure out how to both get the mac address for an arbitrary interface under Windows, and matching that to the device info you get back from WinPCap.
A lot of posts say you should use GetAdaptersInfo or similar functions to get the mac address, but unfortunately, those functions only work with an interface that has ipv4 or ipv6 bound to it. I had a network card that purposely wasn't bound to anything, so that Windows wouldn't send any data over it.
GetIfTable(), however, seems to actually get you every interface on the system (there were 40 some odd on mine). It has the hardware mac address for each interface, so you just need to match it to the corresponding WinPCap device. The device name in WinPCap has a long GUID, which is also present in the name field of the interface table entries you get from GetIfTable. The names don't match exactly, though, so you have to extract the GUID from each name and match that. An additional complication is that the name field in the WinPCap device is a regular character string, but the name in the data you get from GetIfTable is a wide character string. The code below worked for me on two different systems, one Windows 7 and another Windows 10. I used the Microsoft GetIfTable example code as a starting point:
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "IPHLPAPI.lib")
#include <pcap.h>
// Compare the guid parts of both names and see if they match
int compare_guid(wchar_t *wszPcapName, wchar_t *wszIfName)
{
wchar_t *pc, *ic;
// Find first { char in device name from pcap
for (pc = wszPcapName; ; ++pc)
{
if (!*pc)
return -1;
if (*pc == L'{'){
pc++;
break;
}
}
// Find first { char in interface name from windows
for (ic = wszIfName; ; ++ic)
{
if (!*ic)
return 1;
if (*ic == L'{'){
ic++;
break;
}
}
// See if the rest of the GUID string matches
for (;; ++pc,++ic)
{
if (!pc)
return -1;
if (!ic)
return 1;
if ((*pc == L'}') && (*ic == L'}'))
return 0;
if (*pc != *ic)
return *ic - *pc;
}
}
// Find mac address using GetIFTable, since the GetAdaptersAddresses etc functions
// ony work with adapters that have an IP address
int get_mac_address(pcap_if_t *d, u_char mac_addr[6])
{
// Declare and initialize variables.
wchar_t* wszWideName = NULL;
DWORD dwSize = 0;
DWORD dwRetVal = 0;
int nRVal = 0;
unsigned int i;
/* variables used for GetIfTable and GetIfEntry */
MIB_IFTABLE *pIfTable;
MIB_IFROW *pIfRow;
// Allocate memory for our pointers.
pIfTable = (MIB_IFTABLE *)malloc(sizeof(MIB_IFTABLE));
if (pIfTable == NULL) {
return 0;
}
// Make an initial call to GetIfTable to get the
// necessary size into dwSize
dwSize = sizeof(MIB_IFTABLE);
dwRetVal = GetIfTable(pIfTable, &dwSize, FALSE);
if (dwRetVal == ERROR_INSUFFICIENT_BUFFER) {
free(pIfTable);
pIfTable = (MIB_IFTABLE *)malloc(dwSize);
if (pIfTable == NULL) {
return 0;
}
dwRetVal = GetIfTable(pIfTable, &dwSize, FALSE);
}
if (dwRetVal != NO_ERROR)
goto done;
// Convert input pcap device name to a wide string for compare
{
size_t stISize,stOSize;
stISize = strlen(d->name) + 1;
wszWideName = malloc(stISize * sizeof(wchar_t));
if (!wszWideName)
goto done;
mbstowcs_s(&stOSize,wszWideName,stISize, d->name, stISize);
}
for (i = 0; i < pIfTable->dwNumEntries; i++) {
pIfRow = (MIB_IFROW *)& pIfTable->table[i];
if (!compare_guid(wszWideName, pIfRow->wszName)){
if (pIfRow->dwPhysAddrLen != 6)
continue;
memcpy(mac_addr, pIfRow->bPhysAddr, 6);
nRVal = 1;
break;
}
}
done:
if (pIfTable != NULL)
free(pIfTable);
pIfTable = NULL;
if (wszWideName != NULL)
free(wszWideName);
wszWideName = NULL;
return nRVal;
}

Stange behavior with my C string reverse function

I'm just an amateur programmer...
And when reading, for the second time, and more than two years apart, kochan's "Programming in Objective-C", now the 6th ed., reaching the pointer chapter i tried to revive the old days when i started programming with C...
So, i tried to program a reverse C string function, using char pointers...
At the end i got the desired result, but... got also a very strange behavior, i cannot explain with my little programming experience...
First the code:
This is a .m file,
#import <Foundation/Foundation.h>
#import "*pathToFolder*/NSPrint.m"
int main(int argc, char const *argv[])
{
#autoreleasepool
{
char * reverseString(char * str);
char *ch;
if (argc < 2)
{
NSPrint(#"No word typed in the command line!");
return 1;
}
NSPrint(#"Reversing arguments:");
for (int i = 1; argv[i]; i++)
{
ch = reverseString(argv[i]);
printf("%s\n", ch);
//NSPrint(#"%s - %s", argv[i], ch);
}
}
return 0;
}
char * reverseString(char * str)
{
int size = 0;
for ( ; *(str + size) != '\0'; size++) ;
//printf("Size: %i\n", size);
char result[size + 1];
int i = 0;
for (size-- ; size >= 0; size--, i++)
{
result[i] = *(str + size);
//printf("%c, %c\n", result[i], *(str + size));
}
result[i] = '\0';
//printf("result location: %lu\n", result);
//printf("%s\n", result);
return result;
}
Second some notes:
This code is compiled in a MacBook Pro, with MAC OS X Maverick, with CLANG (clang -fobjc-arc $file_name -o $file_name_base)
That NSPrint is just a wrapper for printf to print a NSString constructed with stringWithFormat:arguments:
And third the strange behavior:
If I uncomment all those commented printf declarations, everything work just fine, i.e., all printf functions print what they have to print, including the last printf inside main function.
If I uncomment one, and just one, randomly chosen, of those comment printf functions, again everything work just fine, and I got the correct printf results, including the last printf inside main function.
If I leave all those commented printf functions as they are, I GOT ONLY BLANK LINES with the last printf inside main block, and one black line for each argument passed...
Worst, if I use that NSPrint function inside main, instead of the printf one, I get the desired result :!
Can anyone bring some light here please :)
You're returning a local array, that goes out of scope as the function exits. Dereferencing that memory causes undefined behavior.
You are returning a pointer to a local variable of the function that was called. When that function returns, the memory for the local variable becomes invalid, and the pointer returned is rubbish.

programatic way to find ELF aux header (or envp) in shared library code?

I'm looking for a programatic way to find the powerpc cpu type on Linux. Performing some google searches associated an answer suggesting the mfpvr instruction I found that this is available in the ELF AUX header, and sure enough I can obtain the POWER5 string for the machine I'm running on with the following:
#include <stdio.h>
#include <elf.h>
int main( int argc, char **argv, char **envp )
{
/* walk past all env pointers */
while ( *envp++ != NULL )
;
/* and find ELF auxiliary vectors (if this was an ELF binary) */
#if 0
Elf32_auxv_t * auxv = (Elf32_auxv_t *) envp ;
#else
Elf64_auxv_t * auxv = (Elf64_auxv_t *) envp ;
#endif
char * platform = NULL ;
for ( ; auxv->a_type != AT_NULL ; auxv++ )
{
if ( auxv->a_type == AT_PLATFORM )
{
platform = (char *)auxv->a_un.a_val ;
break;
}
}
if ( platform )
{
printf( "%s\n", platform ) ;
}
return 0 ;
}
In the shared library context where I want to use this info I have no access to envp. Is there an alternate programatic method to find the beginning of the ELF AUX header?
You can get if from /proc/self/auxv file
According to man proc /proc/self/auxv is available since kernel level 2.6.0-test7.
Another option - get some (existing) environment variable - let say HOME,
or PATH, or whatever. Please note that you'll get it's ADDRESS. From here you can go back and find previous env variable, then one before it, etc. After that you can likewise skip all argv arguments. And then you get to the last AUXV entry. Some steps back - and you should be able find your AT_PLATFORM.
EDIT: It looks like glibc now provides a programatic method to get at this info:
glibc-headers-2.17-106: /usr/include/sys/auxv.h : getauxinfo()
Example:
#include <sys/auxv.h>
#include <stdio.h>
int main()
{
unsigned long v = getauxval( AT_PLATFORM ) ;
printf( "%s\n", (char *)v ) ;
return 0 ;
}

Why _vsnprintf crash at windows

When will the _vsnprintf crash?
I use it like this:
void My_Printf(const char *szFormatString, ...)
{
va_list my_args;
va_start(my_args, szFormatString);
AppendToLog(szFormatString, my_args);
va_end(my_args);
}
static void AppendToLog(const char *szFormatString, va_list argptr)
{
char szLine[MAX_LENGTH_STRING] = {0};
if ((NULL != szFormatString) && (0 != strcmp(szFormatString, ""))) {
if (strlen(szFormatString) > MAX_LENGTH_STRING) {
return;
}
#ifdef WIN32
_vsnprintf(szLine, MAX_LENGTH_STRING-1, szFormatString, argptr);
#endif
...
}
and the VC show that it was broken at:
_VALIDATE_RETURN( (ch != _T('\0')), EINVAL, -1); (output.c)
I don't know why.
According to MSND, it should return a value whether it was ok or not.
This is canonical code for using vsnprintf:
void Format( const char * fmt, ... ) {
const int BUFSIZE = 1024;
char buffer[BUFSIZE];
va_list valist;
va_start( valist, fmt );
vsnprintf( &buf[0], BUFSIZE, fmt, valist );
va_end( valist );
// do something with buffer
}
I don't know if this helps, but keep in mind that vsnprintf (and _vsnprintf I guess since Microsoft says they're identical) return different values on Windows and Unix. The Windows version returns -1 if you overflow the buffer, while the Unix version returns how many characters would have been written had the buffer been large enough. Here's a couple of links that I found helpful in this regard:
http://msdn.microsoft.com/en-us/library/1kt27hek(v=vs.80).aspx
http://bytes.com/topic/c/answers/590845-snprintf-return-value
EDIT: And here's an alternate version I found to get around this problem:
http://article.gmane.org/gmane.comp.version-control.git/75280/