Ever wanted to be "logged in" to your AVR microcontroller? Ever thought it would be cool to "cat" a register to see its contents? Have you always wanted a way to power up and power down individual peripheral sub-systems of your AVR or Arduino in *real time* ? Me, too, so I wrote the AVR Shell, a UNIX-like shell.

It's UNIX-like because it's reminiscent of the shell account you went out and bought to run your irc nick collision bots on, as well as having a command or two in common. It also has a filesystem that resembles UNIX extfs, using an external EEPROM, but that's become a project unto itself so I'll be releasing that module separately under a different instructable when it's production-ready.

Here's a list of the things you can currently do with the AVR Shell:
  • Read all your Data Direction Registers (DDRn), ports, and pins in real-time
  • Write to all your DDRn's, ports, and pins to turn on motors, LED's, or read sensors in real-time
  • List all known registers on the system
  • Create and store values in user-defined variables backed up by EEPROM.
  • Create a root password and authenticate against it (used for telnet access)
  • Read the configured CPU clock speed
  • Change your CPU clock speed by setting a prescaler
  • Start and stop 16-bit timers for timing of various things
  • Power up and/or power down peripheral sub-systems: Analog to Digital Converters (ADC), Serial Peripheral Interface (SPI), Two-wire Interface (TWI/I2C), UART/USART. Useful for when you want to reduce power consumption of the microcontroller or to enable certain functions.
  • Written in C++ with reusable objects.

This instructable will walk through the installation, use, and customization of avrsh.

Step 1: What You'll Need

This instructable doesn't require much except that you:

  • Have an Arduino or ATmega328P. Other AVR's could work, but you may need to modify the code to list any registers that are unique to your MCU. The names only need to match what is listed in the <avr/io*.h> header file unique to your MCU. Many of the register names are the same between AVRs, so your mileage may vary when porting.
  • Have a way to connect to the serial USART of your Arduino/AVR. The system has been tested most extensively with the AVR Terminal, a Windows app that makes a serial connection via your USB or COM port. Works with Arduinos using the USB connection and any AVR using the USB-BUB from Moderndevice.com. Other terminal options include: Putty, minicom (Linux and FreeBSD), screen (Linux/FreeBSD), Hyperterminal, Teraterm. I've found putty and teraterm send some garbage when connecting so your first command may be garbled.
  • Have the AVR Shell firmware installed and running, which you can download from these pages, or always get the latest version at BattleDroids.net.

To install the AVR Terminal, just unpack it and run it. To install the AVR Shell firmware, download it and either directly upload the hex file and connect your serial terminal at 9600 baud, or compile it yourself with "make" and then "make program" to upload the hex. Note, you may need to change the AVRDUDE settings to reflect your COM port.

Note: The PROGMEM attribute is broken in the current AVR GCC implementation for C++ and this is a known bug. If you compile it, expect to get many warning messages saying "warning: only initialized variables can be placed into program memory area." Besides being annoying to see, this warning is harmless. As C++ on the embedded platform isn't high on the AVR GCC priorities list, it is unknown when this will be fixed. If you check out the code, you will see where I have made work arounds to reduce this warning by implementing my own attribute statements.

