GithubHelp home page GithubHelp logo

buserror / simavr Goto Github PK

View Code? Open in Web Editor NEW
1.5K 73.0 364.0 5.7 MB

simavr is a lean, mean and hackable AVR simulator for linux & OSX

License: GNU General Public License v3.0

Makefile 0.04% C 99.96%
simavr avr-gcc gtkwave c avr-simulator embedded debugger

simavr's Introduction

simavr - a lean and mean Atmel AVR simulator for linux

simavr is an AVR simulator for linux, or any platform that uses avr-gcc. It uses avr-gcc's own register definition to simplify creating new targets for supported AVR devices. The core was made to be small and compact, and hackable so allow quick prototyping of an AVR project. The AVR core is now stable for use with parts with <= 128KB flash, and with preliminary support for the bigger parts. The simulator loads ELF files directly, and there is even a way to specify simulation parameters directly in the emulated code using an .elf section. You can also load multipart HEX files.

Installation

On OSX, we recommend using homebrew:

brew tap osx-cross/avr
brew install --HEAD simavr

On Ubuntu, SimAVR is available in the Bionic package source:

apt-get install simavr

(Note that the command is made available under the name simavr not run_avr.)

Otherwise, make is enough to just start using bin/simavr. To install the simavr command system-wide, make install RELEASE=1.

Supported IOs

  • eeprom
  • watchdog
  • IO ports (including pin interrupts)
  • Timers, 8 &16 (Normal, CTC and Fast PWM, the overflow interrupt too)
  • The UART, including tx & rx interrupts (there is a loopback/local echo test mode too)
  • SPI, master/slave including the interrupt
  • i2c Master & Slave
  • External Interrupts, INT0 and so on.
  • ADC
  • Self-programming (ie bootloaders!)
  • A lot more!

Emulated Cores (very easy to add new ones!)

  • ATMega2560
  • AT90USB162 (with USB!)
  • ATMega1281
  • ATMega1280
  • ATMega128
  • ATMega128rf1
  • ATMega16M1
  • ATMega169
  • ATMega162
  • ATMega164/324/644
  • ATMega48/88/168/328
  • ATMega8/16/32
  • ATTiny25/45/85
  • ATTIny44/84
  • ATTiny2313/2313v
  • ATTiny13/13a
  • Many more!

Extras:

  • fully working gdb support including some pretty cool “passive modes”.
  • There is also very easy support for “VCD” (Value Change Dump) that can be visualized graphically as “waveforms” with tools like gtkwave (see below).
  • You can even source your own VCD files (for example from your logic analyzer) and feed them into your simulation.
  • There are a few examples of real life firmwares running on simavr, including OpenGL rendering of the display…
  • There is support for Arduino, but no IDE integration

Documentation And Further Information

Contributing

Patches are always welcome! Please submit your changes via Github pull requests.

VCD Support -- built in logic analyzer

simavr can output most of its pins, firmware variables, interrupts and a few other things as signals to be dumped into a file that can be plotted using gtkwave for further, precise analysis. A firmware can contain instructions for simavr to know what to trace, and the file is automatically generated. Example:

const struct avr_mmcu_vcd_trace_t _mytrace[]  _MMCU_ = {
	{ AVR_MCU_VCD_SYMBOL("UDR0"), .what = (void*)&UDR0, },
	{ AVR_MCU_VCD_SYMBOL("UDRE0"), .mask = (1 << UDRE0), .what = (void*)&UCSR0A, },
};

Will tell simavr to generate a trace everytime the UDR0 register changes and everytime the interrupt is raised (in UCSR0A). The MMCU tag tells gcc that it needs compiling, but it won't be linked in your program, so it takes literally zero bytes, this is a code section that is private to simavr, it's free! A program running with these instructions and writing to the serial port will generate a file that will display:

$ ./simavr/run_avr tests/atmega88_example.axf
AVR_MMCU_TAG_VCD_TRACE 00c6:00 - UDR0
AVR_MMCU_TAG_VCD_TRACE 00c0:20 - UDRE0
Loaded 1780 .text
Loaded 114 .data
Loaded 4 .eeprom
Starting atmega88 - flashend 1fff ramend 04ff e2end 01ff
atmega88 init
avr_eeprom_ioctl: AVR_IOCTL_EEPROM_SET Loaded 4 at offset 0
Creating VCD trace file 'gtkwave_trace.vcd'
Read from eeprom 0xdeadbeef -- should be 0xdeadbeef..
Read from eeprom 0xcafef00d -- should be 0xcafef00d..
simavr: sleeping with interrupts off, quitting gracefully

And when the file is loaded in gtkwave, you see: gtkwave

You get a very precise timing breakdown of any change that you add to the trace, down to the AVR cycle.

Example:

simavr is really made to be the center for emulating your own AVR projects, not just a debugger, but also the emulating the peripherals you will use in your firmware, so you can test and develop offline, and now and then try it on the hardware.

You can also use simavr to do test units on your shipping firmware to validate it before you ship a new version, to prevent regressions or mistakes.

simavr has a few 'complete projects/ that demonstrate this, most of them were made using real hardware at some point, and the firmware binary is exactly the one that ran on the hardware. The key here is to emulate the parts or peripherals that are hooked to the AVR. Of course, you don't have to emulate the full hardware, you just need to generate the proper stimulus so that the AVR is fooled.

HD44780 LCD Board Demo

lcd

This example board hooks up an Atmega48 to an emulated HD44780 LCD and display a running counter in the 'lcd'. Everything is emulated, the firmware runs exactly like this on a real hardware.

lcd-gtkwave

And this is a gtkwave trace of what the firmware is doing. You can zoom in, measure, etc in gtkwave, select traces to see etc.

Quite a few other examples are available!

simavr's People

Contributors

