Git Product home page Git Product logo

micronucleus's Introduction

Micronucleus V2.6

Micronucleus is a bootloader designed for AVR ATtiny microcontrollers with a minimal usb interface, cross platform libusb-based program upload tool, and a strong emphasis on bootloader compactness. To the authors knowledge this is, by far, the smallest USB bootloader for AVR ATtiny

The V2.0 release is a complete rewrite of the firmware and offers significant improvements over V1.x:

  • Support for the entire ATtiny family instead of only ATtiny85.
  • Much smaller size. All configurations are below 2kb.
  • Interrupt free V-USB: no patching of the user program INT-vector anymore.
  • Faster uploads due to new protocol.
  • Far jmp also allows using ATtinies with more than 8kb flash.
  • Many robustness improvements, such as compatibility to USB hubs and less erratic time out behavior.

Due to the many changes, also the upload tool had to be updated. The V2.0 upload tool is backwards compatible to the V1.X tool, though.

The last release of the V1.x can be found here:

https://github.com/micronucleus/micronucleus/tree/v1.11

Usage

The bootloader allows uploading of new firmware via USB. In its usual configuration it is invoked at device reset and will identify to the host computer. If no communication is initiated by the host machine within a given time, the bootloader will time out and enter the user program, if one is present.

For proper timing, the command line tool should to be started on the host computer before the bootloader is invoked.

Windows machines will need to install the libusb drivers found in the /windows_drivers folder. Clean Micronucleus devices without uploaded userprogram will not time out and allow sufficient time for proper driver installation. Linux and OS X do not require custom drivers.

Windows 10: Installing unsigned drivers became more difficult in Windows 10. Please use the Zadig driver installer as provided in the /windows_driver_installer folder.

Please invoke the command line tool with "micronucleus -help" for a list of available options.

The bootloader resides in the same memory as the user program, since the ATtiny series does not support a protected bootloader section. Therefore, special care has to be taken not to overwrite the bootloader if the user program uses the self programming features. The bootloader will patch itself into the reset vector of the user program. No other interrupt vectors are changed.

Downloads

The latest release version can be found here: https://github.com/micronucleus/micronucleus/releases

Archives with snapshots of the latest binaries of commandline tool and firmware can be accessed here: https://github.com/micronucleus/micronucleus/releases/tag/master-LATEST

Compiling

Micronucleus can be configured to support all devices of the 'classic' ATtiny series, with the exception of the reduced core ATtiny 4/5/9/10/20/40.

To allow maximum flexibility, micronucleus supports a configuration system. To compile micronucleus with a specific configuration, please invoke the AVR-GCC tool-chain with:

     make CONFIG=<config_name>

The makefile makes use of the gnu binutils and some unix commands such as 'mv' and 'rm'. If you are using Windows, make sure you have proper binaries installed. For example by using the 'Atmel Studio command prompt' or msys/mingw32.

Currently, the following configurations are included and tested. Please check the subfolders /firmware/configurations/ for details.

Configuration Specificity Size
t84_default ATtiny84A default configuration 1476 bytes
t841_default ATtiny841 default configuration 1522 bytes
t45_default ATtiny45 default configuration 1510 bytes
t85_default ATtiny85 default configuration 1510 bytes
t85_aggressive ATtiny85 smaller size - critical 1358 bytes
t88_default ATtiny88 default configuration 1432 bytes
t167_default ATtiny167 default (uses xtal) 1338 bytes
Nanite841 Nanite841 firmware 1546 bytes
m328p_extclock ATMega328p external clock 1490 bytes
t4313_default Attiny 4313 default configuration 1456 bytes

Please note that the configuration "t85_aggressive" may be instable under certain circumstances. Please revert to "t85_default" if downloading of user programs fails.

Precompiled hex files of the bootloader can be found in /firmware/releases. The files can be directly programmed using AVRDUDE or other programmers. The folder /firmware/upgrade contains hex files that can be used to upgrade devices with existing version of micronucleus with a newer version. These can be uploaded using an older version micronucleus.

You can add your own configuration by adding a new folder to /firmware/configurations/. The folder has to contain a customized "Makefile.inc" and "bootloaderconfig.h". Feel free to supply a pull request if you added and tested a previously unsupported device.

If changes to the configuration lead to an increase in bootloader size, it may be necessary to change the bootloader start address. Please consult "Makefile.inc" for details.

Other make options:

    make CONFIG=<config_name> fuse   	# Configure fuses
    make CONFIG=<config_name> flash  	# Upload the bootloader using AVRDUDE

There is also an option to disable the reset line and use it as an I/O. While it may seem tempting to use this feature to make an additional I/O pin available on the ATtiny85, we strongly discourage from doing so, as it led to many issues in the past.

Please "make clean" when switching from one configuration to another.

Devices using Micronucleus

Micronucleus is widely installed on thousands of open source hardware devices. Please find an incomplete list here: https://github.com/micronucleus/micronucleus/blob/master/Devices_with_Micronucleus.md

License

This project is released under the GPLv2 license. Code uploaded via the bootloader is not subject to any license.

