I got a couple of programming questions that I thought I could get some help here. I am programming in C, and I am trying to determineif I am better off using Structures or Array's to store and present the data. Currently I am using array's but it is getting to be a pain to keep trackof everything. It basically acts a monitor circuit and certain events trip as they occur.

I am not that great of a programmer, but I am trying to broaden my horizons as my job is requiring me to learn a lot more

Or if someone has a better idea to collect, organize and process the data for output. The other thing is my Output data can only send 16 bytes at a time through the serial bus it interfaces with so I was trying to use a counter for that.

The only thing I am not that comfortable with is pointers and references. I have been trying to get a grasp on it, but it is taking me a while.

This is for a DSP embedded solution with actual hardware. I am just trying to get some opinions on how to best organize the data.

Thanks for the help.

To Start Press Any Key'. Where's the ANY key? If something's hard to do, then it's not worth doing You know, boys, a nuclear reactor is a lot like a woman. You just have to read the manual and press the right buttons.

As I said at the beginning of my post, I have an OOP background, and usually try to make C mimic a true OOP language. Yes, the struct doesn't have the associated methods, or any notion of polymorphism or inheritance, but it's better organized and will scale better than 2D arrays.

Lenovo W520IBM dx340Nokia Lumia 928Sony a7 with far too many lenses to list or even count

You need to be a bit more specific as to what "better" is. More readable code? Faster reading of the data from the serial bus? Tighter for loop?

The fastest is if you can directly memory map a structure to the memory, then all you need is to just memcpy the data into the beginning address of the struct and it will be automagically filled. However, you have to account for bit fields and compiler auto-padding of member fields. That is assuming the data comes in per battery.

However, if the data stream you get is all voltages, then all currents, etc. then may be your approach makes better sense.

Are we doing work for you or is this some kind of pet project?

The Model M is not for the faint of heart. You either like them or hate them.

The data stream is sent out via RS232 on a serial bus and basically I am filling unsigned bytes one by one to a buffer. The buffer is 16 bytes then I have send the stream and clear the buffer in order to fill the buffer with the next 16 bytes and so on and so forth. In total I have 351 + 2 checksumbytes that I send out at 1Hz at 19200 baud. Each battery of the 16 batteries has 20 bytes to be sent along the bus.

I basically have it working by using the arrays currently with tons of for loops like I demonstrated. I am just in the process of debugging at the system level and what I am finding is I am accessing quite a few wrong spots on the array and subsequentially calculate/output the wrong data which. I guess what I mean by better is what is easier to read and faster to debug and the shortest code if at all possible.

My thought is structures would make it easier to read so other people (including myself) don't have to get bogged down verifying the correct location of the array's.

The project is something I am currently working on at my job where I basically got the short straw to program it because I know more C than anyone else (basically computer science 1). Like I said I guess it doesn't have to be so much for this project but I am trying to get a sense for the future on which would be a better way to attack it if any or if array's would be the best because I see more projects like this down the line and soon.

To Start Press Any Key'. Where's the ANY key? If something's hard to do, then it's not worth doing You know, boys, a nuclear reactor is a lot like a woman. You just have to read the manual and press the right buttons.

