fogbound.net




Sun, 22 Jul 2012

Teensy board example code “usb_debug_only.c” and gcc > 4.6

— SjG @ 9:44 pm

Wow, now there’s a blog title that will have very limited appeal 🙂

I was trying to validate my toolchain worked for building Teensy/ATMEGA32u4 applications. I used the mac port avr-gcc, avr-bintools, avr-libc install, and it failed to build the sample “blinky.c” program. I tried using the recommended AVR CrossPack, just in case it had different versions of the tools, but I got the same results:


samuelg$ make
-------- begin --------
avr-gcc (GCC) 4.7.0
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Compiling C: usb_debug_only.c
avr-gcc -c -mmcu=atmega32u4 -I. -gdwarf-2 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -ffunction-sections -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=./usb_debug_only.lst -std=gnu99 -MMD -MP -MF .dep/usb_debug_only.o.d usb_debug_only.c -o usb_debug_only.o
usb_debug_only.c:96:24: error: variable ‘device_descriptor’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
usb_debug_only.c:113:24: error: variable ‘hid_report_descriptor’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
usb_debug_only.c:128:24: error: variable ‘config1_descriptor’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
usb_debug_only.c:175:52: error: variable ‘string0’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
usb_debug_only.c:180:52: error: variable ‘string1’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
usb_debug_only.c:185:52: error: variable ‘string2’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
usb_debug_only.c:198:11: error: variable ‘descriptor_list’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
make: *** [usb_debug_only.o] Error 1

Google didn’t immediately help me with this. Eventually, I actually went ahead and read the error messages, and then tried following directions, i.e., I looked at line 96, and changed


