On Sep 2, 2015, at 8:54 AM, Rob Groner <[email protected]> wrote:
>
>
> No, just as a variable string descriptor.
>
> By “variable string descriptor”, do you mean what is contained in the example
> in the App Note? I’m just asking for clarification, in case variable string
> descriptor is something different than shown there.
By "variable" I mean "not const". Although they did not explicitly mark any of
the structs "const", their code does not change any of the string descriptors
at runtime.
>
> The way they do the string descriptors in the example is how I have mine now.
> They return a size and address, but it is to something that was defined at
> compile time. I guess I’ve been fixated on that, so I don’t know if I can
> simply pass a different string that what was defined before. And I don’t
> know how to handle something of an unknown size (though in my case, the MAX
> size of the serial number can be defined)
Because the structs are not const, you should be able to write new values into
them at runtime. (It's up to you to do this before the string is actually
requested, but since string descriptors are not requested often, you could do
it in something like GetStringDescriptor() just before it returns.)
You would need to change the "sizeof()" to be the actual length of that struct
at runtime. It's a little tricky, because the base struct is
sizeof(USB_STRING_DESCRIPTOR), and then you need to add 2*strlen(serial_number)
if your copy of the serial number from EEPROM is ASCII. (Note that the ['M',
'i', 'c', 'r', 'o'...] initialization is for a WORD[] rather than char[]. USB
strings are 16-bit little-endian Unicode.)
Dragging in a copy of sprintf() might be overkill, but you could have a loop
that reads in the bytes of the serial number, adds '0' (0x30) to each 4-bit hex
digit, and writes that into the string descriptor.
>
> That’s why I was asking about the variable string descriptor...it sounds more
> like something where you can pass a string of any size and address, which
> would definitely be what I’m looking for.
GetStringDescriptor() is returning a pointer via "return", and a length passed
by reference ("*length = ..."), so as long as you construct the string
descriptor to look the same as the statically-initialized ones, you should be
all set.
>
> Looking at the data being passed, I realized that battery.type is something
> else that I possibly won’t know until the code is running. Our UPS can use
> different attached batteries, and will be able to discern what it is at
> runtime, and that’s when it would be able to report battery.type.
For returning one choice from a limited set, you might want to create one const
string descriptor for each battery type string, and choose one pointer/length
pair at runtime.
>
> Thanks for the help Charles…that is a very good link to the Appnote
> considering you haven’t done PIC32 work. J My google skills failed me.
>
No problem. Using the standard string descriptors means fewer special cases in
our source code :-)
Note that you should be able to test reading the string descriptors by simply
using "lsusb -v -d VID:" on your device (might need to be run as root,
depending on permissions). Next to the iSerialNumber value, it will try to
fetch the corresponding string descriptor and print it.
--
Charles Lepple
clepple@gmail
_______________________________________________
Nut-upsdev mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/nut-upsdev