docs: add page "Go on microcontrollers"
Этот коммит содержится в:
		
							родитель
							
								
									823ecd5167
								
							
						
					
					
						коммит
						0e65b0da1c
					
				
					 2 изменённых файлов: 133 добавлений и 0 удалений
				
			
		| 
						 | 
					@ -12,4 +12,5 @@ Contents:
 | 
				
			||||||
   :maxdepth: 2
 | 
					   :maxdepth: 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   installation
 | 
					   installation
 | 
				
			||||||
 | 
					   microcontrollers
 | 
				
			||||||
   internals
 | 
					   internals
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										132
									
								
								docs/microcontrollers.rst
									
										
									
									
									
										Обычный файл
									
								
							
							
						
						
									
										132
									
								
								docs/microcontrollers.rst
									
										
									
									
									
										Обычный файл
									
								
							| 
						 | 
					@ -0,0 +1,132 @@
 | 
				
			||||||
 | 
					.. microcontrollers:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. highlight:: go
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Go on microcontrollers
 | 
				
			||||||
 | 
					======================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TinyGo was designed to run on microcontrollers, but the Go language wasn't.
 | 
				
			||||||
 | 
					This means there are a few challenges to writing Go code for microcontrollers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Microcontrollers have very little RAM and execute code directly from flash.
 | 
				
			||||||
 | 
					Also, constant globals are generally put in flash whenever possible. The Go
 | 
				
			||||||
 | 
					language itself heavily relies on garbage collection so care must be taken to
 | 
				
			||||||
 | 
					avoid dynamic memory allocation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Heap allocation
 | 
				
			||||||
 | 
					---------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Many operations in Go rely on heap allocation. Some of these heap allocations
 | 
				
			||||||
 | 
					are optimized away, but not all of them. Also, TinyGo does not yet contain a
 | 
				
			||||||
 | 
					garbage collector so heap allocation must be avoided whenever possible outside
 | 
				
			||||||
 | 
					of initialization code.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					These operations currently do heap allocations:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * Taking the pointer of a local variable. This will result in a heap
 | 
				
			||||||
 | 
					    allocation, unless the compiler can see the resulting pointer never
 | 
				
			||||||
 | 
					    escapes. This causes a heap allocation::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var global *int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        func foo() {
 | 
				
			||||||
 | 
					            i := 3
 | 
				
			||||||
 | 
					            global = &i
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This does not cause a heap allocation::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        func foo() {
 | 
				
			||||||
 | 
					            i := 3
 | 
				
			||||||
 | 
					            bar(&i)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        func bar(i *int) {
 | 
				
			||||||
 | 
					            println(*i)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * Converting between ``string`` and ``[]byte``. In general, this causes a
 | 
				
			||||||
 | 
					    heap allocation because one is constant while the other is not: for
 | 
				
			||||||
 | 
					    example, a ``[]byte`` is not allowed to write to the underlying buffer of a
 | 
				
			||||||
 | 
					    ``string``. However, there is an optimization that avoids a heap allocation
 | 
				
			||||||
 | 
					    when converting a string to a ``[]byte`` when the compiler can see the
 | 
				
			||||||
 | 
					    slice is never written to. For example, this ``WriteString`` function does
 | 
				
			||||||
 | 
					    not cause a heap allocation::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        func WriteString(s string) {
 | 
				
			||||||
 | 
					            Write([]byte(s))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        func Write(buf []byte) {
 | 
				
			||||||
 | 
					            for _, c := range buf {
 | 
				
			||||||
 | 
					                WriteByte(c)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * Converting a ``byte`` or ``rune`` into a ``string``. This operation is
 | 
				
			||||||
 | 
					    actually a conversion from a Unicode code point into a single-character
 | 
				
			||||||
 | 
					    string so is similar to the previous point.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * Concatenating strings, unless one of them is zero length.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * Creating an interface with a value larger than a pointer. Interfaces in Go
 | 
				
			||||||
 | 
					    are not a zero-cost abstraction and should be used carefully on
 | 
				
			||||||
 | 
					    microcontrollers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * Closures where the collection of shared variables between the closure and
 | 
				
			||||||
 | 
					    the main function is larger than a pointer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * Creating and modifying maps. Maps have *very* little support at the moment
 | 
				
			||||||
 | 
					    and should not yet be used. They exist mostly for compatibility with some
 | 
				
			||||||
 | 
					    standard library packages.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * Starting goroutines. There is limited support for goroutines and currently
 | 
				
			||||||
 | 
					    they are not at all efficient. Also, there is no support for channels yet
 | 
				
			||||||
 | 
					    so their usefulness is limited.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The ``volatile`` keyword
 | 
				
			||||||
 | 
					------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Go does not have the ``volatile`` keyword like C/C++. This keyword is
 | 
				
			||||||
 | 
					unnecessary in most desktop use cases but is required for memory mapped I/O on
 | 
				
			||||||
 | 
					microcontrollers and interrupt handlers. As a workaround, any variable of a
 | 
				
			||||||
 | 
					type annotated with the ``//go:volatile`` pragma will be marked volatile. For
 | 
				
			||||||
 | 
					example::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //go:volatile
 | 
				
			||||||
 | 
					    type volatileBool bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var isrFlag volatileBool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This is a workaround for a limitation in the Go language and should at some
 | 
				
			||||||
 | 
					point be replaced with something else.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Inline assembly
 | 
				
			||||||
 | 
					---------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The device-specific packages like ``device/avr`` and ``device/arm`` provide
 | 
				
			||||||
 | 
					``Asm`` functions which you can use to write inline assembly::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    arm.Asm("wfi")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There is no support yet for inline assembly that takes (register) parameters or
 | 
				
			||||||
 | 
					returns a value.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Harvard architectures (AVR)
 | 
				
			||||||
 | 
					---------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The AVR architecture is a modified Harvard architecture, which means that flash
 | 
				
			||||||
 | 
					and RAM live in different address spaces. In practice, this means that any
 | 
				
			||||||
 | 
					given pointer may either point to RAM or flash, but this is not visible from
 | 
				
			||||||
 | 
					the pointer itself.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To get TinyGo to work on the Arduino, which uses the AVR architecutre, all
 | 
				
			||||||
 | 
					global variables (which include string constants!) are marked non-constant and
 | 
				
			||||||
 | 
					thus are stored in RAM and all pointer dereferences assume that pointers point
 | 
				
			||||||
 | 
					to RAM. At some point this should be optimized so that obviously constant data
 | 
				
			||||||
 | 
					is kept in read-only memory but this optimization has not yet been implemented.
 | 
				
			||||||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче