Sponsored links

Go Back   MP3Car.com > Mp3Car Technical > Linux


Reply
 
Share Thread Tools Display Modes
Old 05-21-2006, 05:54 PM   #1
FLAC
 
TheLlama's Avatar
 
Join Date: Jul 2004
Location: All over the world
Posts: 970
TheLlama is on a distinguished road
Question HQCT Driver.

Hello everyone.

I decided not to release the HQCT driver this weekend because I want to add some more features (frequency seeking, etc...). The good news is the driver runs very well and my seeking algorithm will be very fast (compared to the HQCT Driver example).

Now, developers -- I have a few options for getting data from the device to userspace.

Option 1: A non blocking read() function. You can read from the device driver as you would with any other file. e.g:
Code:
fd = open("/dev/hqct0", O_RDWR); read(fd, buf, 32);

This function will return immediately with the current data. I.e: it will not wait for the radio to provide new data since the status is buffered. This is optimal for one-shot reads. Now, the problem is, if you put this in a loop to read from the device then you will get many unneeded reads. You will have to rely on a timer which may still cause unneeded reads or lost reports. Please tell me if you do not understand this.

Option 2: A blocking read() function. This will behave like option 1, except that it will wait until new data is available. Therefore, you can safely place a read loop inside a thread to get new data as soon as it is available. The con is that if you want to just get the current data then you will have to wait until the radio sends the next report.

Option 3: A hybrid approach. We can have a read() function that blocks. Then we can an ioctl() function that will return the current data without blocking. So, a non-blocking read would look like:
Code:
fd = open("/dev/hqct0", O_RDWR); ioctl(fd, HQCTIOC_READ, buf);

Option 4: Like option 3 except the read() is nonblocking and the ioctl() blocks.

Option 5: Not really an option, but more of an enhancement to any of the above options. We can also have a proc file (/proc/hqct) which contains human-friendly data of all the attached radios. Oh yeah, the device driver supports multiple units attached.

Of course, all of these details will be hidden behind a friendly C library eventually (no reason there couldn't be a Python,etc. library too). The benefit is, all the hardware details will be stored in the device driver so it is trival to write a user program to interface with the device
TheLlama is offline   Reply With Quote
Advertisement
 
Advertisement
Advertisement Sponsored links

Old 05-21-2006, 10:55 PM   #2
Newbie
 
Kusuriya's Avatar
 
Join Date: Oct 2004
Location: Fort Drum, New York, USA
Posts: 23
Kusuriya is on a distinguished road
would a mixture of Option 3 and Option 5 be an option? or a Blocking read(); with an human readable /proc output?
__________________
---
"Flying is easy, Just jump at the ground and miss"
--Ford Perfect, HHGTTG

Last edited by Kusuriya; 05-21-2006 at 11:02 PM.
Kusuriya is offline   Reply With Quote
Old 05-22-2006, 02:13 AM   #3
FLAC
 
TheLlama's Avatar
 
Join Date: Jul 2004
Location: All over the world
Posts: 970
TheLlama is on a distinguished road
Cool

Quote: Originally Posted by Kusuriya
would a mixture of Option 3 and Option 5 be an option? or a Blocking read(); with an human readable /proc output?

Yes. I think this is what I will end up doing anyways. Option 3 and 5 are already implemented. read() is non-blocking while ioctl(HQCTIOC_READ) blocks. The proc file will come later. The ioctl calls are much more efficient than parsing proc output. Proc is naturally a bit slower, so I will probably only update it every 5 radio-updates or so. You can get the status of the driver and certain radio features with various ioctl calls too, but you need to read the whole report for anything else. There is no reason the C api couldn't parse the report and provide a ton of get_fubar() functions.

Seeking support is finished. It moves between stations much faster than its Windows equivalent. The seeking functions are non-blocking so you can easily use them in non-threaded applications and not lock your program while the radio scans. If you want the seek function to block, it is as simple as:
Code:
ioctl(fd, HQCTIOC_SEEK_UP, 0); ioctl(fd, HQCTIOC_READ, 0);

The first function returns immediately but the read function will not return until the radio is finished seeking and new data is available. Note, you can use standard non-blocking read() while the radio is tuning.

I still need to add some more calls and there is alot of user error checking that needs to be added before I release the first version. The proc file and RDS will come later.

Last edited by TheLlama; 05-22-2006 at 03:39 AM.
TheLlama is offline   Reply With Quote
Old 05-22-2006, 09:51 PM   #4
Newbie
 
Kusuriya's Avatar
 
Join Date: Oct 2004
Location: Fort Drum, New York, USA
Posts: 23
Kusuriya is on a distinguished road
yah normally i just use proc to check if its there or to pull info off with like a TAIL file.. the proc file is just a good way to check if its up or not but its sounding pretty good heh
__________________
---
"Flying is easy, Just jump at the ground and miss"
--Ford Perfect, HHGTTG
Kusuriya is offline   Reply With Quote
Old 05-22-2006, 11:28 PM   #5
FLAC
 
TheLlama's Avatar
 
Join Date: Jul 2004
Location: All over the world
Posts: 970
TheLlama is on a distinguished road
Quote: Originally Posted by Kusuriya
yah normally i just use proc to check if its there or to pull info off with like a TAIL file.. the proc file is just a good way to check if its up or not but its sounding pretty good heh

Yes, I suspect you could also use inotify to signal when the proc file changes.

Now, I found a problem in the seeking method which could cause systems to hardlock. I was using a semaphore from an interrupt handler. I am changing the system to use tasklets for this task. Unfortunately, I am also in the middle of moving, so it may be a couple days before I get anything usable out.

Thanks for you patience! It will be worth the wait. This radio sounds soooo good.
TheLlama is offline   Reply With Quote
Old 05-23-2006, 10:03 PM   #6
Newbie
 
Kusuriya's Avatar
 
Join Date: Oct 2004
Location: Fort Drum, New York, USA
Posts: 23
Kusuriya is on a distinguished road
heh man making me want to build it before i get home XD
__________________
---
"Flying is easy, Just jump at the ground and miss"
--Ford Perfect, HHGTTG
Kusuriya is offline   Reply With Quote
Old 05-23-2006, 11:41 PM   #7
FLAC
 
TheLlama's Avatar
 
Join Date: Jul 2004
Location: All over the world
Posts: 970
TheLlama is on a distinguished road
Ugh!!!! I have a version that works fine but it relies on a busy wait that runs in kernel mode, so basically the whole system is locked out for 30ms everytime you send a request to tune. I'm working with someone to resolve this issue. I don't feel comfortable releasing until this problem is solved.
TheLlama is offline   Reply With Quote
Old 05-24-2006, 12:28 AM   #8
Newbie
 
Kusuriya's Avatar
 
Join Date: Oct 2004
Location: Fort Drum, New York, USA
Posts: 23
Kusuriya is on a distinguished road
that does sound a little ugly.. but man take your time lol the more your hurry it the more bugs there are gonna be expecally if its gonna have its own wait timer or polling code that runs independantly of the kernels "heart beat"
__________________
---
"Flying is easy, Just jump at the ground and miss"
--Ford Perfect, HHGTTG
Kusuriya is offline   Reply With Quote
Sponsored links
Advertisement
 
Advertisement
Old 05-24-2006, 02:43 AM   #9
FLAC
 
TheLlama's Avatar
 
Join Date: Jul 2004
Location: All over the world
Posts: 970
TheLlama is on a distinguished road
Quote: Originally Posted by Kusuriya
that does sound a little ugly.. but man take your time lol the more your hurry it the more bugs there are gonna be expecally if its gonna have its own wait timer or polling code that runs independantly of the kernels "heart beat"

Good news, I just implemented a solution that does not use busy waiting. There is no polling or threads either, everything is driven from interrupts and user requests. I am driving back to my campus tommorow and will be staying there for a few days. I would probably have a version up tommorow otherwise. Fortunately, I can bring my test rig and get some work done there.

I decided to swap the read() and ioctl(HQCTIOC_READ) functions so that read() blocks. I did this because it is ideal to use the blocking read to block until the previous instruction has finished. read() is ideal for the blocking read because you can call it with a buffer of zero length while the ioctl call will assume you have allocated a buffer for it. I suppose one could call the ioctl read with a NULL address in order to block, but a blocking read() is easy to call from bash etc... Any comments? I'm still 50-50 with this decision.

So, with tuning out of the way, all that is left (for the first version) is making sure the common TEF set commands (Volume, Treble, Bass, etc..) can be set through ioctl and providing a method for serializing the TEF configuration back and forth.
TheLlama is offline   Reply With Quote
Old 05-25-2006, 10:19 PM   #10
Newbie
 
Kusuriya's Avatar
 
Join Date: Oct 2004
Location: Fort Drum, New York, USA
Posts: 23
Kusuriya is on a distinguished road
thought read was a kernel blocked funtion by default anyway but sounds like a plan.. heh dont drive to fast tho dont want you to get in a car accident on your way to start your coding marathon. but man it sounds like you have something... have you had a chance to play "bug hunt" on it yet?
__________________
---
"Flying is easy, Just jump at the ground and miss"
--Ford Perfect, HHGTTG
Kusuriya is offline   Reply With Quote
Old 05-26-2006, 04:40 AM   #11
FLAC
 
TheLlama's Avatar
 
Join Date: Jul 2004
Location: All over the world
Posts: 970
TheLlama is on a distinguished road
Quote: Originally Posted by Kusuriya
thought read was a kernel blocked funtion by default anyway but sounds like a plan.. heh dont drive to fast tho dont want you to get in a car accident on your way to start your coding marathon. but man it sounds like you have something... have you had a chance to play "bug hunt" on it yet?

read() is by default because most of the drivers implement it that way. The OS doesn't actually do any of that work. Now, I have everything working fine but there is one place where things seem to mess up. For some reason the HQCT radio stops sending reports if it receives two reports too quickly. So, I need to rework the innards one more time... this time I need to make sure that two reports are never sent less than ~50ms apart. Even if the user places two requests within that time frame.

If you want to try out the current version then let me know. I just finished the user api and you can do pretty much anything (except RDS). Many more flags are configurable than with the Windows demo. Just don't try to send too many message close together or else you will have to cycle power on the radio. So, I'll post it if anyone actually wants it.

Last edited by TheLlama; 05-26-2006 at 04:54 AM.
TheLlama is offline   Reply With Quote
Old 05-26-2006, 10:51 AM   #12
FLAC
 
TheLlama's Avatar
 
Join Date: Jul 2004
Location: All over the world
Posts: 970
TheLlama is on a distinguished road
Humm.. I need some place to dump files.
TheLlama is offline   Reply With Quote
Old 05-26-2006, 01:21 PM   #13
Variable Bitrate
 
intuitionsys's Avatar
 
Join Date: Jul 2005
Location: Ottawa, ON, Canada
Posts: 290
intuitionsys is on a distinguished road
E-mail me at allen@intuitionsys.com and I'll set up an FTP for you if you want...
__________________
Silverwolf 2 is dead.
Silverwolf 3...?
intuitionsys is offline   Reply With Quote
Old 05-26-2006, 02:45 PM   #14
FLAC
 
TheLlama's Avatar
 
Join Date: Jul 2004
Location: All over the world
Posts: 970
TheLlama is on a distinguished road
OK. But in the meantime you can check out this zip file. The forums wouldn't let me upload a tarball.

I worked around the problem from above by simply placing a sleep at the end of the ioctl function. This causes ioctl to always block for at least 100ms, which in turn, doesn't allow you to send messages fast enough to overload the radio. This is just a fix until I redo the mechanics again.

So, it 'works', but it causes needless waiting and some lag. For example, if you send 20 tef commands at once, then you have to wait ~2seconds for them to all be processed. This should be good enough for people to start writing software with the API.

I am going to rework the innards and it will actually end up being a simplification. The user API will not change (except maybe for some additions). I plan to keep a queue of work needed to be done and have a kthread that loops on the queue and sends out the next packet every 100ms. Changing TEF settings (volume, bass, etc..) will still block until the command has executed, but it won't be a dumb wait like it is currently. Also, if the user sends multiple TEF settings then they will be collapsed into a single packet. For instance, if you set the volume to -10,-9,-8, and -7 within 100ms, then only the -7 will be sent.

Development notes I forgot to place in README:
Do not send TEF settings while seeking and do not seek while the module is initializing. These problems are easy to fix, but I'm going to wait for the new version.
You can use hqct_get_tef() to get the current TEF string. You should do this before your program closes and store the output to a file. This way your program can read the settings from file and use it as the 2nd parameter of hqct_init().

Files contained:
hqct.c - HQCT device driver
hqct.h - HQCT device driver header
hqctapi.c - The HQCT C API, check this file for documentation
hqctapi.h - The HQCT C API header, include this file in your programs
demo.c - Demonstation including initialization, blocking seek, and a few TEF settings.
Makefile - builds the driver, api, and demo
README - Read this, it will provides installation and development tips.

Attached Files
File Type: zip linux_hqct-2.zip (16.9 KB, 229 views)

Last edited by TheLlama; 05-26-2006 at 03:08 PM.
TheLlama is offline   Reply With Quote
Old 05-28-2006, 01:30 PM   #15
FLAC
 
TheLlama's Avatar
 
Join Date: Jul 2004
Location: All over the world
Posts: 970
TheLlama is on a distinguished road
I see that the driver has been downloaded several times. Has anyone tried it out? I want to know what kinds of problems people are having with it (hopefully none). I'm also looking for suggestions. I'm not going to work on the new version until I get _some_ feedback for this one. Must... spend... more time.... on MP3 Player!
TheLlama is offline   Reply With Quote
Sponsored links
Advertisement
 
Advertisement
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Line Driver Selection? And Audio advice Philly#1 Lex Car Audio 6 04-24-2006 12:10 PM
Line Driver Vs. Amp Sensitivity Adjustment 3onDubs Car Audio 5 11-28-2005 08:37 PM
XM Driver Install Problem MikeH MacCar 5 04-24-2005 12:22 PM
MS S&T 2005 GPS receiver driver install problem... rdc_3200 GPS 4 01-01-2005 05:19 PM
USB Sound Card with ASIO driver and volume control tbdombrosky General Hardware Discussion 0 02-04-2003 12:00 AM



All times are GMT -5. The time now is 01:10 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.3.2
Copyright © 1999 - 2008 Mp3Car.com Inc.Ad Management by RedTyger
Message Board Statistics