The problem with structs is keeping them in sync with code if changes are made (not that you don't have a lesser but similar problem with the enum). But the advantage, of course, is that the space is pre-allocated and named, which is good.

The problem with arrays is that they are completely disassociated from the data they hold, so you have to be careful to make sure they are the right size and that the values you are indexing are actually at the location you expect.

The advantage to the associative array example is that the space is allocated dynamically, and the name always refers back to the expected value. You could also use an enum instead of a string for the key in the map, to make it more efficient. But of course, to go this route you need to move to C++.

So how is the data ordered in the stream from the serial line? Is it like: voltage(1), current(1), status(1), ... voltage(2), current(2)...? Is the buffer big enough for all data from one battery?

Since this is a DSP embedded system, is C++ even available?

Structs should be better readability wise, but the layout may not be conducive to reading the data from the buffers. How many fields of data are we talking about per battery? You may also need to consider protocol overhead with your target hardware, since you may run into performance issue if you choose to get voltages from different batteries rather than reading all data from 1 battery and then move on to the next (or it can be the other way around).

The Model M is not for the faint of heart. You either like them or hate them.

Flying Fox wrote:So how is the data ordered in the stream from the serial line? Is it like: voltage(1), current(1), status(1), ... voltage(2), current(2)...? Is the buffer big enough for all data from one battery?

Since this is a DSP embedded system, is C++ even available?

Structs should be better readability wise, but the layout may not be conducive to reading the data from the buffers. How many fields of data are we talking about per battery? You may also need to consider protocol overhead with your target hardware, since you may run into performance issue if you choose to get voltages from different batteries rather than reading all data from 1 battery and then move on to the next (or it can be the other way around).

Unfortunately C++ is not available. It is straight C because of the embedded system.

The Battery Line would be exactly the way you presented it.

So the batteries I am using are using the SMBus protocol (similar to I2C and basically a the bus all smart batteries read from) and I have to read in one or two signed/unsigned bytes depending on what data I am reading in. For instance, voltage is unsigned two bytes and current is signed two bytes. I then cycle through a battery getting all the data at once and then transforming that information to be sent on the output for that particular battery.

So basically:

Read Voltage(1), Read Current(1),... Read LastByte(1) --> Process Data from batteries --> Save the data in the output buffer to be sent out on the next timer interrupt --> go to the next battery until the last battery and loop around again forever

In there there would be an interrupt that would occur periodically throughout the cycle. As far as the output buffer goes I could split it up in two parts if need be.

I guess I was mainly just curious if there was an easier coding structure to process the data, but array's look like it might be the easiest solution. Thanks for the help.

To Start Press Any Key'. Where's the ANY key? If something's hard to do, then it's not worth doing You know, boys, a nuclear reactor is a lot like a woman. You just have to read the manual and press the right buttons.

Flying Fox wrote:Since this is a DSP embedded system, is C++ even available?

C++ is becoming increasingly available and used in embedded systems, but it's not available everywhere. Looks like it's not an option here, but there are some places where it is.

Yup... but on some low-cost microcontrollers there isn't enough program or data memory to support the additional overhead.

There are also potential verification issues for safety-critical systems -- it is harder to "prove" (to the satisfaction of the relevant regulatory agencies) that a piece of code is correct when you're using a more complex language like C++. At my day job we routinely use C (even though C++ is available on our platform) for this reason.

The years just pass like trains. I wave, but they don't slow down.-- Steven Wilson

But the first is generally going to be more readable, and is far more useful if you want to build functions that operate on a single battery. The second might be slightly faster if you want to write functions that operate on all the batteries, say to find the lowest voltage. Or if you send all the voltages through the bus, then all the currents. But in general you want to write readable code before fast code.

And you really want to use arrays instead of having battery1, battery2, battery3.. battery16

just brew it! wrote:At my day job we routinely use C (even though C++ is available on our platform) for this reason.

I'd have thought you'd be stuck with Ada, or did that project finally crater?

It's still used in some systems (though not by us). I wouldn't go so far as to say it has completely cratered, but the Pentagon's dream of having a standardized programming language for all military systems has gone out the window, a victim of the push to control costs through the use of COTS (Commercial Off-The-Shelf) tech. Heck, we're even running on an Intel processor; until pretty recently it was practically unheard of to have anything that wasn't PowerPC-based in a military application.

Edit: At least we're not running Windows on it; remember that story a few months back about the military's drone control systems being infected with keyloggers?

The years just pass like trains. I wave, but they don't slow down.-- Steven Wilson

Flying Fox wrote:Since this is a DSP embedded system, is C++ even available?

C++ is becoming increasingly available and used in embedded systems, but it's not available everywhere. Looks like it's not an option here, but there are some places where it is.

I am aware of that. In fact the only real embedded system that I did before was on the MPC platform which has Embedded C++ support (no template and all the weird C++ stuff at the time).

mmmmmdonuts21 wrote:

Flying Fox wrote:So how is the data ordered in the stream from the serial line? Is it like: voltage(1), current(1), status(1), ... voltage(2), current(2)...? Is the buffer big enough for all data from one battery

The Battery Line would be exactly the way you presented it.

So the batteries I am using are using the SMBus protocol (similar to I2C and basically a the bus all smart batteries read from) and I have to read in one or two signed/unsigned bytes depending on what data I am reading in. For instance, voltage is unsigned two bytes and current is signed two bytes. I then cycle through a battery getting all the data at once and then transforming that information to be sent on the output for that particular battery.

So basically:

Read Voltage(1), Read Current(1),... Read LastByte(1) --> Process Data from batteries --> Save the data in the output buffer to be sent out on the next timer interrupt --> go to the next battery until the last battery and loop around again forever

In there there would be an interrupt that would occur periodically throughout the cycle. As far as the output buffer goes I could split it up in two parts if need be.

The only point where I can see potential speedup is if you can read all the data related to 1 battery in one shot, based on that 16-byte buffer that you were talking about. Then in your "process buffer" function, with pointer arithmetic and (!) raw casting to assign values to your struct. If you have to go "read 2 byte as signed/unsigned integer" one value at a time, then there won't be a lot of speedup. The struct approach does seem more logical and readable. Are integers 32-bit on your platform or are we dealing with some weird-ass alignment crap? The fastest is if you can map that structure directly onto the memory buffer (alignment/padding/bitness/endian issues aplenty), not sure if that is available since you have not really answered that.

The Model M is not for the faint of heart. You either like them or hate them.

Flying Fox - I haven't seen any mention of a speed / cpu load issue here and I'm concerned that you are looking for premature optimisation (which is the root of all evil ). I always write the simplest cleanest code I can and see how that runs, then start optimising it if required. If it runs fine then I leave it alone so it is super simple to debug when anyone comes back to it a few years down the road. Over the years I have had to debug too many piles of buggy hand optimised garbage that actually run slower than clean code optimised by the compiler to consider doing anything else.

notfred wrote:Flying Fox - I haven't seen any mention of a speed / cpu load issue here and I'm concerned that you are looking for premature optimisation (which is the root of all evil ). I always write the simplest cleanest code I can and see how that runs, then start optimising it if required. If it runs fine then I leave it alone so it is super simple to debug when anyone comes back to it a few years down the road. Over the years I have had to debug too many piles of buggy hand optimised garbage that actually run slower than clean code optimised by the compiler to consider doing anything else.

Of course if the data format changes you have to keep up to date, but that's how I have seen people done almost as their first attempt. Now if the data do come in 2 bytes at a time then we will have to assign the numbers field by field, which still means the array of structs make more sense.

The Model M is not for the faint of heart. You either like them or hate them.

It's not at all relevant here, or in the context of embedded and/or IO in general, but given the title I should just mention that in HPC or other context where extensive time-critical computation is required (eg gaming), the Array of Struct construct, while far more intuitive, isn't conducive to things like SIMD (at least in the absence of a GATHER instruction). For that reason in those contexts the Struct of Arrays data structure is more common.

&batteryData[n].raw_data is a pointer to a 16 byte buffer in which you dump the raw data coming over the serial bus. You can then access that various values as batteryData[n].Voltage, batteryData[n].Status, etc. As others pointed out, this assumes a static ordering to the raw data stream, but so would just about any other solution unless the data stream contains key value pairs. The uint8 and uint16 data types or something similar are probably defined for your platform. They are pretty common in embedded systems where the data width of "int" is somewhat different than a full blown processor.

One slight suggestion -- get comfortable with pointers. You need them, especially in an embedded system where program memory may be precious. You need them to write C code that does anything of real complexity.

This reminds me of when I used to program JASS scripts for WarCraft 3 and the community had a pre-compiler that accepted pseudo code and converted it into true code for Blizzard's interpreters to work with.

if myStruct__recycle[0] == 0 then if myStruct__count == 8190 then //in JASS, arrays are limited to 8192 indices and the 8192nd index bugs when loading from a saved game so we don't use it return 0 endif set myStruct__count = myStruct__count + 1 set this = myStruct__count else set this = myStruct__recycle[0] set myStruct__recycle[0] = myStruct__recycle[myStruct__recycle[0]] endif