akosthekiss avatar ballessay avatar bsekisser avatar buserror avatar cardoe avatar cskarai avatar dgeelen avatar dougszumski avatar dxxb avatar endofexclusive avatar gin66 avatar hovercraft-github avatar jcreekmore avatar kostic2000 avatar lotharyx avatar maxgerhardt avatar messani avatar mikeplayle avatar msquirogac avatar nnayo avatar paulfertser avatar ppd avatar pwithnall avatar rouseabout avatar schuay avatar stevedrake avatar taylorconor avatar the-real-orca avatar vintagepc avatar xqms 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

simavr's Issues

at90usb162 core stopped working

Commit 242ec6c has broken support of at90usb162 core
(in file simavr/Makefile) you've replaced
upper=$${file/cores/sim_};
with
upper=$$global;

This way you disable at90usb162 core (global=usb162, and filename is 90usb162).
In sim_core_decl.h you check for CONFIG_USB162, and in sim_core_config.h CONFIG_90USB162 is defined.
Unfortunately i don't have OSX to test solution that will work there, so i can't provide any fix. Besides, absolutely same substitution ${files/cores/sim_} is still present on line 161.

Thanks for your work.

Crash when initializing ADC of atmega128

When using the simulator to run atmega128 it crashes.
A gdb trace reveals that avr_adc_init() tries to register ADCSRB with avr_register_io_write().
Because only register A is available in this processor, address 0 is passed. Macro AVR_DATA_TO_IO(addr) produces an invalid output and abort() is called.

_avr_data_read16le throws is invalid in C99 [-Werror,-Wimplicit-function-declaration] on OSX

https://github.com/buserror/simavr/blob/master/simavr/sim/sim_core.c#L678


/Applications/Xcode.app/Contents/Developer/usr/bin/make -C simavr RELEASE=0
CONF obj-x86_64-apple-darwin13.4.0/cores.deps
WARNING cores/sim_mega324.c did not compile, check your avr-gcc toolchain
/Applications/Xcode.app/Contents/Developer/usr/bin/make obj config
make[2]: Nothing to be done for `obj'.
CONF sim_core_decl.h
/Applications/Xcode.app/Contents/Developer/usr/bin/make libsimavr run_avr
CC sim/sim_avr.c
sim/sim_core.c:678:33: error: implicit declaration of function '_avr_data_read16le' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
                                                                        _avr_set_r16le(avr, d, _avr_data_read16le(avr, r));
                                                                                               ^
sim/sim_core.c:678:33: note: did you mean '_avr_flash_read16le'?
sim/sim_core.c:116:1: note: '_avr_flash_read16le' declared here
_avr_flash_read16le(
^
1 error generated.
make[2]: *** [obj-x86_64-apple-darwin13.4.0/sim_core.o] Error 1
make[1]: *** [all] Error 2
make: *** [build-simavr] Error 2

UART hangs when UCSRxA is not read.

Following setup:
The host writes to the UART buffer via the xon-handler (until the buffer is full).
The AVR has the RX-interrupt setup to receive data by reading from the UDRx-register.

Problem:
The AVR stopps receiving data.

Possible cause:
In the RX-interrupt of the UART, a read to the UDRx-register should trigger a call to the xon-handler when the buffer is empty. This is happening when reading UCSRxA but not when only reading UDRx. When writing to UDRx (as in the echo demo) the xon-handler is also called.

When UDRx is only read in the RX-interrupt (which should be ok, Serial from aduino does this) the xon-handler is not called after the buffer has been filled once and the application hangs.

Possible solution:
In avr_uart.c I added this code from function avr_uart_rxc_read to function avr_uart_read:

    // if reception is idle and the fifo is empty, tell whomever there is room
    if (avr_regbit_get(avr, p->rxen) && uart_fifo_isempty(&p->input)) {
        avr_raise_irq(p->io.irq + UART_IRQ_OUT_XOFF, 0);
        avr_raise_irq(p->io.irq + UART_IRQ_OUT_XON, 1);
    }

Now, the AVR continues to consume data (i.e. fill a buffer which is larger than the UART-buffer) without the need to read UCSRxA or write UDRx.

Hooking up UART to stdin/stdout?

Hi, I found this simulator very useful, but I couldn't figure out a way to send/receive data via the UART from the host computer to the microcontroller. Is there a way to do it?

A VCD trace file can not be generated

Hi all,
My system is Fedora 22. My avr install list as bellow:
[nemo@localhost simavr]$ sudo dnf list |grep avr
avr-binutils.x86_64 1:2.24-4.fc22 @System
avr-gcc.x86_64 1:4.9.3-1.fc22 @System
avr-libc.noarch 1.8.0-10.fc22 @System
avr-gcc-c++.x86_64 1:4.9.3-1.fc22 updates
avr-gdb.x86_64 7.1-11.fc22 fedora
binutils-avr32-linux-gnu.x86_64 2.26-8.fc22 updates
eclipse-avr.noarch 2.3.4-9.fc21 fedora
gcc-avr32-linux-gnu.x86_64 5.3.1-2.fc22 updates
gcc-c++-avr32-linux-gnu.x86_64 5.3.1-2.fc22 updates

After make the source code, it works fine.
But I have some problems during the example code running. For example, as the README file described, run the atmega88 example firmware with
./simavr/run_avr` tests/atmega88_example.axf
[nemo@localhost simavr]$ ./simavr/run_avr tests/atmega88_example.axf
AVR_MMCU_TAG_VCD_TRACE 00c6:00 - UDR0
AVR_MMCU_TAG_VCD_TRACE 00c0:20 - UDRE0
Loaded 1722 .text at address 0x0
Loaded 114 .data
Loaded 4 .eeprom

This small section tells simavr to generate a VCD trace dump with changes to these
registers.
Opening it with gtkwave will show you the data being pumped out into the data register
UDR0, and the UDRE0 bit being set, then cleared