Pretty simple. Download and install anything that you might need to then flip the page and let's get crackin'.
<p>how can i use that to read contents of the sram?</p>
<p>This is very inspiring. I am working on an ATmega1284 based microcomputer and your code has given me some valuable insights on how to create a CLI (I mainly do HW not SW so this is very helpful).</p>
<p>Heyas, thanks for the kind words. I'm like your project you mention. I have a similar one, myself. If you have gotten some work done on it or want to discuss more technical aspects of persistent microkernels on MCUs drop me an email.</p><p>Cheers!</p>
little issue here not sure if its me or just the regular look in c but it wont compile at all in avr studio 5 .. been siting an working away the errors buts an very long list of them ..... <br><br>so question is what compiler was used and what platform of c as it really don't want to be nice to me ..
Heyas,<br>Sorry to hear you're having so many problems with the compile. To be honest, I haven't tried compiling it under AVR Studio 5 yet. I believe I used either WinAVR or avr-libc and the avr (gcc 4.5.2) package under Linux.<br><br>If I get some free time I'll try converting the package over to AVR Studio 5 and post a zip file.<br><br>Good luck!<br>-gian
<p>Hello,</p><p>I tried to compile avrsh on linux (using avr-libc and avr-gcc-4.8.2) but all I get is:</p><p>In file included from common.h:15:0,<br> from common.cpp:8:<br>common.h:114:27: error: variable &lsquo;PortPins&rsquo; must be const in order to be put into read-only section by means of &lsquo;__attribute__((progmem))&rsquo;<br> extern PortPin PortPins[] PROGMEM;<br> ^<br>make: *** [obj/common.o] Erreur 1</p><p>Do you have some idea? </p>
nice :)<br><br>hopefully i will learn from it
Wow I am so excited to use this. Seriously thank you so much for making this, nevdull! <br> <br>I had no problem uploading to my Atmega328p and even connecting to it with CoolTerm (Mac OS) since I can see the 'root@Atmega328p' command prompt. But I'm having problems sending messages. I get things like the following: <br> <br>root@ATmega328p&gt; print registers <br>&lt;&gt; p....reVk..rs.: unknown command. <br> <br>Anyone using CoolTerm and having the same problem? I'm assuming there's some setting within CoolTerm that may fix it?
Ok just in case anyone is using CoolTerm to connect, make sure of the following under 'Options': <br> <br>(1) Make sure 'Line Mode' is selected under 'Terminal' <br>(2) Make sure 'Use transmit character delay' is selected under 'Transmit Options' with its default delay of 3ms
Do you have the ability to simply launch 'telnet' from the command line on your mac? That might be another alternative. <br> <br>-gian
@pitachip, <br> <br>Hey, I'm glad you liked my project and instructable. As for your problem, I had many of the same type of errors but the two main culprits always were either: <br> <br>1. The telnet client is sending telnet packets/commands and the AVR shell doesn't know how to interpret them. I'm just riding on port 23 TCP but don't implement any of the telnet protocol. I've found TerraTerm and a couple other windows telnet clients did this. I wrote my own which I've linked in the project elsewhere. <br>2. There is a baud-rate mismatch. If you have your baud rate based on your FCPU MHz set very far outside of the specs for the AVR shell, they won't sync up and all you'll get is garbage. <br> <br>So, depends whether you're constantly getting garbage (problem 1) or just getting garbage upon connection (problem 2). <br> <br>Hope you manage to figure out the issue and have some fun with the shell. For a full-throttle, extreme version of this, check out the MUNIX project which endeavors to build a viable UNIX-like workstation using nothing but 8-bit AVRs and linear/logic chips. From the keyboard controller (ATtiny45) to the USB host controller (ATmega32U) to the main dual processors (ATxmega256A3), this workstation has all the code for filesystems, unix-like shells, process control, memory management, linking and loading. More at http://www.munixos.net <br> <br>Have fun and thanks for the comment! <br>Gian
This is truly amazing. But one question comes to mind. How'd I go about sending the resulting HEX file to the Arduino? Does it use one of the tools that're otherwise popular for the hardware platform?
Thanks for sharing your project! <br><br>I like it, max Kudos!<br><br>rf_
&nbsp;Can you view the code on the avr? thats what im looking for...
Nice job.&nbsp; How long did it take to write this (the code, not the Instructable)?&nbsp; Maybe someday I'll know enough to use this!
thanks mathman,<br /> I wrote the shell over the course of a weekend, and the windows terminal in about&nbsp; a week.&nbsp; It took longer for the terminal than I&nbsp;expected because I was doing research-oriented development and added a TCP/IP server to it so it could proxy telnet to my AVR and Arduino.&nbsp; I have a half-written &quot;Telnet to your Arduino&quot; instructable that I just never had the heart to finish. haha.<br /> <br /> The shell is somewhat naive, being a first-pass stand-alone shell.&nbsp; I have a much more robust command interpreter that's being released with the <a href="http://www.munixos.net" rel="nofollow">&mu;nix workstation and &mu;nix Operating System</a> when it gets to some level of usability.
Project at <a href="http://launchpad.net/munix" rel="nofollow">&mu;nix Launchpad</a>, if you're really bored.<br />
Would pins 2 and 3 be used for RX and TX for this? I loaded the .hex on my Atmega168 (Avrdude verified it after and looked ok)&nbsp;and setup a Bus Pirate V3 as:<br /> Uart 9600<br /> no parity <br /> 1 stop bit&nbsp;<br /> Receive polarity idle 0<br /> Output type normal (high=3.3volts, low=ground)<br /> <br /> I was trying to use it as a Uart bridge which makes the bus pirate act as a regular RS232 usb adapter. When i connect i get nothing but 0xFF&nbsp;over and over. <br /> <br /> Any ideas?
See my reply below, as well, but I&nbsp;think this version of avrsh was compiled at 57600 baud.<br />
I&nbsp;think i saw F_CPU defined as 16Mhz in one of the source files. I just remembered that my Atmega168 was fresh and not set to use the 16Mhz crystal yet...<br /> <br /> That's probably whats messing with mine, i'll fix it and post reply if everything works out.<br />
Yah, if it's a fresh ATmega168 then I&nbsp;believe it defaults to the internal 8MHz RC oscillator with the CKDIV8 fuse enabled, making fcpu&nbsp; effectively 1 MHz..&nbsp; As for the pins, it's PIND0 and PIND1 for RX and TX which are pins 2 and 3 of the chip itself (ie the 2nd and 3rd pins from the top on the left where pin 1 is marked).<br /> <br /> Good luck!<br />
dude, I love this one ... really really nice, we like!
We thankses yous!
I guess you have seen bitlash? <a rel="nofollow" href="http://bitlash.net">http://bitlash.net</a><br/>
That's an interesting project, but looks tied to Arduino libraries?
Congrats - this is not only a unique and powerful project, but also one of the best written Instructables. Kudos.
Thanks trialex and Xiver. I appreciate the kind words. I'm slowly rolling a UNIX-like operating system together to run on 8-bit AVR's. Finishing up the filesystem now, and have been testing the telnet interface. It's pretty cool being able to telnet from school and login to my AVR at home. lol. maybe that's going too far. ;) Cheers!
Excellent. Thanks for taking the time to toss it out to us.
Thank you thank you thank you!! This is going to be great for debugging my arduino projects. Many more thanks to you nevdull.
Thanks a lot! I hope it integrates well with your projects!
This is amazing! What a great way to poke around at the more low-level stuff of the AVR, without sitting through a write/upload/run loop. I can't wait to try this!
Thanks! I hope you like it!

About This Instructable




Bio: Gian is a computational biologist and is the Managing Director at Open Design Strategies, LLC. He holds a BA in Molecular/Cellular Biology and an ... More »
More by nevdull:Create A Custom Medieval-/Fantasy-Style Calligraphy Quill Practical DACs Using Enumerated Types as Bitflags 
Add instructable to: