Response by Eric Lippert. This man has such a talent for eloquence.
Response by Eric Lippert. This man has such a talent for eloquence.
Full tutorial and walk through along with source.
For the past year on the side in my free time I have been working on building what will eventually be a small Villa at my parents house. This project is an exploration of carpentry and all that goes into building a house. A few pictures follow:
Into this project I plan on doing something interesting. I thought it would be interesting to be able to control the house from my phone. I was originally going to use a Rasberry PI board to accomplish this, but due to availability issues I ended up using a Arduino Uno R3 instead:
The Arduino will be the “computer” driving the house. It will talk to the outside world, and decide what circuits should be turned on and off. Unfortunately I can’t just jam 10 amps of 110AC into this bored without potentially starting a myriad of forest fires. In order to control the circuits I need a way to control larger AC voltages with smaller DC voltages.
Relays are a great way to accomplish this. At first I was looking at mechanical relays, but these had two issues. One is that they are noisy. I don’t want to hear clicking noises every time a circuit turns off and on. The other problem is the ones I looked at were on at low voltage. This is undesirable if the system fails in some way as it would mean lights and other services would be stuck on.
To address this I ended up going with an 8-channel solid state relay. These are quiet and the particular model I looked at was off at low voltage. You can see it working below:
I have a temperature/humidity sensor on the way. This will provide me with data to be able to figure out whether heating or cooling circuits should be activated. I also have an Ethernet shield on the way which will allow me to plug this board into my home network.
Communicating with my Phone
The idea is that I can forward and route a public port on my router directly to the UNO. I can then develop a phone application to communicate on this public port. With this system I should be able to turn lights on and off, and adjust temperatures all from my phone, while sitting on the couch.
Wall Mounted Color Touch Screen
I also plan on eventually using a color touch screen that will sit in the wall, and allow users to set temperature schedules and turn circuits on and off. (http://imall.iteadstudio.com/im120417020.html) The TFT touch screen I am looking at has a physical mounting issue, but this is easily alleviated with pin header extenders (http://www.amazon.com/gp/product/B004G56J8W).
I was hoping to spend more time working close to the hardware on firmware, but the ADK is too convenient. I’m still trying to figure out a good reason to do some kernel work.
I was having a discussion about a week ago with some other students, and a question came up in class. “Why don’t we just use a static class?”
The professor replied: Static class?
I elaborated on the original question: In C# we are able to use a static class to create a non-instantiable class with only static methods. Java has static methods. Why not static classes like C#?
The professor, a little puzzled, replied: A standard idiom is just to have a private constructor and only have public static methods.
He then moved on, paying little more attention to the question, sufficiently satisfied that the discussion itself was addressed.
Why doesn’t Java have static classes?
Well to answer this question we need to have a bit more enlightenment about what a static class is in C#.
The .NET family of languages compile down to a byte-code coined IL Code. It is like an assembly language with object oriented support, that eventually get’s compiled and cached on the fly into native assembly. There are numerous benefits to doing things this way, but that’s outside the scope of this article.
So when we write C#, the C# compiler isn’t converting our code to native assembly, it is converting it to IL Code.
Lets look at what a static class looks like in IL Code
Notice that ILCode the static class gets compiled into
There’s a couple things to notice. First is that there is no static modifier. The second is that there is now an abstract keyword and a sealed keyword.
An abstract modifier means that we can’t instantiate the class. A sealed modifier means we can’t inherit from the class. So a static class is, glossing over a couple small details, a non-instantiable class that cannot be inherited from.
It’s a hop and a skip over a small but dangerous creek, to realize that in Java we could probably get away with the same functionality by using an abstract modifier with a final modifer or what may be the more standard idiom of making a private constructor on a normal class, with a final modifier in the class declaration.
static class could be loosely translated into Java as abstract final class
Your self appointed ruler of the world,
Why Build a Boot-Loader?
I’ve been needing something outside of what I do as a job to invest my more eccentric energies. So I have started moonlighting on the side of operating systems and embedded systems. My first self-proposed project was to learn what a boot-loader was, how it worked, and how to build one. After encountering GPT partitions in my research I was also curious where something like GPT fits in. GPT is something you might have run into as a requirement when you try to format a hard-drive more than 2 TB in size, as MBR only supports up to 2 TB of space.. Having achieved the goals and answered the questions listed above I am now writing about it
How Easy is it to Build (and Test) A Boot-Loader?
It was actually pretty easy. There are many guides out there that made it quite enjoyable. I am even more excited to say that I tested the boot-loader with a very low level, but easy approach that doesn’t seem to have been done before, that is from the light research I did when I was trying to achieve it. This method basically consists of writing the boot-loader directly into a VirtualBox HardDisk by hand.
Boot-loaders themselves are actually quite simple to build. As long as you follow a few rules you have a valid bootloader.
The processor actually starts in 16 bit mode and is in 16 bit mode when your boot-loader code is called. Somewhere in your code you actually have to switch it to 32 bit in order to take advantage of 32 bit functionally. The terminology for these two states is real mode and protected mode.
When compiling with GAS (the Gnu assembler) I had problems. I couldn’t get my generated binary/HEX to have the correct ending signature of 0xAA55h. I switched over to NASM and everything seemed to work well.
How Do I Test the Boot-Loader?
I have a net-book, and I don’t have any spare USB drives. This means I couldn’t write my boot-loader to an actual piece of hardware. I also didn’t want to break my computer. These constraints meant I needed to use a virtual machine, and either create a floppy disk image or write the boot-loader directly to disk.
I really liked the idea of writing my boot-loader directly onto the VDI by hand. It seemed like this might help solidify how things work and where things are actually on the disk in my mind. It’s still abstracted when you use a tool to write a boot-loader to the disk, I mean who knows what all that tool is doing? When you do it by hand though, you know exactly what is on the physical media, and what needs to happen to make a boot-loader work.
There aren’t any guides that seem to tackle this problem in this way so I had to do a little bit of investigation and discovery.
Looking at the VDI specs I found that it has a 512 Byte header. I figured the disk image is supposed to start right after that. I found, however, when writing boot-loader into this address space that it didn’t work.
I tried a couple more times failing, and then decided to just launch a LiveCD iso image I downloaded and run cfdisk on the partition.
Cfdisk is the graphical version of fdisk, and basically lets you easily create partitions. It also lets you mark them as bootable. Marking them as bootable adds that AA 55 marker I was talking about earlier. So I just searched for this marker in the VDI file (after running cfdisk above), and low and behold I found a basic MBR with some partition information. I simply went to the offset 512 bytes prior to the marker, turned on insert mode, and pasted my assembled boot-loader from one window to the other. To my astonishment it worked!
For my environment I used the Linux distrobution JolliOS, which is ubuntu based.
I also read a tool called bochs, a PC-Emulator, works well for testing boot-loaders. I toyed with it a little, but after only a little trouble decided to pursue the virtualized approach instead.
My next objective is to get the processor into 32-bit mode and load in my own kernel.
There is likely more work involved than I realize, but once that is working I’d like to build the Linux kernel from source and then have my boot-loader load the Linux kernel.
Weight ROI towards Quality
In business there seems to be a tendency to migrate torwards asking the question “How can we deliver a decent product more quickly with the same resources?” Of course with the assumption that more product means more value, and more ROI.
I think the question should instead be “How can we deliver a quality product without the extra fluff and in the most productive way possible?” We need to look more at the ROI of quality. We have to be careful with this though. These are dangerous waters.
This goal implied by this question doesn’t mean spending more time on over-engineering, excessive design, or slowing development. This goal implies taking time to develop existing code well, paying down technical debt, and loosening the expectations in length of development; but what does this really say? Basically I am making the point that management should be desiring a Quality product and ensuring that plenty of time is allowed for the product to be of certain level of quality. Management should not be squeezing deadlines or making teams feel pressured to deliver faster, they should be encouraging them to develop a product thoroughly. In return developers need to be more efficient and avoid wasting excessive time on quality that provides little value (Pre-optimization, over-design, beautifying code, etc.).
Avoid Burning Your Creative Process On Improvements With Small Returns
Often matured developers tend to want to spend significant amounts of time on optimizations, generalizations, and design under the warrant of craftsmanship, pride, and aspirations of creating a perfect product. These aspirations are noble, but when these aspirations are engaged prior to a demonstrated need they are short-sighted and lacking in wisdom. Creating a perfect product is impossible. You can’t build perfection on the first go around no matter how much you decouple, open-close, or compose. We need to stop trying to achieve perfection as developers. There is a cost to perfection, it is high, and most importantly perfection is short-lived in a world of changing needs.
Remember Why You Do What You Do
We are in the business of providing value. This value is manifested in two forms. One form is of course the stakeholder or what is sometimes called the client. Producing value for the client means producing something they can use to achieve their goals. Our code also provides value both to and via future developers. This future developer may very well be you six months down the road. Well designed extensible software is wonderful. It makes everyone’s lives easier. The value here though is an indirect return, and often diminishes as requirements shift. You can make the code as shiny and pretty as you want, but at a certain point you are providing very little value at the cost of massive amounts of time. There is a diminishing return to your coding brethren. The direct value you provide is in providing a functioning easy to use product for the stakeholder; always remember this value is most of your value. I believe you should get to that goal as quickly as possible while sticking to your coding morals. Design but don’t linger on design, you need to ship, and design can always be re factored. Optimize code if convenient, but don’t go out of your way. Avoid investing yourself into things that do not have reasonable answers.
Our Reinvented Wheels Are Often Squares
We should also avoid rewriting software. If the first developer did a bad job with a solution, how likely is it that we can really do better; especially considering the existing software may have years of fixes and usage represented in it’s code base? We need to improve code to a better product. It’s easier to write code than to read and understand code. It’s the easy way out to write new solutions, and often we build a worse solution. Do the work to reap the insights from an existing solution both via it’s shortcomings and its time-tested working parts.
Time and Focus are Limited Resources
We have a tendency to think there is always more time. You learn the more you mature the lesson that both focus and time are limited resources, and as you build more complex products both of these become more precious. Avoid falling into the trap of always thinking you can do something more in your extra time, or that you can just “buckle down” and get more done. Be reasonable with yourself, and stop deluding yourself into thinking there is always a “later”.
May the Source be with You,
Hi you. I’m going to give you a task. I want you to write an application to allow users to submit feedback about The Company….
Oh and while your at it I would like you to make sure users are logged-in….
Also users should only be allowed to submit one feedback comment….
Oh and they should only be able to submit feedback on Tuesdays after we provide them with free updates, and send every fifth comment a gift basket.
Oh and make sure it’s bug-free. 100% maintainable (whatever that means), and that it can make me coffee.
One last thing….you need to have it on my desk tomorrow or your fired.
Requirements are refined over time. Time in the end is what matters. Nearly every decision has time as a motivating factor. It’s a very sad truth, but a sad truth nonetheless. So where does optimization fit into this?
As software developers we are tasked with wearing many hats, and solving some incredibly complex problems. Ideally we would make a perfect product. That’s not possible. We have limited time, and we need to make maintainable ,flexible, adequate products. The problem with optimization when done wrong is it costs time. It doesn’t only cost time when optimizing. It frequently costs time in future maintenance cost.
Optimization often destroys clear consistent code, and makes it less consistent. Optimization by nature usually requires solving a very specific problem with very specific logic.The problem with very specific logic for very specific problems is it is different from generic consistent logic.
Now before I lose you, Optimization is necessary. Your product needs to perform well. The problem is when you spend 40 hours blindly optimizing your product turning that beautiful generic CRUD code into a lean performance beast for a net gain of 1% performance when 99% of your time is spent in travel across the Atlantic to your servers in another country.
In order to optimize you need to profile the code. You need to know where performance costs are. Blindly optimizing and destroying consistency and maintainability in the name of performance kills kittens every day, and leaves the real performance monsters in the closet.
Unless it’s really a problem and you know the performance profile, save the kittens and don’t compromise design and consistency for performance.
With a Single Tear,