According to code comment, it will generate a VCD trace file, but it seems not works on my computer.
It seems miss the message as bellow:
Starting atmega88 - flashend 1fff ramend 04ff e2end 01ff
atmega88 init
avr_eeprom_ioctl: AVR_IOCTL_EEPROM_SET Loaded 4 at offset 0
Creating VCD trace file 'gtkwave_trace.vcd'
Read from eeprom 0xdeadbeef -- should be 0xdeadbeef..
Read from eeprom 0xcafef00d -- should be 0xcafef00d..
simavr: sleeping with interrupts off, quitting gracefully
What is the problems about that? Did my environment is not correct? I am new to start this tools, hope to get some feedback about it :).

ADC conversion with noise canceller does not work

Some AVR chips (e.g. ATMega328) has ADC noise canceller, which does ADC conversion when the MCU is sleeping to reduce noise. To start ADC conversion in this way, the ADC should be enabled in single conversion mode, ADC interrupt enabled, and MCU must be put to ADC sleep (SLEEP_MODE_ADC). The conversion is not started by ADSC bit, but by entering the sleep mode.
This does not seem to be supported in the simulation. I was not able to start ADC conversion without setting the ADSC bit explicitly.

ADC definition for atmega328 is wrong

The definition of ADC pins (SIM_CORENAME.adc.muxmode) in sim_megax8.h is specifying 7 ADC inputs (0-6) and input 7 as temperature:

        .muxmode = {
            [0] = AVR_ADC_SINGLE(0), [1] = AVR_ADC_SINGLE(1),
            [2] = AVR_ADC_SINGLE(2), [3] = AVR_ADC_SINGLE(3),
            [4] = AVR_ADC_SINGLE(4), [5] = AVR_ADC_SINGLE(5),
            [6] = AVR_ADC_SINGLE(6), [7] = AVR_ADC_TEMP(),
            [14] = AVR_ADC_REF(1100),   // 1.1V
            [15] = AVR_ADC_REF(0),      // GND
        },

According to Atmega328 datasheet, temperature pin is input 8. DIL version of 328 has 6 inputs, SMD versions 8, so the current config does not correspond in any case.
I would create pull request with a fix, but I would like to know first, what is the reason for 7 inputs? Has any of the MCUs using this definition 7 inputs? Can I directly fix it here, or do I need a new definition specific for Atmega328 (and possibly others)?

Watchdog timer interrupt mode doesn't work

Watchdog timer interrupt mode doesn't work.

When watchdog interrupt mode is enabled and system reset mode is disabled interrupt is not triggered.

It appears that when watchdog system reset is disabled (WDE bit cleared) watchdog timer is disabled completely. When WDIE bit is set it should be enabled regardless of WDE value.

Please have look at "AVR132: Using the Enhanced Watchdog Timer" figure 2-1. (http://www.atmel.com/Images/doc2551.pdf)

RXC interrupt will not fire when UCSRnA is not polled

In avr_uart_rxc_read(), registered as an IO write handler for UCSRnA, a pair of XOFF/XON IRQs is raised if RXENn is set and the input FIFO is empty. If the simulated firmware does not read UCSRnA, no such IRQ pair is generated.

In uart_pty, just in front of uart_pty_xon_hook() there is a comment

/*
 * Called when the uart has room in it's input buffer. This is called repeateadly
 * if necessary, while the xoff is called only when the uart fifo is FULL
 */

Clearly this is not the case if firmware is not polling UCSRnA. Thus some of my firmwares using RXC interrupts will not work ;)

I'm not quite sure on how to proceed. Would it make sense to periodically raise XON IRQs to activate UART I/O implementations running in their own threads? Are there other solutions?

I have implemented a proof-of-concept fix. When RXENn and RXCIEn are set, I set up a periodic timer firing every p->usec_per_byte us that will raise a XOFF/XON interrupt pair. That way, only firmwares setting RXCIE will pay the execution time penalty. The timer period is updated on UBRR writes. Are you interested in merging this?

I had an issue running make install

/Applications/Xcode.app/Contents/Developer/usr/bin/make -C simavr install RELEASE=0
/Applications/Xcode.app/Contents/Developer/usr/bin/make obj config
make[2]: Nothing to be done for obj'. make[2]: Nothing to be done forconfig'.
/Applications/Xcode.app/Contents/Developer/usr/bin/make libsimavr run_avr
sim/sim_elf.c:32:10: fatal error: 'libelf.h' file not found

include <libelf.h>

     ^

1 error generated.
make[2]: *** [obj-x86_64-apple-darwin14.0.0/sim_elf.o] Error 1
make[1]: *** [all] Error 2
make: *** [install] Error 2

/Applications/Xcode.app/Contents/Developer/usr/bin/make -C simavr install RELEASE=0
/Applications/Xcode.app/Contents/Developer/usr/bin/make obj config
make[2]: Nothing to be done for obj'. make[2]: Nothing to be done forconfig'.
/Applications/Xcode.app/Contents/Developer/usr/bin/make libsimavr run_avr
sim/sim_elf.c:33:10: fatal error: 'gelf.h' file not found

include <gelf.h>

     ^

1 error generated.
make[2]: *** [obj-x86_64-apple-darwin14.0.0/sim_elf.o] Error 1
make[1]: *** [all] Error 2
make: *** [install] Error 2

Section offsets applied twice when debugging with gdb

I am seeing an error when using gdb to debug a simple test program that has a global variable (initialised or uninitialised). I am unable to inspect variables, including predefined ones such as PORTB, instead getting an error message such as:

Cannot access memory at address 0x1000025

I'm using simavr master along with avr-gcc 4.9.1 and avr-gdb 7.6.1 from MacPorts. Here is a test case that I can use to reproduce the problem (compiled with avr-gcc -O0 -g -mmcu=atmega48):