static uint8_t PROGMEM device_descriptor[] = {

to


static const uint8_t PROGMEM device_descriptor[] = {

That’s all it took to make gcc happy with that line. Repeat the process for all of the error lines, and it compiles and builds correctly.

Evidently, the change to gcc happened between 4.5.3 and 4.6, and, once I knew what to look for, I found numerous discussions of why and wherefore (although these discussions were quite frankly beyond my comprehension). I was, however, happy to find the simple solution detailed above.


Wed, 13 Jun 2012

Building Direct IO library for PHP with Mac Ports

— SjG @ 11:47 am

Say you’re developing on a Mac, and want to test some PHP code that has calls to the direct IO library. You may not actually have a physical serial port, but your unit tests will fail in the wrong way if the library isn’t present. You want the unit tests to fail in the right way!

If you do the expected thing, you’ll find that dio is currently beta:

root# pecl install dio
Failed to download pecl/dio within preferred state "stable", latest release is version 0.0.5, stability "beta", use "channel://pecl.php.net/dio-0.0.5" to install
install failed

So you have to try to do it the hard way:

samuel:~ root# pecl install channel://pecl.php.net/dio-0.0.5
downloading dio-0.0.5.tgz ...

Easy-peasy, eh? Not so fast!


/private/tmp/pear/temp/dio/dio.c: In function 'zif_dio_fdopen':
/private/tmp/pear/temp/dio/dio.c:138: error: 'EBADFD' undeclared (first use in this function)
/private/tmp/pear/temp/dio/dio.c:138: error: (Each undeclared identifier is reported only once
/private/tmp/pear/temp/dio/dio.c:138: error: for each function it appears in.)
make: *** [dio.lo] Error 1
ERROR: `make' failed

Fortunately, via this bug report, we can see what to do:

# pecl download channel://pecl.php.net/dio-0.0.5
# tar xzvf dio-0.0.5.tgz
# cd dio-0.0.5
# phpize
# ./configure

Then edit dio.c, and change line 138 to:

if ((fcntl(fd, F_GETFL, 0) == -1) && (errno == EBADF)) {

Then, finish up:

# make
# make install

Then, create a file called “dio.ini” in /opt/local/var/db/php5/ containing:

extension=dio.so

Now you can run your tests!


Tue, 12 Jun 2012

Spelling Suggestions from Solr using Yii-solr

— SjG @ 7:48 pm

So a Yii app wants to query Solr using the Yii-solr extension, and wants to provide spelling suggestions for the provided search term. We need the suggestions to be unique, i.e., no repeated suggesttions, and we don’t want negative suggestions, i.e., if the user’s search wanted to exclude “foo”, we don’t want to suggest “foo” as a possible correction. There’s probably a better way to do all this, but I couldn’t figure it out. Here’s what I did instead (as always, forgive the code style/formatting):

I created a subclass of ASolrConnection that switches to using the “spell” Solr servlet:


class SolrSpellingConnection extends ASolrConnection {
public $servlet_type;
public $servlet_path;
public function resetClient()
{
parent::resetClient();
if (isset($this->servlet_type) && isset($this->servlet_path))
{
$this->_client->setServlet($this->servlet_type,$this->servlet_path);
}
}
}

This is instantiated in the app’s config file:

'solr' => array(
'class'=>'app.components.SolrSpellingConnection',
'clientOptions'=>array(
'hostname'=>'localhost',
'port'=>8983,
),
'servlet_type'=>SolrClient::SEARCH_SERVLET_TYPE,
'servlet_path'=>'spell'
),

Then, my Solr query data-provider looks something like:


$criteria = new ASolrCriteria;
$criteria->query = $queryterm;
$criteria->set('spellcheck','true');
$pages=array('pageSize'=>15);
$dataprovider = new ASolrDataProvider(ASolrDocument::model(),array('criteria'=>$criteria,'pagination'=>$pages));
return $dataprovider;

In my controller, I add some code to process the suggestions:

public function buildSuggestionList($dataprovider, $originalQueryString)
{
$suggestions = array();
$terms = array();
if ($dataprovider != null)
{
$facets = $dataprovider->getQueryFacets();
$resp = $dataprovider->getSolrQueryResponse()->getSolrObject();
if (isset($resp['spellcheck']))
{
if (isset($resp['spellcheck']['suggestions']))
{
foreach ($resp['spellcheck']['suggestions'] as $thisSuggest)
{
if (is_object($thisSuggest) && get_class($thisSuggest) == 'SolrObject')
{
if (isset($thisSuggest['suggestion']) && is_array($thisSuggest['suggestion']))
{
foreach($thisSuggest['suggestion'] as $thisTerm)
{
$terms[$thisTerm]=1;
}
}
}
}
}
}
}
foreach($terms as $termKey=>$val)
{
// Solr adds negated or added terms to suggestions if they don't match case
if (!preg_match('/\b'.$termKey.'\b/i',$originalQueryString))
{
$suggestions[] = CHtml::link($termKey,'/index.php/mysearchcontroller?q='.urlencode($termKey));
}
}
return $suggestions;
}

I can then display the main collection of results using a CWidget. For displaying suggestions, however, a bit of specific code is required:


$suggestions = $this->buildSuggestionList($dataprovider, $originalQueryString);
if (count($suggestions) > 0)
{
echo '<p>Did you mean '.implode(' or ',$suggestions).'?</p>';
}
?>

When this is all in place, you should get decent suggestions from Solr. Of course, you will need to have Solr build a spelling index! The easiest way to do that is simply connect to Solr’s web interface and tell it to build the index:

http://localhost:8983/solr/spell?spellcheck.build=true


Sat, 25 Feb 2012

Bad Business

— SjG @ 9:48 am

Now, I don’t shop at Target stores any more because they give campaign money to candidates who have regressive social agendas. However, being a realist, I know that it’s not always possible to live in modern society and remain pure to ideals. Instead of buying clothes at Target, I could buy them at Amazon, for example, but they have their own labor issues. So, despite my ethical concerns, I visited the Target web site.

Access Denied!
Are you f'n serious???

Yep. That’s right. They won’t even let you look at their site unless you accept their evil tracking cookies.
I guess it goes without saying that they failed to win me back.

(P.S. If you’re not running Ghostery, or the equivalent, you should be.)


Fri, 20 Jan 2012

A Modest Proposal

— SjG @ 9:45 am

Property owners in the United States1 pay property tax. While it makes the Randists froth at the mouth, the reason for this is quite pragmatic: people pay for the infrastructure, defense, and other public services in their communities that support their property. The theory is that a homeowner, for example, has a vested interest in the neighborhood roads being maintained, in having an active fire department, and so on. Similarly, businesses rely on decent roads, an educated workforce, and similar services to do business. We all depend on law enforcement and our defense forces to keep us safe from criminals and the odd invasion.

With the exception of the aforementioned Randists and related lunatics, everyone agrees that the concept of property tax is reasonable. We may all argue about what falls within the realm of appropriate services or infrastructure, and we all feel that our own particular property tax burden is too great, but we agree that there are necessities that we need to help pay for.

Recent events (e.g., the SOPA/PIPA debacle) have brought intellectual property into the spotlight. Corporations owning music, film, and book copyrights are justly upset about the degree of “piracy” taking place on the Internet. While the numbers they present as their financial losses have been widely debunked, there are, in fact, actual losses. So they spend a lot of money lobbying and contributing to political campaigns, and we get fiascos like SOPA/PIPA.

Similarly, we have a patent system that’s wildly out of control. People can and do patent ideas that are …er… patently obvious, or tiny increments over widespread practice. Those patents are then used to suppress whole classes of technologies and programs. Technology companies like Apple, Unisys, and SCO are notoriously litigious, and have often succeeded in using the legal system to suppress competition via patents. Patent trolls or patent clearing houses leverage ridiculous patents to essentially blackmail programmers for ideas that can be found in textbooks. We see small players put out of business on a regular basis, often because they can’t afford to defend against spurious patent claims.

It got me thinking. As a homeowner, I pay annual taxes, commensurate with the value of my house. This money, in effect, pays to protect the value of my property.

The “Content Industry” (RIAA/MPAA) and technology companies claim a great deal of value for their intellectual property, but rely on public money to defend that value. Sure, they pay lawyers, but they use my public courts and (attempt to) pass ever more restrictive laws to protect their assets. A huge amount of government time and public money is wasted on these cases, and we find congress ignoring important issues to focus on extending copyright ad infinitum. The public cost due to lost innovation is staggering2. It’s time for the intellectual property owners to share the burden of that cost. It’s time for a tax on intellectual property.

Intellectual property is hard to appraise for value — thus the owner should be allowed to declare what that value is. The catch is that they will be taxed on that declared value. Like most other property taxes, the value will be appraised on a yearly basis, with limits on the maximum amount of change from one year to the next. If owners decide their property is worth a great deal, then they can pay a great deal to help defend it. If they decide it’s worth nothing, then they cannot claim huge damages when it is not protected and the property is infringed upon.

Intellectual Property Tax. It’s only fair.

1 Most countries have some form of property tax, even if it’s not exactly the same thing as in the US.
2 Patents are, by their nature, designed to foster innovation by giving owners a temporary monopoly. We agree to tweak an otherwise free market to encourage people and companies to invest time into research and development. This system only works if, in fact, the kinds of things that are granted this protection are actual innovations rather than mundane and obvious incremental improvements. As they exist today patents are largely abused, and actually end up preventing new ideas from reaching the market while increasing the cost of products that do.