MOD54415 file handling
-
- Posts: 192
- Joined: Mon Dec 17, 2012 6:24 am
MOD54415 file handling
Hi all -
I'm a little new to programming with object oriented languages, and kind of going through a "baptism by fire" with it, if you will. I'm fairly good at C, but not enough to answer this question. So My task at work at the moment is to take the "UDP Send and Receive" example, and add a subroutine to it that manipulates the incoming data payload. The data payload will consist of 1 byte machine instructions to be executed, each followed by data variables. I need this data in an indexed array, and when I'm done, I need to send out an array of data back to the computer through the network. My question is, when the incoming data is stripped from the header, where is it stored? How can I access it, and where can I put my return data to make sure it gets back out? I've already written the software to handle the data, I just have no idea how to access it, and this system is a little obscure for me at the moment. If anyone can help, I'd appreciate it!
Tony
I'm a little new to programming with object oriented languages, and kind of going through a "baptism by fire" with it, if you will. I'm fairly good at C, but not enough to answer this question. So My task at work at the moment is to take the "UDP Send and Receive" example, and add a subroutine to it that manipulates the incoming data payload. The data payload will consist of 1 byte machine instructions to be executed, each followed by data variables. I need this data in an indexed array, and when I'm done, I need to send out an array of data back to the computer through the network. My question is, when the incoming data is stripped from the header, where is it stored? How can I access it, and where can I put my return data to make sure it gets back out? I've already written the software to handle the data, I just have no idea how to access it, and this system is a little obscure for me at the moment. If anyone can help, I'd appreciate it!
Tony
Re: MOD54415 file handling
If your more comfortable in 'C' style interface look at the UDP sockets example...
nburn\examples\udp\UDPSockets...
That is a C style interface to UDP...
To answer your origional question...
When you construct a UDP object off of a receive FIFO as long as the UDP object is still in scope
the data should still be valid... you can get a pointer to the data with the
PBYTE GetDataBuffer( void );
and WORD GetDataSize( void ) const;
Unless you call ReleaseBuffer( void ) the data buffer is held by the object and still valid...
When the UDP object goes out of scope IE crosses the } defining the block the udp object was constructed in...
then the automagically called destructor will clean up the buffer... and any pointer you grabbed with GetDataBuffer
will now be pointing at a buffer that is possibly invalid...
If your doing something like receive a packet and send back a response to the sameplace...
you can use the same UDP object... BUT process all your incoming data before you start putting thing back into the object..
You porbably want to call ResetData before putting things in to send back...as this will modify the buffer it holds....
Did this help?
nburn\examples\udp\UDPSockets...
That is a C style interface to UDP...
To answer your origional question...
When you construct a UDP object off of a receive FIFO as long as the UDP object is still in scope
the data should still be valid... you can get a pointer to the data with the
PBYTE GetDataBuffer( void );
and WORD GetDataSize( void ) const;
Unless you call ReleaseBuffer( void ) the data buffer is held by the object and still valid...
When the UDP object goes out of scope IE crosses the } defining the block the udp object was constructed in...
then the automagically called destructor will clean up the buffer... and any pointer you grabbed with GetDataBuffer
will now be pointing at a buffer that is possibly invalid...
If your doing something like receive a packet and send back a response to the sameplace...
you can use the same UDP object... BUT process all your incoming data before you start putting thing back into the object..
You porbably want to call ResetData before putting things in to send back...as this will modify the buffer it holds....
Did this help?
-
- Posts: 192
- Joined: Mon Dec 17, 2012 6:24 am
Re: MOD54415 file handling
Thanks pbreed, I'm going to look into the C-style socket example you suggested. And you've helped me understand a little more... thanks!
I guess I'm having a tough time visualizing what happens to the data when you acquire a pointer to it (I'm an electrical engineer shoved into the embedded software world, bear with me on this, I'm slow to catch on... sorry). I'm assuming based on the documentation that the GetDataBuffer() gets a pointer that aligns with the memory location of the first byte of the data buffer? and when you call for the data size, "const" holds the value of the size of the array? (buffer). Is this data buffer size represented in words or bytes? and if I need to address each individual byte in the buffer, how would I go about doing that?
Basically, I'm visualizing the data landing in a defined array like data_buffer[80] where I can move through the index and pick out each piece that I want. basically, how can I make that happen? I'll look over the other socket example, thanks again for helping!!
Tony
I guess I'm having a tough time visualizing what happens to the data when you acquire a pointer to it (I'm an electrical engineer shoved into the embedded software world, bear with me on this, I'm slow to catch on... sorry). I'm assuming based on the documentation that the GetDataBuffer() gets a pointer that aligns with the memory location of the first byte of the data buffer? and when you call for the data size, "const" holds the value of the size of the array? (buffer). Is this data buffer size represented in words or bytes? and if I need to address each individual byte in the buffer, how would I go about doing that?
Basically, I'm visualizing the data landing in a defined array like data_buffer[80] where I can move through the index and pick out each piece that I want. basically, how can I make that happen? I'll look over the other socket example, thanks again for helping!!
Tony
- Chris Ruff
- Posts: 222
- Joined: Thu Apr 24, 2008 4:09 pm
- Location: topsail island, nc
- Contact:
Re: MOD54415 file handling
How was it that you chose to use UDP instead of TCP? I am supposing that you know about the whole non-guaranteed delivery thing with UDP. Are you putting together VXI-11 control for an instrument?
Basically, when you have a pointer to a buffer, you need to go to some offset in the data, get what you want, create a response, load it into the buffer and send it back without the pointer going out of scope. For UDP I would vector to a known data pattern in the buffer and use that as the root for any offset into the received data. I have used UDP for message transfer, but your application must be able to lose packets without any degradation in performance.
Chris
Basically, when you have a pointer to a buffer, you need to go to some offset in the data, get what you want, create a response, load it into the buffer and send it back without the pointer going out of scope. For UDP I would vector to a known data pattern in the buffer and use that as the root for any offset into the received data. I have used UDP for message transfer, but your application must be able to lose packets without any degradation in performance.
Chris
Real Programmers don't comment their code. If it was hard to write, it should be hard to understand
Re: MOD54415 file handling
I've recently been teaching some robotics students how to program in C++. I created a youtube playlist of key concepts, you might want to watch Lesson 16 parts a, b,c on pointers. If you prefer to read and want specific examples...
Sticking with the original method names you and Paul were talking about, specifically:
PBYTE and WORD are typedefs and defined in basictypes.h but PBYTE will ultimately be a pointer to an unsigned char (a single byte). C (and C++) pointers know what they point to so when you increment the pointer it points to the next object, in this case inrementing the pointer advances by bytes. If it pointed to a short (16 bits) then the pointer would move by 2 bytes when incremented. So
GetDataSize() returns a WORD (which is most likely typedef'd to a 32 bit integer - i.e. 4 bytes).
In the declaration for the method:
The "const" at the end of the method is a C++ keyword. It stipulates that the method GetDataBuffer() itself is constant, meaning that it doesn't modify the state of the class. This is important and it makes the method const correct. You can worry about what that means another day, for today just realize it's not a variable name.
Sticking with the original method names you and Paul were talking about, specifically:
Code: Select all
PBYTE GetDataBuffer( void );
and WORD GetDataSize( void ) const;
Code: Select all
PBYTE my_pointer = GetDataBuffer();
char my_byte = *my_pointer; //deref the pointer to get what is pointed to
++my_pointer; //now it points to the next byte
my_pointer +=5; //now it points 6 bytes past the original byte.
char another_byte = *my_pointer;
Code: Select all
WORD data_size = GetDataSize();
Code: Select all
PBYTE GetDataBuffer( void ) const;
Code: Select all
//Here's an (uncompiled/untested) example of how you might use these two methods to loop through the received data and send the data out to the std output.
PBYTE my_pointer = GetDataBuffer();
WORD bytes_read = GetDataSize();
for (int i =0; i < bytes_read; ++i)
{
unsigned char my_data_byte = *my_pointer;
std::cout << static_cast<short>(my_data_byte); //force it to show up as a numerical value not a char (many chars are unprintable)
++my_pointer;
}
-
- Posts: 192
- Joined: Mon Dec 17, 2012 6:24 am
Re: MOD54415 file handling
Chris - thanks for the help, but your answer, although simple to you, is still a little abstract to me. Also, UDP was the spec I was given, I have no control over that; and I'm not at liberty to divulge the nature of the system other than to say that it's controlling a machine. Sorry.
Tod - thanks for the link!! I'll be watching them this week for sure! And thanks for dumbing it down a bit so I can understand it better, and the code examples helped too! A couple of questions:
-does "WORD GetDataSize();" need a variable in the parenthesis? It would be great to know the size of the data packet coming in lol.
-why did you choose this rout in your code (below)?
unsigned char my_data_byte = *my_pointer;
std::cout << static_cast<short>(my_data_byte); //force it to show up as a numerical value not a char (many chars are unprintable)
++my_pointer;
-Why not use "unsigned int my_data_byte = *my_pointer;" instead and eliminate the next line?
-I'm going to need to send data back out to the host computer, is there a separate buffer to do that or do I just reload the original buffer? and if I do, do I need to erase the buffer or can I just re-size it somehow to fit my data?
lastly, are there any time constraints to be aware of? I'm basically making a subroutine to run through one of the example projects that was supplied because, well, I'm not one to re-invent the wheel...
thanks again for everything!
Tony
Tod - thanks for the link!! I'll be watching them this week for sure! And thanks for dumbing it down a bit so I can understand it better, and the code examples helped too! A couple of questions:
-does "WORD GetDataSize();" need a variable in the parenthesis? It would be great to know the size of the data packet coming in lol.
-why did you choose this rout in your code (below)?
unsigned char my_data_byte = *my_pointer;
std::cout << static_cast<short>(my_data_byte); //force it to show up as a numerical value not a char (many chars are unprintable)
++my_pointer;
-Why not use "unsigned int my_data_byte = *my_pointer;" instead and eliminate the next line?
-I'm going to need to send data back out to the host computer, is there a separate buffer to do that or do I just reload the original buffer? and if I do, do I need to erase the buffer or can I just re-size it somehow to fit my data?
lastly, are there any time constraints to be aware of? I'm basically making a subroutine to run through one of the example projects that was supplied because, well, I'm not one to re-invent the wheel...
thanks again for everything!
Tony
Re: MOD54415 file handling
Tony, have you taken a look at the UDP class in the runtime library documents? When I first started using the UDP class it helped a lot. It seems to answer most of the questions you are asking here. I would take the examples and experiment a bit, printing out values for length, etc, until you get comfortable with the 4 or 5 functions used for the UDP class.
Re: MOD54415 file handling
No. although it could have the keyword void there, I never put void in my methods that take no parameters. The size you're after is the returned value of the function, in C and C++ you don't give a name to the returned value just the type. So the above function takes no parameters and returns a WORD (should be the same as an int on the NB platforms I am familiar with).-does "WORD GetDataSize();" need a variable in the parenthesis? It would be great to know the size of the data packet coming in lol.
For the same reason I didn't just write it-why did you choose this rout in your code (below)?
unsigned char my_data_byte = *my_pointer;
std::cout << static_cast<short>(my_data_byte); //force it to show up as a numerical value not a char (many chars are unprintable)
++my_pointer;
-Why not use "unsigned int my_data_byte = *my_pointer;" instead and eliminate the next line?
Code: Select all
cout << (short) *my_pointer++;
In your example you are asking the compiler to dereference a pointer to an unsigned char and put it in an unsigned int. That means a hidden cast happens from char to int. Plus my code was just an example to show you how to cout the value properly. Surely you want to do something real with the read data. Are you going to have to cast it back to char to do that? If so not only haven't you gained any CPU cycles (the hidden cast takes just as long) but now you have to do an additional cast. Plus you'll notice I'm a fan of the new C++ casting methods. They are ugly and verbose, but very easy to find in your code.
The questions so far have just been C++ language questions. Now I have to assume you're using the UDPPacket class (of which the above two methods are member functions.) I'm not that familiar with this class so as always trust Paul Breed, or anyone else from NB, or anyone else with experience with the class over my opinions, but I'll still offer one! Somewhere in your code you are creating an instance of this class, something like-I'm going to need to send data back out to the host computer, is there a separate buffer to do that or do I just reload the original buffer? and if I do, do I need to erase the buffer or can I just re-size it somehow to fit my data?
Code: Select all
UDPPacket my_packet(&fifo,0);
I would suggest you allocate your own buffer (either on the stack or heap, depending on your design) and use that. If you put it on the heap don't leak it.
I'm not sure what you're asking.lastly, are there any time constraints to be aware of? I'm basically making a subroutine to run through one of the example projects that was supplied because, well, I'm not one to re-invent the wheel...
Re: MOD54415 file handling
Chris, Todd and Mr Nixon..
Thanks for helping people figure things out, in this case and in all the others you help with,
it really helps to provide several different views of how things work...
Thanks for being helpful loyal customers!
Happy holidays from Everyone at Netburner.
Paul
Thanks for helping people figure things out, in this case and in all the others you help with,
it really helps to provide several different views of how things work...
Thanks for being helpful loyal customers!
Happy holidays from Everyone at Netburner.
Paul
-
- Posts: 192
- Joined: Mon Dec 17, 2012 6:24 am
Re: MOD54415 file handling
Hi everyone! Hope you all had a great christmas and happy new year to all!!
Tod, sorry I didn't get back to you sooner, the company closed until today for inventory. Thanks again for all the help you've thrown my way, Although a bit slow to comprehend the material, I'm getting it. I can give a little more information on my project - just learned my boundaries on divulging. So I have a list of about twelve 1 byte instructions (can be one word instructions if need be) which will be sent out from a computer over a network to the netburner device. These instructions will have a data value immediately following it, then the next instruction, its data value, etc. Some of these instructions will turn on or off certain functions, some will send data to DACs, and some will poll the device to collect data for temperature, voltage levels, etc. and return them to the computer. There will always be a returned data packet to the computer from the netburner unit, but it needs to be sent out AFTER all the instructions have been processed (one full second maximum time - which is why I asked about time constraints for sending data back).
Ideally, I would like to take that incoming data packet, and put it into an array that I can access by index (array size would be determined by the packet size in the header). This would be my simplest solution (KISS method when possible) but if there's an easier way, I'm all ears. My outgoing packet will be in array form as well. So moving this in and out of my_packet should or shouldn't be hard to do? I will have a test GUI with check boxes and data fields, etc. so when I click the "send" button all the data will be organized into an outgoing packet and sent to the netburner unit, which will operate and return it's data withing 1 second. I already have a sizable chunk of the subroutine written to handle the data, I just need to understand how to access it.
Thanks again for the help, sorry if some of my questions are redundant, or I'm slow on the intake. I learned basic C in 2001, never used it. I was just recently thrust into the embedded design world, so I'm having to learn on the fly. All help is appreciated!!
Tony
Tod, sorry I didn't get back to you sooner, the company closed until today for inventory. Thanks again for all the help you've thrown my way, Although a bit slow to comprehend the material, I'm getting it. I can give a little more information on my project - just learned my boundaries on divulging. So I have a list of about twelve 1 byte instructions (can be one word instructions if need be) which will be sent out from a computer over a network to the netburner device. These instructions will have a data value immediately following it, then the next instruction, its data value, etc. Some of these instructions will turn on or off certain functions, some will send data to DACs, and some will poll the device to collect data for temperature, voltage levels, etc. and return them to the computer. There will always be a returned data packet to the computer from the netburner unit, but it needs to be sent out AFTER all the instructions have been processed (one full second maximum time - which is why I asked about time constraints for sending data back).
Ideally, I would like to take that incoming data packet, and put it into an array that I can access by index (array size would be determined by the packet size in the header). This would be my simplest solution (KISS method when possible) but if there's an easier way, I'm all ears. My outgoing packet will be in array form as well. So moving this in and out of my_packet should or shouldn't be hard to do? I will have a test GUI with check boxes and data fields, etc. so when I click the "send" button all the data will be organized into an outgoing packet and sent to the netburner unit, which will operate and return it's data withing 1 second. I already have a sizable chunk of the subroutine written to handle the data, I just need to understand how to access it.
Thanks again for the help, sorry if some of my questions are redundant, or I'm slow on the intake. I learned basic C in 2001, never used it. I was just recently thrust into the embedded design world, so I'm having to learn on the fly. All help is appreciated!!
Tony