#include <avr/io.h>
#include <util/delay.h>

uint8_t x = 0;

int main(void) {
    DDRB = 1<<DDB7;

    while (1) {
        PORTB ^= 1<<PB7;
        _delay_ms(x++);
    }
    return 1;
}

After starting simavr and loading the file in gdb, info files shows the following section info:

    0x00800100 - 0x00800100 is .data
    0x00000000 - 0x0000040a is .text
    0x00800100 - 0x00800101 is .bss

But after connecting to simavr with target remote :1234, the section info changes to:

    0x00800100 - 0x00800100 is .data
    0x00000000 - 0x0000040a is .text
    0x01000100 - 0x01000101 is .bss

At this point I'm not able to inspect global variables directly, but you can still see them with a bit of persistence:

(gdb) print PORTB
Cannot access memory at address 0x1000025
(gdb) print &PORTB
$1 = (uint8_t *) 0x800025 ""
(gdb) print *&PORTB
$3 = 0 '\000'

An adequate workaround for this problem is to (re)load the file into gdb after connecting to simavr. The existing information is wiped away and reloaded directly from the file, and I haven't seen any further problems with that approach.

Another workaround I have tested successfully is to apply this patch:

diff --git a/simavr/sim/sim_gdb.c b/simavr/sim/sim_gdb.c
index e7d95ef..04bee1c 100644
--- a/simavr/sim/sim_gdb.c
+++ b/simavr/sim/sim_gdb.c
@@ -301,9 +301,9 @@ gdb_handle_command(
                                 */
                                gdb_send_reply(g, "1");
                                break;
-                       } else if (strncmp(cmd, "Offsets", 7) == 0) {
-                               gdb_send_reply(g, "Text=0;Data=800000;Bss=800000");
-                               break;
+                       // } else if (strncmp(cmd, "Offsets", 7) == 0) {
+                       //      gdb_send_reply(g, "Text=0;Data=800000;Bss=800000");
+                       //      break;
                        } else if (strncmp(cmd, "Xfer:memory-map:read", 20) == 0) {
                                snprintf(rep, sizeof(rep),
                                                "l<memory-map>\n"

It looks to me like specifying the offsets over the wire to gdb results in them being applied again to sections that already have the correct offsets. Disabling this part of the response fixes the problem that I am seeing. Not that I'm necessarily suggesting this as a fix, since presumably that code serves a purpose - but perhaps this will be helpful to someone who knows what they're looking at :)

simulation speed control

Current simavr implementation

  • sleep is implemented with usleep. It works only for 1x speed. Why not have slower or faster speeds?
    I could make a workaround in pysimavr for slower speeds, but faster speed is not possible because of this implementation.
  • the controlling thread is implemented always in the examples (maybe without speed control, running at fastest possible speed?)

I have a solution for controlling the speed of the simulation (max 1x speed because of usleep problem):
https://github.com/ponty/pysimavr/blob/master/pysimavr/swig/simavr.i

How it works:
I make small time intervals (e.g. 20 ms for 50 FPS).
The next cycle count is calculated for the beginning of the next interval using F_CPU and simulation speed.
The simulation runs in the thread at fastest possible speed until next cycle count is reached,
then sleeping until next interval.

"ld r27, X" does not work correctly

Load Indirect does not work correctly when the destination register is a part of the pointer register

For example, "ld r27, X" does not work correctly. r27 is written with the right value, but it is overwritten with the write to R_XH later.

https://github.com/buserror-uk/simavr/blob/ab4b6b04c4fa7059f21e03a0b3a4cbc1dd167385/simavr/sim/sim_core.c#L954

The same problem is likely to exist for Y(r28:r29) and Z(r30:r31) registers as well.

Here's a small test demonstrating the issue:
https://gist.github.com/katiska/7352a8af341275db070d

Don't list available cores by default

When running simavr without any arguments, it helpfully prints usage info, followed by a list of supported cores. However, the list of supported cores is so long (yay!) that it pushes the usage information off of the screen on reasonably sized terminal windows.

Since listing available cores isn't that critical to using the software, I suggest not printing them by default and adding a --list command line argument for listing them.

Make fail at building libsimavr.so if not from clean make

if building to recompile a single file in core, I am getting this error:

SHARED obj-i486-linux-gnu/libsimavr.so.1
/home/mghughes/Projects/simavr/simavr/../simavr/obj-i486-linux-gnu/libsimavr.so: file not recognized: File truncated

if I do:

make clean; make

the compile completes without issues.

since I recently changed hardware and done a complete install I was thinking the problem could possibly be on my end, however after checking recent changes, I found that reverting commit 1be4877 seems to resolve the issue.

complete sample make session showing the problem follows:

mghughes@debian:~/Projects/simavr$ make
make -C simavr RELEASE=0
make[1]: Entering directory /home/mghughes/Projects/simavr/simavr' make obj config make[2]: Entering directory/home/mghughes/Projects/simavr/simavr'
make[2]: Nothing to be done for obj'. make[2]: Nothing to be done forconfig'.
make[2]: Leaving directory /home/mghughes/Projects/simavr/simavr' make libsimavr run_avr make[2]: Entering directory/home/mghughes/Projects/simavr/simavr'
CC sim/sim_core.c
AR obj-i486-linux-gnu/libsimavr.a
SHARED obj-i486-linux-gnu/libsimavr.so.1
/home/mghughes/Projects/simavr/simavr/../simavr/obj-i486-linux-gnu/libsimavr.so: file not recognized: File truncated
collect2: error: ld returned 1 exit status
make[2]: *** [obj-i486-linux-gnu/libsimavr.so.1] Error 1
make[2]: Leaving directory /home/mghughes/Projects/simavr/simavr' make[1]: *** [all] Error 2 make[1]: Leaving directory/home/mghughes/Projects/simavr/simavr'
make: *** [build-simavr] Error 2

UART broken

I tried to replace the version of simavr coming with simreprap with the current one by replacing the entire directory of simreprap/shared/simavr with this repository. Hint: you have to replace all occurrences of SIMAVR in simrepraps' top Makefile with something like SIMAVR_DIR to get this working.

It worked when spooling simavr back to tag v1.0, but not with v1.1 or current master. When not working, the firmware (the one coming with simreprap) would simply not accept characters on the serial connection. Connecting with a G-code sender like Pronterface doesn't allow to establish a connection (Pronterface looks for the word "start" or "ok" on the serial line to recognize the connection).

Bisecting pointed to commit 890c3dc, which brings in the broken behaviour.

board_simduino segfaults on run

It compiles fine, and seems to try to initialize, but it prints a bunch of garbage and segfaults before anything can be done.

Git tells me 3c5e1ae is to blame:

$ git bisect bad
3c5e1ae3f560ba1568da247f4e835206ff12a264 is the first bad commit

The backtrace at this commit is as follows:

#0  0x00007ffff7bcba80 in pthread_kill () from /usr/lib/libpthread.so.0
#1  0x0000000000402bb2 in uart_pty_stop (p=0x69f780 <uart_pty>) at ../parts/uart_pty.c:246
#2  0x0000000000405682 in avr_reset (avr=avr@entry=0x6a1010) at sim/sim_avr.c:132
#3  0x000000000040579b in avr_init (avr=0x6a1010) at sim/sim_avr.c:97
#4  0x0000000000401f06 in main (argc=1, argv=0x7fffffffdb18) at simduino.c:210

Please tell me if I can help further. Hopefully this is something simple, although I don't know much about the structure of this project.

Building on OS X with CrossPack-AVR and homebrew doesn't work

By default, simavr wouldn't build on my laptop. I've got CrossPack-AVR providing my avr toolchain, and libelf etc. installed from homebrew (into /usr/local). The makefile as it is, and one of the c files, assume some things that don't match with what I have installed.

I patched things as shown below to make simavr play nicely with my system. I hope this can help someone else later! I've also included a log of the errors I got before this patch, in case someone googles them some day.

diff --git a/Makefile.common b/Makefile.common
index 42c7004..3ea2352 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -46,13 +46,13 @@ CORE_CFLAGS = -nostdinc -DAVR_CORE=1
 ifeq (${shell uname}, Darwin)
 # gcc 4.2 from MacOS is really not up to scratch anymore
 CC         = clang
-AVR_ROOT   := "/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/"
-AVR_INC    := ${AVR_ROOT}/avr-4/
+AVR_ROOT   := /usr/local/CrossPack-AVR
+AVR_INC    := ${AVR_ROOT}/avr/
 AVR        := ${AVR_ROOT}/bin/avr-
 # Thats for MacPorts libelf
-ifeq (${shell test -d /opt/local && echo Exists}, Exists)
-IPATH      += /opt/local/include
-LFLAGS     = -L/opt/local/lib/
+ifeq (${shell test -d /usr/local && echo Exists}, Exists)
+IPATH      += /usr/local/include
+LFLAGS     = -L/usr/local/lib/
 endif
 else
 LINUX_AVR_ROOTS := /usr/lib/avr /usr/avr /opt/cross/avr/avr /usr/local/avr
diff --git a/simavr/sim/sim_elf.c b/simavr/sim/sim_elf.c
index a0a49ee..3732ae9 100644
--- a/simavr/sim/sim_elf.c
+++ b/simavr/sim/sim_elf.c
@@ -29,8 +29,8 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include <libelf.h>
-#include <gelf.h>
+#include <libelf/libelf.h>
+#include <libelf/gelf.h>

 #include "sim_elf.h"
 #include "sim_vcd_file.h"
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C simavr RELEASE=0
CONF obj-x86_64-apple-darwin13.3.0/cores.deps
WARNING cores/sim_90usb162.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega128.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega1280.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega1281.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega1284.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega128rfa1.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega128rfr2.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega16.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega164.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega168.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega169.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega16m1.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega2560.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega32.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega324.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega328.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega48.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega644.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega8.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_mega88.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_tiny13.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_tiny2313.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_tiny24.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_tiny25.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_tiny44.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_tiny45.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_tiny84.c did not compile, check your avr-gcc toolchain
WARNING cores/sim_tiny85.c did not compile, check your avr-gcc toolchain
/Applications/Xcode.app/Contents/Developer/usr/bin/make obj config
make[2]: Nothing to be done for `obj'.
CONF sim_core_decl.h
/Applications/Xcode.app/Contents/Developer/usr/bin/make libsimavr run_avr
CC sim/sim_avr.c
CC sim/sim_core.c
CC sim/sim_cycle_timers.c
sim/sim_elf.c:32:10: fatal error: 'libelf.h' file not found
#include <libelf.h>
         ^
1 error generated.
make[2]: *** [obj-x86_64-apple-darwin13.3.0/sim_elf.o] Error 1
make[1]: *** [all] Error 2
make: *** [build-simavr] Error 2

_MMCU_ from avr_mcu_section.h breaks curly braces initialization

For simulating my code I used following lines and found some variables to be wrongly initialized.

#include "avr_mcu_section.h"
AVR_MCU(F_CPU, "attiny85");

Debugging the problem showed that _MMCU_ attribute from avr_mcu_section.h was the cause of the problem.

#include "avr_mcu_section.h"

const uint8_t _mmcu[2] _MMCU_ = { 0, 0 };

int main()
{
    int arr[] = {1, 2, 3};
    return 0;
}

The above test code will result in:

arr = {2, 3, -1}

It seems to me that __data_start is off by two bytes.

I don't understand the simavr code too well, so I'm not able to provide a patch just now. Any hints are welcome though.

I'm using Arch Linux with avr-gcc 5.2.0-1, avr-binutils 2.25.1-1, avr-libc 1.8.1-4 and up to date simavr from github.

Timers: interrupt flags reset failure

In the avr_timer.c file, function avr_timer_write_pending instead of clearing interrupt flags, may set it. This is due to this call:
avr_core_watch_write(avr, addr, v);

Fast PWM mode not working

Hi,

It seems that there is an issue with Fast PWM mode at least on the ATMEGA1280 core.

#include <avr/io.h>

void main(void) {
        DDRH = 255;
        TCCR4A |= (1<<COM4A0) | (1<<COM4A1) | (1<<WGM41);
        TCCR4B |= (1<<WGM43) | (1<<WGM42);
        TCCR4B |= (1<<CS42) | (1<<CS40);
        ICR4 = 1000;
        OCR4A = 800;

        for(;;);
}

This works on the real hardware work but does not work on the simulator (port is never set).

Loaded 1 section of ihex
Load HEX flash 00000000, 318
firmware f-1460556263.hex f=16000000 mmcu=atmega1280
TIMER: avr_timer_write-4 clock turned off
TIMER: avr_timer_write-4 clock turned off
TIMER: avr_timer_configure-4 TOP 15625.00Hz = 512 cycles = 32usec

Thank you very much

Makefile issue: `uname -o`

The Makefiles assume the GNU uname with its -o option, which doesn't exist on the BSD uname on OSX amongst others. Would it make sense to just use uname -s instead?

UART Parity bit support

I am trying to get 9N1 to work. [1]

Modifying the uart-loop-testcode to use the parity bit does not work.

On sending, TXB8 will be set.

Inspecting the gtkwave file, the parity bit will not be set during recieve from the loopback.

The project implementing the sending/receive can be found here:
https://github.com/computerlyrik/haqbus-avr-lib

This is my first AVR-C project and under heavy development, so the code might be a little in chaos

[1] 9N1 is a mode using the parity bit as a 9th databit. Default mode is 8N1 where only UDR matters.

Precision of timer

I think that timers in simavr are not precise. I will try to describe it...
I made callback in HOST code:

void callback(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void *param)
{
  static uint64_t prevCycle = 0;
  uint64_t diff = avr->cycle - prevCycle;
  prevCycle = avr->cycle;

  if (diff != 262144)
  {
    // this should not happen
  }
}

...

avr_register_io_write(avr, 0xff, callback, nullptr);

In AVR code I can call this callback this way:

  _SFR_MEM8(0xff) = 0xff;

I configured divider of TIMER0 to 1024 so it overflows every 1024*256=262144 CPU cycles. If I call callback from ISR(TIMER0_OVF_vect), it works as expected - cycle difference between calls is 262144.
The issue is when I need to use output capture register (OCR0A). When I write OCR0A, timer is shifted by small amount of time. Here is callstack right at the moment, when internal timer is shifted:

1  avr_timer_tov         avr_timer.c 169  0x7f0f6f1775ac 
2  avr_timer_configure   avr_timer.c 324  0x7f0f6f177e6c 
3  avr_timer_reconfigure avr_timer.c 339  0x7f0f6f177ef7 
4  avr_timer_write_ocr   avr_timer.c 380  0x7f0f6f1780d9 
5  _avr_set_r            sim_core.c  186  0x7f0f6f165071 
6  _avr_set_ram          sim_core.c  237  0x7f0f6f1652c0 
7  avr_run_one           sim_core.c  1315 0x7f0f6f168df0 
8  avr_callback_run_raw  sim_avr.c   317  0x7f0f6f16df20 
9  avr_run               sim_avr.c   354  0x7f0f6f16e026 
10 main                  main.cpp    83   0x401afb       

At this moment, program counter is at instruction, which is writing to the register OCR0A:

            OCR0A = minHwTimeRaw & 0xff;
     c68:       c7 bc           out     0x27, r12       ; 39

Version: 1f8eab5
Simulated mcu: atmega328p

Adding elements to struct avr_t reveals memory corruption issues...

Debian 6; gcc 4.4.5 (Debian 4.4.5-8)
Debian 7; gcc 4.7.2 (Debian 4.7.2-5) << still setting up though the issues still seem to exist.

Have several bug fixes I'll be putting pull requests (assuming I can figure it out...;)for issues I have found so far (one definite(elf symbols), one potential(loading code)) and another I'll should be pushing asap (irq observed memory block movement errors)... I see recent commits (which I still need to pull) and am still observing telltale signs of memory corruption issues even with the fixes I have made to my code base... Therefore it was time to put up an issue in case others find themselves faced with unknown oddities.

crash when simulating a ATtiny2313A

The problem seems to be that avr_reset in simavr/sim/sim_avr.c clears more memory than what small ATtinys actually have. This patch should fix it:

diff --git a/simavr/sim/sim_avr.c b/simavr/sim/sim_avr.c
index 6c985cc..265a0a6 100644
--- a/simavr/sim/sim_avr.c
+++ b/simavr/sim/sim_avr.c
@@ -121,7 +121,7 @@ void avr_reset(avr_t * avr)
        AVR_LOG(avr, LOG_TRACE, "%s reset\n", avr->mmcu);

        avr->state = cpu_Running;
-       for(int i = 0x20; i <= MAX_IOs; i++)
+       for(int i = 0x20; i <= MAX_IOs && i <= avr->ramend; i++)
                avr->data[i] = 0;
        _avr_sp_set(avr, avr->ramend);
        avr->pc = 0;

Writing to PIN register does not generate change in VCD file for PORT register

Steps to reproduce:

  1. Set up a VCD trace on any PORT register
  2. Update that register by writing a non-zero value to the associated PIN register

Observed result:
No change is reflected in the VCD file

Expected result:
the updated value is reflected in the VCD file

Example code:

AVR_MCU_SIMAVR_COMMAND (& TWBR ) ;

const struct avr_mmcu_vcd_trace_t _mytrace [] _MMCU_ = {
  { AVR_MCU_VCD_SYMBOL ( " PORTB " ) ,
    .what = ( void *) & PORTB , } ,
};

int main(void)
{
    TWBR = SIMAVR_CMD_VCD_START_TRACE ;
    DDRB = 1;
    for(int i=0; i<20;++i){
        PINB = 1;
    //  PORTB = PORTB;
    }
    TWBR = SIMAVR_CMD_VCD_STOP_TRACE ;
    return 0; 
}

Uncommenting the no-op assignment to PORTB will result in the updates being reflected in the VCD file.

Build on Windows

I'm trying to build simavr under Win XP 32bit. I've installed latest Mingw32 with Msys 1.0. It has GCC 4.8.1. During compilation first I've got: "usleep is deprectated" error due to "-Werror=deprecated-declaration" in Makefile (just -Werror), then I've got:

make -C simavr RELEASE=0
make[1]: Entering directory `/c/Documents and Settings/All Users/Documents/simavr/simavr'
make obj config
make[2]: Entering directory `/c/Documents and Settings/All Users/Documents/simavr/simavr'
make[2]: Nothing to be done for `obj'.
make[2]: Nothing to be done for `config'.
make[2]: Leaving directory `/c/Documents and Settings/All Users/Documents/simavr/simavr'
make libsimavr run_avr
make[2]: Entering directory `/c/Documents and Settings/All Users/Documents/simavr/simavr'
In file included from sim/sim_gdb.c:22:0:
sim/sim_network.h:43:24: error: expected declaration specifiers or '...' before '(' token
 #define sleep(x) Sleep((x)*1000)
                        ^
sim/sim_network.h:43:24: error: expected declaration specifiers or '...' before '(' token
 #define sleep(x) Sleep((x)*1000)
                        ^
In file included from sim/sim_gdb.c:29:0:
c:\mingw\include\pthread.h:320:8: error: redefinition of 'struct timespec'
 struct timespec {
        ^
In file included from c:\mingw\include\unistd.h:95:0,
                 from sim/sim_gdb.c:26:
c:\mingw\include\parts\time.h:65:8: note: originally defined here
 struct timespec
        ^
make[2]: *** [obj-mingw32/sim_gdb.o] Error 1
make[2]: Leaving directory `/c/Documents and Settings/All Users/Documents/simavr/simavr'
make[1]: *** [all] Error 2
make[1]: Leaving directory `/c/Documents and Settings/All Users/Documents/simavr/simavr'
make: *** [build-simavr] Error 2

Wrong TWSR status when sending address

Hi,
When doing a write transaction, I'm getting the wrong status in TWSR after sending the address. I'm reading 0x28 which stands for data write w ack, I was expecting 0x18, sda+w w ack, which is also what the silicon is replying. How is this status register updated?

_avr_vcd_notify log size runnaway (255) flush problem?
Supply Voltage: 3292 mV..
avr_twi_write a4 START:1 STOP:0 ACK:0 INT:1 TWSR:f8 (state 00)

I2C start
_avr_twi_status_set 08
avr_twi_write 85 START:0 STOP:0 ACK:0 INT:1 TWSR:08 (state 11)
I2C Master address 80
eeprom received start
avr_twi_irq_input 01800800
I2C received ACK:1
_avr_twi_status_set 28

Cheers,
Ronald

Make error about fatal error: libelf.h: No such file or directory

Hi all,
My system is fedora 22, the libelf-dev package seems not be install with command: sudo dnf install libelf-dev, the error is list as bellow:

Last metadata expiration check performed 1:33:15 ago on Wed Sep 7 22:19:25 2016.
No package libelf-dev available.
Error: no package matched: libelf-dev

I have one problem during my compiling the source code, the error is listed as bellow:

[nemo@localhost simavr]$ make
make -C simavr RELEASE=0
make[1]: Entering directory '/home/nemo/extra/simavr/simavr/simavr'
make obj config
make[2]: Entering directory '/home/nemo/extra/simavr/simavr/simavr'
make[2]: Nothing to be done for 'obj'.
make[2]: Nothing to be done for 'config'.
make[2]: Leaving directory '/home/nemo/extra/simavr/simavr/simavr'
make libsimavr run_avr
make[2]: Entering directory '/home/nemo/extra/simavr/simavr/simavr'
sim/sim_elf.c:32:20: fatal error: libelf.h: No such file or directory
compilation terminated.
../Makefile.common:187: recipe for target 'obj-x86_64-redhat-linux/sim_elf.o' failed
make[2]: *** [obj-x86_64-redhat-linux/sim_elf.o] Error 1
make[2]: Leaving directory '/home/nemo/extra/simavr/simavr/simavr'
Makefile:34: recipe for target 'all' failed
make[1]: *** [all] Error 2
make[1]: Leaving directory '/home/nemo/extra/simavr/simavr/simavr'
Makefile:15: recipe for target 'build-simavr' failed
make: *** [build-simavr] Error 2

Watchdog timeout should do a reset.

RIght now watchdog just stops the CPU (without GDB even sadly_crashes()), but enabling watchdog and tightlooping is quite common and valid techinque to do a reset.

Supported cores on Mac OS 10.8

Hi,

Used simavr about 12 months ago when I was running 10.6 (Snow Leopard) and found it really useful.

Doing some arduino stuff again on 10.8 (Mountain Lion), but when I compile and execute run_avr I get:

Usage: run_avr [-t] [-g] [-v] [-m <device>] [-f <frequency>] firmware
       -t: Run full scale decoder trace
       -g: Listen for gdb connection on port 1234
       -ff: Load next .hex file as flash
       -ee: Load next .hex file as eeprom
       -v: Raise verbosity level (can be passed more than once)
   Supported AVR cores:

(i.e. no AVR cores supported).

I've checked out sim_core_decl.h and related files and all the avr kinds are declared. Can't find anything obviously missing.

I did tweak Makefile.common a bit for my avr-gcc toolchain, but everything compiles fine and the tests pass, so I'm pretty sure I got it right.

Simavr revision 4e64e8b, compiling with Apple clang 4.1.

Any advice appreciated.

thanks,

Cam

Tried the test and nothing happened

Hi, I have tried the test from the README:

$ ./simavr/run_avr tests/atmega88_example.axf
AVR_MMCU_TAG_VCD_TRACE 00c6:00 - UDR0
AVR_MMCU_TAG_VCD_TRACE 00c0:20 - UDRE0
Loaded 1722 .text at address 0x0
Loaded 114 .data
Loaded 4 .eeprom

the produced gtkwave_trace.vcd is empty.

Timer: Broken timing in CTC mode

The current timer implementation fails to correctly handle code which
sets the OCRxA register in (at least) CTC mode.

The following program, when compiled for an atmega328 and run on real
hardware, will produce a square wave at ~300Hz with a duty on cycle of
50% on PB3. Running it on simavr gives ~234Hz and a duty cycle of 40%.

/* Fuses: E:07, H:D9, L:D7 */
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
ISR(TIMER2_COMPA_vect)
{
    static int phase = 0;
    PORTB ^= _BV(3);
    if (phase)
        _delay_ms(1.0);
    phase = !phase;
    OCR2A = 25;
}
int main (void)
{
    sei(); /* Enable interrupts */
    DDRB |= _BV(3);
    /* Timer in CTC mode, interrupt when compare match */
    OCR2A = 25;
    TIMSK2 = _BV(OCIE2A);
    TCCR2A = _BV(WGM21);
    TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20);

    while (1)
        ;
    return 0;
}

Looking at the implementation, it appears that there is a bug in how
the cycle timer delay is calculated. When the delay to the next
compare match is calculated the current TCNTx is not considered.
Unfortunately it is not clear to me how this can be fixed without
subtly breaking the other timer modes.

Compile errors on gcc 5.2.0 under arch-linux

If i compile under arch-linux wich has the newest gcc i get the following errors:

In file included from atmega88_uart_echo.c:22:0:
atmega88_uart_echo.c:34:23: error: initialization of flexible array member in a nested context
  { AVR_MCU_VCD_SYMBOL("UDR0"), .what = (void*)&UDR0, },
                       ^
../simavr/sim/avr/avr_mcu_section.h:142:10: note: in definition of macro 'AVR_MCU_VCD_SYMBOL'
  .name = _name
      ^
atmega88_uart_echo.c:34:23: note: (near initialization for '_mytrace[0]')
  { AVR_MCU_VCD_SYMBOL("UDR0"), .what = (void*)&UDR0, },
                       ^
../simavr/sim/avr/avr_mcu_section.h:142:10: note: in definition of macro 'AVR_MCU_VCD_SYMBOL'
  .name = _name

I made a Dockerfile that reproduces the exactly same problem:
https://gist.github.com/TheCrazyT/cef7b8ee796845a76bf4
(build it with "docker build -t archtest ." , run make-command with "docker run -ti archtest")

Because I can compile under ubuntu (gcc version 4.8.4) i guess it has something to do with changes in gcc.

OS-X Compile Error: atmega88_coroutine.c:61: error: expected string literal before ')' token

OS X 10.9.1 (13B42)
Xcode Version 5.0.2 (5A3005)
Arduino 1.0.5 app bundle with "avr-gcc (GCC) 4.3.2"

"Make" the 'tests' directory and fails with error:
atmega88_coroutine.c:61: error: expected string literal before ')' token

cd tests
make clean
make
AVR-CC atmega88_example.c
   1932     118       6    2056     808 atmega88_example.axf
AVR-CC attiny85_crash_gdb.c
    135       0       0     135      87 attiny85_crash_gdb.axf
AVR-CC atmega48_enabled_timer.c
    215       0       0     215      d7 atmega48_enabled_timer.axf
AVR-CC atmega88_timer16.c
    360       0       2     362     16a atmega88_timer16.axf
AVR-CC atmega48_watchdog_test.c
    385      82       6     473     1d9 atmega48_watchdog_test.axf
AVR-CC atmega88_uart_echo.c
   1908      68      88    2064     810 atmega88_uart_echo.axf
AVR-CC atmega644_adc_test.c
   2154     160      22    2336     920 atmega644_adc_test.axf
AVR-CC atmega88_coroutine.c
atmega88_coroutine.c: In function '_set_stack':
atmega88_coroutine.c:61: error: expected string literal before ')' token
make: *** [atmega88_coroutine.axf] Error 1

cores: sim_mega324.c broken

At least on FC20, avr-libc 1.8.0 (release 7.fc20) there is no "iom324.h". Probably requires looking at some datasheets; changing to an a/p variant (which are defined) highlights other issues.

Code throws 'AVR not known' error after compiling on ubuntu 12.10

I get the following error when trying to run example.

alex@ubuntu:~/simavr$ ./simavr/run_avr tests/atmega88_example.axf
AVR_MMCU_TAG_VCD_TRACE 00c6:00 - UDR0
AVR_MMCU_TAG_VCD_TRACE 00c0:20 - UDRE0
Loaded 1722 .text
Loaded 114 .data
Loaded 4 .eeprom
avr_make_mcu_by_name: AVR 'atmega88' not known

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.