In addition, we'd like you to consider these points if you intend to sell products using micronucleus:

  • Please make your hardware open source. At least the schematic needs to be published according to the license inherited from V-USB.

  • Your documentation should mention Micronucleus and include a link to the main repository (https://github.com/micronucleus/)

  • Please do not "rebrand" micronucleus by renaming the USB device.

  • Feel welcome to submit a pull request to include your product in the "Devices using Micronucleus"-list.

Changes

  • v2.0b June 6th, 2015 This pull request documents changes leading to V2.0: #43

  • v2.01 July 26th, 2015 This pull request documents changes leading to V2.1: #66

    • Fixes "unknown USB device" issue when devices with <16MHz CPU clock were connected to a USB3.0 port.
    • Fixes one bug that could lead to a deadlock if no USB was connected while the bootloader was active and noise was injected into the floating D+ input.
    • D- line is released before the user program is started, instead of pulling it down. This solves various issues where Micronucleus was not recognized after a reset depending on the duration of the reset button activation. Att: This may lead to a "Unknown device" pop-up in Windows, if the user program does not have USB functionality itself.
  • v2.02 August 3rd, 2015

    • Fixes timing bug with Windows 10 USB drivers. Some Win 10 drivers reduce the delay between reset and the first data packet to 20 ms. This led to an issue with osccalASM.S, which did not terminate correctly.
  • v2.03 February 13th, 2016

    • Added page buffer clearing if a new block transfer is initiated. This fixes a critical, but extremely rare bug that could lead to bricking of the device if micronucleus is restarted after an USB error.
    • #74 Fixed LED_INIT macro so it only modifies the DDR register bit of the LED. (Thanks @russdill)
  • v2.04 Dec 8th, 2018

    • Merged changed to support ATMega328p by @AHorneffer (#132)
    • Idlepolls is now only reset when traffic to the current endpoint is detected. This will let micronucleus timeout also when traffic from other USB devices is present on the bus.
  • v2.5 March 5th, 2021

    • Removed zero in version numbering as it confused some people. The minor version number of this release is 5.
    • Huge update by @ArminJo addressing many issues especially for ATTinyCore integration:
      • Improved exit handling for USB_CFG_PULLUP_IOPORTNAME and LED_MODE != ACTIVE_LOW
      • Convert ISR into function and optimized CRC handling to save further bytes
      • added code for FAST_EXIT_NO_USB_MS and START_WITHOUT_PULLUP
      • different MCUSR handling for SAVE_MCUSR
      • end with usbDeviceConnect(); or usbDeviceDisconnect(); or USBDDR = 0; instead of initHardware();
      • Remove redundant code in usbdriver to reduce code size.
    • Automated build system for the command line tool using Github actions thanks to @quinot
    • Static binaries for MacOS and linux command line tool. Thanks @stonehippo
    • Increase available user program size by 64 bytes for most implementations
    • Cumulative minor fixes contributed throughout 2019-2020. Big thanks to everyone!
    • "make release" will now rebuild all release hexfiles. Thanks to @Ho-Ro.
    • Added new osccal code by @nerdralph, significantly reducing code size and fixing a bug that led to issues when micronucleus was operated on an USB hub together with other low-speed USB devices.
  • v2.6 November 5th, 2021

    • Added compile flag STORE_CONFIGURATION_REPLY_IN_RAM.
    • Added 2 bytes USB config data for Bootloader feature flags and application version.
    • Added --info flag for micronucleus executable.
    • Swapped D+ and D- and set OSCCAL_HAVE_XTALfor t88 to support MH-ET LIVE Tiny88 boards.

Credits

Firmware:

  • Micronucleus V2.6 (c) 2021 Current maintainers: @ArminJo, @cpldcpu
  • Micronucleus V2.04 (c) 2019 Current maintainers: @cpldcpu, @AHorneffer
  • Micronucleus V2.0x (c) 2016 Tim Bo"scke - [email protected] (c) 2014 Shay Green
  • Original Micronucleus (c) 2012 Jenna Fox
  • Based on USBaspLoader-tiny85 (c) 2012 Louis Beaudoin
  • Based on USBaspLoader (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH

Commandline tool:

  • Original commandline tool (c) 2012 by ihsan Kehribar [email protected] (c) 2012 Jenna Fox
  • Updates for V2.x (c) 2014 T. Bo"scke

Special Thanks:

  • Objective Development's great V-USB bitbanging usb driver
  • Embedded Creations' pioneering and inspiring USBaspLoader-tiny85
  • Digistump for motivation and contributing the VID/PID pair
  • Numerous supporters for smaller bug fixes and improvements.

micronucleus's People

Contributors

5shekel avatar ahorneffer avatar arminjo avatar cpldcpu avatar cub-uanic avatar ericonr avatar gblargg avatar github-actions[bot] avatar ho-ro avatar hramrach avatar jej avatar kehribar avatar mauferrari avatar michaelphipps avatar mjbcopland avatar nabijaczleweli avatar nerdralph avatar nfriedly avatar nicolacimmino avatar nixnax avatar nonchip avatar pimium avatar psychogenic avatar qu1j0t3 avatar quinot avatar rayddteam avatar reinoutheeck avatar robertdalesmith avatar sodabrew avatar stonehippo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

micronucleus's Issues

Idea: updating micronucleus by itself

disclaimer: Dunno if this will work, I may give it a try, comments/opinions are welcome.

The Plan:
Write a program 'updater' which wraps a new version of micronucleus and flash that to the chip.
Upon the next boot this program will self-program the new micronucleus to the begin of the flash.

the tricky parts are that the updater (including the new micronucleus image) should be aligned to the end of the flash or must at least start after the to-be end of the new micronucleus after self-flashing.
Also upon successful flashing it needs to disable itself to prevent reboot/reflash loops.

commandline: error -5 during erasing

When uploading any hex file always gives a -5 error in the erasing part. I've tested it with 1.3 and 1.4 bootloader. I'm using the littlewire schematic only that instead of zener diodes I'm powering the attiny85 using a 3.3 regulator. Littlewire, it's bootloader and USBaspLoader-tiny85 work fine.

nanite841 or nanite85 not working

hi.
i bought a couple of nanite boards at watterott recently and tried to get them working on os x (as well tried them on linux, windows 10) and none of the get recognised from the usb device manager.
are there known issues with the bootloader / boards that they are not working properly? do i have to flash a new bootloader with an isp?

micronucleus uploader fails, both 1.1 and v2

I compiled the bootloader v 1.1 for attiny45, the device enumerates successfully on both windows (7 x64) and linux (mint17 x64).
On both windows and linux, the erasing process runs and then the write fails with:

Starting to upload ...

Flash write error -1 has occured ...

The pagecount and pagesize are recognized correctly (35 free, 64B pagesize). Btw, in micronucleus.c there's an uncommented debug output (printf("> Device looks like ATtiny45!\n");) wich tests for a pagesize of 32, while according to the datasheet both the 85 and 45 have a pagesize of 64 Byte.

I then tried v2, it enumerates, the uploader fails on both systems with

micronucleus: library/micronucleus_lib.c:69: micronucleus_connect: Assertion `res >= 4' failed.

I have rights 666 set on the device using udev, running as root does not help.
The kernel says

[15126.208194] usb 4-1: usbfs: USBDEVFS_CONTROL failed cmd micronucleus rqt 192 rq 0 len 6 ret -71

What else needs to be changed for the tiny45 other than the macros and pin assignments in bootloaderconfig.h and BOOTLOADER_ADDRESS?

My hardware is self built, 68 ohm series resistors, 3v6 zeners to ground and 1k5 pullup for D-. Any chance the uploading fails because of the hardware, even though the enumeration and erasing works?

V2 with attiny44

I am trying to get micronucleus running with attiny44 without an external oscillator. I have created a new configuration folder t44_default based on t84_default, with the following changes:

  • DEVICE = attiny44
  • Different BOOTLOADER_ADDRESS based on the size of main.hex
  • BOOTLOADER_ADDRESS = 9C0 with size of main.hex being 1580.
  • Same PB0 (USB D-) and PB1 (USB D+) as for attiny84

Everything seems to work fine and I can run make to create the hex file and flash it via ArduinoISP like so:

make CONFIG=t44_default PROGRAMMER="-c arduino -P /dev/cu.usbmodem21541 -b 19200 -v" all flash
Building Micronucleus configuration: t44_default
Size of sections:
   text    data     bss     dec     hex filename
   1580       0      44    1624     658 main.bin
Size of binary hexfile. Use the data size to calculate the bootloader address:
   text    data     bss     dec     hex filename
      0    1580       0    1580     62c main.hex
avrdude -c arduino -P /dev/cu.usbmodem21541 -b 19200 -v -p attiny44  -U flash:w:main.hex:i -B 10

avrdude: Version 6.0.1, compiled on Dec 16 2013 at 17:26:24
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch

         System wide configuration file is "/usr/local/CrossPack-AVR-20131216/etc/avrdude.conf"
         User configuration file is "/Users/kaspars/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/cu.usbmodem21541
         Using Programmer              : arduino
         Overriding Baud Rate          : 19200
         Setting bit clk period        : 10.0
         AVR Part                      : ATtiny44
         Chip Erase delay              : 4500 us
         PAGEL                         : P00
         BS2                           : P00
         RESET disposition             : possible i/o
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65     6     4    0 no        256    4      0  4000  4500 0xff 0xff
           flash         65     6    32    0 yes      4096   64     64  4500  4500 0xff 0xff
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
           lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00

         Programmer Type : Arduino
         Description     : Arduino
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e9207
avrdude: safemode: lfuse reads as E2
avrdude: safemode: hfuse reads as DD
avrdude: safemode: efuse reads as FE
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "main.hex"
avrdude: writing flash (4076 bytes):

Writing | ################################################## | 100% 0.00s

avrdude: 4076 bytes of flash written
avrdude: verifying flash memory against main.hex:
avrdude: load data flash data from input file main.hex:
avrdude: input file main.hex contains 4076 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: 4076 bytes of flash verified

avrdude: safemode: lfuse reads as E2
avrdude: safemode: hfuse reads as DD
avrdude: safemode: efuse reads as FE
avrdude: safemode: Fuses OK (H:FE, E:DD, L:E2)

avrdude done.  Thank you.

However, the attiny44 doesn't seem to show up as a USB device when connected to OS X.

My question is -- how does the clock rate required for USB_CFG_CLOCK_KHZ relate to the clock settings of the chip (fuse settings), and if/how it works when you set f_cpu to something like 16000000L on a chip with a 8 MHz internal clock. Currently I am using the same fuse settings as for attiny84.

Not compiling in fedora 23 x64

It gives a lot of errors because of usb.h:

Executing make in Fedora 23 x64 gives a lot of errors like this:

In file included from library/micronucleus_lib.c:30:0:
library/micronucleus_lib.h:68:3: error: unknown type name ‘libusb_device_handle’
libusb_device_handle *device;
.
.
.
.

I 've compiled it with a little workaround in micronucleus_lib.h:

#if defined WIN
  #include <libusb.h>     // this is libusb, see http://libusb.sourceforge.net/
#else
  //include <usb.h>        // this is libusb, see http://libusb.sourceforge.net/
  #include <libusb-1.0/libusb.h>

And also in the Makefile:

#CFLAGS  = $(USBFLAGS) $(LIBS) -I$(INCLUDE) -O -g $(OSFLAG)
CFLAGS  = -lusb-1.0 $(LIBS) -I$(INCLUDE) -O -g $(OSFLAG)

I have no experience with make neither compiling, maybe just adding an additional condition depending of the linux distro solve the problem.

In the meantime, you can use this if you are getting trouble compiling in fedora.

Greetings!

Error compiling with avr-gcc 4.5.3

Hello,

I got the following error on Ubuntu 12.04 with avr-gcc 4.5.3

avr-gcc -Wall -Os -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions -I. -Ilibs-device -mmcu=attiny85 -DF_CPU=16500000 -DBOOTLOADER_ADDRESS=0x17c0 -x assembler-with-cpp -c usbdrv/usbdrvasm.S -o usbdrv/usbdrvasm.o
avr-gcc -Wall -Os -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions -I. -Ilibs-device -mmcu=attiny85 -DF_CPU=16500000 -DBOOTLOADER_ADDRESS=0x17c0 -c usbdrv/oddebug.c -o usbdrv/oddebug.o -Wa,-ahls=usbdrv/oddebug.c.lst
avr-gcc -Wall -Os -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions -I. -Ilibs-device -mmcu=attiny85 -DF_CPU=16500000 -DBOOTLOADER_ADDRESS=0x17c0 -c main.c -o main.o -Wa,-ahls=main.c.lst
In file included from main.c:31:0:
usbdrv/usbdrv.c: In function ‘usbDriverDescriptor’:
usbdrv/usbdrv.c:318:9: warning: implicit declaration of function ‘usbFunctionDescriptor’
main.c: In function ‘leaveBootloader’:
main.c:374:1: warning: ‘noreturn’ function does return
avr-gcc -Wall -Os -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions -I. -Ilibs-device -mmcu=attiny85 -DF_CPU=16500000 -DBOOTLOADER_ADDRESS=0x17c0 -c libs-device/osccal.c -o libs-device/osccal.o -Wa,-ahls=libs-device/osccal.c.lst
libs-device/osccal.c: In function ‘calibrateOscillator’:
libs-device/osccal.c:34:9: warning: implicit declaration of function ‘usbMeasureFrameLength’
avr-gcc -Wall -Os -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions -I. -Ilibs-device -mmcu=attiny85 -DF_CPU=16500000 -DBOOTLOADER_ADDRESS=0x17c0 -o main.bin usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o libs-device/osccal.o -Wl,--relax,--gc-sections -Wl,--section-start=.text=17c0,-Map=main.map
/usr/lib/gcc/avr/4.5.3/../../../avr/bin/ld: address 0x2058 of main.bin section .text' is not within regiontext'
/usr/lib/gcc/avr/4.5.3/../../../avr/bin/ld: address 0x2058 of main.bin section .text' is not within regiontext'
collect2: ld returned 1 exit status
make: *** [main.bin] Error 1

Also note the warning on the return with noreturn, I have no idea what gcc thinks that function returns.

Best regards,

size optimization: Change protocol to avoid USBfunctionwrite

This has to be considered for future versions. would also improve robustness due to shorter usb transfers.

from #21

  • changed Page Loading from using a long message loading 4 words at a time in usbFunctionWrite, to using just usbFunctionSetup and loading 1 word at a time - saves ~50 bytes of flash but slows programming down by ~1 second because of the inefficient transfer

Drivers don't install on windows 10

nothing happens when i try to install the drivers on a win10 64bit.
running the installer_x64.exe just exits and trying to install from the .inf file doesn't do anything either.

USB- forced low on reset even when micronucleus is set to run user program immediately

When micronucleus is configured to not be invoked under normal circumstances (e.g. only on external reset, ENTRYMODE=ENTRY_EXT_RESET), on any device reset it disturbs the USB data lines by pulling them low via usbDeviceDisconnect() in leaveBootloader(). This can be a problem if a program uses watchdog resets as a lightweight mechanism to wake it from sleep while the host is suspended, as it signals a USB disconnect to the host on every reset and can wake the host.

This was my quick fix to main.c around line 240 (present in V1 and V2 testing versions):

static inline void leaveBootloader(void) {

    bootLoaderExit();

    if ( usbConfiguration ) // added
        usbDeviceDisconnect();  /* Disconnect micronucleus */

Ideally usbDeviceDisconenct() would be called from main() when exiting after any USB activity has been done. usbConfiguration being non-zero doesn't perfectly capture whether any USB activity has occurred, for example before configuration has occurred if main() exits for some reason.

This came up in a USB keyboard driver. When the host goes into suspend (sleep), my device wants to shut down and use minimal power until the host resumes (wakes). My program goes into a deep sleep state and is woken periodically by a watchdog timer reset, where it checks whether the host is active. micronucleus runs first on each of these watchdog resets, and would pull USB- low before I made the above fix. Some hosts would interpret this as a request to resume.

PWM Pins?

I cant find out/understand how many PWM pins supportted with micronucleus bootloader? or It is nothing to do with bootloader? Picoduino says it has 3 PWM pins for RGB led driving uses micronucleus bootloader.

Store clock calibration with program upload in flash, restore when no usb

@semicolo on digistump forums suggested the idea that micronucleus store it's OSCCAL value along with the program during uploads, so it can restore that value during startup if there is no USB traffic to calibrate from. This would help make the chip have a more consistent clock speed, instead of the 16.0mhz or 16.5mhz it currently has depending on if it was booted on a computer or from a random other power supply.

Missing Copyright info in source files

Please, add Copyright information into all source files.

I am creating the Debian package now, and licensecheck reports a lot of source files without Copyright.

regards

LED_INIT macro clears DDR register

LED_INIT is called after initHardware. If one of the pins is configured as the pullup enable pin, USB_CFG_PULLUP_BIT, then initHardware will call usbDeviceConnect which will set that pin as an output. LED_INIT then clears all the bits in the DDR register, disabling the pullup.

This is true of all the LED_INIT macros in all the bootloaderconfig.h headers. The LED_INIT macro just needs to be changed to a bit set (|=) instead of a simple assign.

Forks of micronucleus

There are a number of forks of micronucleus that implement features that have not yet been ported to the main branch or were incompatible with it. Check them out!

Due to lack of a better place, I link them here. Fell free to add more.

Prebuilt firmware does not fit in a Digispark ATtiny85

I downloaded from github, compiled the 'micronucleus' program and tried uploading the prebuilt firmware. I tried versions 1.05 and 1.06, but both give an error stating that the program is roughly 2100 bytes too big for the Digispark.

What to do?

AUTO_EXIT_MS at 250ms silenced my Digispark :)

Hi,
I wanted to speed-up the boot time and I played with the AUTO_EXIT_MS delay, so that the Digispark waits less before starting the program.
At 1000ms it was ok. I tried 250ms and now it is not responding to uploads........ I tried to tweak down some delay in the commandline (CONNECT_WAIT) but nothing helped.
Any idea how I could recover it? without guru hacks (fuses, isp and so on...)
In another repository (https://github.com/andihofmeister/micronucleus-t85/blob/master/firmware/bootloader-timer-mode.h) I saw that there is a way to warn against that mistake:

    #if AUTO_EXIT_MS < (MICRONUCLEUS_WRITE_SLEEP * (BOOTLOADER_ADDRESS / SPM_PAGESIZE))
    #    warning "AUTO_EXIT_MS is shorter than the time it takes to perform erase function - might affect reliability?"
    #    warning "Try increasing AUTO_EXIT_MS if you have stability problems"
    #endif

Maybe that's not up-to-date with the current source of micronucleus, but in that condition AUTO_EXIT_MS should be >= 792.

Thanks for your help.

Wiki Topic: Flashing both micronucleus and user program in one "hex"

Could someone in the know "document" how a user would go about programming the micronucleus bootloader and the user program with one hex file?

Example Use Case:
End-Product is a hobby device with a built-in user program to control an LED.
During manufacturing of end-product; would like to supply the PCB house with a single .hex file which contains both the bootloader and the user program so they only have to "socket"/program once.

Hardware setup

I have an attiny85 running at 5V from the USB-port, datalines are connected to pb3/4 using 3.6v Zeners. D- is pulled up with a 1K5 resistor. I have flashed this file: https://github.com/Bluebie/micronucleus-t85/blob/master/firmware/releases/micronucleus-1.04.hex through ISP

Both Windows and Linux failed to enumerate the device, I have not fiddled with any fuses whatsoever, might this be the problem? Do I need to set fuses or does the .hex file account for that? Or is something else wrong?

micronucleus on attiny45

Hello i'm not able to get the micronucleus bootloader on attiny45, i'm pretty much a beginner, i tried to flash attiny85 build directly which may seem stupid, and it said the address of the beginning line on the hex file is out of the memory space. It does make sense, i checked the hex file and the addresses wasn't starting from 0, i guess the firmware places itself starting from an address which is already beyond the attiny45's memory size.

I'm not able to build the source code of the micronucleus for attiny because i'm a beginner, are there any ready to use builds or can anyone build me one?

My programmer works fine and i just need a bootloader to get my attiny 45 working with usb.

Thanks.

Bootloader doesn't fit in < 2.1kb when compiled with avr-gcc 4.5.x

When I compile it using avr-gcc 4.3.3 from Version 2010-01-15 of http://www.obdev.at/products/crosspack/download.html, it compiles almost small enough to fit within 2.01kb, and certainly small enough to fit in 2.07kb, yet when I try to build the same thing with avr-gcc version 4.5.1 from Version 2012-02-17 or 4.5.3 on Linux micronucleus balloons out more than a hundred bytes longer, requiring manual adjustment of the BOOTLOADER_ADDRESS setting in Makefile to allow compilation.

I have no idea how to resolve this.

compile error in micronucleos-commandline

I tried to set up the arduino IDE with the micronucleos bootloader, for the DigiSpark.

i went through: http://digistump.com/wiki/digispark/tutorials/connecting#linux

but at the point where i had to compile the micronucleos thingie, i ran into problems.

cave@cave:/digispark/micronucleus-t85-master/commandline> make
Building library: micronucleus_lib...
gcc libusb-config --cflags libusb-config --libs -Ilibrary -O -g -D LINUX -c library/micronucleus_lib.c
Building library: littleWire_util...
gcc libusb-config --cflags libusb-config --libs -Ilibrary -O -g -D LINUX -c library/littleWire_util.c
Building example: micronucleus...
gcc libusb-config --cflags libusb-config --libs -Ilibrary -O -g -D LINUX -o micronucleus examples/micronucleus.c micronucleus_lib.o littleWire_util.o libusb-config --libs
cave@cave:
/digispark/micronucleus-t85-master/commandline>

i am running openSuse 12.1 Linux

br
cave

update.rb: error TRANSFER_STALL (LIBUSB::ERROR_PIPE)

Not sure where to begin debugging this...

bundle exec ./upload.rb ../upgrade/releases/micronucleus-1.10-upgrade.hex
parsing input file as intel hex
Plug in programmable device now: (waiting)
Attached to device: <MicroBoot 1.2: 5.9 kb programmable>
Attempting to write supplied program in to device's memory
erasing
erased chip
uploading @ 0 of 6010
uploading @ 64 of 6010
uploading @ 128 of 6010
uploading @ 192 of 6010
uploading @ 256 of 6010
uploading @ 320 of 6010
uploading @ 384 of 6010
uploading @ 448 of 6010
uploading @ 512 of 6010
uploading @ 576 of 6010
uploading @ 640 of 6010
uploading @ 704 of 6010
uploading @ 768 of 6010
uploading @ 832 of 6010
uploading @ 896 of 6010
uploading @ 960 of 6010
uploading @ 1024 of 6010
uploading @ 1088 of 6010
uploading @ 1152 of 6010
uploading @ 1216 of 6010
uploading @ 1280 of 6010
uploading @ 1344 of 6010
uploading @ 1408 of 6010
uploading @ 1472 of 6010
uploading @ 1536 of 6010
uploading @ 1600 of 6010
uploading @ 1664 of 6010
uploading @ 1728 of 6010
uploading @ 1792 of 6010
uploading @ 1856 of 6010
uploading @ 1920 of 6010
uploading @ 1984 of 6010
uploading @ 2048 of 6010
uploading @ 2112 of 6010
uploading @ 2176 of 6010
uploading @ 2240 of 6010
uploading @ 2304 of 6010
uploading @ 2368 of 6010
uploading @ 2432 of 6010
uploading @ 2496 of 6010
uploading @ 2560 of 6010
uploading @ 2624 of 6010
uploading @ 2688 of 6010
uploading @ 2752 of 6010
micronucleus/ruby/vendor/bundle/ruby/2.0.0/gems/libusb-0.4.0/lib/libusb/dev_handle.rb:471:in `submit_transfer': error TRANSFER_STALL (LIBUSB::ERROR_PIPE)
  from micronucleus/ruby/vendor/bundle/ruby/2.0.0/gems/libusb-0.4.0/lib/libusb/dev_handle.rb:447:in `control_transfer'
  from micronucleus/ruby/micronucleus.rb:106:in `control_transfer'
  from micronucleus/ruby/micronucleus.rb:68:in `block in program='
  from micronucleus/ruby/micronucleus.rb:64:in `each'
  from micronucleus/ruby/micronucleus.rb:64:in `each_slice'
  from micronucleus/ruby/micronucleus.rb:64:in `program='
  from ./upload.rb:28:in `<main>'

BOOTLOADER_ADDRESS = 1700? How can that be right?

It seems the BOOTLOADER_ADDRESS is in units of eight bytes of progmem. But then, embedded-creations USBaspLoader-tiny85 was set to 1500, and the pagesize on a tiny85 is 64 bytes, yet 1500/(64 / 8) = 187.5 and 1700/(64/8) = 212.5

Shouldn't these be whole numbers? Doesn't this have some terrible implication for the writing and erasing of the tiny vector table? I'm totally boggled as to why this isn't breaking things, but I shouldn't be up coding past 1am. A problem for tomorrow @Bluebie :)

Trouble uploading on windows 10

Hi,

I have 2 digisparks with micronucleus v1.11 on them. When I try to use the micronucleus commandline tool to update either one of them, they are not found and nothing happens, the device goes to the user program after 5 seconds (preloaded with blink sketch). In those 5 seconds, the device is found by windows (I installed the drivers with zadig and/or digistump installer), but somehow the commandline tool can't see the device.

I took one of the devices to a windows 7 machine, installed the driver with zadig, downloaded the micronucleus repo, created a toolchain to build a v2 bootloader, built the v2 bootloader and flashed it to the device using the micronucleus commandline tool. So, the device works at least, yay!

Back to the windows 10 machine. No user program, so the device stays in micronucleus mode and windows sees the device (Device manager shows it, Zadig shows it), but when I start, for instance, micronucleus --erase-only and then plug-in the device, nothing happens.

What am I missing here? I'm sure the device is not bricked, it still works on the win7 machine...

Need build instructions for Mac

I'm currently unable to build the command line micronucleus tool (the v2 branch) on Mac.

The makefile is looking for libusb-config which does not exist (as far as I can tell) on Mac. I modified it to use pkgconfig like this:

USBFLAGS=$(shell pkg-config libusb-1.0 --cflags || libusb-config --cflags || libusb-legacy-config --cflags)
USBLIBS=$(shell pkg-config libusb-1.0 --libs || libusb-config --libs || libusb-legacy-config --libs)

Next it fails looking for usb.h instead of libusb.h. The libusb website seems to indicate we should use the libusb.h version.

I changed that in the micronucleus_lib.h file and now it fails with the below errors. Could this be a Mac / Clang specific issue?

➜ commandline git:(testing-V2-New) ✗ make
Building library: micronucleus_lib...
gcc -I/usr/local/include/libusb-1.0 -L/usr/local/lib -lusb-1.0 -Ilibrary -O -g -D MAC_OS -c library/micronucleus_lib.c
clang: warning: -lusb-1.0: 'linker' input unused
clang: warning: argument unused during compilation: '-L/usr/local/lib'
In file included from library/micronucleus_lib.c:30:
library/micronucleus_lib.h:67:3: error: unknown type name 'usb_dev_handle'
usb_dev_handle device;
^
library/micronucleus_lib.c:38:3: warning: implicit declaration of function 'usb_init' is invalid in C99 [-Wimplicit-function-declaration]
usb_init();
^
library/micronucleus_lib.c:39:3: warning: implicit declaration of function 'usb_find_busses' is invalid in C99
[-Wimplicit-function-declaration]
usb_find_busses();
^
library/micronucleus_lib.c:40:3: warning: implicit declaration of function 'usb_find_devices' is invalid in C99
[-Wimplicit-function-declaration]
usb_find_devices();
^
library/micronucleus_lib.c:42:12: warning: implicit declaration of function 'usb_get_busses' is invalid in C99
[-Wimplicit-function-declaration]
busses = usb_get_busses();
^
library/micronucleus_lib.c:42:10: warning: incompatible integer to pointer conversion assigning to 'struct usb_bus *' from 'int'
[-Wint-conversion]
busses = usb_get_busses();
^ ~~~~~~~~~~~~~~~~
library/micronucleus_lib.c:44:36: error: incomplete definition of type 'struct usb_bus'
for (bus = busses; bus; bus = bus->next) {
~~~^
library/micronucleus_lib.c:35:10: note: forward declaration of 'struct usb_bus'
struct usb_bus *busses;
^
library/micronucleus_lib.c:47:19: error: incomplete definition of type 'struct usb_bus'
for (dev = bus->devices; dev; dev = dev->next) {
~~~^
library/micronucleus_lib.c:35:10: note: forward declaration of 'struct usb_bus'
struct usb_bus *busses;
^
library/micronucleus_lib.c:47:44: error: incomplete definition of type 'struct usb_device'
for (dev = bus->devices; dev; dev = dev->next) {
~~~^
library/micronucleus_lib.c:45:12: note: forward declaration of 'struct usb_device'
struct usb_device *dev;
^
library/micronucleus_lib.c:49:14: error: incomplete definition of type 'struct usb_device'
if (dev->descriptor.idVendor == MICRONUCLEUS_VENDOR_ID && dev->descriptor.idProduct == MICRONUCLEUS_PRODUCT_ID) {
~~~^
library/micronucleus_lib.c:45:12: note: forward declaration of 'struct usb_device'
struct usb_device *dev;
^
library/micronucleus_lib.c:49:68: error: incomplete definition of type 'struct usb_device'
if (dev->descriptor.idVendor == MICRONUCLEUS_VENDOR_ID && dev->descriptor.idProduct == MICRONUCLEUS_PRODUCT_ID) {
~~~^
library/micronucleus_lib.c:45:12: note: forward declaration of 'struct usb_device'
struct usb_device *dev;
^
library/micronucleus_lib.c:51:38: error: incomplete definition of type 'struct usb_device'
nucleus->version.major = (dev->descriptor.bcdDevice >> 8) & 0xFF;
~~~^
library/micronucleus_lib.c:45:12: note: forward declaration of 'struct usb_device'
struct usb_device *dev;
^
library/micronucleus_lib.c:52:37: error: incomplete definition of type 'struct usb_device'
nucleus->version.minor = dev->descriptor.bcdDevice & 0xFF;
~~~^
library/micronucleus_lib.c:45:12: note: forward declaration of 'struct usb_device'
struct usb_device *dev;
^
library/micronucleus_lib.c:63:27: warning: implicit declaration of function 'usb_open' is invalid in C99 [-Wimplicit-function-declaration]
nucleus->device = usb_open(dev);
^
library/micronucleus_lib.c:68:21: warning: implicit declaration of function 'usb_control_msg' is invalid in C99
[-Wimplicit-function-declaration]
int res = usb_control_msg(nucleus->device, USB_ENDPOINT_IN| USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, 0, 0, (char *)buffer...
^
library/micronucleus_lib.c:149:7: warning: implicit declaration of function 'usb_close' is invalid in C99
[-Wimplicit-function-declaration]
usb_close(deviceHandle->device);
^
8 warnings and 8 errors generated.
make: *
* [micronucleus_lib] Error 1
➜ commandline git:(testing-V2-New) ✗

Readme file at the commandline folder

Hi Jenna!

I think you should update the Readme file under the commandline folder. I commited that with my first pull request but it is outdated now i guess :)

Best,
ihsan.

Build automated test rig

Build a LittleWire and a digispark-type-thing and write some tool to automatically run unit tests on an attiny85, automatically resetting and talking to the µBoot software, doing firmware dumps through the ISP and making sure everything looks right, uploading simple programs and testing they work via the LittleWire and another program which talks over the USB bus to make sure the pinchange interrupts are working with V-USB.

This will make experimenting to make bootloader sizes smaller much safer.

Micronucleus and other USB functionality

Hi all,

I have a project that I would like to add bootloader functionality to. However, this project already has its own USB descriptor and functionality as a gamepad. I know that V-USB supports switching between different descriptors at runtime, but I'm not sure how that interacts with micronucleus.

I'd like to be able to do the following:

  • On boot, the user can hold a button to enter bootloader mode. Otherwise it would act normally.
  • I would like to be able to update the USB descriptor for my gamepad functionality along with the rest of the program.
  • It would be nice(but not necessary) if I could reuse the V-USB library existing in the micronucleus bootloader without needing to reimport it in the user program.

How compatible are these goals with micronucleus? I'd really like to use this project(the post on interrupt-free V-USB inspired me to add USB functionality), but I'm not familiar enough with the project to know whether they're possible.

HID versus libusb

Deae Bluebie,

Any reason to don't used a HID interface?

I cannot install a driver in the machine and I would like to use your bootloader using a HID interface.

Can you suggest to me some advices to change the firmware/commandline to use a HID interface?

Thanks

Julio

Support for ATtiny45 (compiled correctly; connect/disconnect issues)

Hello, I've been able to compile micronucleus for the ATtiny45 but it seems that there is a little problem with either my hardware or the software itself. While I'm checking my connections I'd like to know the RAM usage of micronucleus. The device is automatically connecting and disconnecting (I think it enumerates because Windows is trying to install drivers) with the standard intervals. Except from loose connections I'm guessing the SRAM capacity of the '45 is not enough. Has enough tried it before? I've also tried a couple of computers and USB controllers and my connections seem correct.

That's the output of avr-size if anyone wants it:

AVR Memory Usage
----------------
Device: attiny45

Program:    1096 bytes (26.8% Full)
(.text + .data + .bootloader)

Data:         18 bytes (7.0% Full)
(.data + .bss + .noinit)

writeLength isn't really needed

Change usbFunctionWrite to just check currentAddress has reached next page boundary, and depend on programmer app to always send entire pages, padded out with 0xFFs if need be.

Easy change, but requires testing

Segfault after running compiled linux binary

peterrus@ubuntu:~/Desktop/micronucleus-t85-master/commandline$ ./micronucleus --run /home/peterrus/Dropbox/Development\ Sync/arduino/Fade.cpp.hex

Please plug in the device ...
Press CTRL+C to terminate the program.
micronucleus: library/micronucleus_lib.c:63: micronucleus_connect: Assertion `res == 4' failed.
Aborted (core dumped)

Is immediately displayed after plugging in the device, binary was compiled with simply 'make'

tiny85FlashInit could be removed to save 30 bytes

@andihofmeister pointed out that tiny85FlashInit() is only useful to initialise the reset and in particular the pcint0 vector the first time the device starts up after having micronucleus installed. The only reason it needs to be initialised is that the hex files produced by the firmware build system do not have those vectors already included in the first page - all pages until bootloader are left blank.

If we can figure out a good way to include those vectors in the hex file, we can remove this code and make the bootloader a bit smaller. 30 bytes is already nearly enough for a whole extra page on future tiny45 target.

Upgrader already patches across every vector in the main chip interrupt vector table (page 0) to the first page of bootloader data, so would require no modification - we could build micronucleus today with tiny85FlashInit commented out entirely and it would just work when installed via upgrader. If we do modify the firmware hex files in the build process in the future, upgrader will need to be able to skip over the interrupt vector table somehow - perhaps the generate-data.rb script could verify that if there is anything in the vector table of the hex file (not 0x0000 or 0xFFFF) that what is there is only jumps to the first page of the bootloader at the same offset. Shouldn't be too hard. Then the build process should remain safe.

Use Alternate Oscillator Calibration Routine to Save Flash

I started looking into the alternate oscillator calibration options in VUSB. I haven't had much luck so far, but I'll share what I found, and hopefully together we can find something that works.

I first just tried removing the osccal.o module and adding the routine in osctune.h, and enabled the timer as specified, but the routine never seemed to settle on an appropriate OSCCAL value. It often ended up towards 0x00 or 0xff. I looked into the details of what it was doing, and to me, the routine seems to be a bit flawed. Unless it starts with a OSCCAL value close to calibrated, it can easily get stuck far off and not recover.

The routine works by setting a timer to run freely, counting the timer ticks between SOF events, though the timer is expected to overflow several times before a SOF is detected. When the SOF is detected, it takes the remainder of the ticks, and compares it to the expected remainder value, but it ignores the number of timer overflows.

E.g. at 16.5MHz and a /8 timer prescaler, the timer should overflow 8 times and have a remainder value of ~14 after 1ms.

Every SOF, the routine compares the remainder left in the timer counter to 14, and if the value is higher, it assumes the clock is fast and decreases OSCCAL. If the value is lower than 14, it assumes the clock is slow and increases OSCCAL. If the clock is majorly slow however, e.g. the timer overflowed only 7 times instead of 8, and the remainder is, for example, 200, it still thinks the timer is fast (200 > 14), and slows the clock down even more. Same thing if there were 9 overflows instead of 8 and a small remainder, it speeds the clock up even more.

A larger timer would be able to handle this easier, as it could count the total number of ticks, not just the remainder, but there are only 8-bit timers on the ATtiny85. You can link the 8-bit timer and the USI 4-bit counter together to make a 12-bit counter. I started on this but quickly found another issue.

I was writing my own USB_SOF_HOOK routine to capture the TCNT0 value and USI counter value, and reset the two, but I was capturing only zeros for some reason. After debugging, I found the USB_SOF_HOOK routine was being executed twice per SOF, and the second pass through was reading my just-reset values. I traced this back to using the pin-change interrupt which sets the interrupt flag on any change, rising or falling edge, where V-USB ideally expects a rising-edge interrupt. The USB_SOF_HOOK routine will have to compensate for being run twice per frame somehow, this is probably fixed.

This behavior could explain some of what was seen with osctune.h. Perhaps the routine would work if there was only one execution per SOF.

Segmentation Fault 11

When running on OS X 10.7 Late 2011 Mac Mini i7 processor I was getting a segmentation fault 11 until I added

_DARWIN_USE_64_BIT_INODE=1

To the osx compile flags to get it to work

Got the hint for that here: nodejs/node-v0.x-archive@7ef208b

Not sure if this is specific to my version/hardware or if this could be added to the makefile for all os x builds?

User program doesn't start, programming successful

I'm having a weird behaviour on my custom board: the programming via DigisparkArduino goes well: I click upload, connect my module to the computer and about 5 seconds later the upload is complete, but the LED keeps flickering like when the bootloader was loaded the first time. To me it seems the bootloader is unable to finish and launch the user program.

When using the master branch the user program is launched as expected.

OS: OSX 10.10
Branch: testing-V2-new

Question about eeprom

Hi,
I am kinda noob and this is my silly questions:

  • Is it possible to "burn" eeprom of Tiny85 along with flash using micronucleus?
  • Is it possible to "burn" eeprom of Tiny85 without touching the flash area, using micronucleus?
    Thanks,
    Simon Vu

Documentation says 6380 bytes in 1.11, but uploader only says 6330

Please plug in the device ...
Press CTRL+C to terminate the program.
Device is found!
connecting: 16% complete
connecting: 19% complete
connecting: 22% complete
connecting: 25% complete
connecting: 28% complete
connecting: 33% complete
Device has firmware version 1.11
Available space for user applications: 6330 bytes
Suggested sleep time between sending pages: 8ms
Whole page count: 99 page size: 64
Erase function sleep duration: 792ms
parsing: 33% complete
parsing: 50% complete
Program file is 16 bytes too big for the bootloader!

Attiny167

Tried writing 2.0b hex file to attiny167. Worked successfully but chip doesn't respond at all now. Haven't tried high voltage reset just yet but I'm wondering could it be the fuse settings? Or perhaps that the d+ pin on the bootloaderconfig.h file is listed as portb4 which is also xtal1???

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.