0%

PIO相关

1
2
3
4
5
6
.program squarewave
set pindirs, 1 ; Set pin to output
again:
set pins, 1 [1] ; Drive pin high and then delay for one cycle
set pins, 0 ; Drive pin low
jmp again ; Set PC to label `again`

OpenOCD烧写调试

1
~$ ../configure --enable-cmsis-dap --enable-sysfsgpio --enable-imx_gpio --enable-bcm2835gpio  --enable-xds110 --enable-ftdi --enable-stlink
  • 添加支持Pyua PY25Q32H nor flash的支持
1
2
3
4
5
6
7
8
9
10
11
12
13
~ openocd$ git diff
diff --git a/src/flash/nor/spi.c b/src/flash/nor/spi.c
index bf654f9f6..ac3e1e069 100644
--- a/src/flash/nor/spi.c
+++ b/src/flash/nor/spi.c
@@ -184,6 +184,7 @@ const struct flash_device flash_devices[] = {
FLASH_ID("xtx xt25q64b", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0017600b, 0x100, 0x10000, 0x800000),
FLASH_ID("xtx xt25q128b", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0018600b, 0x100, 0x10000, 0x1000000),
FLASH_ID("zetta zd25q16", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001560ba, 0x100, 0x10000, 0x200000),
+ FLASH_ID("pyua py25q32h", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00162085, 0x100, 0x10000, 0x400000),

/* FRAM, no erase commands, no write page or sectors */

  • 烧写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
~$ openocd -f interface/ftdi/ft232h-module-swd.cfg  -f target/rp2040.cfg -c "program blink.elf verify reset exit"
Open On-Chip Debugger 0.12.0+dev-01369-gb388f4805 (2023-11-04-10:01)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : FTDI SWD mode enabled
swd
Warn : Transport "swd" was already selected
Info : Hardware thread awareness created
Info : Hardware thread awareness created
Warn : An adapter speed is not selected in the init scripts. OpenOCD will try to run the adapter at very low speed (100 kHz).
Warn : To remove this warnings and achieve reasonable communication speed with the target, set "adapter speed" or "jtag_rclk" in the init scripts.
Info : clock speed 100 kHz
Info : SWD DPIDR 0x0bc12477, DLPIDR 0x00000001
Info : SWD DPIDR 0x0bc12477, DLPIDR 0x10000001
Info : [rp2040.core0] Cortex-M0+ r0p1 processor detected
Info : [rp2040.core0] target has 4 breakpoints, 2 watchpoints
Info : [rp2040.core1] Cortex-M0+ r0p1 processor detected
Info : [rp2040.core1] target has 4 breakpoints, 2 watchpoints
Info : starting gdb server for rp2040.core0 on 3333
Info : Listening on port 3333 for gdb connections
Warn : [rp2040.core1] target was in unknown state when halt was requested
[rp2040.core0] halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ee msp: 0x20041f00
[rp2040.core1] halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ee msp: 0x20041f00
** Programming Started **
Info : Found flash device 'win w25q16jv' (ID 0x001540ef)
Info : RP2040 B0 Flash Probe: 2097152 bytes @0x10000000, in 32 sectors

Info : Padding image section 1 at 0x10002190 with 112 bytes (bank write end alignment)
Warn : Adding extra erase range, 0x10002200 .. 0x1000ffff
** Programming Finished **
** Verify Started **
** Verified OK **
** Resetting Target **
shutdown command invoked

学习理解tinyusb+pico-sdk编译工程结构

  • TinyUSB is an open-source cross-platform USB Host/Device stack for embedded system, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events are deferred then handled in the non-ISR task function.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
~$ git clone https://github.com/hathach/tinyusb

~$ cd tinyusb
~$ tinyusb$ tree -L 2 -d
.
├── docs
│   ├── assets
│   ├── contributing
│   ├── info
│   └── reference
├── examples
│   ├── build
│   ├── device
│   ├── dual
│   ├── host
│   └── typec
├── hw
│   ├── bsp
│   └── mcu
├── lib
│   ├── embedded-cli
│   ├── fatfs
│   ├── networking
│   └── SEGGER_RTT
├── src
│   ├── class
│   ├── common
│   ├── device
│   ├── host
│   ├── osal
│   ├── portable
│   └── typec
├── test
│   ├── fuzz
│   ├── hil
│   └── unit-test
└── tools
├── cmake
├── codespell
├── make
└── usb_drivers

37 directories


  • 下面以tinyusb/examples/device/cdc_msc的工程为例。
1
2
3
4
5
6
7
8
9
10
11
12
13
tinyusb/examples/device/cdc_msc$ tree
.
├── CMakeLists.txt
├── Makefile
├── skip.txt
└── src
├── main.c
├── msc_disk.c
├── tusb_config.h
└── usb_descriptors.c

2 directories, 7 files

  • 分析CMakeLists.txt文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
tinyusb/examples/device/cdc_msc$ cat -n CMakeLists.txt
1 cmake_minimum_required(VERSION 3.17)
2 set_property(GLOBAL PROPERTY USE_FOLDERS ON) # 设置全局的属性,名为:USE_FOLDERS, 值为ON。
3
4 include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
5
6 # gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
7 family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
8
9 project(${PROJECT} C CXX ASM)
10
11 # Checks this example is valid for the family and initializes the project
12 family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) # 定义在 family_support.cmake 内的函数。通过这里调用到tinyusb/hw/bsp/rp2040/family.cmake
13
14 # Espressif has its own cmake build system
15 if(FAMILY STREQUAL "espressif")
16 return()
17 endif()
18
19 add_executable(${PROJECT})
20
21 # Example source
22 target_sources(${PROJECT} PUBLIC
23 ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
24 ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk.c
25 ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
26 )
27
28 # Example include
29 target_include_directories(${PROJECT} PUBLIC
30 ${CMAKE_CURRENT_SOURCE_DIR}/src
31 )
32
33 # Configure compilation flags and libraries for the example... see the corresponding function
34 # in hw/bsp/FAMILY/family.cmake for details.
35 family_configure_device_example(${PROJECT} noos) # 需要在family.cmake里扩展的函数。

  • 上面的CMakeLists.txt第4行引入其它的tinyusb/hw/bsp/family_support.cmake文件,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
tinyusb/hw/bsp$ cat family_support.cmake
include_guard(GLOBAL) # 防止重复include当前的文件。

include(CMakePrintHelpers) # Convenience functions for printing properties and variables, useful e.g. for debugging.

# TOP is path to root directory
set(TOP "${CMAKE_CURRENT_LIST_DIR}/../..") # 设置变量TOP的值。
get_filename_component(TOP ${TOP} ABSOLUTE) # cmake 内置的函数,获取`${TOP}`完全路径。

# Default to gcc
if (NOT DEFINED TOOLCHAIN)
set(TOOLCHAIN gcc)
endif ()

# FAMILY not defined, try to detect it from BOARD
if (NOT DEFINED FAMILY)
if (NOT DEFINED BOARD)
message(FATAL_ERROR "You must set a FAMILY variable for the build (e.g. rp2040, espressif).
You can do this via -DFAMILY=xxx on the cmake command line")
endif ()

# Find path contains BOARD
file(GLOB BOARD_PATH LIST_DIRECTORIES true
RELATIVE ${TOP}/hw/bsp
${TOP}/hw/bsp/*/boards/${BOARD}
)
if (NOT BOARD_PATH)
message(FATAL_ERROR "Could not detect FAMILY from BOARD=${BOARD}")
endif ()

# replace / with ; so that we can get the first element as FAMILY
string(REPLACE "/" ";" BOARD_PATH ${BOARD_PATH})
list(GET BOARD_PATH 0 FAMILY)
endif ()

if (NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/${FAMILY}/family.cmake)
message(FATAL_ERROR "Family '${FAMILY}' is not known/supported")
endif()

if (NOT FAMILY STREQUAL rp2040)
# enable LTO if supported skip rp2040
include(CheckIPOSupported)
check_ipo_supported(RESULT IPO_SUPPORTED)
cmake_print_variables(IPO_SUPPORTED)
if (IPO_SUPPORTED)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
endif()

set(WARNING_FLAGS_GNU
-Wall
-Wextra
-Werror
[...]
)

set(WARNINGS_FLAGS_IAR "")

# Filter example based on only.txt and skip.txt
function(family_filter RESULT DIR)
get_filename_component(DIR ${DIR} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR})

if (EXISTS "${DIR}/only.txt")
file(READ "${DIR}/only.txt" ONLYS)
# Replace newlines with semicolon so that it is treated as a list by CMake
string(REPLACE "\n" ";" ONLYS_LINES ${ONLYS})

# For each mcu
foreach(MCU IN LISTS FAMILY_MCUS)
# For each line in only.txt
foreach(_line ${ONLYS_LINES})
# If mcu:xxx exists for this mcu or board:xxx then include
if (${_line} STREQUAL "mcu:${MCU}" OR ${_line} STREQUAL "board:${BOARD}")
set(${RESULT} 1 PARENT_SCOPE)
return()
endif()
endforeach()
endforeach()

# Didn't find it in only file so don't build
set(${RESULT} 0 PARENT_SCOPE)

elseif (EXISTS "${DIR}/skip.txt")
file(READ "${DIR}/skip.txt" SKIPS)
# Replace newlines with semicolon so that it is treated as a list by CMake
string(REPLACE "\n" ";" SKIPS_LINES ${SKIPS})

# For each mcu
foreach(MCU IN LISTS FAMILY_MCUS)
# For each line in only.txt
foreach(_line ${SKIPS_LINES})
# If mcu:xxx exists for this mcu then skip
if (${_line} STREQUAL "mcu:${MCU}")
set(${RESULT} 0 PARENT_SCOPE)
return()
endif()
endforeach()
endforeach()

# Didn't find in skip file so build
set(${RESULT} 1 PARENT_SCOPE)
else()

# Didn't find skip or only file so build
set(${RESULT} 1 PARENT_SCOPE)
endif()
endfunction()


function(family_add_subdirectory DIR)
family_filter(SHOULD_ADD "${DIR}")
if (SHOULD_ADD)
add_subdirectory(${DIR})
endif()
endfunction()


function(family_get_project_name OUTPUT_NAME DIR)
get_filename_component(SHORT_NAME ${DIR} NAME)
set(${OUTPUT_NAME} ${TINYUSB_FAMILY_PROJECT_NAME_PREFIX}${SHORT_NAME} PARENT_SCOPE)
endfunction()


function(family_initialize_project PROJECT DIR)
# set output suffix to .elf (skip espressif and rp2040)
if(NOT FAMILY STREQUAL "espressif" AND NOT FAMILY STREQUAL "rp2040")
set(CMAKE_EXECUTABLE_SUFFIX .elf PARENT_SCOPE)
endif()

family_filter(ALLOWED "${DIR}")
if (NOT ALLOWED)
get_filename_component(SHORT_NAME ${DIR} NAME)
message(FATAL_ERROR "${SHORT_NAME} is not supported on FAMILY=${FAMILY}")
endif()
endfunction()


#-------------------------------------------------------------
# Common Target Configure
# Most families use these settings except rp2040 and espressif
#-------------------------------------------------------------

# Add RTOS to example
function(family_add_rtos TARGET RTOS)
if (RTOS STREQUAL "freertos")
# freertos config
if (NOT TARGET freertos_config)
add_library(freertos_config INTERFACE)
target_include_directories(freertos_config INTERFACE ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${FAMILY}/FreeRTOSConfig)
# add board definition to freertos_config mostly for SystemCoreClock
target_link_libraries(freertos_config INTERFACE board_${BOARD})
endif()

# freertos kernel
if (NOT TARGET freertos_kernel)
add_subdirectory(${TOP}/lib/FreeRTOS-Kernel ${CMAKE_BINARY_DIR}/lib/freertos_kernel)
endif ()

target_link_libraries(${TARGET} PUBLIC freertos_kernel)
endif ()
endfunction()


# Add common configuration to example
function(family_configure_common TARGET RTOS)
family_add_rtos(${TARGET} ${RTOS})

string(TOUPPER ${BOARD} BOARD_UPPER)
string(REPLACE "-" "_" BOARD_UPPER ${BOARD_UPPER})
target_compile_definitions(${TARGET} PUBLIC
BOARD_${BOARD_UPPER}
)

# run size after build
add_custom_command(TARGET ${TARGET} POST_BUILD
COMMAND ${CMAKE_SIZE} $<TARGET_FILE:${TARGET}>
)

# Add warnings flags
target_compile_options(${TARGET} PUBLIC ${WARNING_FLAGS_${CMAKE_C_COMPILER_ID}})

# Generate linker map file
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
target_link_options(${TARGET} PUBLIC "LINKER:-Map=$<TARGET_FILE:${TARGET}>.map")
endif()

# ETM Trace option
if (TRACE_ETM STREQUAL "1")
target_compile_definitions(${TARGET} PUBLIC TRACE_ETM)
endif ()

# LOGGER option
if (DEFINED LOGGER)
target_compile_definitions(${TARGET} PUBLIC LOGGER_${LOGGER})

# Add segger rtt to example
if(LOGGER STREQUAL "RTT" OR LOGGER STREQUAL "rtt")
if (NOT TARGET segger_rtt)
add_library(segger_rtt STATIC ${TOP}/lib/SEGGER_RTT/RTT/SEGGER_RTT.c)
target_include_directories(segger_rtt PUBLIC ${TOP}/lib/SEGGER_RTT/RTT)
#target_compile_definitions(segger_rtt PUBLIC SEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL)
endif()
target_link_libraries(${TARGET} PUBLIC segger_rtt)
endif ()
endif ()
endfunction()


# Add tinyusb to example
function(family_add_tinyusb TARGET OPT_MCU RTOS)
# tinyusb target is built for each example since it depends on example's tusb_config.h
set(TINYUSB_TARGET_PREFIX ${TARGET}-)
add_library(${TARGET}-tinyusb_config INTERFACE)

# path to tusb_config.h
target_include_directories(${TARGET}-tinyusb_config INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/src)
target_compile_definitions(${TARGET}-tinyusb_config INTERFACE CFG_TUSB_MCU=${OPT_MCU})

if (DEFINED LOG)
target_compile_definitions(${TARGET}-tinyusb_config INTERFACE CFG_TUSB_DEBUG=${LOG})
if (LOG STREQUAL "4")
# no inline for debug level 4
target_compile_definitions(${TARGET}-tinyusb_config INTERFACE TU_ATTR_ALWAYS_INLINE=)
endif ()
endif()

if (RTOS STREQUAL "freertos")
target_compile_definitions(${TARGET}-tinyusb_config INTERFACE CFG_TUSB_OS=OPT_OS_FREERTOS)
endif ()

# tinyusb's CMakeList.txt
add_subdirectory(${TOP}/src ${CMAKE_CURRENT_BINARY_DIR}/tinyusb)

if (RTOS STREQUAL "freertos")
# link tinyusb with freeRTOS kernel
target_link_libraries(${TARGET}-tinyusb PUBLIC freertos_kernel)
endif ()

# use max3421 as host controller
if (MAX3421_HOST STREQUAL "1")
target_compile_definitions(${TARGET}-tinyusb_config INTERFACE CFG_TUH_MAX3421=1)
target_sources(${TARGET}-tinyusb PUBLIC
${TOP}/src/portable/analog/max3421/hcd_max3421.c
)
endif ()

endfunction()


# Add bin/hex output
function(family_add_bin_hex TARGET)
add_custom_command(TARGET ${TARGET} POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${TARGET}> $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.bin
COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${TARGET}> $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.hex
VERBATIM)
endfunction()


#----------------------------------
# Example Target Configure (Default rule)
# These function can be redefined in FAMILY/family.cmake
#----------------------------------

function(family_configure_example TARGET RTOS)
# empty function, should be redefined in FAMILY/family.cmake
endfunction()

# Configure device example with RTOS
function(family_configure_device_example TARGET RTOS)
family_configure_example(${TARGET} ${RTOS})
endfunction()


# Configure host example with RTOS
function(family_configure_host_example TARGET RTOS)
family_configure_example(${TARGET} ${RTOS})
endfunction()


# Configure host + device example with RTOS
function(family_configure_dual_usb_example TARGET RTOS)
family_configure_example(${TARGET} ${RTOS})
endfunction()

function(family_example_missing_dependency TARGET DEPENDENCY)
message(WARNING "${DEPENDENCY} submodule needed by ${TARGET} not found, please run 'python tools/get_deps.py ${DEPENDENCY}' to fetch it")
endfunction()

#----------------------------------
# RPI specific: refactor later
#----------------------------------
function(family_add_default_example_warnings TARGET)
target_compile_options(${TARGET} PUBLIC
-Wall
-Wextra
[...]
)

if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0)
target_link_options(${TARGET} PUBLIC "LINKER:--no-warn-rwx-segments")
endif()

# GCC 10
if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10.0)
target_compile_options(${TARGET} PUBLIC -Wconversion)
endif()
[...]
endfunction()

#----------------------------------
# Flashing target
#----------------------------------

# Add flash pycod target
function(family_flash_pyocd TARGET)
if (NOT DEFINED PYOC)
set(PYOCD pyocd)
endif ()

add_custom_target(${TARGET}-pyocd
DEPENDS ${TARGET}
COMMAND ${PYOCD} flash -t ${PYOCD_TARGET} $<TARGET_FILE:${TARGET}>
)
endfunction()


function(family_flash_dfu_util TARGET OPTION)
if (NOT DEFINED DFU_UTIL)
set(DFU_UTIL dfu-util)
endif ()

add_custom_target(${TARGET}-dfu-util
DEPENDS ${TARGET}
COMMAND ${DFU_UTIL} -R -d ${DFU_UTIL_VID_PID} -a 0 -D $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.bin
VERBATIM
)
endfunction()

#----------------------------------
# Family specific
#----------------------------------

# family specific: can override above functions
include(${CMAKE_CURRENT_LIST_DIR}/${FAMILY}/family.cmake)
# 这里调用不同的BSP或者MCU的目录的`cmake`文件,以rp2040为例是:tinyusb/hw/bsp/rp2040/family.cmake

if (NOT FAMILY_MCUS)
set(FAMILY_MCUS ${FAMILY})
endif()

# if use max3421 as host controller, expand FAMILY_MCUS to include max3421
if (MAX3421_HOST STREQUAL "1")
set(FAMILY_MCUS ${FAMILY_MCUS} MAX3421)
endif ()

# save it in case of re-inclusion
set(FAMILY_MCUS ${FAMILY_MCUS} CACHE INTERNAL "")

ta

  • TinyUSB是一个嵌入式系统下开源跨平台的USB协议栈,以RP2040为例,它的开发实现是要依赖于pico-sdk的。

  • 编译工程

1
2
3
4
~ examples/device/video_capture$ mkdir build && cd build
~ examples/device/video_capture/build $
~ examples/device/video_capture/build $ cmake -DFAMILY=rp2040 -DPICO_SDK_PATH=/home/michael/3TB-DISK/RaspberryPi/RP2040/pico-sdk/ ../
~ examples/device/video_capture/build $ openocd -f interface/ftdi/ft232h-module-swd.cfg -f target/rp2040.cfg -c "program video_capture.elf verify reset exit"

使用TFT_eSPI(ardion)驱动ili9341 16bit并口屏

安装rp2040 bsp支持

  • 安装第三方的arduino-pico库,让Arduino IDE可以支持rp2040板子。
  • 首先在Arduino IDE -> File -> Preference -> Additional Boards Manager URLs:添加下面的链接:
1
https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
  • 再打开Board Manager进行联网更新,搜索pico并且安装Raspberry Pi Pico/RP2040的包。

配置TFT_eSPI

  • 打开已经预定义好的文件:~/Arduino/libraries/TFT_eSPI/User_Setups/Setup107_RP2040_ILI9341_16bit_parallel.h,把屏幕与RP2040按照文件的线序进行连接。

  • 再打开~/Arduino/libraries/TFT_eSPI/User_Setups/User_Setup_Select.h,只打开上面这一个文件的注释。

1
#include <User_Setups/Setup107_RP2040_ILI9341_16bit_parallel.h>
  • 选择打开一个TFT_eSPI内置的测试工程。这里使用的是官方的板子,就选择Tools -> Boards -> Rasperry Pi RP2040 Boards -> Rasperry Pi Pico. 编译上传就可以看到结果,烧写过程中有可能需要手动复位BOOTSEL按键。

简单逻辑分析仪示例

  • Install Rust
1
2
3
4
~$ rustup target add thumbv6m-none-eabi
~$ rustup component add llvm-tools-preview
~$ cargo install cargo-binutils
~$ cargo install elf2uf2-rs
  • 连机编译与烧写运行
1
2
~$ git clone https://github.com/dotcypress/ula

  • Hold the BOOTSEL button while connecting your board to the computer, then run following command.
1
2
~$ cd ula
~$ cargo run --release

PulseView

  • Select Openbench Logic Sniffer & SUMP compatible protocol when connecting to μLA.

SigrokCli

  • Scan for devices
1
~$ sigrok-cli -d ols:conn=/dev/tty.usbmodem_ula_1 --scan
  • Sample two 10 MHz square waves with 90° phase shift
1
2
3
4
5
6
7
8
9
10
~$ sigrok-cli -d ols:conn=/dev/tty.usbmodem_ula_1
-O ascii:charset='_`\/'
--config samplerate=100m
--samples 70

libsigrok 0.5.2
Acquisition with 16/16 channels at 100 MHz
0:``\____/`````\___/`````\___/`````\___/`````\___/`````\___/`````\___/``
1:____/`````\____/````\____/````\____/````\____/````\____/````\____/````
2:______________________________________________________________________

LoRa通信

USB协议栈

USB结构简介

descriptor-table.svg

Descriptor Types

  • The most commonly used descriptors include:

    • Device Descriptor
    • Configuration Descriptor
    • Interface Descriptor
    • Endpoint Descriptor
    • String Descriptor
  • Every USB device must have one Device Descriptor and at least one each of the Configuration, Interface, and Endpoint Descriptors.

Device Descriptor

  • The Device Descriptor is the first descriptor read by the Host during enumeration. The purpose of the Device Descriptor is to let the Host know what specification of USB the device complies with and how many possible configurations are available on the device. Upon successful processing of the Device Descriptor, the Host will read all the Configuration Descriptors.

Configuration Descriptor

  • A device may have more than one configuration. Each device configuration is assigned a number. The Configuration Descriptor serves two purposes:

    Informs the Host as to how many interfaces (i.e., virtual devices) are in the configuration. While it is common for a configuration to offer only one interface, Devices that appear like two or more products have more than one interface.
    How much power the device will consume if this configuration is activated by the Host. If the device is capable of controlling its power consumption, it may offer more than one configuration. Each configuration will advertise how much power would be consumed if the configuration were to be activated.

Interface Descriptor

An Interface Descriptor describes the details of the function of the product. Key elements include the number of endpoints on the device and which USB device class is implemented by the endpoints. For example, if the device were a keyboard, the specified device class would be Human Interface Device (HID) and the number of endpoints would be two.

Endpoint Descriptor

  • Each endpoint on a device has its own descriptor. The descriptor provides the endpoint address (i.e., endpoint number), the size of the endpoint, and the data transfer type used to access the endpoint.
  • Endpoint 0 (EP0IN and EP0OUT) are reserved in every device for control purposes.
  • A USB device can have up to 32 endpoints (16 OUT and 16 IN). Since EP0IN and EP0OUT are set aside as control endpoints, the maximum number of endpoints available to transmit application data is 30.

String Descriptor

  • Strings Descriptors are optional human readable strings which the Host OS may display.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
~$ lsusb -v -s 001:005

Bus 001 Device 005: ID cafe:4020 TinyUSB TinyUSB Device
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0xcafe
idProduct 0x4020
bcdDevice 1.00
iManufacturer 1 TinyUSB
iProduct 2 TinyUSB Device
iSerial 3 E6609CB2D3995B33
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x00a7
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 0
bInterfaceCount 2
bFunctionClass 14 Video
bFunctionSubClass 3 Video Interface Collection
bFunctionProtocol 0
iFunction 4 TinyUSB UVC
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 14 Video
bInterfaceSubClass 1 Video Control
bInterfaceProtocol 1
iInterface 4 TinyUSB UVC
VideoControl Interface Descriptor:
bLength 13
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdUVC 1.50
wTotalLength 0x0028
dwClockFrequency 27.000000MHz
bInCollection 1
baInterfaceNr( 0) 1
VideoControl Interface Descriptor:
bLength 18
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0201 Camera Sensor
bAssocTerminal 0
iTerminal 0
wObjectiveFocalLengthMin 0
wObjectiveFocalLengthMax 0
wOcularFocalLength 0
bControlSize 3
bmControls 0x00000000
VideoControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 2
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bSourceID 1
iTerminal 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 1
iInterface 4 TinyUSB UVC
VideoStreaming Interface Descriptor:
bLength 14
bDescriptorType 36
bDescriptorSubtype 1 (INPUT_HEADER)
bNumFormats 1
wTotalLength 0x0055
bEndpointAddress 0x81 EP 1 IN
bmInfo 0
bTerminalLink 2
bStillCaptureMethod 0
bTriggerSupport 0
bTriggerUsage 0
bControlSize 1
bmaControls( 0) 0
VideoStreaming Interface Descriptor:
bLength 27
bDescriptorType 36
bDescriptorSubtype 4 (FORMAT_UNCOMPRESSED)
bFormatIndex 1
bNumFrameDescriptors 1
guidFormat {32595559-0000-0010-8000-00aa00389b71}
bBitsPerPixel 16
bDefaultFrameIndex 1
bAspectRatioX 0
bAspectRatioY 0
bmInterlaceFlags 0x00
Interlaced stream or variable: No
Fields per frame: 2 fields
Field 1 first: No
Field pattern: Field 1 only
bCopyProtect 0
VideoStreaming Interface Descriptor:
bLength 38
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 1
bmCapabilities 0x00
Still image unsupported
wWidth 160
wHeight 120
dwMinBitRate 307200
dwMaxBitRate 7680000
dwMaxVideoFrameBufferSize 307200
dwDefaultFrameInterval 400000
bFrameIntervalType 0
dwMinFrameInterval 400000
dwMaxFrameInterval 10000000
dwFrameIntervalStep 400000
VideoStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 13 (COLORFORMAT)
bColorPrimaries 1 (BT.709,sRGB)
bTransferCharacteristics 1 (BT.709)
bMatrixCoefficients 4 (SMPTE 170M (BT.601))
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Device Status: 0x0000
(Bus Powered)

USB Transfer Types

Desc Interrupt Transfers Isochronous Transfers Bulk Transfers
Benefits High-reliability data transfers with a fixed response time High bandwidth High reliability with the potential for high bandwidth
Drawback Bandwidth may be limited (64 KBytes for Full-Speed USB) No CRC hardware. If a CRC is needed it must be done in software. Long packets can limit the number of devices being enumerated. Bandwidth may vary depending upon the number of interrupt endpoints enumerated and the activity of enumerated Isochronous endpoints.
Typical Use Mice, Keyboards, and Medical Devices Audio/Video streaming, serial port emulation Mass Storage and Printers
Notes Up to 90 percent of the frame can be allocated for Interrupt endpoints.The maximum length of the transfer depends upon the frame size used. Up to 90 percent of the frame can be allocated for interrupt endpoints. When not in use the bandwidth used will be released. The maximum length of the transfer depends upon the frame size used. Will take advantage of unused Isochronous bandwidth.The maximum length of the transfer depends upon the frame size used.

Linux USB手抓包分析

1
2
3
4
5
~$ lsmod | grep "usbmon"
usbmon 40960 0
usbcore 389120 12 ftdi_sio,usbserial,xhci_hcd,usbmon,usbhid,cdc_acm,usb_storage,uvcvideo,btusb,xhci_pci,uas,hid_logitech_hidpp
usb_common 16384 4 xhci_hcd,usbmon,usbcore,uvcvideo

  • 这里测试需要监听的要目标设备,是TinyUSB的设备,在Bus 3, Device 90,
1
2
~$  lsusb  | grep "TinyUSB"
Bus 003 Device 090: ID cafe:4020 TinyUSB TinyUSB Device
  • 打开wireshark, 选择usbmon3开始抓包。如下图所示,这里抓到的是错误码的UVC的包。

usbmon-capture-by-wireshark.png

  • 下面示例抓取一个正常的UVC的协议包。在Bus 3, Device 91,
1
2
~$ lsusb | grep "EM-Camera"
Bus 003 Device 091: ID 1e4e:0110 Cubeternet USB 2.0 EM-Camera2 5M

usbmon-capture-by-wireshark-uvc_ok.png

UVC相关

CC1101

联系作者

Arduino支持

ESP32-CAM

ESP8266

安装esp-idf设置编译环境

  • 安装系统依赖库
1
~$ apt-get install dfu-util cmake ninja-build -y
  • 安装esp-idf源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
~$ git clone https://github.com/espressif/esp-idf
~$ cd esp-idf
~$ git submodule update --init --recursive
~$ ./install.sh
~$ source export.sh
esp-idf$ source export.sh
Setting IDF_PATH to '/fullpath//github/espressif/esp-idf'
Detecting the Python interpreter
Checking "python3" ...
Python 3.11.3
"python3" has been detected
Checking Python compatibility
Checking other ESP-IDF version.
ERROR: tool xtensa-esp-elf-gdb has no installed versions. Please run '/home/michael/.pyenv/versions/3.11.3/bin/python3 /fullpath//github/espressif/esp-idf/tools/idf_tools.py install' to install it.
ERROR: tool riscv32-esp-elf-gdb has no installed versions. Please run '/home/michael/.pyenv/versions/3.11.3/bin/python3 /fullpath//github/espressif/esp-idf/tools/idf_tools.py install' to install it.
ERROR: tool xtensa-esp-elf has no installed versions. Please run '/home/michael/.pyenv/versions/3.11.3/bin/python3 /fullpath//github/espressif/esp-idf/tools/idf_tools.py install' to install it.
ERROR: tool riscv32-esp-elf has no installed versions. Please run '/home/michael/.pyenv/versions/3.11.3/bin/python3 /fullpath//github/espressif/esp-idf/tools/idf_tools.py install' to install it.
ERROR: tool esp32ulp-elf has no installed versions. Please run '/home/michael/.pyenv/versions/3.11.3/bin/python3 /fullpath//github/espressif/esp-idf/tools/idf_tools.py install' to install it.
ERROR: tool openocd-esp32 has no installed versions. Please run '/home/michael/.pyenv/versions/3.11.3/bin/python3 /fullpath//github/espressif/esp-idf/tools/idf_tools.py install' to install it.
An unsupported version of tool openocd-esp32 was found in PATH: unknown. To use it, run '/home/michael/.pyenv/versions/3.11.3/bin/python3 /fullpath//github/espressif/esp-idf/tools/idf_tools.py export --prefer-system'
ERROR: tool esp-rom-elfs has no installed versions. Please run '/home/michael/.pyenv/versions/3.11.3/bin/python3 /fullpath//github/espressif/esp-idf/tools/idf_tools.py install' to install it.
  • maunal run it again
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
~$ /home/michael/.pyenv/versions/3.11.3/bin/python3 /fullpath//github/espressif/esp-idf/tools/idf_tools.py install

Updating /home/michael/.espressif/idf-env.json
Selected targets are: esp32c6, esp32c2, esp32p4, esp32, esp32s3, esp32h2, esp32c3, esp32s2
Current system platform: linux-amd64
Installing tools: xtensa-esp-elf-gdb, riscv32-esp-elf-gdb, xtensa-esp-elf, riscv32-esp-elf, esp32ulp-elf, openocd-esp32, esp-rom-elfs
Installing xtensa-esp-elf-gdb@12.1_20221002
Downloading https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/xtensa-esp-elf-gdb-12.1_20221002-x86_64-linux-gnu.tar.gz
Destination: /home/michael/.espressif/dist/xtensa-esp-elf-gdb-12.1_20221002-x86_64-linux-gnu.tar.gz.tmp
Done
Extracting /home/michael/.espressif/dist/xtensa-esp-elf-gdb-12.1_20221002-x86_64-linux-gnu.tar.gz to /home/michael/.espressif/tools/xtensa-esp-elf-gdb/12.1_20221002
Installing riscv32-esp-elf-gdb@12.1_20221002
Downloading https://github.com/espressif/binutils-gdb/releases/download/esp-gdb-v12.1_20221002/riscv32-esp-elf-gdb-12.1_20221002-x86_64-linux-gnu.tar.gz
Destination: /home/michael/.espressif/dist/riscv32-esp-elf-gdb-12.1_20221002-x86_64-linux-gnu.tar.gz.tmp
Done
Extracting /home/michael/.espressif/dist/riscv32-esp-elf-gdb-12.1_20221002-x86_64-linux-gnu.tar.gz to /home/michael/.espressif/tools/riscv32-esp-elf-gdb/12.1_20221002
Installing xtensa-esp-elf@esp-13.2.0_20230928
Downloading https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20230928/xtensa-esp-elf-13.2.0_20230928-x86_64-linux-gnu.tar.xz
Destination: /home/michael/.espressif/dist/xtensa-esp-elf-13.2.0_20230928-x86_64-linux-gnu.tar.xz.tmp
Done
Extracting /home/michael/.espressif/dist/xtensa-esp-elf-13.2.0_20230928-x86_64-linux-gnu.tar.xz to /home/michael/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20230928
Installing riscv32-esp-elf@esp-13.2.0_20230928
Downloading https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20230928/riscv32-esp-elf-13.2.0_20230928-x86_64-linux-gnu.tar.xz
Destination: /home/michael/.espressif/dist/riscv32-esp-elf-13.2.0_20230928-x86_64-linux-gnu.tar.xz.tmp
Done
Extracting /home/michael/.espressif/dist/riscv32-esp-elf-13.2.0_20230928-x86_64-linux-gnu.tar.xz to /home/michael/.espressif/tools/riscv32-esp-elf/esp-13.2.0_20230928
Installing esp32ulp-elf@2.35_20220830
Downloading https://github.com/espressif/binutils-gdb/releases/download/esp32ulp-elf-v2.35_20220830/esp32ulp-elf-2.35_20220830-linux-amd64.tar.gz
Destination: /home/michael/.espressif/dist/esp32ulp-elf-2.35_20220830-linux-amd64.tar.gz.tmp
Done
Extracting /home/michael/.espressif/dist/esp32ulp-elf-2.35_20220830-linux-amd64.tar.gz to /home/michael/.espressif/tools/esp32ulp-elf/2.35_20220830
Installing openocd-esp32@v0.12.0-esp32-20230921
Downloading https://github.com/espressif/openocd-esp32/releases/download/v0.12.0-esp32-20230921/openocd-esp32-linux-amd64-0.12.0-esp32-20230921.tar.gz
Destination: /home/michael/.espressif/dist/openocd-esp32-linux-amd64-0.12.0-esp32-20230921.tar.gz.tmp
Done
Extracting /home/michael/.espressif/dist/openocd-esp32-linux-amd64-0.12.0-esp32-20230921.tar.gz to /home/michael/.espressif/tools/openocd-esp32/v0.12.0-esp32-20230921
Installing esp-rom-elfs@20230320
Downloading https://github.com/espressif/esp-rom-elfs/releases/download/20230320/esp-rom-elfs-20230320.tar.gz
Destination: /home/michael/.espressif/dist/esp-rom-elfs-20230320.tar.gz.tmp
Done
Extracting /home/michael/.espressif/dist/esp-rom-elfs-20230320.tar.gz to /home/michael/.espressif/tools/esp-rom-elfs/20230320

  • 提示错误
1
2
3
~ esp-idf$ source export.sh
ERROR: /home/michael/.espressif/python_env/idf5.2_py3.11_env/bin/python doesn't exist! Please run the install script or "idf_tools.py install-python-env" in order to create it

1
2
~ esp-idf$ idf_tools.py install-python-env
~ esp-idf$ ls ~/.espressif/python_env/idf5.2_py3.11_env/bin/

HelTec WiFi_LoRa_32_V3

缺少依赖库报错

RadioLib

1
2
3
4
 #include <RadioLib.h>
^~~~~~~~~~~~
compilation terminated.
*** [.pio/build/heltec_wifi_lora_32/src/src/Radio/Radio.o] Error 1
  • 安装RadioLib by Jan Gromes,在PIO Home -> Libraries -> Registry选择合适的版本,Add to Project. 详情描述如下:
1
2
RadioLib by Jan Gromeš
Universal wireless communication library. User-friendly library for sub-GHz radio modules (SX1278, RF69, CC1101, SX1268, and many others), as well as ham radio digital modes (RTTY, SSTV, AX.25 etc.).

NTPClient

1
2
3
4
5
6
7
8
   #warning "God mode active, I hope it was intentional. Buckle up, lads."
^~~~~~~
In file included from /fullpath//github/tinyGS/tinyGS/tinyGS.ino:79:
lib/ESPNtpClient/src/ESPNtpClient.h:29:10: fatal error: include/time.h: No such file or directory
#include "include/time.h"
^~~~~~~~~~~~~~~~
compilation terminated.
*** [.pio/build/heltec_wifi_lora_32/src/tinyGS.ino.cpp.o] Error 1
  • 去掉头文件里的#include "include/time.h".

Error: Unknown board ID ‘heltec_wifi_lora_32_V3’

  • 需要更新平台的库文件
1
~$ pio pkg update -g -p espressif32

ESP32-WROOM-32U

安装esp-idf开发环境

  • 这里按官方文档把它clone在用户目录下。这里示例只安装支持esp32所需要的环境支持。
1
2
3
4
5
~$ cd $HOME/
~$ git clone https://github.com/espressif/esp-idf
~$ cd esp-idf
~$ git submodule update --init --recursive
~$ ./install.sh esp32
  • 添加一个别名命令,用来加载esp-idf的开发环境。
1
~$ echo "alias get_idf='. $HOME/esp-idf/export.sh'" >> ~/.bashrc

编译安装示例工程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
~$ cd esp-idf/examples/zigbee/esp_zigbee_gateway
~ esp-idf/examples/zigbee/esp_zigbee_gateway$ get_idf
~ esp-idf/examples/zigbee/esp_zigbee_gateway$ idf.py set-target esp32
dding "set-target"'s dependency "fullclean" to list of commands with default set of options.
Executing action: fullclean
Build directory '/fullpath//github/espressif/esp-idf/examples/zigbee/esp_zigbee_gateway/build' not found. Nothing to clean.
Executing action: set-target
Set Target to: esp32, new sdkconfig will be created.
Running cmake in directory /fullpath//github/espressif/esp-idf/examples/zigbee/esp_zigbee_gateway/build
Executing "cmake -G Ninja -DPYTHON_DEPS_CHECKED=1 -DPYTHON=/home/michael/.espressif/python_env/idf5.2_py3.11_env/bin/python -DESP_PLATFORM=1 -DIDF_TARGET=esp32 -DCCACHE_ENABLE=0 /fullpath//github/espressif/esp-idf/examples/zigbee/esp_zigbee_gateway"...
-- Found Git: /bin/git (found version "2.39.2")
-- The C compiler identification is GNU 13.2.0
-- The CXX compiler identification is GNU 13.2.0
-- The ASM compiler identification is GNU
-- Found assembler: /home/michael/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /home/michael/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /home/michael/.espressif/tools/xtensa-esp-elf/esp-13.2.0_20230928/xtensa-esp-elf/bin/xtensa-esp32-elf-g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Building ESP-IDF components for target esp32
Dependencies lock doesn't exist, solving dependencies.
Using component placed at /fullpath//github/espressif/esp-idf/examples/common_components/protocol_examples_common for dependency protocol_examples_common(*), specified in /fullpath//github/espressif/esp-idf/examples/zigbee/esp_zigbee_gateway/main/idf_component.yml
.....Updating lock file at /fullpath//github/espressif/esp-idf/examples/zigbee/esp_zigbee_gateway/dependencies.lock
Processing 4 dependencies:
[1/4] espressif/esp-zboss-lib (0.7.2)
[2/4] espressif/esp-zigbee-lib (0.9.5)
[3/4] idf (5.2.0)
[4/4] protocol_examples_common (*)
[....]
  • 菜单配置,会出现一个TUI(Text-based user interface)的配置菜单,与u-boot,buildroot,kernel所用的配置是一样的。
1
~ esp-idf/examples/zigbee/esp_zigbee_gateway$ idf.py menuconfig
  • 编译工程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
esp-idf/examples/zigbee/esp_zigbee_gateway$ idf.py build
Executing action: all (aliases: build)
Running ninja in directory /fullpath/github/espressif/esp-idf/examples/zigbee/esp_zigbee_gateway/build
Executing "ninja all"...
[0/1] Re-running CMake...
-- Building ESP-IDF components for target esp32
Processing 4 dependencies:
[4/4] protocol_examples_common (*)
-- Project sdkconfig file /fullpath/github/espressif/esp-idf/examples/zigbee/esp_zigbee_gateway/sdkconfig
Loading defaults file /fullpath/github/espressif/esp-idf/examples/zigbee/esp_zigbee_gateway/sdkconfig.defaults...
-- Compiler supported targets: xtensa-esp-elf
-- App "esp_zigbee_gateway" version: v5.2-dev-3775-gb4268c874a
-- Adding linker script /fullpath/github/espressif/esp-idf/examples/zigbee/esp_zigbee_gateway/build/esp-idf/esp_system/ld/memory.ld
-- Adding linker script /fullpath/github/espressif/esp-idf/components/esp_system/ld/esp32/sections.ld.in
-- Adding linker script /fullpath/github/espressif/esp-idf/components/esp_rom/esp32/ld/esp32.rom.ld
-- Adding linker script /fullpath/github/espressif/esp-idf/components/esp_rom/esp32/ld/esp32.rom.api.ld
-- Adding linker script /fullpath/github/espressif/esp-idf/components/esp_rom/esp32/ld/esp32.rom.libgcc.ld
-- Adding linker script /fullpath/github/espressif/esp-idf/components/esp_rom/esp32/ld/esp32.rom.newlib-data.ld
-- Adding linker script /fullpath/github/espressif/esp-idf/components/esp_rom/esp32/ld/esp32.rom.syscalls.ld
-- Adding linker script /fullpath/github/espressif/esp-idf/components/esp_rom/esp32/ld/esp32.rom.newlib-funcs.ld
-- Adding linker script /fullpath/github/espressif/esp-idf/components/soc/esp32/ld/esp32.peripherals.ld
[...]
[19/917] Generating ../../partition_table/partition-table.bin
Partition table binary generated. Contents:
*******************************************************************************
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs,data,nvs,0x9000,24K,
phy_init,data,phy,0xf000,4K,
factory,app,factory,0x10000,1150K,
zb_storage,data,fat,0x130000,16K,
zb_fct,data,fat,0x134000,1K,
*******************************************************************************
[...]
Project build complete. To flash, run:
idf.py flash
or
idf.py -p PORT flash
or
python -m esptool --chip esp32 -b 460800 --before default_reset --after hard_reset write_flash --flash_mode dio --flash_size 2MB --flash_freq 40m 0x1000 build/bootloader/bootloader.bin 0x8000 build/partition_table/partition-table.bin 0x10000 build/esp_zigbee_gateway.bin
or from the "/fullpath/github/espressif/esp-idf/examples/zigbee/esp_zigbee_gateway/build" directory
python -m esptool --chip esp32 -b 460800 --before default_reset --after hard_reset write_flash "@flash_args"

  • 烧写工程到目标板子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
~ esp-idf/examples/zigbee/esp_zigbee_gateway$ idf flash
idf.py flash
Executing action: flash
Serial port /dev/ttyUSB1
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting....
Detecting chip type... ESP32
Running ninja in directory /fullpath/github/espressif/esp-idf/examples/zigbee/esp_zigbee_gateway/build
Executing "ninja flash"...
[1/5] cd /fullpath/github/espressif/esp-idf/examples/zigbee/esp_zigbee_gateway/build/esp-idf/esptool_...in /fullpath/github/espressif/esp-idf/examples/zigbee/esp_zigbee_gateway/build/esp_zigbee_gateway.bin
esp_zigbee_gateway.bin binary size 0xfd270 bytes. Smallest app partition is 0x11f800 bytes. 0x22590 bytes (12%) free.
[1/1] cd /fullpath/github/espressif/esp-idf/examples/zigbee/esp_zigbee_gateway/build/bootloader/esp-i.../fullpath/github/espressif/esp-idf/examples/zigbee/esp_zigbee_gateway/build/bootloader/bootloader.bin
Bootloader binary size 0x6810 bytes. 0x7f0 bytes (7%) free.
[4/5] cd /fullpath/github/espressif/esp-idf/components/esptool_py && /usr/bin/cmake -D IDF_PATH=/home...igbee_gateway/build -P /fullpath/github/espressif/esp-idf/components/esptool_py/run_serial_tool.cmake
esptool.py --chip esp32 -p /dev/ttyUSB1 -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 2MB 0x1000 bootloader/bootloader.bin 0x10000 esp_zigbee_gateway.bin 0x8000 partition_table/partition-table.bin
esptool.py v4.7.dev2
Serial port /dev/ttyUSB1
Connecting....
Chip is ESP32-D0WDQ6-V3 (revision v3.0)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 78:21:84:9c:16:a0
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Flash will be erased from 0x00001000 to 0x00007fff...
Flash will be erased from 0x00010000 to 0x0010dfff...
Flash will be erased from 0x00008000 to 0x00008fff...
Compressed 26640 bytes to 16335...
Writing at 0x00001000... (100 %)
Wrote 26640 bytes (16335 compressed) at 0x00001000 in 0.7 seconds (effective 313.8 kbit/s)...
Hash of data verified.
Compressed 1036912 bytes to 664903...
Writing at 0x00109d51... (100 %)
Wrote 1036912 bytes (664903 compressed) at 0x00010000 in 15.2 seconds (effective 546.5 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 137...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (137 compressed) at 0x00008000 in 0.1 seconds (effective 310.6 kbit/s)...
Hash of data verified.

Leaving...lsus
Hard resetting via RTS pin...
Done

  • 通过串口查看设备详情
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
esp-idf/examples/zigbee/esp_zigbee_gateway$ idf.py -p /dev/ttyUSB1 monitor
Executing action: monitor
Running idf_monitor in directory /fullpath/github/espressif/esp-idf/examples/zigbee/esp_zigbee_gateway
Executing "/home/michael/.espressif/python_env/idf5.2_py3.11_env/bin/python /fullpath/github/espressif/esp-idf/tools/idf_monitor.py -p /dev/ttyUSB1 -b 115200 --toolchain-prefix xtensa-esp32-elf- --target esp32 --revision 0 /fullpath/github/espressif/esp-idf/examples/zigbee/esp_zigbee_gateway/build/esp_zigbee_gateway.elf -m '/home/michael/.espressif/python_env/idf5.2_py3.11_env/bin/python' '/fullpath/github/espressif/esp-idf/tools/idf.py' '-p' '/dev/ttyUSB1'"...
--- esp-idf-monitor 1.3.3 on /dev/ttyUSB1 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
a72d4...
ts Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:7140
load:0x40078000,len:15500
load:0x40080400,len:4
0x40080400: _init at ??:?

load:0x40080404,len:3904
entry 0x40080640
I (29) boot: ESP-IDF v5.2-dev-3775-gb4268c874a 2nd stage bootloader
I (29) boot: compile time Nov 1 2023 15:52:14
I (31) boot: Multicore bootloader
I (35) boot: chip revision: v3.0
I (39) boot.esp32: SPI Speed : 40MHz
I (44) boot.esp32: SPI Mode : DIO
I (48) boot.esp32: SPI Flash Size : 2MB
I (53) boot: Enabling RNG early entropy source...
I (58) boot: Partition Table:
I (62) boot: ## Label Usage Type ST Offset Length
I (69) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (76) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (84) boot: 2 factory factory app 00 00 00010000 0011f800
I (91) boot: 3 zb_storage Unknown data 01 81 00130000 00004000
I (99) boot: 4 zb_fct Unknown data 01 81 00134000 00000400
[....]

TFT_eSPI测试ILI9341 2.8inch LCD

  • 测试SPI接口屏,打开~/Arduino/libraries/TFT_eSPI/User_Setups/Setup42_ILI9341_ESP32.h,定义连接如下:
1
2
3
4
5
6
7
8
9

#define ILI9341_DRIVER

#define TFT_MISO 21 // (leave TFT SDO disconnected if other SPI devices share MISO)
#define TFT_MOSI 19
#define TFT_SCLK 18
#define TFT_CS 15 // Chip select control pin
#define TFT_DC 2 // Data Command control pin
#define TFT_RST 4 // Reset pin (could connect to RST pin)
  • 再打开~/Arduino/libraries/TFT_eSPI/User_Setups/User_Setup_Select.h,只打开上面这一个文件的注释。
1
2
3
[...]
#include <User_Setups/Setup42_ILI9341_ESP32.h>
[...]
  • Arduino IDE内选择:DOIT ESP32 DEVKIT Board V1. Tools -> Boards -> ESP32 Arduino -> DOIT ESP32 DEVKIT Board V1.

lv_port_esp32测试ILI9341 2.8inch LCD

  • lv_port_esp32长时间没有更新了,目前只支持ESP-IDF 4.x,LVGL 7.x
1
2
3
git clone --recurse-submodules https://github.com/lvgl/lv_port_esp32.git
cd lv_port_esp32 && idf.py menuconfig

  • 通过menuconfig -> Component config -> LVGL TFT Display controller -> Display Pin Assignments 配置管脚如下:
1
2
3
4
5
6
7
8
9
10
(23) GPIO for MOSI (Master Out Slave In)
[ ] GPIO for MISO (Master In Slave Out)
(18) GPIO for CLK (SCK / Serial Clock)
[*] Use CS signal to control the display
(5) GPIO for CS (Slave Select)
[*] Use DC signal to control the display
(2) GPIO for DC (Data / Command)
(4) GPIO for Reset
[ ] Enable control of the display backlight by using an GPIO.

  • 上面是使用了板子VSPI定义管脚。在menuconfig -> Component config -> lv_example_configuration里,可以配置测试的参数。

错误

  • 通过串口发现,不断重复输出如下的信息,烧写其它程序后也是如此。经排查后发现,GPIO12连接到某个外设上面,导致的结果。先断开GPIO12的连接,再烧写其它的程序,就能正常使用了。
1
2
3
4
5
6
7
8
9
10
rst:0x10 (RTCWDT_RTC_RESET),boot:0x33 (SPI_FAST_FLASH_BOOT)
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
ets Jul 29 2019 12:21:46
[...]
  • 编译缺少组件,可以把缺少的组使用git submodule add方式下载到IDF的目录下,也可以使用idf.py add-dependency "xxxx"方式加入到本工程依赖库里。
1
2
3
4
5
6
7
8
9
[1/1] idf (4.4.6)
CMake Error at ~/espressif/esp-idf-v4.4.6/tools/cmake/build.cmake:201 (message):
Failed to resolve component 'lvgl'.
Call Stack (most recent call first):
~/espressif/esp-idf-v4.4.6/tools/cmake/build.cmake:241 (__build_resolve_and_add_req)
~/espressif/esp-idf-v4.4.6/tools/cmake/build.cmake:518 (__build_expand_requirements)
~/espressif/esp-idf-v4.4.6/tools/cmake/project.cmake:476 (idf_build_process)
CMakeLists.txt:6 (project)

CC1101测试

esp-hosted使用

esp-camera

1
2
3
4
5
6
I (472) cam_hal: Allocating 153600 Byte frame buffer in PSRAM
E (479) cam_hal: cam_dma_config(300): frame buffer malloc failed
E (485) cam_hal: cam_config(384): cam_dma_config failed
E (491) camera: Camera config failed with error 0xffffffff
E (497) example:take_picture: Camera Init Failed
I (502) main_task: Returned from app_main()

谢谢支持

  • 微信二维码:

连接工具

OpenSK

nRF52-U2F

1
git clone --recursive https://github.com/makerdiary/nrf52-u2f

直接下载官方固件

U2F-bootloader

1

编程烧写工具

编译固件

  • 安装rustup
1
2
~$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
~$ source $HOME/.cargo/env
  • 安装nrfutil
1
~$ pip3 install nrfutil
  • 安装OpenSK.
1
2
3
4
~$ git clone --recurse-submodules https://github.com/google/OpenSK.git
~$ cd OpenSK
~$ git switch -c develop origin/develop
~$ ./setup.sh
  • 烧写之前,要确保nrfutil是可以正常使用的。先要按设备上的reset键,进入DFU bootloader模式,在按Enter确认进行烧写.不知为何在OpenSK/stable分支上没有测试成功。这里使用了develop分支测试成功。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
OpenSK$ ./deploy.py --board=nrf52840_dongle_dfu --opensk --programmer=nordicdfu
info: Updating rust toolchain to nightly-2020-06-10
info: syncing channel updates for 'nightly-2020-06-10-x86_64-unknown-linux-gnu'
info: checking for self-updates
info: component 'rust-std' for target 'thumbv7em-none-eabi' is up to date
info: Rust toolchain up-to-date
info: Building Tock OS for board nrf52840_dongle_dfu
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: The currently active `rustc` version is `rustc 1.45.0-nightly (fe10f1a49 2020-06-02)`
Finished release [optimized + debuginfo] target(s) in 0.01s
info: Building OpenSK application
Finished release [optimized] target(s) in 0.02s
info: Generating Tock TAB file for application/example ctap2
info: Generating all-merged HEX file: target/nrf52840_dongle_dfu_merged.hex
info: Creating DFU package
info: Please insert the dongle and switch it to DFU mode by keeping the button pressed while inserting...
info: Press [ENTER] when ready.
info: Flashing device using DFU...
[####################################] 100%
Device programmed.
info: Programming OpenSK device AAGUID fdecda13-0c04-4463-82c4-43f425871f2f (CtapHidDevice('/dev/hidraw4')).
info: Certificate: Missing
info: Private Key: Missing
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 26.69it/s]
info: Your device is not yet configured, and lacks some functionality. If you run into issues, this command might help:

./tools/configure.py \
--certificate=crypto_data/opensk_cert.pem \
--private-key=crypto_data/opensk.key

Please read the Certificate considerations in docs/customization.md to understand the privacy trade-off.
  • 如果上面烧写操作后,不能正常工作,先把运行下面的命令,再重复一次,上面的烧写命令。
1
2
./deploy.py --board=nrf52840_dongle_dfu --programmer=nordicdfu --erase_storage

  • 烧写错误
1
2
3
4
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
manifest-tool 1.5.2 requires colorama<0.4.0,>=0.3.9, but you have colorama 0.4.5 which is incompatible.
manifest-tool 1.5.2 requires protobuf<3.6.0,>=3.5.0, but you have protobuf 3.20.1 which is incompatible.

  • 出现上述错误,需要使用PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python来处理protobuf.

在线网站测试

  • https://webauthn.io/
  • 这里使用Firefox打开上述网站,随意输入一个用户名,再点击Regster,浏览器会弹出提示窗口,并且板上的LD1,LD2出现交替闪烁,表示需要按SW1进行下一步.这里按下SW1后,网站会提示注册成功.
  • 网站登录测试,点击界面上的Login后,浏览器会弹出提示窗口,并且板上的LD1,LD2出现交替闪烁,此时按下板上的SW1,网站会提示登录成功。

使用U2F登录OpenSSH服务

1
2
3
4
5
6
7
8
9
~$ cat ~/.ssh/config
[...]
Host vps
Hostname YOUR_SERVER_IP
User root
Port YOUR_SSH_PORT
Compression yes
IdentityFile ~/.ssh/id_ecdsa_sk

谢谢支持

  • 微信二维码:

NFC概述[摘自维基]

  • 近距离无线通信(英语:Near-field communication,NFC),又简称近距离通信或近场通信,是一套通信协议,让两个电子设备(其中一个通常是移动设备,例如智能手机)在相距几厘米之内进行通信.NFC,如同过去的电子票券智能卡一般,将允许移动支付取代或支持这类系统.NFC应用于社交网络,分享联系方式,照片,视频或文件.具备 NFC 功能的设备可以充当电子身份证和钥匙卡.NFC 提供了设置简便的低速连接,也可用于引导能力更强的无线连接.
  • 近场通信技术由非接触式射频识别(RFID)演变而来,由飞利浦半导体(现恩智浦半导体 NXP)’诺基亚和索尼共同于2004年研制开发[4],其基础是RFID及互连技术.近场通信是一种短距高频的无线电技术,在13.56MHz频率运行于20厘米距离内.其传输速度有106 Kbit/秒,212 Kbit/秒或者424 Kbit/秒三种.目前近场通信已通过成为ISO/IEC IS 18092国际标准,EMCA-340标准与ETSI TS 102 190标准.NFC采用主动和被动两种读取模式.
  • 每一个完整的NFC设备可以用三种模式工作:
    • 卡模拟模式(Card emulation mode):这个模式其实就是相当于一张采用RFID技术的IC卡.可以替代现在大量的IC卡(包括信用卡)场合商场刷卡,IPASS,门禁管制,车票,门票等等.此种方式下,有一个极大的优点,那就是卡片通过非接触读卡器的RF域来供电,即便是寄主设备(如手机)没电也可以工作.NFC设备若要进行卡片模拟(Card Emulation)相关应用,则必须内置安全组件(Security Element, SE)之NFC芯片或通过软件实现主机卡模拟(Host Card Emulation,HCE).
    • 读卡器模式(Reader/Writer mode):作为非接触读卡器使用,比如从海报或者展览信息电子标签上读取相关信息.
    • 点对点模式(P2P mode):这个模式和红外线差不多,可用于数据交换,只是传输距离较短,传输创建速度较快,传输速度也快些,功耗低(蓝牙也类似).将两个具备NFC功能的设备链接,能实现数据点对点传输,如下载音乐,交换图片或者同步设备地址薄.因此通过NFC,多个设备如数位相机,PDA,计算机和手机之间都可以交换资料或者服务.

与藍牙的比较

  • NFC和蓝牙都是短距离通信技术,而且都被集成到移动电话.但NFC不需要复杂的设置程序.NFC也可以简化蓝牙连接.
  • NFC略胜蓝牙的地方在于设置程序较短,但无法达到低功率蓝牙(Bluetooth Low Energy)的传输速率.在两台NFC设备相互连接的设备识别过程中,使用NFC来替代人工设置会使创建连接的速度大大加快:少于十分之一秒.NFC的最大资料传输量424 kbit/s远小于Bluetooth V2.1(2.1 Mbit/s).虽然NFC在传输速度与距离比不上蓝牙(小于20 cm),但相应可以减少不必要的干扰.这让NFC特别适用于设备密集而传输变得困难的时候.
  • 相对于蓝牙,NFC兼容于现有的被动RFID(13.56 MHz ISO/IEC 18000-3)设施.NFC的能量需求更低,与蓝牙V4.0低功耗协议类似.当NFC在一台无供电的设备(比如一台关机的手机,非接触式智能信用卡,或是智能海报)上工作时,NFC的能量消耗会要大于低功率蓝牙V4.0.
  • 对于移动电话或是行动消费性电子产品来说,NFC的使用比较方便.NFC的短距离通信特性正是其优点,由于耗电量低,一次只和一台机器链接,拥有较高的保密性与安全性,NFC有利于信用卡交易时避免被盗用.NFC的目标并非是取代蓝牙等其他无线技术,而是在不同的场合,不同的领域起到相互补充的作用.

Linux连接使用

1
~$ sudo apt-get install libnfc-bin libnfc-examples mfoc mfcuk
  • 这里是直接使用uart来连接,只要一个USB-TTL连接到电脑就要可以,修改/etc/nfc/libnfc.conf成如下内容:
1
2
3
4
5
6
7
~$ grep  '=' /etc/nfc/libnfc.conf
#allow_autoscan = true
#allow_intrusive_scan = false
#log_level = 1
#device.name = "microBuilder.eu"
device.connstring = "pn532_uart:/dev/ttyUSB0"

  • 如下图所示,连接UART后,并且通过板上的拨码开关设置成HSV模式.

PN532_nfc.jpg

1
2
3
4
5
6
  USB-TTL      PN532

3.3vVCC <-----> VCC
GND <-----> GND
RX <-----> TX
TX <-----> RX
  • 列出所有的NFC列表,如果LIBNFC_LOG_LEVEL=3会有更加丰富的信息输出.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
~$ LIBNFC_LOG_LEVEL=1 nfc-list -v
nfc-list uses libnfc 1.8.0
NFC device: opened
0 ISO14443A passive target(s) found.

0 Felica (212 kbps) passive target(s) found.

0 Felica (424 kbps) passive target(s) found.

0 ISO14443B passive target(s) found.

0 ISO14443B passive target(s) found.

0 ISO14443B-2 ST SRx passive target(s) found.

0 ISO14443B-2 ASK CTx passive target(s) found.

0 ISO14443B iClass passive target(s) found.

0 ISO14443A-3 Jewel passive target(s) found.

0 ISO14443A-2 NFC Barcode passive target(s) found.

  • 直接放上一张卡,读取它的基本信息.如下面所示,这张卡的UID370656b3.
1
2
3
4
5
6
7
8
~$ nfc-list
nfc-list uses libnfc 1.8.0
NFC device: opened
1 ISO14443A passive target(s) found:
ISO/IEC 14443A (106 kbps) target:
ATQA (SENS_RES): 00 04
UID (NFCID1): 37 06 56 b3
SAK (SEL_RES): 08
  • 再读一张
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
~$ ~$ nfc-list -v
nfc-list uses libnfc 1.8.0
NFC device: opened
1 ISO14443A passive target(s) found:
ISO/IEC 14443A (106 kbps) target:
ATQA (SENS_RES): 00 04
* UID size: single
* bit frame anticollision supported
UID (NFCID1): 0f b7 85 32
SAK (SEL_RES): 28
* Compliant with ISO/IEC 14443-4
* Not compliant with ISO/IEC 18092
ATS: 77 33 a0 02 22 30 00 01 01
* Max Frame Size accepted by PICC: 128 bytes
* Bit Rate Capability:
* PICC to PCD, DS=2, bitrate 212 kbits/s supported
* PICC to PCD, DS=4, bitrate 424 kbits/s supported
* PCD to PICC, DR=2, bitrate 212 kbits/s supported
* PCD to PICC, DR=4, bitrate 424 kbits/s supported
* Frame Waiting Time: 309.3 ms
* No Start-up Frame Guard Time required
* Node Address not supported
* Card IDentifier supported
* Historical bytes Tk: 22 30 00 01 01
* Proprietary format

Fingerprinting based on MIFARE type Identification Procedure:
* SmartMX with MIFARE 1K emulation
Other possible matches based on ATQA & SAK values:
* JCOP31 v2.3.1


  • 这是一张NXPSmartMX系列的卡片,同时附带MIFARE Classic 1K模拟.SmartMXNXPJCOP卡系列,也就是说这张卡是一种CPU卡(也有叫做Java卡).CPU卡意味着卡中有一个完整功能的CPU,并且带有操作系统,卡片的功能是基于软件实现的,而不是像MIFAREClassic这种基于ASIC的卡,用硬件电路实现卡片功能.这种类型的卡相比较MifareClassic类型的卡要安全的多,几乎不可能被破解和复制.

相关源码编译

1

树莓派

手机应用

NRF52840

ESP32

烧写工具

谢谢支持

  • 微信二维码:

Lattice ECP5ECP5-5G系列FPGA简介

  • ECP5是属于Lattice公司里的高端产品线,ECP5 FPGA器件提供低成本,低功耗,小尺寸的解决方案,用于实现大批量应用中的连接,视频和图像功能,如小型蜂窝网络,工业摄像头和宽带接入设备。
    • 特點:
      • 新型应用中FPGAASICASSP相结合,
      • 快速构建灵活的系统,可以满足严格的成本,功耗和尺寸限制。
      • 在开发ECP5TM FPGA系列的过程中,莱迪思打破了FPGA产品密度极高,功耗惊人和价格昂贵的陈规。
      • ECP5ECP5-5G针对低成本,小封装尺寸和低功耗进行了优化,
      • 比竞争对手的FPGA产品成本更低,使用更好的布线架构,双通道SERDES以及增强的DSP模块,减少高达4倍的乘法器资源使用,这些特性使得ECP5器件非常适用于辅助ASIC和ASSP的可编程连接解决方案。
    • 用途:
      • ECP5/ECP5- 5g设备系列FPGA包括可查找表(LUT)容量为85K的逻辑元件,支持最多365个用户I/O。
      • 同时还提供多达156个18x18乘法器和广泛的并行I/O标准。
      • ECP5/ECP5- 5g FPGA在低功耗,低成本的前提下进行了高性能的优化。
      • 利用可重新配置的SRAM逻辑技术,提供lutb的逻辑,分布式和嵌入式内存,锁相环(PLLs),延迟锁相环(DLLs),预先设计的源同步I/O支持,增强的sysDSP片和高级配置支持,包括加密和双启动功能。
      • 支持广泛的接口标准,包括DDR2/3,LPDDR2/3,XGMII和7:1 LVDS

开源工具

  • 开发FPGA,从verilog到可以烧录的bitstream有以下几步:

    • Synthesis:一般叫合成,把verilogRTL生成为逻辑门。
    • Place and Route:布线,依照逻辑门的的数量限制,生成逻辑的连线。
    • Bitstream Creation:將逻辑门的连线,依照对应的FPGA型号生成可烧写的bitstream的文件。
  • 开源Verilog逻辑综合(Synthesis)工具Yosys,可以用于LatticeXilinxFPGAClifford Wolf创建了FPGA的整条开源工具链:

    • YosysHQ/yosys:用来将verilog RTL综合生成网表文件
    • YosysHQ/nextpnr: 根据网表文件和约束文件进行布局布线
    • YosysHQ/prjtrellis:针对Lattice ECP5 FPGA架构信息库和完整生成bitstream的烧写文件。
    • icestorm:针对Lattice iCE40 FPGA架构信息库和完整生成bitstream工具链组合,依靠反向工程创建出来的。
  • 上面三个开源工具链被SymbiFlow收入整合了。也可以用YosysHQ/oss-cad-suite-build去做开发环境的构建。

SymbiFlow

  • ECP5_FPGA

  • SymbiFlow is a fully open source toolchain for the development of FPGAs of multiple vendors. Currently, it targets the Xilinx 7-Series, Lattice iCE40, Lattice ECP5 FPGAs, QuickLogic EOS S3 and is gradually being expanded to provide a comprehensive end-to-end FPGA synthesis flow.

  • SymbiFlow相当于是FPGAs开源界的GCC工具。

构建环境

prjtrellis

1
2
3
4
5
~$ git clone --recursive https://github.com/YosysHQ/prjtrellis
~$ export LATTICE_TOOLS_PATH=~/Lattice-OpenTools
~$ cd libtrellis
~$ cmake -DCMAKE_INSTALL_PREFIX=$LATTICE_TOOLS_PATH .
~$ make install
  • 如果出现python3开发版本不匹配的错误,可以参照下面修改到合适的版本。删除CMakeCache.txt,重新运行cmake生成配置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
prjtrellis/libtrellis$ rm CMakeCache.txt
prjtrellis/libtrellis$ git diff CMakeLists.txt
diff --git a/libtrellis/CMakeLists.txt b/libtrellis/CMakeLists.txt
index 540368e..868bd2b 100644
--- a/libtrellis/CMakeLists.txt
+++ b/libtrellis/CMakeLists.txt
@@ -49,10 +49,10 @@ else()
add_definitions(-DNO_THREADS)
endif()
set(Boost_NO_BOOST_CMAKE ON)
-find_package(PythonInterp 3.5 REQUIRED)
+find_package(PythonInterp 3.9 REQUIRED)

if (BUILD_PYTHON)
- find_package(PythonLibs 3.5 REQUIRED)
+ find_package(PythonLibs 3.9 REQUIRED)
set(PythonInstallTarget "pytrellis")
endif()

nextpnr

  • 我现在手上只有ECP5 Evaluation Board,这只选择编译-DARCH=ecp5,具体更多的参数,查看源码脚本。
    1
    2
    3
    ~$ git clone --recursive https://github.com/YosysHQ/nextpnr
    ~$ cmake . -DARCH=ecp5 -DTRELLIS_INSTALL_PREFIX=$LATTICE_TOOLS_PATH -DCMAKE_INSTALL_PREFIX=$LATTICE_TOOLS_PATH
    ~$ make install

Yosys

  • 安装编译工具与其它依赖,命令文档指南.注意别与apt-get install yosys混用了,旧版的yosys会报错ERROR: Found netlist using legacy-style JSON parameter values, please update your Yosys.

    1
    2
    3
    4
    ~$ sudo apt-get install build-essential clang bison flex \
    libreadline-dev gawk tcl-dev libffi-dev git \
    graphviz xdot pkg-config python3 libboost-system-dev \
    libboost-python-dev libboost-filesystem-dev zlib1g-dev libjson11-1-dev
  • 编码编译,安装目录与前面的工具一样,默认使用clang,可以传送参数变量CONFIG=gcc,用gcc来编译。

    1
    2
    3
    4
    ~$ git clone https://github.com/YosysHQ/yosys
    ~$ cd yosys && mkdir build
    ~$ cd build
    ~$ PREFIX=$LATTICE_TOOLS_PATH make -j20 -f ../Makefile install
  • 因为系统安装了qflow它会依赖安装一个较旧的发行版,最终还是使用了最新源码去覆盖旧的发行版。

1
~$ PREFIX=/usr sudo make -j20 -f ../Makefile install

openFPGALoader

编译openFPGALoader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
~$ apt-get install libftdi1-2 libftdi1-dev libudev-dev cmake  # 这装必要的支持库
~$ git clone https://github.com/trabucayre/openFPGALoader

~$ cd openFPGALoader
~$ sudo cp 99-openfpgaloader.rules /etc/udev/rules.d/
~$ sudo udevadm control --reload-rules && udevadm trigger # 强制重新加载rules
~$ mkdir build && cd build
build$ cmake -DCMAKE_INSTALL_PREFIX=$LATTICE_TOOLS_PATH ../
-- The CXX compiler identification is GNU 10.2.1
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.2")
-- Checking for module 'libftdi1'
-- Found libftdi1, version 1.5
-- Checking for module 'libusb-1.0'
-- Found libusb-1.0, version 1.0.24
-- Checking for module 'hidapi-hidraw'
-- Found hidapi-hidraw, version 0.10.1
-- Checking for module 'zlib'
-- Found zlib, version 1.2.11
-- Checking for module 'libudev'
-- Found libudev, version 247
cmsis_dap support enabled
-- Configuring done
-- Generating done
-- Build files have been written to: /home/michael/openTools-For-Lattice/openFPGALoader/build
~$ make && make install
[...]
Install the project...
-- Install configuration: ""
-- Installing: /home/michael/Lattice-OpenTools/bin/openFPGALoader
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/test_sfl.svf
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/spiOverJtag_xc6slx100fgg484.bit
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/spiOverJtag_xc6slx45csg324.bit
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/spiOverJtag_xc7a100tfgg484.bit
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/spiOverJtag_xc7a200tsbg484.bit
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/spiOverJtag_xc7a35tcpg236.bit
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/spiOverJtag_xc7a35tcsg324.bit
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/spiOverJtag_xc7a35tftg256.bit
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/spiOverJtag_xc7a50tcpg236.bit
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/spiOverJtag_xc7a75tfgg484.bit
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/spiOverJtag_10cl025256.rbf
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/spiOverJtag_5ce223.rbf
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/spiOverJtag_ep4ce2217.rbf
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/spiOverJtag_5ce423.rbf.gz
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/spiOverJtag_ep4ce1523.rbf.gz
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/spiOverJtag_xc7a100tcsg324.bit.gz
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/spiOverJtag_xc7s25csga324.bit.gz
-- Installing: /home/michael/Lattice-OpenTools/share/openFPGALoader/spiOverJtag_xc7s50csga324.bit.gz

1
2
3
~$ openFPGALoader --list-boards
~$ openFPGALoader --list-fpga
~$ openFPGALoader --list-cables

测试编译示例

编译

1
2
3
4
5
6
7
~$ cd prjtrellis/examples/ecp5_evn
~$ make
[....]
2.51. Executing JSON backend.
ERROR: Module top contains processes, which are not supported by JSON backend (run `proc` first).
make: *** [Makefile:7: blinky.json] Error 1
rm blinky.json
  • 默认编译显示上面的错误,找到错误行,显示:yosys -p "synth_ecp5 -json $@" $<.按照理论上来,我安装的是最新版本的yosys版本,不应该出现这样的错误。这种写法是省掉的读取verilog的参数,完整的命令行写法,如下:

    1
    ~$ yosys -p "read_verilog blink.v; read_verilog rst_gen.v; synth_ecp5 -json main.json"
  • 这里需要修改Makefile,修改成如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    prjtrellis/examples/ecp5_evn$ git diff
    diff --git a/examples/ecp5_evn/Makefile b/examples/ecp5_evn/Makefile
    index 40622b0..02f0d9d 100644
    --- a/examples/ecp5_evn/Makefile
    +++ b/examples/ecp5_evn/Makefile
    @@ -4,7 +4,7 @@ TRELLIS?=/usr/share/trellis
    all: ${PROJ}.bit

    %.json: %.v
    - yosys -p "synth_ecp5 -json $@" $<
    + yosys -p "read_verilog -sv $<" -p "synth_ecp5 -json $@" $<

    %_out.config: %.json
    nextpnr-ecp5 --json $< --textcfg $@ --um5g-85k --package CABGA381 --lpf ecp5evn.lpf

    ~$ make
    [...]
    Info: Program finished normally.
    ecppack --svf blinky.svf blinky_out.config blinky.bit
    rm blinky.json blinky_out.config

烧写到板上的RAM

  • openFPGALoader默认是加载到FPGA的内存里的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ~$ openFPGALoader -b ecp5_evn blinky.bit
    write to ram
    Jtag frequency : requested 6.00MHz -> real 6.00MHz
    Open file: DONE
    Parse file: DONE
    Enable configuration: DONE
    SRAM erase: DONE
    Loading: [==================================================] 100.00%
    Done
    Disable configuration: DONE
  • 烧写成功后,就能看到板上的流水灯的效果。

  • 这里也可以使用一个外部的JTAG烧写。比如使用一个独立的FTDI 2232HL连接到板上的J1 JTAG,再把JP1跳线安装上,就可以下载调试了。

1
2
3
4
5
6
7
8
9
10
11
~$ openFPGALoader -d /dev/ttyUSB1 --detect
write to ram
Jtag frequency : requested 6.00MHz -> real 6.00MHz
index 0:
idcode 0x1113043
manufacturer lattice
family ECP5
model LFE5U-85
irlength 8

~$ openFPGALoader -d /dev/ttyUSB1 -b ecp5_evn blinky.bit

烧写到SPI Flash

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
prjtrellis/examples/ecp5_evn_multiboot$ openFPGALoader -b ecp5_evn -f blinky1.bit
write to flash
Jtag frequency : requested 6.00MHz -> real 6.00MHz
Open file DONE
Parse file DONE
Enable configuration: DONE
SRAM erase: DONE
Detail:
Jedec ID : c2
memory type : 20
memory capacity : 18
EDID + CFD length : c2
EDID : 1820
CFD :
flash chip unknown: use basic protection detection
Erasing: [==================================================] 100.00%
Done
Writing: [==================================================] 100.00%
Done
Refresh: DONE
  • 烧写flash的时间会略长一些。每次上电启动,都是从spi flash加载程序来运行。如果烧写的是openFPGALoader -b ecp5_evn -f multiboot.bin,可以通过板上的PGMN SW3按键来切换从不同的flash位置加载启动。

RISC-V

VexRiscv

运行linux-on-litex-vexriscv

  • 这里可以接合参照我写的另一篇文章XILINX_Arty-A7-35T实践指南去实践。要先编译安装riscv toolchains.

  • 编译工程

    1
    ~$ ./make.py --board ecpix5 --toolchain=symbiflow --build
  • 加载工程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
~$ ./make.py --board ecpix5 --load
[....]
python3 -m litex.soc.software.mkmscimg bios.bin --little
python3 -m litex.soc.software.memusage bios.elf /home/michael/workspace-xilinx/RISC-V/litex-hub/litex/linux-on-litex-vexriscv/build/ecpix5/software/bios/../include/generated/regions.ld riscv64-unknown-elf

ROM usage: 39.21KiB (61.27%)
RAM usage: 0.61KiB (7.62%)

make: Leaving directory '/home/michael/workspace-xilinx/RISC-V/litex-hub/litex/linux-on-litex-vexriscv/build/ecpix5/software/bios'
INFO:SoC:Initializing ROM rom with contents (Size: 0x9cf4).
INFO:SoC:Auto-Resizing ROM rom from 0x10000 to 0x9cf4.
write to ram
Jtag frequency : requested 6.00MHz -> real 6.00MHz
Open file: DONE
Parse file: DONE
Enable configuration: DONE
SRAM erase: DONE
Loading: [==================================================] 100.00%
Done
Disable configuration: DONE

直接运行litex-boards

  • 编译工程

    1
    ~$ litex-boards/litex_boards$ ./targets/lattice_ecp5_evn.py --cpu-type vexriscv --sys-clk-freq 100e6 --build
  • 加载工程

    1
    2
    ~$ litex-boards/litex_boards$ ./targets/lattice_ecp5_evn.py --cpu-type vexriscv --sys-clk-freq 100e6 --load

  • 更换连接uart的管脚配置,把原板上的FTDI P2,P3换成M19,M20,因为P2,P3有复用到其它功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
litex-boards/litex_boards$ git diff platforms/lattice_ecp5_evn.py
diff --git a/litex_boards/platforms/lattice_ecp5_evn.py b/litex_boards/platforms/lattice_ecp5_evn.py
index 1a96862..7892dc0 100644
--- a/litex_boards/platforms/lattice_ecp5_evn.py
+++ b/litex_boards/platforms/lattice_ecp5_evn.py
@@ -48,8 +48,8 @@ _io = [

# Serial
("serial", 0,
- Subsignal("rx", Pins("P2"), IOStandard("LVCMOS33")),
- Subsignal("tx", Pins("P3"), IOStandard("LVCMOS33")),
+ Subsignal("rx", Pins("M19"), IOStandard("LVCMOS33")),
+ Subsignal("tx", Pins("M20"), IOStandard("LVCMOS33")),
),

# SPIFlash

  • 连接成功后如下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
litex>
__ _ __ _ __
/ / (_) /____ | |/_/
/ /__/ / __/ -_)> <
/____/_/\__/\__/_/|_|
Build your hardware, easily!

(c) Copyright 2012-2022 Enjoy-Digital
(c) Copyright 2007-2015 M-Labs

BIOS built on Feb 26 2022 23:37:36
BIOS CRC passed (23ff10b6)

Migen git sha1: ac70301
LiteX git sha1: 7f49c523

--=============== SoC ==================--
CPU: VexRiscv @ 100MHz
BUS: WISHBONE 32-bit @ 4GiB
CSR: 32-bit data
ROM: 128KiB
SRAM: 8KiB


--============== Boot ==================--
Booting from serial...
Press Q or ESC to abort boot completely.
sL5DdSMmkekro
Timeout
No boot medium found

--============= Console ================--


通过SDCard Boot加载linux系统

其它

谢谢支持

  • 微信二维码:

简介

Vivado安装

RISC-V

LiteX框架

  • litex/wiki
  • The LiteX framework provides a convenient and efficient infrastructure to create FPGA Cores/SoCs, to explore various digital design architectures and create full FPGA based systems.

Xc3sprog

  • xc3sprog是一套实用程序套件,用于使用Xilinx并行电缆和其他JTAG适配器对Xilinx FPGA,CPLDEEPROM进行编程

OpenSBI

  • riscv-software-src/opensbi
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    ~$ git clone https://github.com/litex-hub/opensbi
    ~$ cd opensbi
    ~$ make PLATFORM_RISCV_XLEN=32 PLATFORM_RISCV_ABI=ilp32 CROSS_COMPILE=riscv32-unknown-elf- PLATFORM=litex/vexriscv
    ~$ tree build/platform/litex/vexriscv/
    build/platform/litex/vexriscv/
    ├── firmware
    │   ├── fw_dynamic.bin
    │   ├── fw_dynamic.dep
    │   ├── fw_dynamic.elf
    │   ├── fw_dynamic.elf.ld
    │   ├── fw_dynamic.o
    │   ├── fw_jump.bin
    │   ├── fw_jump.dep
    │   ├── fw_jump.elf
    │   ├── fw_jump.elf.ld
    │   ├── fw_jump.o
    │   ├── fw_payload.bin
    │   ├── fw_payload.dep
    │   ├── fw_payload.elf
    │   ├── fw_payload.elf.ld
    │   ├── fw_payload.o
    │   └── payloads
    │   ├── test.bin
    │   ├── test.dep
    │   ├── test.elf
    │   ├── test.elf.ld
    │   ├── test_head.dep
    │   ├── test_head.o
    │   ├── test_main.dep
    │   ├── test_main.o
    │   └── test.o
    ├── lib
    │   └── libplatsbi.a
    ├── litex.dep
    ├── litex.o
    ├── platform.dep
    └── platform.o

LibreSOC

自编译工具链(riscv64-unknown-elf-gcc)

  • riscv-gnu-toolchain
  • building-a-pure-rv32i-toolchain
  • SiFive提供二进制的工具链,但是需要注册帐号才能下载,而且注册帐号和邮箱,还必须是公司或者是大学的.或者就下载使用开源的版本sifive/freedom-tools/releases.还有可以从Hex Five下载.这里还是自已去下载源码编译出来.这里GCC编译环境就算是配置好,下面提据源码文档指导,完成工具链的编译.编译过程中它会去网上下载组件,第一次编译时间会比较长.
1
~$ git clone https://github.com/riscv/riscv-gnu-toolchain
  • 支持32位newlib,--host=riscv32-unknown-elf-

    1
    2
    3
    ~$ ./configure --prefix=/home/michael/riscv-toolchain  --with-multilib-generator="rv32imac-ilp32--f*c" \
    --with-abi=ilp32 --with-arch=rv32imc
    ~$ make
  • 支持64位newlib,--host=riscv64-unknown-elf-

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    ~$ ./configure --prefix=/home/michael/riscv64-toolchain  --with-multilib-generator="rv32imac-ilp32--f*c" \
    --enable-multilib --target=riscv64-multilib-elf
    ~$ make

    ~$ ~/riscv64-toolchain/bin/riscv64-unknown-elf-gcc -v
    Using built-in specs.
    COLLECT_GCC=/home/michael/riscv64-toolchain/bin/riscv64-unknown-elf-gcc
    COLLECT_LTO_WRAPPER=/home/michael/riscv64-toolchain/libexec/gcc/riscv64-unknown-elf/11.1.0/lto-wrapper
    Target: riscv64-unknown-elf
    Configured with: /home/michael/3TB-DISK/github/risc-v/riscv-gnu-toolchain/riscv-gcc/configure --target=riscv64-unknown-elf --prefix=/home/michael/riscv64-toolchain --disable-shared --disable-threads --enable-languages=c,c++ --with-system-zlib --enable-tls --with-newlib --with-sysroot=/home/michael/riscv64-toolchain/riscv64-unknown-elf --with-native-system-header-dir=/include --disable-libmudflap --disable-libssp --disable-libquadmath --disable-libgomp --disable-nls --disable-tm-clone-registry --src=.././riscv-gcc --enable-multilib --with-multilib-generator='rv32imac-ilp32--f*c' --with-abi=lp64d --with-arch=rv64imafdc --with-tune=rocket 'CFLAGS_FOR_TARGET=-Os -mcmodel=medlow' 'CXXFLAGS_FOR_TARGET=-Os -mcmodel=medlow'
    Thread model: single
    Supported LTO compression algorithms: zlib zstd
    gcc version 11.1.0 (GCC)

  • 支持64位linux,--host=riscv64-unknown-linux-gnu-

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    ~$ ./configure --prefix=/home/michael/riscv64-toolchain  --with-multilib-generator="rv32imac-ilp32--f*c"   -enable-multilib --target=riscv64-linux-multilib

    ~$ make linux

    ~$ ~/riscv64-toolchain/bin/riscv64-unknown-linux-gnu-gcc -v
    Using built-in specs.
    COLLECT_GCC=/home/michael/riscv64-toolchain/bin/riscv64-unknown-linux-gnu-gcc
    COLLECT_LTO_WRAPPER=/home/michael/riscv64-toolchain/libexec/gcc/riscv64-unknown-linux-gnu/11.1.0/lto-wrapper
    Target: riscv64-unknown-linux-gnu
    Configured with: /home/michael/3TB-DISK/github/risc-v/riscv-gnu-toolchain/riscv-gcc/configure --target=riscv64-unknown-linux-gnu --prefix=/home/michael/riscv64-toolchain --with-sysroot=/home/michael/riscv64-toolchain/sysroot --with-system-zlib --enable-shared --enable-tls --enable-languages=c,c++,fortran --disable-libmudflap --disable-libssp --disable-libquadmath --disable-libsanitizer --disable-nls --disable-bootstrap --src=.././riscv-gcc --enable-multilib --with-abi=lp64d --with-arch=rv64imafdc --with-tune=rocket 'CFLAGS_FOR_TARGET=-O2 -mcmodel=medlow' 'CXXFLAGS_FOR_TARGET=-O2 -mcmodel=medlow'
    Thread model: posix
    Supported LTO compression algorithms: zlib zstd
    gcc version 11.1.0 (GCC)

  • 上面命令编译完成后,它会自动安装到prefix目录下.因为这边的PC系统就是x86_64的,所以就选择--enable-multilib --target=riscv64-multilib-elf,启用multilib就可通过传送-march=rv32来支持生成32位版的程序.

  • 查看它支持的目标架构信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    ~$ riscv64-unknown-elf-gcc -Q --help=target
    The following options are target specific:
    -mabi= lp64d
    -malign-data= xlen
    -march= rv64imafdc
    -mbig-endian [disabled]
    -mbranch-cost=N 3
    -mcmodel= medlow
    -mcpu=PROCESSOR
    -mdiv [enabled]
    -mexplicit-relocs [enabled]
    -mfdiv [enabled]
    -misa-spec= 2.2
    -mlittle-endian [enabled]
    -mplt [enabled]
    -mpreferred-stack-boundary= 0
    -mrelax [enabled]
    -mriscv-attribute [enabled]
    -msave-restore [disabled]
    -mshorten-memrefs [enabled]
    -msmall-data-limit=N 8
    -mstack-protector-guard-offset=
    -mstack-protector-guard-reg=
    -mstack-protector-guard= global
    -mstrict-align [enabled]
    -mtune=PROCESSOR rocket

    Supported ABIs (for use with the -mabi= option):
    ilp32 ilp32d ilp32e ilp32f lp64 lp64d lp64f

    Known code models (for use with the -mcmodel= option):
    medany medlow

    Supported ISA specs (for use with the -misa-spec= option):
    2.2 20190608 20191213

    Known data alignment choices (for use with the -malign-data= option):
    natural xlen

    Valid arguments to -mstack-protector-guard=:
    global tls

SiFive Freedom

下载开源工具链

1
2
~$ wget -c https://static.dev.sifive.com/dev-tools/freedom-tools/v2020.12/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz
~$ wget -c https://static.dev.sifive.com/dev-tools/freedom-tools/v2020.12/riscv-openocd-0.10.0-2020.12.1-x86_64-linux-ubuntu14.tar.gz

编译Freedom

  • freedom这个项目已经进入归档状态,没有更新与维护了,按它的说明文档还是可以编译的.
1
2
3
4
~$ git clone --recursive https://github.com/sifive/freedom
~$ cd freedom
~$ git submodule sync
~$ git submodule update --recursive --init
  • 指定工具链的位置变量(RISCV)并编译verilogmcs.这里如果是使用Arty-A7-100T的板子,要设定成BOARD=arty_a7_100.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    ~$ export RISCV=/fullpath/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14
    ~$ export PATH=/fullpath/Xilinx/Vivado/2021.1/bin:$PATH
    ~$ make BOARD=arty -f Makefile.e300artydevkit clean
    ~$ make BOARD=arty -f Makefile.e300artydevkit verilog
    ~$ make BOARD=arty -f Makefile.e300artydevkit mcs
    [...]
    Writing file /home/michael/workspace-xilinx/RISC-V/freedom/builds/e300artydevkit/obj/E300ArtyDevKitFPGAChip.mcs
    Writing log file /home/michael/workspace-xilinx/RISC-V/freedom/builds/e300artydevkit/obj/E300ArtyDevKitFPGAChip.prm
    ===================================
    Configuration Memory information
    ===================================
    File Format MCS
    Interface SPIX4
    Size 16M
    Start Address 0x00000000
    End Address 0x00FFFFFF

    Addr1 Addr2 Date File(s)
    0x00000000 0x0021728B Oct 31 16:43:46 2021 /home/michael/workspace-xilinx/RISC-V/freedom/builds/e300artydevkit/obj/E300ArtyDevKitFPGAChip.bit
    0 Infos, 0 Warnings, 0 Critical Warnings and 0 Errors encountered.
    write_cfgmem completed successfully
    INFO: [Common 17-206] Exiting Vivado at Sun Oct 31 16:44:16 2021...
  • 下载开发板配置文件(board_files)到Vivado目录下,如下面所示,因为我这里的板子是REV E版本,也就是最新版,所以选择new目录下的配置.
    1
    2
    ~$ git clone https://github.com/Digilent/vivado-boards.git
    ~$ cp -r vivado-boards/new/board_files ~/Xilinx/Vivado/2021.1/data/boards

烧写FPGAmcs镜像

  • 连接板子的J10 USB接口:
    • 打开Vivado 2021 > Tasks > Open Hardware Manager,点击Hardware下面的Auto Connect图标,连接设备.
    • 显示:localhost(1) > xilinx_tcf/Digilent/21031xxxxxxx(1) > xc7a35t_0(1).
    • xc7a35t_0(1)点击右键,选择Add Configuration Memory Device ....
    • 这里会一个选择内存的窗口例表,对应自已的板上型号去选择,因为这里是REV E的版本,所以实际用的是s25fl128sxxxxxx0-spi-x1_x2_x4,厂商是Spansion的.
  • 添加完成内存,就会弹出一个Program Configuration Memorg Device的窗口,在Configuration File里选择编译出来的mcs文件,位置在freedom/builds/e300artydevkit/obj/E300ArtyDevKitFPGAChip.mcs下,按完成进行烧写.成功后,按板上的PROG加载到FPGA运行.

Freedom-E-SDK(应用软件)示例

1
2
3
~$ git clone https://github.com/sifive/freedom-e-sdk.git
~$ git submodule sync
~$ git submodule update --recursive --init
  • 这里需要设置两个环境变量:RISCV_PATH,RISCV_OPENOCD_PATH,脚本里写的与sifive/freedom不一样.
    1
    2
    3
    4
    5
    6
    ~$ export RISCV_PATH=/fullpath/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14
    ~$ export RISCV_OPENOCD_PATH=/fullpath/riscv-openocd-0.10.0-2020.12.1-x86_64-linux-ubuntu14

    ~$ make BSP=metal PROGRAM=hello TARGET=freedom-e310-arty clean
    ~$ make BSP=metal PROGRAM=hello TARGET=freedom-e310-arty software

  • 注意,工程默认设置OpenOCD配置文件支持Olimex OpenOCD JTAG ARM-USB-TINY-H调试器的,而我这边手上只有一个FTDI 232H的设备,所以要做一些配置的修改,这里是使用interface/ftdi/um232h.cfg的配置.对照Freedom E310 Arty FPGA Dev Kit Getting Started GuideDS_FT232H.pdf两边的接口文档,以及interface/ftdi/um232h.cfg里的描述,连接如下:
1
2
3
4
5
6
7
8
9
10
11
12
Arty-A7-35T JD Header                   FT232H

TDO (Pin 1) <-----------> TDO AD2
nTRST (Pin 2) <-----------> TRST AC0
TCK (Pin 3) <-----------> TCK AD0
GND (Pin 5) <-----------> GND GND
VREF (Pin 6) <-----------> 3.3V 3.3V
TDI (Pin 7) <-----------> TDI AD1
TMS (Pin 8) <-----------> TMS AD3
nRST (Pin 9) <-----------> TMS AC1
GND (Pin 11) <-----------> GND GND
VREF (Pin 12) <-----------> 3.3V 3.3V
  • 再修改freedom-e-sdk/bsp/freedom-e310-arty/openocd.cfg文件,把olimex-arm-usb-tiny-h.cfg换成um232h.cfg,也可以应用下面的补丁.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
diff --git a/bsp/freedom-e310-arty/openocd.cfg b/bsp/freedom-e310-arty/openocd.cfg
index 8ab6ff6..3529100 100644
--- a/bsp/freedom-e310-arty/openocd.cfg
+++ b/bsp/freedom-e310-arty/openocd.cfg
@@ -19,7 +19,8 @@ set debug_config "${protocol}_${connection}"
switch ${debug_config} {
jtag_probe {
echo "Using JTAG"
- source [find interface/ftdi/olimex-arm-usb-tiny-h.cfg]
+ #source [find interface/ftdi/olimex-arm-usb-tiny-h.cfg]
+ source [find interface/ftdi/um232h.cfg]
set chain_length 5
}
cjtag_probe {
@@ -69,4 +70,4 @@ halt

flash protect 0 64 last off

-echo "Ready for Remote Connections"
\ No newline at end of file
+echo "Ready for Remote Connections"

  • 烧写测试应用程序,先按板子上的PROG键,确保FPGA跑起来,再upload,如果,无法通过JTAG烧入应用,该板子无任何输出的.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    ~$ make BSP=metal PROGRAM=hello TARGET=freedom-e310-arty upload
    [....]
    For bug reports:
    https://github.com/sifive/freedom-tools/issues
    DEPRECATED! use 'adapter speed' not 'adapter_khz'
    Using JTAG
    Info : auto-selecting first available session transport "jtag".To override use 'transport select <transport>'.
    Info : ftdi: if you experience problems at higher adapter clocks, try the command "ftdi_tdo_sample_edge falling"
    Info : clock speed 10000 kHz
    Info : JTAG tap: riscv.cpu tap/device found: 0x20000913 (mfg: 0x489 (SiFive Inc), part: 0x0000, ver: 0x2)
    Info : datacount=1 progbufsize=16
    Info : Disabling abstract command reads from CSRs.
    Info : Examined RISC-V core; found 1 harts
    Info : hart 0: XLEN=32, misa=0x40001105
    Info : starting gdb server for riscv.cpu on 3333
    Info : Listening on port 3333 for gdb connections
    Info : Found flash device 'sp s25fl128s' (ID 0x00182001)
    Ready for Remote Connections
    Info : Listening on port 6666 for tcl connections
    Info : Listening on port 4444 for telnet connections
    Info : accepting 'gdb' connection on tcp/3333
    metal_shutdown (code=0) at /home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/freedom-metal/src/shutdown.c:19
    19 __asm__ volatile("nop");
    Info : JTAG tap: riscv.cpu tap/device found: 0x20000913 (mfg: 0x489 (SiFive Inc), part: 0x0000, ver: 0x2)
    JTAG tap: riscv.cpu tap/device found: 0x20000913 (mfg: 0x489 (SiFive Inc), part: 0x0000, ver: 0x2)
    cleared protection for sectors 64 through 255 on flash bank 0

    cleared protection for sectors 64 through 255 on flash bank 0

    Info : Disabling abstract command writes to CSRs.

    Thread 1 (Remote target):
    Info : JTAG tap: riscv.cpu tap/device found: 0x20000913 (mfg: 0x489 (SiFive Inc), part: 0x0000, ver: 0x2)
    Loading section .init, size 0x2c2 lma 0x20400000
    Loading section .init_array, size 0x4 lma 0x204002c8
    Loading section .ctors, size 0x24 lma 0x204002cc
    Loading section .rodata, size 0x33c lma 0x204002f0
    Loading section .text, size 0x4c80 lma 0x20400680
    Loading section .data, size 0x780 lma 0x20405300
    Info : Padding image section 0 at 0x204002c2 with 6 bytes
    Info : Padding image section 1 at 0x2040062c with 84 bytes
    Info : JTAG tap: riscv.cpu tap/device found: 0x20000913 (mfg: 0x489 (SiFive Inc), part: 0x0000, ver: 0x2)
    Start address 0x20400000, load size 23078
    Transfer rate: 43 KB/sec, 3296 bytes/write.
    shutdown command invoked
    shutdown command invoked
    A debugging session is active.

    Inferior 1 [Remote target] will be detached.

    Quit anyway? (y or n) [answered Y; input not from terminal]
    Remote connection closed

  • 如上面所示,烧写应用成功,电脑上会有一个/dev/ttyUSB2的串口,连接后,每按一次PROG或者RESET键,会打印一次Hello, World!.

    1
    2
    3
    4
    5
    6
    7
    8
    ~$ sudo minicom -o -b 57600 -D /dev/ttyUSB2
    OPTIONS: I18n
    Port /dev/ttyUSB2, 21:07:42

    Press CTRL-A Z for help on special keys

    Hello, World!
    Hello, World!

使用QEMU模拟运行

  • 我这边系统里已经编译好了qemu最新版,并且支持了riscv32-softmmu,riscv64-softmmu.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    ~$ qemu-system-riscv32 -cpu help
    any
    lowrisc-ibex
    rv32
    sifive-e31
    sifive-e34
    sifive-u34

    ~$ qemu-system-riscv32 -machine help
    Supported machines are:
    none empty machine
    opentitan RISC-V Board compatible with OpenTitan
    sifive_e RISC-V Board compatible with SiFive E SDK
    sifive_u RISC-V Board compatible with SiFive U SDK
    spike RISC-V Spike board (default)
    virt RISC-V VirtIO board
  • 编译软件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    ~$ make PROGRAM=hello TARGET=qemu-sifive-e31 CONFIGURATION=debug software
    [...........]
    ./home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/venv/bin/activate && scripts/ldscript-generator/generate_ldscript.py -d /home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/bsp/qemu-sifive-e31/design.dts -o /home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/bsp/qemu-sifive-e31/metal.default.lds
    Generating linker script with default layout
    Using layout:
    rom: 0x20400000-0x3fffffff (/soc/spi@10014000)
    ram: 0x80000000-0x803fffff (/soc/dtim@80000000)
    RAM memories:
    dtim_0: 0x80000000-0x00400000
    Consolidated RAM memories:
    dtim_0: 0x80000000-0x00010000
    mkdir -p /home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/software/hello/debug/
    make -C /home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/software/hello hello \
    PORT_DIR= \
    PROGRAM=hello \
    AR=/home/michael/riscv64-toolchain/bin/riscv64-unknown-elf-ar \
    CC=/home/michael/riscv64-toolchain/bin/riscv64-unknown-elf-gcc \
    CXX=/home/michael/riscv64-toolchain/bin/riscv64-unknown-elf-g++ \
    ASFLAGS="-march=rv32imac -mabi=ilp32 -mcmodel=medlow --specs=nano.specs -O0 -g" \
    CCASFLAGS="-march=rv32imac -mabi=ilp32 -mcmodel=medlow -I/home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/bsp/qemu-sifive-e31/install/include --specs=nano.specs" \
    CFLAGS="-march=rv32imac -mabi=ilp32 -mcmodel=medlow -ffunction-sections -fdata-sections -I/home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/bsp/qemu-sifive-e31/install/include --specs=nano.specs -DMTIME_RATE_HZ_DEF=10000000 -O0 -g" \
    CXXFLAGS="-march=rv32imac -mabi=ilp32 -mcmodel=medlow -ffunction-sections -fdata-sections -I/home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/bsp/qemu-sifive-e31/install/include --specs=nano.specs -DMTIME_RATE_HZ_DEF=10000000 -O0 -g" \
    XCFLAGS="-DMETAL_WAIT_CYCLE=0" \
    LDFLAGS="-Wl,--gc-sections -Wl,-Map,hello.map -nostartfiles -nostdlib -L/home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/bsp/qemu-sifive-e31/install/lib/debug/ -T/home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/bsp/qemu-sifive-e31/metal.default.lds" \
    LDLIBS="-Wl,--start-group -lc -lgcc -lm -lmetal -lmetal-gloss -Wl,--end-group" \
    FREERTOS_METAL_VENV_PATH="/home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/venv"
    make[1]: Entering directory '/home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/software/hello'
    /home/michael/riscv64-toolchain/bin/riscv64-unknown-elf-gcc -march=rv32imac -mabi=ilp32 -mcmodel=medlow -ffunction-sections -fdata-sections -I/home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/bsp/qemu-sifive-e31/install/include --specs=nano.specs -DMTIME_RATE_HZ_DEF=10000000 -O0 -g -Wl,--gc-sections -Wl,-Map,hello.map -nostartfiles -nostdlib -L/home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/bsp/qemu-sifive-e31/install/lib/debug/ -T/home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/bsp/qemu-sifive-e31/metal.default.lds hello.c -Wl,--start-group -lc -lgcc -lm -lmetal -lmetal-gloss -Wl,--end-group -o hello
    make[1]: Leaving directory '/home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/software/hello'
    mv /home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/software/hello/hello /home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/software/hello/debug/hello.elf
    mv /home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/software/hello/hello.map /home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/software/hello/debug/
    touch -c /home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/software/hello/debug/hello.elf
    /home/michael/riscv64-toolchain/bin/riscv64-unknown-elf-objdump --source --all-headers --demangle --line-numbers --wide /home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/software/hello/debug/hello.elf > /home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/software/hello/debug/hello.lst
    /home/michael/riscv64-toolchain/bin/riscv64-unknown-elf-size /home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/software/hello/debug/hello.elf
    text data bss dec hex filename
    26204 2004 3236 31444 7ad4 /home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/software/hello/debug/hello.elf
    /home/michael/riscv64-toolchain/bin/riscv64-unknown-elf-objcopy -O ihex /home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/software/hello/debug/hello.elf /home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/software/hello/debug/hello.hex
  • 模拟运行

    1
    2
    3
    4
    5
    ~$ make PROGRAM=hello TARGET=qemu-sifive-e31 CONFIGURATION=debug simulate
    scripts/simulate --elf /home/michael/workspace-xilinx/RISC-V/freedom-e-sdk/software/hello/debug/hello.elf --qemu qemu-system-riscv32 --qemu-config bsp/qemu-sifive-e31/qemu.cfg
    Launching QEMU! Press Ctrl-A, X to exit
    Hello, World!

Arduino环境测试开发

  • sifive/cinco
  • Arty-A7-35T板子上原本就带有兼容Arduino的接口,这里根据sifive/cinco指导,配置Arduino IDE支持一个名为SiFive Freedom Boards的板子,有两种方式:
    • 打开Arduino IDE > File > Perferences > Additional Boards Manaer URLs:,配置添加一行:http://static.dev.sifive.com/bsp/arduino/package_sifive_index.json ,完成.
    • 第二种手动克隆sifive/cincoArduino IDEhardware目录.Arduino IDE有两个位置hardware:
      • 一个是Arduino IDE安装自带的avr,位于arduin-1.x.xx/hardware,我一般不会把新增的硬件放入到这里.
      • 另一个就是用户目录下的:~/.arduino15/packages/*/hardware,如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ls ~/.arduino15/packages/*/hardware
/home/michael/.arduino15/packages/arduino/hardware:
avr megaavr sam samd samd_beta stm32f4

/home/michael/.arduino15/packages/atmel-avr-xminis/hardware:
avr

/home/michael/.arduino15/packages/ATTinyCore/hardware:
avr

/home/michael/.arduino15/packages/esp32/hardware:
esp32

/home/michael/.arduino15/packages/sifive/hardware:
riscv

/home/michael/.arduino15/packages/SparkFun/hardware:
avr

/home/michael/.arduino15/packages/STM32/hardware:
stm32
  • 打开Arduino IDE > Tools > Board: XXXX > Boards Manager ...管理界面,它会自动去更新板子数据库,更新完成.在上面输入:sifive,就会过滤SiFive Freedom Boards,现在最新的版本是1.0.2,安装它.
  • 安装完成后,本地用户目录下会有如下文件目录结构,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
~$ tree -L 4  ~/.arduino15/packages/sifive/
/home/michael/.arduino15/packages/sifive/
├── hardware
│   └── riscv
│   └── 1.0.2
│   ├── boards.txt
│   ├── cores
│   ├── freedom-e-sdk
│   ├── libraries
│   ├── platform.txt
│   ├── programmers.txt
│   ├── system
│   └── variants
└── tools
├── openocd
│   └── 9bab0782d313679bb0bfb634e6e87c757b8d5503
│   ├── bin
│   └── share
└── riscv32-unknown-elf-gcc
└── 3f7b3696217548bc31aeccf9a0c89bdfa4e16a8f
├── bin
├── include
├── lib
├── lib64
├── libexec
├── riscv32-unknown-elf
└── share

  • 它就是从网上下载安装了SiFive Freedom Boards所要用到的riscv32-unknown-elf-gcc的工具链,以及JTAG调试烧写的OpenOCD.同时打开Arduino IDE > Tools > Board: XXXX列表,会看到Freedom E300 Boards > Freedom E300 Arty DevKit.

Blink测试

  • 这里打开Arduino IDE > File > Examples > 01.Basics > Blink工程.并配置Arduino IDE > Tools下的连接参数如下:
    • Board: “Freedom E300 Arty DevKit”
    • CPU Clock Frequency: “65MHz FPGA Clock”
    • Tool Install Localtion: “Default”
    • Port: “/dev/ttyUSB2”
    • Programmer: “Manual SiFive OpenOCD”
  • 上面配置有两个要注意:
    • Tool Install Localtion: "Default"就是使用~/.arduino15/packages/sifive/tools/riscv32-unknown-elf-gcc下面的工具链进行编译,否则就是从$PATH变量里去要找riscv32-unknown-elf-gcc运行.
    • Programmer指定也是类似,我这里没有选SiFive OpenOCD,而是选择了Manual SiFive OpenOCD,意思就是从$PATH变量里去要找openocd运行.因为这里的openocd版本比较旧,且默认openocd.cfg是仅支持Olimex OpenOCD JTAG ARM-USB-TINY-H调试,这里需要把上面Freedom-E-SDK修改过的openocd.cfg复制到~/.arduino15/packages/sifive/hardware/riscv/1.0.2/freedom-e-sdk/bsp/env/freedom-e300-arty下.
    • 点击Arduino IDE工具栏的Upload编译并上传到板子上运行,日志如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/home/michael/.arduino15/packages/sifive/tools/riscv32-unknown-elf-gcc/3f7b3696217548bc31aeccf9a0c89bdfa4e16a8f/bin/riscv32-unknown-elf-g++ -T /home/michael/.arduino15/packages/sifive/hardware/riscv/1.0.2/freedom-e-sdk/bsp/env/freedom-e300-hifive1/link.lds -nostartfiles -Wl,-N -Wl,--gc-sections -Wl,--wrap=malloc -Wl,--wrap=free -Wl,--wrap=sbrk /tmp/arduino_build_232653/sketch/Blink.ino.cpp.o -nostdlib -Wl,--start-group /tmp/arduino_cache_428477/core/core_6ccdbc8b93e71222b4d531274eba2283.a -lm -lstdc++ -lc -lgloss -Wl,--end-group -lgcc -o /tmp/arduino_build_232653/Blink.ino.elf
/home/michael/.arduino15/packages/sifive/tools/riscv32-unknown-elf-gcc/3f7b3696217548bc31aeccf9a0c89bdfa4e16a8f/bin/riscv32-unknown-elf-objcopy -R .rel.dyn -O binary /tmp/arduino_build_232653/Blink.ino.elf /tmp/arduino_build_232653/Blink.ino.bin
/home/michael/.arduino15/packages/sifive/tools/riscv32-unknown-elf-gcc/3f7b3696217548bc31aeccf9a0c89bdfa4e16a8f/bin/riscv32-unknown-elf-objcopy -R .rel.dyn -O srec /tmp/arduino_build_232653/Blink.ino.elf /tmp/arduino_build_232653/Blink.ino.hex
/home/michael/.arduino15/packages/sifive/tools/riscv32-unknown-elf-gcc/3f7b3696217548bc31aeccf9a0c89bdfa4e16a8f/bin/riscv32-unknown-elf-size -B /tmp/arduino_build_232653/Blink.ino.elf
Sketch uses 6816 bytes (0%) of program storage space.Maximum is 8388608 bytes.
openocd -f /home/michael/.arduino15/packages/sifive/hardware/riscv/1.0.2/freedom-e-sdk/bsp/env/freedom-e300-arty/openocd.cfg -c flash protect 0 64 last off; program /tmp/arduino_build_232653/Blink.ino.elf verify; resume 0x20400000; exit
Open On-Chip Debugger 0.10.0+dev-01524-g861e75f54-dirty (2020-12-06-19:34)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
DEPRECATED! use 'adapter speed' not 'adapter_khz'
Using JTAG
Info : auto-selecting first available session transport "jtag".To override use 'transport select <transport>'.
Info : ftdi: if you experience problems at higher adapter clocks, try the command "ftdi_tdo_sample_edge falling"
Info : clock speed 10000 kHz
Info : JTAG tap: riscv.cpu tap/device found: 0x20000913 (mfg: 0x489 (SiFive Inc), part: 0x0000, ver: 0x2)
Info : datacount=1 progbufsize=16
Info : Disabling abstract command reads from CSRs.
Info : Examined RISC-V core; found 1 harts
Info : hart 0: XLEN=32, misa=0x40001105
Info : starting gdb server for riscv.cpu on 3333
Info : Listening on port 3333 for gdb connections
Info : Found flash device 'sp s25fl128s' (ID 0x00182001)
Ready for Remote Connections
Info : JTAG tap: riscv.cpu tap/device found: 0x20000913 (mfg: 0x489 (SiFive Inc), part: 0x0000, ver: 0x2)
** Programming Started **
Info : Disabling abstract command writes to CSRs.
** Programming Finished **
** Verify Started **
** Verified OK **
  • 此时,板子上的LD1会出现一秒周期的闪烁,实踐成功.

Hex Five

  • 参考链接:
  • Hex Five Security(RISC-V International的长期成员)已开发了MultiZone Security IoT Stack,可免费下载RISC-V IoT安全栈.由Hex Five Security公司开发的MultiZone Security IoT Stack,是第一个RISC-V IoT安全栈.可使用由该公司开发的开源软核X300,编程到Digilent Arty A7-35T FPGA开发板上进行框架评估.
  • Hex Five发布了第一个支持FreeRTOSRISC-V安全IoT协议栈.MultiZone安全物联网堆栈,第一个用于RISC-V的安全IoT堆栈:FreeRTOS的安全实现,在操作系统,TCP/IP堆栈和TLS 1.3/ECC的信任根之间采用硬件强制软件定义的分隔,以实现安全的物联网应用.

编译

  • 下载源码,这里会耗时比较长,因为会从网上同步非常多的submodule.这里最终找到了hex-five/multizone-fpga来实践,它们的代码结构是一样的.

    1
    2
    3
    ~$ git clone https://github.com/hex-five/multizone-fpga
    ~$ cd multizone-fpga
    ~$ git submodule update --init --recursive --jobs 8
  • 编译Verilog,这里第一次运行,会要从网上下载很多Scala的插件.

    1
    2
    3
    ~$ source ~/Xilinx/Vivado/2021.1/settings64.sh
    ~$ cd multizone-fpga
    ~$ make -j 16 -f Makefile.x300arty35devkit verilog
  • 编译mcs,是要用到risc-v toolchain的.因为系统用的是python3.x,所以这里还要打一个patch.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    ~$ cat ~/vlsi_rom_gen-fixed.patch
    diff --git a/scripts/vlsi_rom_gen b/scripts/vlsi_rom_gen
    index 3e97070db..c0185d1d2 100755
    --- a/scripts/vlsi_rom_gen
    +++ b/scripts/vlsi_rom_gen
    @@ -94,7 +94,7 @@ def iterate_by_n(it, n):
    'Iterable length not evenly divisible by {}'.format(n)
    )
    else:
    - raise
    + return
    yield batch

    ~$ cd multizone-fpga/rocket-chip
    ~$ git apply ~/vlsi_rom_gen-fixed.patch
  • 设置RISCV变量,并编译.这里会有一些耗时.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
~$ make  -f Makefile.x300arty35devkit mcs

[...]
Creating config memory files...
Creating bitstream load up from address 0x00000000
Loading bitfile /home/michael/workspace-xilinx/RISC-V/multizone-fpga/builds/x300arty35devkit/obj/X300ArtyDevKitFPGAChip.bit
Writing file /home/michael/workspace-xilinx/RISC-V/multizone-fpga/builds/x300arty35devkit/obj/X300ArtyDevKitFPGAChip.mcs
Writing log file /home/michael/workspace-xilinx/RISC-V/multizone-fpga/builds/x300arty35devkit/obj/X300ArtyDevKitFPGAChip.prm
===================================
Configuration Memory information
===================================
File Format MCS
Interface SPIX4
Size 16M
Start Address 0x00000000
End Address 0x00FFFFFF

Addr1 Addr2 Date File(s)
0x00000000 0x0021728B Oct 23 23:34:23 2021 /home/michael/workspace-xilinx/RISC-V/multizone-fpga/builds/x300arty35devkit/obj/X300ArtyDevKitFPGAChip.bit
0 Infos, 0 Warnings, 0 Critical Warnings and 0 Errors encountered.
write_cfgmem completed successfully
INFO: [Common 17-206] Exiting Vivado at Sat Oct 23 23:34:54 2021...

烧写到QSPI Flash

  • Launch Vivado
  • Open Hardware Manager, click the auto-connect icon, and open the target board
  • Right click on the FPGA device and select ”Add Configuration Memory Device”
  • Select Part “s25fl128sxxxxxx0-spi-x1_x2_x4” (“mt25ql128-spi-x1_x2_x4” if you have an old Arty 35T)
    artya735t_add_config_mem_dev.png
  • Click OK to ”Do you want to program the configuration memory device now?”
  • Add X300ArtyA7-35T.mcs or X300ArtyA7-100T.mcs depending on your board
    artya735t_program_config_mcs.png
  • Select OK
  • Once the programming completes in Vivado, press the “PROG” Button on the Arty board to load the image into the FPGA

OpenOCD

VexRiscv

linux-on-litex-vexriscv

安装LiteX/Migen及工具

  • 参考链接:
  • The LiteX framework provides a convenient and efficient infrastructure to create FPGA Cores/SoCs, to explore various digital design architectures and create full FPGA based systems.
  • 首先这里的LiteX跟一个加密货币链是同名的.Migen是基于FHDL(嵌入Python的eDSL)的EDA工具箱,它还包含了MiSoC/nMigen之类的衍生和扩展来更好的简化硬件设计/开发.而LiteX则是一个基于MiGenCore/SoC构建器,它包含了SoC设计框架和一组IP库/实用程序来高效地创建SoC和进行全定制FPGA设计.LiteX的生态正日益成熟,已支持各种常见的硬件IP和多种RISC-V软核,并在真正的硬件产品开发中使用.
  • 安装必要的工具与一些库文件.
1
2
3
~$ sudo apt-get install verilator libevent-dev libjson-c-dev
~$ pip3 install meson ninja
~$ sdk install sbt
  • 在运行litex_setup.py时,它会网上下载很多的开源工具库下,大部分都是python,scala两种语写的.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    $ wget https://raw.githubusercontent.com/enjoy-digital/litex/master/litex_setup.py
    $ chmod +x litex_setup.py
    $ ./litex_setup.py init install --user (--user to install to user directory)

    ~$ tree -L 1
    .
    ├── litedram
    ├── liteeth
    ├── litehyperbus
    ├── liteiclink
    ├── litejesd204b
    ├── litepcie
    ├── litesata
    ├── litescope
    ├── litesdcard
    ├── litespi
    ├── litex
    ├── litex-boards
    ├── litex_setup.py
    ├── migen
    ├── nmigen
    ├── pythondata-cpu-blackparrot
    ├── pythondata-cpu-cv32e40p
    ├── pythondata-cpu-ibex
    ├── pythondata-cpu-lm32
    ├── pythondata-cpu-microwatt
    ├── pythondata-cpu-minerva
    ├── pythondata-cpu-mor1kx
    ├── pythondata-cpu-picorv32
    ├── pythondata-cpu-rocket
    ├── pythondata-cpu-serv
    ├── pythondata-cpu-vexriscv
    ├── pythondata-cpu-vexriscv-smp
    ├── pythondata-misc-tapcfg
    ├── pythondata-misc-usb_ohci
    ├── pythondata-software-compiler_rt
    └── pythondata-software-picolibc
  • 关于LiteX更详细的资料,一定要参考它的litex/wiki,及以一些常用的命令

常用命令

  • 可以时常升级保持更新
    1
    ~$ ./litex_setup.py --update
  • 使用它的脚本,一键编译做工具链RISC-V toolchain.
    1
    ~$  ./litex_setup.py --gcc=riscv

Litex-Buildenv

  • litex-buildenv An environment for building LiteX based FPGA designs.Makes it easy to get everything you need!
  • 但是测试发现这个库有一点过时了,有很多东西没有维护了.

Litex-VexRiscv

模拟器运行

  • 第一次运行它会下载相应的源码并编译.并且需要在images目录下有如下文件:
    1
    2
    ~$ ls images/
    boot.json Image opensbi.bin rootfs.cpio rv32.dtb
  • 主要三个类型的文件:Linux Kernel, OpenSBI(uboot), Rootfs.可以先不自己构建,下载对应的的文件做快速测,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
~$ export PATH=~/riscv64-toolchain/bin:$PATH

~$ git clone https://github.com/litex-hub/linux-on-litex-vexriscv
~$ cd linux-on-litex-vexriscv
~$ ./sim.py
[xgmii_ethernet] loaded (0x55e196f0d090)
[clocker] loaded
[spdeeprom] loaded (addr = 0x0)
[serial2tcp] loaded (0x55e196f0d090)
[serial2console] loaded (0x55e196f0d090)
[gmii_ethernet] loaded (0x55e196f0d090)
[ethernet] loaded (0x55e196f0d090)
[clocker] sys_clk: freq_hz=1000000, phase_deg=0

__ _ __ _ __
/ / (_) /____ | |/_/
/ /__/ / __/ -_)> <
/____/_/\__/\__/_/|_|
Build your hardware, easily!

(c) Copyright 2012-2021 Enjoy-Digital
(c) Copyright 2007-2015 M-Labs

BIOS CRC passed (38bb961c)

Migen git sha1: 7507a2b
LiteX git sha1: af5167c7

--=============== SoC ==================--
CPU: VexRiscv SMP-LINUX @ 100MHz
BUS: WISHBONE 32-bit @ 4GiB
CSR: 32-bit data
ROM: 32KiB
SRAM: 8KiB
L2: 0KiB
SDRAM: 65536KiB 32-bit @ 100MT/s (CL-2 CWL-2)

--========== Initialization ============--
Initializing SDRAM @0x40000000...
Switching SDRAM to software control.
Switching SDRAM to hardware control.

--============== Boot ==================--
Booting from serial...
Press Q or ESC to abort boot completely.
sL5DdSMmkekro
Timeout
Executing booted program at 0x40f00000

--============= Liftoff! ===============--

OpenSBI v0.8-1-gecf7701
____ _____ ____ _____
/ __ \ / ____| _ \_ _|
| | | |_ __ ___ _ __ | (___ | |_) || |
| | | | '_ \ / _ \ '_ \ \___ \| _ < | |
| |__| | |_) | __/ | | |____) | |_) || |_
\____/| .__/ \___|_| |_|_____/|____/_____|
| |
|_|

Platform Name : LiteX / VexRiscv-SMP
Platform Features : timer,mfdeleg
Platform HART Count : 8
Boot HART ID : 0
Boot HART ISA : rv32imas
BOOT HART Features : time
BOOT HART PMP Count : 0
Firmware Base : 0x40f00000
Firmware Size : 124 KB
Runtime SBI Version : 0.2

MIDELEG : 0x00000222
MEDELEG : 0x0000b101

# 这里好像有问题,没有运行下去,出现一个shell console.
  • 也可以使用lxsim运行,它是litex_setup.py安装的工具集,位于~/.local/bin/lxsim.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    ~$ lxsim --cpu-type=vexriscv
    INFO:SoC: __ _ __ _ __
    INFO:SoC: / / (_) /____ | |/_/
    INFO:SoC: / /__/ / __/ -_)> <
    INFO:SoC: /____/_/\__/\__/_/|_|
    INFO:SoC: Build your hardware, easily!
    INFO:SoC:--------------------------------------------------------------------------------
    INFO:SoC:Creating SoC...(2021-11-06 22:03:10)
    INFO:SoC:--------------------------------------------------------------------------------
    INFO:SoC:FPGA device : SIM.
    INFO:SoC:System clock: 1.000MHz.
    INFO:SoCBusHandler:Creating Bus Handler...
    INFO:SoCBusHandler:32-bit wishbone Bus, 4.0GiB Address Space.
    INFO:SoCBusHandler:Adding reserved Bus Regions...
    INFO:SoCBusHandler:Bus Handler created.
    INFO:SoCCSRHandler:Creating CSR Handler...
    INFO:SoCCSRHandler:32-bit CSR Bus, 32-bit Aligned, 16.0KiB Address Space, 2048B Paging, big Ordering (Up to 32 Locations).
    INFO:SoCCSRHandler:Adding reserved CSRs...
    INFO:SoCCSRHandler:CSR Handler created.
    INFO:SoCIRQHandler:Creating IRQ Handler...
    INFO:SoCIRQHandler:IRQ Handler (up to 32 Locations).
    INFO:SoCIRQHandler:Adding reserved IRQs...
    INFO:SoCIRQHandler:IRQ Handler created.
    [...]
    [...]
    [xgmii_ethernet] loaded (0x5575a247c090)
    [clocker] loaded
    [spdeeprom] loaded (addr = 0x0)
    [serial2tcp] loaded (0x5575a247c090)
    [serial2console] loaded (0x5575a247c090)
    [gmii_ethernet] loaded (0x5575a247c090)
    [ethernet] loaded (0x5575a247c090)
    [clocker] sys_clk: freq_hz=1000000, phase_deg=0

    __ _ __ _ __
    / / (_) /____ | |/_/
    / /__/ / __/ -_)> <
    /____/_/\__/\__/_/|_|
    Build your hardware, easily!

    (c) Copyright 2012-2021 Enjoy-Digital
    (c) Copyright 2007-2015 M-Labs

    BIOS built on Nov 6 2021 22:03:21
    BIOS CRC passed (5bc979b3)

    Migen git sha1: 7507a2b
    LiteX git sha1: af5167c7

    --=============== SoC ==================--
    CPU: VexRiscv @ 1MHz
    BUS: WISHBONE 32-bit @ 4GiB
    CSR: 32-bit data
    ROM: 128KiB
    SRAM: 8KiB


    --============== Boot ==================--
    Booting from serial...
    Press Q or ESC to abort boot completely.
    sL5DdSMmkekro
    Timeout
    No boot medium found

    --============= Console ================--

    litex>

板上运行

编译FPGA bitstream

1
linux-on-litex-vexriscv$ ./make.py --board=arty  --build
  • 编译完成后,有如下目录.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    linux-on-litex-vexriscv$ tree -L 2  build
    build
    ├── arty
    │   ├── arty.dtb
    │   ├── arty.dts
    │   ├── csr.csv
    │   ├── csr.json
    │   ├── gateware
    │   └── software
    └── sim
    ├── csr.json
    ├── gateware
    ├── sim.dts
    └── software

  • 它的内存文件,以及其它文件都可以在gateware目录可以找到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
linux-on-litex-vexriscv$ tree -L 2  build/arty/gateware/
build/arty/gateware/
├── arty.bin
├── arty.bit
├── arty.cache
│   └── wt
├── arty_clock_utilization.rpt
├── arty_control_sets.rpt
├── arty_drc.rpt
├── arty.hw
│   └── arty.lpr
├── arty_io.rpt
├── arty.ip_user_files
├── arty_power.rpt
├── arty.prm
├── arty_route.dcp
├── arty_route_status.rpt
├── arty.tcl
[...]

使用OpenOCD加载

  • 因为LiteX是完全使用开源工具集合来开发自己的硬件,所以烧写器,可以使用FT2232 + OpenOCD这种组合来支持,OpenOCD这里无需特定分支版本,就用官方的标准版本就可以.也可以使用Vivado烧写它.还有这里可能有一个小的问题,因为linux-on-litex-vexriscv/prog下无openocd的配置文件,需要先把从litex-boards/litex_boards/prog把文件复制或者链到该目录下.
  • 为了能让普通用户访问到FT2232/dev/ttyUSBX,确做了如下的设置.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
~$ cat /etc/udev/rules.d/98-openocd.rules

# Adding Arduino M0/M0 Pro, Primo UDEV Rules for CMSIS-DAP port

ACTION!="add|change", GOTO="openocd_rules_end"
SUBSYSTEM!="usb|tty|hidraw", GOTO="openocd_rules_end"

#Please keep this list sorted by VID:PID

#CMSIS-DAP compatible adapters
ATTRS{product}=="*CMSIS-DAP*", MODE="664", GROUP="plugdev"

# Original FT232/FT245 VID:PID
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", MODE="664", GROUP="plugdev"

# Original FT2232 VID:PID
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", MODE="664", GROUP="plugdev"

LABEL="openocd_rules_end"
  • 指定参数编译并加载,目标板--board=arty.或者使用./make.py --board=arty --flash烧写到flash.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
linux-on-litex-vexriscv$ ./make.py --board=arty  --load

[...]
OBJCOPY bios.bin
chmod -x bios.bin
python3 -m litex.soc.software.mkmscimg bios.bin --little
python3 -m litex.soc.software.memusage bios.elf /home/michael/workspace-xilinx/RISC-V/litex-hub/linux-on-litex-vexriscv/build/arty/software/bios/../include/generated/regions.ld riscv64-unknown-elf

ROM usage: 39.94KiB (62.40%)
RAM usage: 0.61KiB (7.62%)

make: Leaving directory '/home/michael/workspace-xilinx/RISC-V/litex-hub/linux-on-litex-vexriscv/build/arty/software/bios'
INFO:SoC:Initializing ROM rom with contents (Size: 0x9fd8).
INFO:SoC:Auto-Resizing ROM rom from 0x10000 to 0x9fd8.
build/arty/arty.dts:767.34-778.19: Warning (unit_address_vs_reg): /soc/clk@f0005000/CLKOUT0: node has a reg or ranges property, but no unit name
build/arty/arty.dts:780.34-791.19: Warning (unit_address_vs_reg): /soc/clk@f0005000/CLKOUT1: node has a reg or ranges property, but no unit name
Open On-Chip Debugger 0.11.0+dev-00433-g97db87c22 (2021-11-01-22:36)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
DEPRECATED! use 'adapter driver' not 'interface'
DEPRECATED! use 'ftdi vid_pid' not 'ftdi_vid_pid'
DEPRECATED! use 'ftdi channel' not 'ftdi_channel'
DEPRECATED! use 'ftdi layout_init' not 'ftdi_layout_init'
Info : auto-selecting first available session transport "jtag".To override use 'transport select <transport>'.
DEPRECATED! use 'adapter speed' not 'adapter_khz'
fpga_program
Info : ftdi: if you experience problems at higher adapter clocks, try the command "ftdi tdo_sample_edge falling"
Info : clock speed 25000 kHz
Info : JTAG tap: xc7.tap tap/device found: 0x0362d093 (mfg: 0x049 (Xilinx), part: 0x362d, ver: 0x0)
  • 加载成功后,板上的流水灯就会开始闪烁了.用lxterm /dev/ttyUSB1 --speed=1e6直接进入litex boot界面,如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
     ~/.local/bin/lxterm /dev/ttyUSB1 --speed=1e6
    BIOS CRC passed (cf084352)

    Migen git sha1: 7507a2b
    LiteX git sha1: 67431f41

    --=============== SoC ==================--
    CPU: VexRiscv SMP-LINUX @ 100MHz
    BUS: WISHBONE 32-bit @ 4GiB
    CSR: 32-bit data
    ROM: 64KiB
    SRAM: 8KiB
    L2: 0KiB
    FLASH: 16384KiB
    SDRAM: 262144KiB 16-bit @ 800MT/s (CL-7 CWL-5)

    --========== Initialization ============--
    Ethernet init...
    Initializing SDRAM @0x40000000...
    Switching SDRAM to software control.
    Write latency calibration:
    m0:0 m1:0
    Read leveling:
    m0, b00: |00000000000000000000000000000000| delays: -
    m0, b01: |00000000000000000000000000000000| delays: -
    m0, b02: |11111111110000000000000000000000| delays: 05+-05
    m0, b03: |00000000000011111111111110000000| delays: 19+-07
    m0, b04: |00000000000000000000000000011111| delays: 30+-02
    m0, b05: |00000000000000000000000000000000| delays: -
    m0, b06: |00000000000000000000000000000000| delays: -
    m0, b07: |00000000000000000000000000000000| delays: -
    best: m0, b03 delays: 19+-07
    m1, b00: |00000000000000000000000000000000| delays: -
    m1, b01: |00000000000000000000000000000000| delays: -
    m1, b02: |11111111110000000000000000000000| delays: 05+-05
    m1, b03: |00000000000111111111111111000000| delays: 18+-07
    m1, b04: |00000000000000000000000000001111| delays: 30+-02
    m1, b05: |00000000000000000000000000000000| delays: -
    m1, b06: |00000000000000000000000000000000| delays: -
    m1, b07: |00000000000000000000000000000000| delays: -
    best: m1, b03 delays: 19+-07
    Switching SDRAM to hardware control.
    Memtest at 0x40000000 (2.0MiB)...
    Write: 0x40000000-0x40200000 2.0MiB
    Read: 0x40000000-0x40200000 2.0MiB
    Memtest OK
    Memspeed at 0x40000000 (Sequential, 2.0MiB)...
    Write speed: 31.7MiB/s
    Read speed: 33.1MiB/s

    Initializing S25FL128L SPI Flash @0xd0000000...
    SPI Flash clk configured to 25 MHz
    Memspeed at 0xd0000000 (Sequential, 4.0KiB)...
    Read speed: 2.5MiB/s
    Memspeed at 0xd0000000 (Random, 4.0KiB)...
    Read speed: 1.1MiB/s

    --============== Boot ==================--
    Booting from serial...
    Press Q or ESC to abort boot completely.
    sL5DdSMmkekro
    Timeout
    Booting from SDCard in SD-Mode...
    Booting from boot.json...
    Booting from boot.bin...
    SDCard boot failed.
    Booting from network...
    Local IP: 192.168.1.50
    Remote IP: 192.168.1.100
    Booting from boot.json...
    Booting from boot.bin...
    Copying boot.bin to 0x40000000...
    Network boot failed.
    No boot medium found

    --============= Console ================--

    litex> help

加载运行Linux系统

  • 同样lxterm也是litex_setup.py安装的工具集之一,位于~/.local/bin/lxterm.如果你用的是Mate Desktop,它也有一个同名的工具,别混用了.运行下面命令时,要按一下板上的PROG键, 让它进入烧写状态.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    linux-on-litex-vexriscv$ ~/.local/bin/lxterm --images=images/boot.json /dev/ttyUSB1 --speed=1e6
    BIOS CRC passed (f7d62022)

    Migen git sha1: 7507a2b
    LiteX git sha1: af5167c7

    --=============== SoC ==================--
    CPU: VexRiscv SMP-LINUX @ 100MHz
    BUS: WISHBONE 32-bit @ 4GiB
    CSR: 32-bit data
    ROM: 64KiB
    SRAM: 8KiB
    L2: 0KiB
    FLASH: 16384KiB
    SDRAM: 262144KiB 16-bit @ 800MT/s (CL-7 CWL-5)

    --========== Initialization ============--
    Ethernet init...
    Initializing SDRAM @0x40000000...
    Switching SDRAM to software control.
    Write latency calibration:
    m0:0 m1:0
    Read leveling:
    m0, b00: |00000000000000000000000000000000| delays: -
    m0, b01: |00000000000000000000000000000000| delays: -
    m0, b02: |11111111110000000000000000000000| delays: 05+-05
    m0, b03: |00000000000011111111111110000000| delays: 18+-06
    m0, b04: |00000000000000000000000000011111| delays: 29+-02
    m0, b05: |00000000000000000000000000000000| delays: -
    m0, b06: |00000000000000000000000000000000| delays: -
    m0, b07: |00000000000000000000000000000000| delays: -
    best: m0, b03 delays: 18+-06
    m1, b00: |00000000000000000000000000000000| delays: -
    m1, b01: |00000000000000000000000000000000| delays: -
    m1, b02: |11111111110000000000000000000000| delays: 05+-05
    m1, b03: |00000000000111111111111110000000| delays: 18+-07
    m1, b04: |00000000000000000000000000011111| delays: 29+-02
    m1, b05: |00000000000000000000000000000000| delays: -
    m1, b06: |00000000000000000000000000000000| delays: -
    m1, b07: |00000000000000000000000000000000| delays: -
    best: m1, b03 delays: 18+-07
    Switching SDRAM to hardware control.
    Memtest at 0x40000000 (2.0MiB)...
    Write: 0x40000000-0x40200000 2.0MiB
    Read: 0x40000000-0x40200000 2.0MiB
    Memtest OK
    Memspeed at 0x40000000 (Sequential, 2.0MiB)...
    Write speed: 31.7MiB/s
    Read speed: 33.1MiB/s

    Initializing S25FL128L SPI Flash @0xd0000000...
    SPI Flash clk configured to 25 MHz
    Memspeed at 0xd0000000 (Sequential, 4.0KiB)...
    Read speed: 2.5MiB/s
    Memspeed at 0xd0000000 (Random, 4.0KiB)...
    Read speed: 1.1MiB/s

    --============== Boot ==================--
    Booting from serial...
    Press Q or ESC to abort boot completely.
    sL5DdSMmkekro
    [LXTERM] Received firmware download request from the device.
    [LXTERM] Uploading images/Image to 0x40000000 (7420864 bytes)...
    [LXTERM] Upload calibration...(inter-frame: 10.00us, length: 64)
    [LXTERM] Upload complete (86.2KB/s).
    [LXTERM] Uploading images/rv32.dtb to 0x40ef0000 (12130 bytes)...
    [LXTERM] Upload calibration...(inter-frame: 10.00us, length: 64)
    [LXTERM] Upload complete (78.9KB/s).
    [LXTERM] Uploading images/rootfs.cpio to 0x41000000 (4010496 bytes)...
    [LXTERM] Upload calibration...(inter-frame: 10.00us, length: 64)
    [LXTERM] Upload complete (86.2KB/s).
    [LXTERM] Uploading images/opensbi.bin to 0x40f00000 (53640 bytes)...
    [LXTERM] Upload calibration...(inter-frame: 10.00us, length: 64)
    [LXTERM] Upload complete (85.3KB/s).
    [LXTERM] Booting the device.
    [LXTERM] Done.
    Executing booted program at 0x40f00000

    --============= Liftoff! ===============--

    OpenSBI v0.8-1-gecf7701
    ____ _____ ____ _____
    / __ \ / ____| _ \_ _|
    | | | |_ __ ___ _ __ | (___ | |_) || |
    | | | | '_ \ / _ \ '_ \ \___ \| _ < | |
    | |__| | |_) | __/ | | |____) | |_) || |_
    \____/| .__/ \___|_| |_|_____/|____/_____|
    | |
    |_|

    Platform Name : LiteX / VexRiscv-SMP
    Platform Features : timer,mfdeleg
    Platform HART Count : 8
    Boot HART ID : 0
    Boot HART ISA : rv32imas
    BOOT HART Features : time
    BOOT HART PMP Count : 0
    Firmware Base : 0x40f00000
    Firmware Size : 124 KB
    Runtime SBI Version : 0.2

    MIDELEG : 0x00000222
    MEDELEG : 0x0000b101
    [ 0.000000] Linux version 5.12.0-rc4 (florent@panda) (riscv32-buildroot-linux-gnu-gcc.br_real (Buildroot 2020.11-281-g69e5046e7b) 10.2.0, GNU ld (GNU Binutils) 2.35.2) #2 SMP Mon Mar 29 10:07:39 CEST 2021
    [ 0.000000] Zone ranges:
    [ 0.000000] Normal [mem 0x0000000040000000-0x000000004fffffff]
    [ 0.000000] Movable zone start for each node
    [ 0.000000] Early memory node ranges
    [ 0.000000] node 0: [mem 0x0000000040000000-0x000000004fffffff]
    [ 0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x000000004fffffff]
    [ 0.000000] SBI specification v0.2 detected
    [ 0.000000] SBI implementation ID=0x1 Version=0x8
    [ 0.000000] SBI v0.2 TIME extension detected
    [ 0.000000] SBI v0.2 IPI extension detected
    [ 0.000000] SBI v0.2 RFENCE extension detected
    [ 0.000000] SBI v0.2 HSM extension detected
    [ 0.000000] Invalid cpuid [8] for hartid [8]
    [ 0.000000] riscv: ISA extensions aim
    [ 0.000000] riscv: ELF capabilities aim
    [ 0.000000] percpu: Embedded 10 pages/cpu s19148 r0 d21812 u40960
    [ 0.000000] CPU node for /cpus/cpu@8 exist but the possible cpu range is :0-7
    [ 0.000000] CPU node for /cpus/cpu@9 exist but the possible cpu range is :0-7
    [ 0.000000] CPU node for /cpus/cpu@10 exist but the possible cpu range is :0-7
    [ 0.000000] CPU node for /cpus/cpu@11 exist but the possible cpu range is :0-7
    [ 0.000000] CPU node for /cpus/cpu@12 exist but the possible cpu range is :0-7
    [ 0.000000] CPU node for /cpus/cpu@13 exist but the possible cpu range is :0-7
    [ 0.000000] CPU node for /cpus/cpu@14 exist but the possible cpu range is :0-7
    [ 0.000000] CPU node for /cpus/cpu@15 exist but the possible cpu range is :0-7
    [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 65024
    [ 0.000000] Kernel command line: console=liteuart earlycon=liteuart,0xf0001000 rootwait root=/dev/ram0
    [ 0.000000] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes, linear)
    [ 0.000000] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes, linear)
    [ 0.000000] Sorting __ex_table...
    [ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
    [ 0.000000] Memory: 243356K/262144K available (5596K kernel code, 572K rwdata, 860K rodata, 214K init, 221K bss, 18788K reserved, 0K cma-reserved)
    [ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=8, Nodes=1
    [ 0.000000] rcu: Hierarchical RCU implementation.
    [ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
    [ 0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
    [ 0.000000] riscv-intc: 32 local interrupts mapped
    [ 0.000000] Couldn't find cpu id for hartid [8]
    [ 0.000000] Couldn't find cpu id for hartid [9]
    [ 0.000000] Couldn't find cpu id for hartid [10]
    [ 0.000000] Couldn't find cpu id for hartid [11]
    [ 0.000000] Couldn't find cpu id for hartid [12]
    [ 0.000000] Couldn't find cpu id for hartid [13]
    [ 0.000000] Couldn't find cpu id for hartid [14]
    [ 0.000000] Couldn't find cpu id for hartid [15]
    [ 0.000000] Couldn't find cpu id for hartid [8]
    [ 0.000000] Couldn't find cpu id for hartid [9]
    [ 0.000000] plic: handler already present for context 19.
    [ 0.000000] Couldn't find cpu id for hartid [10]
    [ 0.000000] plic: handler already present for context 21.
    [ 0.000000] Couldn't find cpu id for hartid [11]
    [ 0.000000] plic: handler already present for context 23.
    [ 0.000000] Couldn't find cpu id for hartid [12]
    [ 0.000000] plic: handler already present for context 25.
    [ 0.000000] Couldn't find cpu id for hartid [13]
    [ 0.000000] plic: handler already present for context 27.
    [ 0.000000] Couldn't find cpu id for hartid [14]
    [ 0.000000] plic: handler already present for context 29.
    [ 0.000000] Couldn't find cpu id for hartid [15]
    [ 0.000000] plic: handler already present for context 31.
    [ 0.000000] plic: interrupt-controller@f0c00000: mapped 32 interrupts with 16 handlers for 32 contexts.
    [ 0.000000] random: get_random_bytes called from start_kernel+0x360/0x4d0 with crng_init=0
    [ 0.000000] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [0]
    [ 0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x171024e7e0, max_idle_ns: 440795205315 ns
    [ 0.000021] sched_clock: 64 bits at 100MHz, resolution 10ns, wraps every 4398046511100ns
    [ 0.002019] Couldn't find cpu id for hartid [8]
    [ 0.002715] Couldn't find cpu id for hartid [9]
    [ 0.003406] Couldn't find cpu id for hartid [10]
    [ 0.004035] Couldn't find cpu id for hartid [11]
    [ 0.004647] Couldn't find cpu id for hartid [12]
    [ 0.005269] Couldn't find cpu id for hartid [13]
    [ 0.005888] Couldn't find cpu id for hartid [14]
    [ 0.006510] Couldn't find cpu id for hartid [15]
    [ 0.008712] Console: colour dummy device 80x25
    [ 0.009694] Calibrating delay loop (skipped), value calculated using timer frequency..200.00 BogoMIPS (lpj=400000)
    [ 0.011160] pid_max: default: 32768 minimum: 301
    [ 0.015359] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
    [ 0.016601] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
    [ 0.039744] ASID allocator using 9 bits (512 entries)
    [ 0.042606] rcu: Hierarchical SRCU implementation.
    [ 0.052177] smp: Bringing up secondary CPUs ...
    [ 1.106334] CPU1: failed to come online
    [ 2.174473] CPU2: failed to come online
    [ 3.242724] CPU3: failed to come online
    [ 4.310959] CPU4: failed to come online
    [ 5.379125] CPU5: failed to come online
    [ 6.447274] CPU6: failed to come online
    [ 7.515486] CPU7: failed to come online
    [ 7.516400] smp: Brought up 1 node, 1 CPU
    [ 7.522412] devtmpfs: initialized
    [ 7.631706] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
    [ 7.633017] futex hash table entries: 2048 (order: 5, 131072 bytes, linear)
    [ 7.639479] NET: Registered protocol family 16
    [ 7.880381] FPGA manager framework
    [ 7.895223] clocksource: Switched to clocksource riscv_clocksource
    [ 8.064355] NET: Registered protocol family 2
    [ 8.073113] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 6144 bytes, linear)
    [ 8.074433] TCP established hash table entries: 2048 (order: 1, 8192 bytes, linear)
    [ 8.076232] TCP bind hash table entries: 2048 (order: 2, 16384 bytes, linear)
    [ 8.077425] TCP: Hash tables configured (established 2048 bind 2048)
    [ 8.079928] UDP hash table entries: 256 (order: 1, 8192 bytes, linear)
    [ 8.081038] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear)
    [ 8.092717] Unpacking initramfs...
    [ 8.858450] Initramfs unpacking failed: invalid magic at start of compressed archive
    [ 8.916140] Freeing initrd memory: 8192K
    [ 8.932899] workingset: timestamp_bits=30 max_order=16 bucket_order=0
    [ 9.193838] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
    [ 9.194565] io scheduler mq-deadline registered
    [ 9.195468] io scheduler kyber registered
    [ 9.223323] No litex,nclkout entry in the dts file
    [ 9.225515] LiteX SoC Controller driver initialized: subreg:4, align:4
    [ 10.286467] f0001000.serial: ttyLXU0 at MMIO 0x0 (irq = 0, base_baud = 0) is a liteuart
    [ 10.388082] printk: console [liteuart0] enabled
    [ 10.443080] libphy: Fixed MDIO Bus: probed
    [ 10.445897] liteeth f0002000.mac: unable to get rx-fifo-depth
    [ 10.447597] liteeth: probe of f0002000.mac failed with error -22
    [ 10.451740] i2c /dev entries driver
    [ 10.459084] i2c i2c-0: Not I2C compliant: can\'t read SCL
    [ 10.460008] i2c i2c-0: Bus may be unreliable
    [ 10.491212] litex-mmc f0009000.mmc: Requested clk_freq=12500000: set to 12500000 via div=8
    [ 10.523707] fpga_manager fpga0: LiteX ICAPBitstream FPGA Manager registered
    [ 10.549391] NET: Registered protocol family 10
    [ 10.558414] litex-mmc f0009000.mmc: Requested clk_freq=0: set to 390625 via div=256
    [ 10.565072] Segment Routing with IPv6
    [ 10.567088] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
    [ 10.582063] NET: Registered protocol family 17
    [ 10.594660] Freeing unused kernel memory: 208K
    [ 10.596083] Kernel memory protection not selected by kernel config.
    [ 10.597491] Run /init as init process
    Starting syslogd: OK
    Starting klogd: OK
    Running sysctl: OK
    Saving random seed: [ 12.456910] random: dd: uninitialized urandom read (512 bytes read)
    OK
    Starting network: OK

    Welcome to Buildroot
    buildroot login:

  • 通过串口加载是稍慢的,加载成功后,会有一个shell console登录提示.lxterm是通过板上J10 USB接口使用JTAGUART协议来通信的,脚本是位于
    litex/litex/tools/litex_term.py.也可以使用sudo minicom -D /dev/ttyUSB1 -b 1000000来连接,注意它的速率是1000000.有一些USB to UART不支持这种速率,通常表现为乱码,无法输入等.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
buildroot login: root
__ _
/ / (_)__ __ ____ __
/ /__/ / _ \/ // /\ \ /
/____/_/_//_/\_,_//_\_\
/ _ \/ _ \
__ _ __ _ _\___/_//_/ ___ _
/ / (_) /____ | |/_/__| | / /____ __ / _ \(_)__ _____ __
/ /__/ / __/ -_)> </___/ |/ / -_) \ // , _/ (_-</ __/ |/ /
/____/_/\__/\__/_/|_|____|___/\__/_\_\/_/|_/_/___/\__/|___/
/ __/ |/ / _ \
_\ \/ /|_/ / ___/
/___/_/ /_/_/
32-bit RISC-V Linux running on LiteX / VexRiscv-SMP.

login[103]: root login on 'console'
root@buildroot:~# cat /proc/cpuinfo
processor : 0
hart : 0
isa : rv32ima
mmu : sv32

root@buildroot:~# free -m
total used free shared buff/cache available
Mem: 245 3 236 0 5 233
Swap: 0 0 0

  • images/boot.json就是内存地址的映射表.
1
2
3
4
5
6
7
8
linux-on-litex-vexriscv$ cat images/boot.json
{
"Image": "0x40000000",
"rv32.dtb": "0x40ef0000",
"rootfs.cpio": "0x41000000",
"opensbi.bin": "0x40f00000"
}

  • 也可以直接使用OpenOCD来加载,如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    linux-on-litex-vexriscv$  openocd -f prog/openocd_xc7_ft2232.cfg -c "transport select jtag; init; pld load 0 build/arty/gateware/arty.bit; exit"
    Open On-Chip Debugger 0.11.0+dev-00433-g97db87c22 (2021-11-01-22:36)
    Licensed under GNU GPL v2
    For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
    DEPRECATED! use 'adapter driver' not 'interface'
    DEPRECATED! use 'ftdi vid_pid' not 'ftdi_vid_pid'
    DEPRECATED! use 'ftdi channel' not 'ftdi_channel'
    DEPRECATED! use 'ftdi layout_init' not 'ftdi_layout_init'
    Info : auto-selecting first available session transport "jtag".To override use 'transport select <transport>'.
    DEPRECATED! use 'adapter speed' not 'adapter_khz'
    fpga_program
    Warn : Transport "jtag" was already selected
    Info : ftdi: if you experience problems at higher adapter clocks, try the command "ftdi tdo_sample_edge falling"
    Info : clock speed 25000 kHz
    Info : JTAG tap: xc7.tap tap/device found: 0x0362d093 (mfg: 0x049 (Xilinx), part: 0x362d, ver: 0x0)

通过SDCard Boot加载linux系统

  • 通过TF/SD启动,需要一张空白卡,格式成W95 FAT32,现在我只测试了W95 FAT32exFAT两种格式,只有W95 FAT32可以成功加载,还发现对TF/SD卡有兼容问题,我手上有一块较老的512MBSD卡就是无法识别加载,最终还是买了一张新的SD格式化,才成功加载。具体格式化如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
~$ fdisk /dev/sdb
[....]
Disk /dev/sdb: 116.36 GiB, 124939927552 bytes, 244023296 sectors
Disk model: STORAGE DEVICE
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device Boot Start End Sectors Size Id Type
/dev/sdb1 2048 244023295 244021248 116.4G b W95 FAT32

~$ sudo mkfs.fat /dev/sdb1
mkfs.fat 4.2 (2021-01-31)
  • 再把linux-on-litex-vexriscv/images下的所有文件复制到SD卡根目录下。

    1
    2
    3
    litex/linux-on-litex-vexriscv$ ls images/
    boot.json Image opensbi.bin rootfs.cpio rv32.dtb

  • 因为Digilent Arty-A7-35T板上没集成SD卡插槽,只能通过其它外接的方式来实现,linux-on-litex-vexriscv项目默认是通过定义配置PMOD-D来支持SDCard,关于Pmod MicroSD又有两种接口,一种是digilent,另一种是numato.当时在某宝上对比发现,digilent接口是在5x-1xx元左右,后来就选择了一个numato的。numato相较于digilent少了一个插卡检测(CD)信号脚,同时管脚功能定义也不一样,linux-on-litex-vexriscv项目默认是配置digilent类型,且没参数可以选择,如果是像我这里使用了numato的类型的PMOD,需要修改linux-on-litex-vexriscv/make.py源码.而在litex-hub/litex-boards的项目里是可以通过--sdcard-adapter=numato来配置选择的。numato的补丁如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
litex-hub/linux-on-litex-vexriscv$ git diff make.py
diff --git a/make.py b/make.py
index 300cbce..83979ee 100755
--- a/make.py
+++ b/make.py
@@ -575,7 +575,7 @@ class Qmtech_EP4CE15(Board):
"serial",
})

-# ... and its bigger brother
+# ... and its bigger brother

class Qmtech_EP4CE55(Board):
soc_kwargs = {
@@ -760,8 +760,8 @@ def main():

# SoC peripherals --------------------------------------------------------------------------
if board_name in ["arty", "arty_a7"]:
- from litex_boards.platforms.arty import _sdcard_pmod_io
- board.platform.add_extension(_sdcard_pmod_io)
+ from litex_boards.platforms.arty import _numato_sdcard_pmod_io
+ board.platform.add_extension(_numato_sdcard_pmod_io)

if board_name in ["orangecrab"]:
from litex_boards.platforms.orangecrab import feather_i2c
  • 上面补丁相当于是--sdcard-adapter=numato转给了litex-boards. 执行./make.py --board=arty --build --flash,如果编译正常,从SDCard boot的显示如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
[....]
--============== Boot ==================--
Booting from serial...
Press Q or ESC to abort boot completely.
sL5DdSMmkekro
Timeout
Booting from SDCard in SD-Mode...
Booting from boot.json...
Copying Image to 0x40000000 (7531468 bytes)...
[########################################]
Copying rv32.dtb to 0x40ef0000 (5290 bytes)...
[########################################]
Copying rootfs.cpio to 0x41000000 (3786240 bytes)...
[########################################]
Copying opensbi.bin to 0x40f00000 (53640 bytes)...
[########################################]
Executing booted program at 0x40f00000

--============= Liftoff! ===============--

OpenSBI v0.8-1-gecf7701
____ _____ ____ _____
/ __ \ / ____| _ \_ _|
| | | |_ __ ___ _ __ | (___ | |_) || |
| | | | '_ \ / _ \ '_ \ \___ \| _ < | |
| |__| | |_) | __/ | | |____) | |_) || |_
\____/| .__/ \___|_| |_|_____/|____/_____|
| |
|_|

Platform Name : LiteX / VexRiscv-SMP
Platform Features : timer,mfdeleg
Platform HART Count : 8
Boot HART ID : 0
Boot HART ISA : rv32imas
BOOT HART Features : time
BOOT HART PMP Count : 0
Firmware Base : 0x40f00000
Firmware Size : 124 KB
Runtime SBI Version : 0.2

MIDELEG : 0x00000222
MEDELEG : 0x0000b101
[ 0.000000] Linux version 5.14.0 (michael@debian) (riscv32-buildroot-linux-gnu-gcc.br_real (Buildroot 2021.11-rc2-39-g37004bde66) 10.3.0, GNU ld (GNU Binutils) 2.36.1) #1 SMP Tue Nov 30 22:44:10 CST 2021
[ 0.000000] earlycon: liteuart0 at I/O port 0x0 (options '')
[ 0.000000] Malformed early option 'console'
[ 0.000000] earlycon: liteuart0 at MMIO 0xf0001000 (options '')
[ 0.000000] printk: bootconsole [liteuart0] enabled
[ 0.000000] Zone ranges:
[ 0.000000] Normal [mem 0x0000000040000000-0x000000004fffffff]
[....]

直接使用Litex-Boards脚本编译

  • 前面运行litex_setup.py --install --user时,它就会在当前目录下,同步https://github.com/litex-hub/litex-boards的源码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    ~$ cd litex-boards/litex-boards

    ~$ ./targets/digilent_arty.py --cpu-type vexriscv --with-spi-flash --with-sdcard --with-ethernet --with-pmod-gpio --sdcard-adapter=numato --build --flash

    [....]
    ===================================
    Configuration Memory information
    ===================================
    File Format BIN
    Interface SPIX4
    Size 16M
    Start Address 0x00000000
    End Address 0x00FFFFFF

    Addr1 Addr2 Date File(s)
    0x00000000 0x0021728B Nov 21 23:17:41 2021 digilent_arty.bit
    0 Infos, 0 Warnings, 0 Critical Warnings and 0 Errors encountered.
    write_cfgmem completed successfully
    # quit
    INFO: [Common 17-206] Exiting Vivado at Sun Nov 21 23:17:42 2021...

    ~$ ./targets/digilent_arty.py --cpu-type vexriscv --sys-clk-freq 100e6 --with-ethernet --with-sdcard --load

烧写到Flash

  • 下面是以openFPGALoader烧写Arty A7-100T为例。
1
./make.py --board=arty --variant=a7-100 --cpu-count=1 --build
1
~$ openFPGALoader -b arty --fpga-part xc7a100tcsg324 build/arty/gateware/arty.bit -f --verify

编译错误

  • 下面提示: FPGA的逻辑容量不够大,因为这里使用了--cpu-count=16命令参数,使用默认或者--cpu-count=1就会无错.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [....]
    WARNING: [DRC RPBF-3] IO port buffering is incomplete: Device port i2c0_scl expects both input and output buffering but the buffers are incomplete.
    INFO: [Vivado_Tcl 4-198] DRC finished with 7 Errors, 1 Warnings
    ERROR: [Vivado_Tcl 4-23] Error(s) found during DRC.Placer not run.
    INFO: [Vivado_Tcl 4-199] Please refer to the DRC report (report_drc) for more information.
    INFO: [Common 17-83] Releasing license: Implementation
    9 Infos, 1 Warnings, 0 Critical Warnings and 8 Errors encountered.
    place_design failed
    place_design: Time (s): cpu = 00:01:00 ; elapsed = 00:00:17 .Memory (MB): peak = 4696.504 ; gain = 0.000 ; free physical = 17632 ; free virtual = 88828
    ERROR: [Common 17-39] 'place_design' failed due to earlier errors.
    [...]

定制编译buildroot

  • 这里其实只下载buildroot的官方源码,指定linux-on-litex-vexriscv/buildroot内的配置文件,就可以一键编译完成,因为这里当时编译时有一个小错误,这里改了使用了git://github.com/litex-hub/linux.git另一个commit(版本): a2a2a69d144d66e0c36697da062b3949e3c2c870,它是Linux 5.15的版本.这里几乎不需要修改,使用默认的配置就能编译出一个可用的kernelrootfs.
1
2
3
4
5
6
7
8
9
10
11
~$ git clone http://github.com/buildroot/buildroot
~$ cd buildroot
~$ make BR2_EXTERNAL=../linux-on-litex-vexriscv/buildroot/ litex_vexriscv_defconfig
~$ make menuconfig

~$ buildroot$ tree output/images
output/images
├── Image
├── rootfs.cpio
└── rootfs.tar

  • BuildRoot里的Linux几个关键配置如下:

    1
    2
    3
    4
    5
    6
    ~$ cat .config
    [...]
    BR2_LINUX_KERNEL_CUSTOM_REPO_VERSION="a2a2a69d144d66e0c36697da062b3949e3c2c870"
    BR2_LINUX_KERNEL_VERSION="a2a2a69d144d66e0c36697da062b3949e3c2c870"
    BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_LITEX_VEXRISCV_PATH)/board/litex_vexriscv/linux.config"
    [...]
  • 上面的选项是Kernel -> Linux kernel -> Custom Git repository里的设置,也可以指定Custom version,比如直接使用5.16.15这样的linux kernel主线版本号,默认在kernel主分支是支持risc-v架构的。

  • 单独配置编译内核

    1
    2
    3
    buildroot$ cd dl/linux/git/
    ~$ ARCH=riscv CROSS_COMPILE=riscv64-unknown-elf- make menuconfig
    ~$ ARCH=riscv CROSS_COMPILE=riscv64-unknown-elf- make -j10
  • buildroot/output/images里的Image,rootfs.cpio复制到linux-on-litex-vexriscv/images替换同名的文件.再加载到板上运行如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Starting network: OK

Welcome to Buildroot
buildroot login: root
__ _
/ / (_)__ __ ____ __
/ /__/ / _ \/ // /\ \ /
/____/_/_//_/\_,_//_\_\
/ _ \/ _ \
__ _ __ _ _\___/_//_/ ___ _
/ / (_) /____ | |/_/__| | / /____ __ / _ \(_)__ _____ __
/ /__/ / __/ -_)> </___/ |/ / -_) \ // , _/ (_-</ __/ |/ /
/____/_/\__/\__/_/|_|____|___/\__/_\_\/_/|_/_/___/\__/|___/
/ __/ |/ / _ \
_\ \/ /|_/ / ___/
/___/_/ /_/_/
32-bit RISC-V Linux running on LiteX / VexRiscv-SMP.

login[69]: root login on 'console'
root@buildroot:~# uname -a
Linux buildroot 5.15.0 #1 SMP Sun Nov 7 10:44:48 CST 2021 riscv32 GNU/Linux
  • 开启网络
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    root@buildroot:~# ifconfig eth0 up
    root@buildroot:~# udhcpd eth0
    udhcpc eth0
    udhcpc: started, v1.35.0
    udhcpc: broadcasting discover
    udhcpc: broadcasting discover
    udhcpc: broadcasting select for 192.168.1.238, server 192.168.1.1
    udhcpc: lease of 192.168.1.238 obtained from 192.168.1.1, lease time 43200
    deleting routers
    adding dns 8.8.8.8
    adding dns 8.8.4.4

运行64位Linux

  • RISC-V-Linux
  • litex-hub/linux-on-litex-rocket
  • Rocket Core是一款处理器的核,它最大的特点是:使用Chisel(Constructing Hardware in an ScalaEmbedded Language)语言进行开发的.而Rocket-ChipSoC生成器.

BOOM Core

  • RISC-V BOOM
  • riscv-boom/riscv-boom
  • BOOM Core的全称是Berkeley Out-of-Order Machine,与Rocket Core不同的是,BOOM Core面向更高性能的目标,是一款超标量乱序发射,乱序执行的处理器核.

LowRISC SOC

编译

1
~$ litex-boards/litex_boards/targets/digilent_arty.py --build --cpu-type rocket --cpu-variant linux4 --sys-clk-freq 50e6    --with-ethernet --with-sdcard --uart_name=usb_acm

开源工具链开发

简介

Chisel/FIRRTL硬件编译框架

  • sbt
    • sbt是一个代码编译工具,是scala界的mvn,可以编译scala,java等,需要java1.6以上.作为Scala的标准构建工具,使用风格与Maven类似,由Scala语言写的,参考官方网站,目前的版本是1.54,虽然说Scala的项目可以通过Maven来构建和管理,但是依然推荐sbt,更适合一些.
  • Chisel/FIRRTL Hardware Compiler Framework
  • chipsalliance/rocket-chip
    • Rocket-chip是一个SoC生成器,在很多场景下我们常用Rocket指代Rocket处理器,而实际上Rocket-chip是一个SoC生成器(Generator),它用来根据不同的配置参数产生不同处理器的RTL代码,而后者才是一个真正的处理器.
  • chipsalliance/chisel3
    • Chisel(Constructing Hardware In a Scala Embedded Language)是UC Berkeley开发的一种开源硬件构造语言.它是建构在Scala语言之上的领域专用语言(DSL),支持高度参数化的硬件生成器.
  • chipsalliance/firrtl
    • Firrtl is an intermediate representation (IR) for digital circuits designed as a platform for writing circuit-level transformations.This repository consists of a collection of transformations (written in Scala) which simplify, verify, transform, or emit their input circuit.

SymbiFlow

Microblaze

创建工程

  • 打开Vivado点击Create New Project:
    • Project Name:设置名称与工程位置,下一步.
    • Project Type:选择RTL Project,并勾上Do not secify sources at this time,下一步.
    • Default Part:选择Boards,下拉Name选择对应的板子型号,如果列表内没有找到,先按Refresh从网上更新,再去列表内选择.这里是选择择了Arty-A7 35T的板子.
    • New Project Summary:显示工程的摘要信息,按Finish,完成工程创建,显示如下的界面.
      vivado-project.png

Create Block Design

  • 从左边导航栏里IP INTEGRATOR > Create Block Design,改名为system, 如图:
    create_new_block_design.png
  • 切换到Boardtab 页,会显示Arty A7-35的所支持硬件资源列表,这个列表的所有项,都是由该板子的board file定义的.右边Diagram,按提示: This design is empty, Press the + button to add IP,来添加一些必要的IP核.也可以从左边的树型栏,拖入控件.

配置System Clock.

  • Arty A7-35 > Clocks,拖入System ClockDiagram的画布内.
  • 双击控件下方的Clocking Wizard,打开时钟配置界面.右边表格,切换到Output Clocks页面,修改如:
    • clk_out1:勾选上,Requested,Actual栏改成166.667.
    • clk_out2:勾选上,Requested,Actual栏改成200.00.
    • Reset Type:选择Active Low.完成.

配置DDR3 SDRAM.

  • Arty A7-35 > External Memery,拖入DDR3 SDRAMDiagram的画布内.Vivado会把两个控件,自动连接.
  • 这里先要删除clk_ref_i,sys_clk_i两个默认自动连接,再用鼠标拖线连接端口,如下:
1
2
3
sys_clock           mig_7series
clk_out1 <---> sys_clk_i
clk_out2 <---> clk_ref_i

sdram_block_diagram.png

  • 点击Diagram里的高亮提示链接:Run Connection Automation.勾选上顶层All Automation,OK完成.

添加Microblaze处理器与配置

  • 点击左边栏上方IP Catalog,会在右边Diagram在边上添加一个IP Catalog的新TAB页.在页内的Search:输入Microblaze.
    microblaze_ip_core.png
  • 再双击MicroblazeAdd IP,点击Add IP to Block Design, 它就加入到设计页面里.再点击Run Block Automaction,就弹出一个配置界面,如下
    microblaze_ip_config.png
  • 确保配置参数如上图所示,尤其是Clock Connection必须连接到/mig_7series_0/ui_clk上.OK完成后,先不进行Run Connection Automation.

添加外设(Peripheral)

  • Arty A7-35 > UART,拖入USB UARTDiagram的画布内.
  • 点击Run Connection Automation,勾选顶层All Automation,OK完成.
  • Diagram上,点击右键菜单Regenerate Layout.最终布局如下:
    microblaze_layout.png

校验设计,添加HDL Wrapper

  • 点击Tools > Validate Design (F6),它检验出设计或连接错误.
  • 检验完成后无报错,打开Sources页,Design Sources > system(systemd.bd_)右键菜单,选择Create HDL Wrapper...,再选Let Vivado manage wrapper and auto-update,OK完成.

生成Bitstream文件

  • 点击左边导航栏,PROGRAM AND DEBUG > Generate Bitstream, 会出现Launch Runs对话框,配置编译项的,这里直接OK完成.这个过程的时间,会根据电脑系统的性能,以及工程设计文件的大小所决定的.在Vivado最左上角会有Running xxxxxxxxx Cancel进程条与Cancel链接.完成后,如下:
    microblaze_bitstream_done.png
  • 因为这里不需要做任何修改,就直接Cancel完成.

导出HDLSDK

  • File > Export > Export Hardware, Output选项,选择Include bitstream,下一步,可以修改XSA文件名,以及Export to的具体路径目录.完成后,会在导出的目录下,看到一个类似system_wrapper.xsa的文件.

创建应用工程(Vitis IDE)

创建平台工程

  • 这里可以从Vivado> Tools> Launch Vitis IDE运行它,Vitis IDE看它的界面,与大多数的厂商IDE差不多,都是基于Java Eclipse开发的.
  • 打开Vitis IDE> File> New> Platform Project.
    • Platform Project Name:在Platform project name:输入hello_microblaze_platform.
    • Platform:这里默认选择Create a new platform hardware (XSA),通过Browse选择前面导出的硬件文件:system_wrapper.xsa.完成.
      microblaze_app_create.png

创建应用工程

  • 上面已经创建好平台工程(platform),再创建一个应用工程File > New > Application Project:
    • Welcome:第一页,直接点下一步.
    • Platform:默认已经选择Select a platform from repository页,并且选择高亮了hello_microblaze_platform,下一步.
    • Application Project Details:输入项目名称:hello_microblaze_app.
    • Domain:默认就是standalone_domain,下一步.
    • Templates:这里会有一个模版的列表,这里就选择Hello World的模版,完成.
  • 最终工程文件结构如下图
    microblaze_apps_done.png

烧写设备

  • 打开Xilinx> Program Device对话框, 这里都是默认配置,连接Arty A7-35到电脑,直接点Program.下方的Console会有如下日志:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    updatemem -force -meminfo \
    /home/michael/workspace-xilinx/Project-ROOT/hello_microblaze_app/_ide/bitstream/system_wrapper.mmi \
    -bit \
    /home/michael/workspace-xilinx/Project-ROOT/hello_microblaze_app/_ide/bitstream/system_wrapper.bit \
    -data \
    /Xilinx-Installed-ROOT/Xilinx/Vitis/2021.1/data/embeddedsw/lib/microblaze/mb_bootloop_le.elf \
    -proc system_i/microblaze_0 -out \
    /home/michael/workspace-xilinx/Project-ROOT/hello_microblaze_app/_ide/bitstream/download.bit

    ****** updatemem v2021.1 (64-bit)
    **** SW Build 3247384 on Thu Jun 10 19:36:07 MDT 2021
    ** Copyright 1986-2021 Xilinx, Inc.All Rights Reserved.

    source /Xilinx-Installed-ROOT/Xilinx/Vitis/2021.1/scripts/updatemem/main.tcl -notrace
    Command: update_mem -meminfo /home/michael/workspace-xilinx/Project-ROOT/hello_microblaze_app/_ide/bitstream/system_wrapper.mmi -data /Xilinx-Installed-ROOT/Xilinx/Vitis/2021.1/data/embeddedsw/lib/microblaze/mb_bootloop_le.elf -proc system_i/microblaze_0 -bit /home/michael/workspace-xilinx/Project-ROOT/hello_microblaze_app/_ide/bitstream/system_wrapper.bit -out /home/michael/workspace-xilinx/Project-ROOT/hello_microblaze_app/_ide/bitstream/download.bit -force
    Loading bitfile /home/michael/workspace-xilinx/Project-ROOT/hello_microblaze_app/_ide/bitstream/system_wrapper.bit
    Loading data files...
    Updating memory content...
    Creating bitstream...
    Writing bitstream /home/michael/workspace-xilinx/Project-ROOT/hello_microblaze_app/_ide/bitstream/download.bit...
    0 Infos, 0 Warnings, 0 Critical Warnings and 0 Errors encountered.
    update_mem completed successfully
    update_mem: Time (s): cpu = 00:00:07 ; elapsed = 00:00:06 .Memory (MB): peak = 2143.617 ; gain = 873.242 ; free physical = 17872 ; free virtual = 88610
    INFO: [Common 17-206] Exiting updatemem at Sun Oct 17 00:19:15 2021...

编译及运行工程

  • 先点Explorer > hello_microblaze_app,右键Build Project,编译工程.
  • 再点Explorer > hello_microblaze_app,右键Run As > Launch Hardware (Single Application Debug).
  • 现在可以连接到本机的UART串口去观看,板子的输出.可以在IDE下方Vitis Serial Terminal页里,按**+**图标,添加一个串端配置.配置如:/dev/ttyUSB1, 9600, 0, 8.

谢谢支持

  • 微信二维码:

PYNQ-Z1

简介

  • 用于Zynq-7000 ARM/FPGA SoCDigilent PYNQ-Z1 Python编程开发板是面向嵌入式系统的通用可编程平台,其设计旨在与PYNQ配套使用.PYNQ是一套开源框架,使嵌入式编程人员可以在无需设计可编程逻辑电路的情况下探索Xilinx Zynq All Programmable SoC (APSoC)的功能.编程人员还可以使用PythonAPSoC进行编程,然后直接在PYNQ-Z1上开发和测试代码,此时可编程逻辑电路会作为硬件库导入,并且编程人员可通过其API进行编程.PYNQ-Z1开发板是PYNQ开源框架的硬件平台.
  • PYNQ-Z1支持带有板载音频和视频接口的多媒体应用.该开发板在设计上可以轻松借助Pmod、ArduinoGrove外设以及通用IO引脚来实现扩展.PYNQ-Z1开发板还可以通过USB外设进行扩展,这些外设包括WiFi,蓝牙和网络摄像头.
  • 在使用上,可以说PYNQ开发是ZYNQ开发的集大成,也可以说PYNQZYNQ的全栈式开发,里面涉及到的内容不仅包括FPGA设计、PS与PL的协同交互、HLSlinux驱动开发,而且还要熟悉Python开发并且使用Python各种库.

PS(Process System)部分

Getting Started

  • Getting Started

  • PS部分对来说,相对比较简单,就是如何把板上的硬核跑起来,这里按照官方的文档,用一张MicroSD卡刷上Pynq-Z1 v2.1 image的镜像,插入卡槽,调整跳线为SD启动.

  • 通过板上的PROG UARTUSB接口,可以连接串口输出,它是一个完整功能的Linux系统.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
~$ minicom -o -b 115200 -D /dev/ttyUSB1
[...]
Ubuntu 16.04 LTS pynq ttyPS0

pynq login: xilinx (automatic login)

Last login: Wed Feb 14 23:17:29 UTC 2018 on ttyPS0
Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.9.0-xilinx armv7l)

* Documentation: https://help.ubuntu.com/
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

xilinx@pynq:~$
  • 在终端里设置好网络部份,系统默认静态IP是:http://192.168.2.99,连接上网线,浏览器打开http://192.168.2.99,就会打开Jupyter NoteBook的服务器页面.
  • 也可以用smbclient查看它的CIFS共享目录:
1
2
3
4
5
6
7
8
~$ smbclient -m SMB3 -N  -L 192.168.2.99

Sharename Type Comment
--------- ---- -------
print$ Disk Printer Drivers
xilinx Disk
IPC$ IPC IPC Service (pynq server (Samba, Ubuntu))
SMB1 disabled -- no workgroup available

Overlays

  • PYNQ Overlays
    zynq_block_diagram.jpg
  • Overlays,或者硬件库,都是可编程FPGA的设计理念.Overlay由两个主要部分组成:bitstream文件和hwh(Hardware Handoff)文件.

TUL-PYNQ-Z2

ZYBO

SD Image

定制Linux启动镜像

BuildRoot测试

1

U-boot

AXI与PL通信

谢谢支持

  • 微信二维码:

环境安装

  • 这里没有使用AppleBox,参照了OSX-KVM使用qemu-system-x86_64安装一个Virtual Hackintosh系统来做开发.

安装Xcode

  • Xcode需要apple ID登录后下载.

安装Homebrew

1
~$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 brew install nghttp2
Updating Homebrew...
fatal: Could not resolve HEAD to a revision
==> Searching for similarly named formulae...
Error: No similarly named formulae found.
Error: No available formula or cask with the name "nghttp2".
==> Searching for a previously deleted formula (in the last month)...
Error: No previously deleted formula found.
==> Searching taps on GitHub...
Error: No formulae found in taps.
lcy@lcys-iMac-Pro ~ % git -C $(brew --repository homebrew/core) checkout master
Updating files: 100% (5923/5923), done.
Branch 'master' set up to track remote branch 'master' from 'origin'.
Already on 'master'

安装依赖库

1
~$ brew install nghttp2 nopoll  rapidjson pkg-config

编译源码到库

  • 安装编译时要用的工具.

    1
    ~$ brew install autoconf automake libtool
  • 这里以protobuf为例

    1
    2
    3
    4
    5
    6
    7
    ~$ git clone -b v2.6.0 --depth=1 https://github.com/protocolbuffers/protobuf
    ~$ cd protobuf && ./autogen.sh
    ~$ mkdir build && cd build && ../configure CC=clang CXX=clang++ CXXFLAGS="-std=c++11 -stdlib=libc++ -O3 -g" \
    LDFLAGS="-stdlib=libc++" LIBS="-lc++ -lc++abi" \
    --libdir=/usr/local/protobuf --includedir=/usr/local/protobuf/include --with-zlib && \
    make && sudo make install
    ~$
  • 安装appdmg打包脚本

    1
    2
    ~$ brew install node
    ~$ npm install appdmg -g

库版本不兼容的问题

  • 库版本不兼容的问题,因为程序是在Catalina 10.15.17编译构建的,而且通过brew安装的二进制库,都是根据系统版本(Catalina)下载的,下面错误,是在High Sierra 10.13.17下去运行,出现下面错误,这两个系统版本不兼容.
1
2
3
4
5
6
7
	dyld: lazy symbol binding failed: Symbol not found: ____chkstk_darwin
Referenced from: /Applications/MyApp.app/Contents/MacOS/./../Frameworks/libssl.1.1.dylib (which was built for Mac OS X 10.15)
Expected in: /usr/lib/libSystem.B.dylib

dyld: Symbol not found: ____chkstk_darwin
Referenced from: /Applications/MyApp.app/Contents/MacOS/./../Frameworks/libssl.1.1.dylib (which was built for Mac OS X 10.15)
Expected in: /usr/lib/libSystem.B.dylib
  • 处理上述问题,必须从源码去编译相应的依赖库,指定export MACOSX_DEPLOYMENT_TARGET=10.12变量,在Qt5工程配置是QMAKE_MACOSX_DEPLOYMENT_TARGET变量.

错误记录

签名权限错误

  • Running codesign over SSH with a new key

  • 必须在OSX图形系统内,使用termiator运行签名.下面是通过SSH运行codesign所出现的错误.

    1
    2
    3
    Error: Command failed: codesign --verbose --sign Developer ID Application: My Company Technology Co. Ltd. (XXXXXXXX) /Users/tuser/dailybuild_mac/felo-client-mac-2021.19.137.dmg
    /Users/tuser/dailybuild_mac/felo-client-mac-2021.19.137.dmg: errSecInternalComponent

  • 通过下面操作终端(shell)导入签名证书.再试试看,再尝试通过SSH去签名,看是否成功.

    1
    2
    3
    ~$ sudo security import developer_id.p12 -k /Library/Keychains/System.keychain -P "<your password>" -T /usr/bin/codesign
    # must run below in the shell.
    ~$ security unlock-keychain
  • 下面这个错误也是类似,只是现在Linux下.QT程序内调用root权限,通过远程ssh -X运行的GUI程序会有下面错误,而在它的本机上面确不会,如,使用pkexec运行,会调出一个输入密码的窗口.

    1
    Error creating textual authentication agent: Error opening current controlling terminal for the process (`/dev/tty'): No such device or address

打包错误

  • 下面的错误,要确认主工程内的info.plist文件里的CFBundleExecutable,CFBundleName节点值,是否与bundle名称对应,是否与主工程.pro里的TARGET对应.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
~$ macdeployqt output/myappqt.app
ERROR: Could not find bundle binary for "/Users/tuser/myapp-desktop/build-myappqt-Desktop_x86_darwin_generic_mach_o_64bit-Release/output/myappqt.app"
ERROR: "error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/otool-classic: can't open file: (No such file or directory)\n"
ERROR: "error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/otool-classic: can't open file: (No such file or directory)\n"
ERROR: "error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/otool-classic: can't open file: (No such file or directory)\n"
WARNING:
WARNING: Could not find any external Qt frameworks to deploy in "/Users/tuser/myapp-desktop/build-myappqt-Desktop_x86_darwin_generic_mach_o_64bit-Release/output/myappqt.app"
WARNING: Perhaps macdeployqt was already used on "/Users/tuser/myapp-desktop/build-myappqt-Desktop_x86_darwin_generic_mach_o_64bit-Release/output/myappqt.app" ?
WARNING: If so, you will need to rebuild "/Users/tuser/myapp-desktop/build-myappqt-Desktop_x86_darwin_generic_mach_o_64bit-Release/output/myappqt.app" before trying again.
Empty filename passed to function
ERROR: Could not find bundle binary for "/Users/tuser/myapp-desktop/build-myappqt-Desktop_x86_darwin_generic_mach_o_64bit-Release/output/myappqt.app"
ERROR: "error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/strip: can't open file: (No such file or directory)\n"
ERROR: ""

  • macdeployqt错误

    1
    2
    ERROR: no file at “/usr/local/opt/libiodbc/lib/libiodbc.2.dylib”
    ERROR: no file at “/Applications/Postgres.app/Contents/Versions/9.6/lib/libpq.5.dylib”
  • 上面错误是缺失两个依赖的库,须要安装下面支持

    1
    2
    3
    4
    5
    6
    ~$ brew install libiodbc postgres

    ~$ sudo mkdir -pv /Applications/Postgres.app/Contents/Versions/9.6
    ~$ sudo ln -svf /usr/local/Cellar/postgresql/13.3/lib /Applications/Postgres.app/Contents/Versions/9.6
    /Applications/Postgres.app/Contents/Versions/9.6/lib -> /usr/local/Cellar/postgresql/13.3/lib

  • 不能加载插件的错误,如果不是从终端(shell)打开目标程序,就表显为程序闪退.终端打开运行显示如下:

    1
    2
    3
    4
    5
    qt.qpa.plugin: Could not load the Qt platform plugin "cocoa" in "" even though it was found.
    This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

    Available platform plugins are: cocoa.

  • 上面错误信息,只是初步定位了错误,如果是在Linux下,上面错误基本是因为文件不存造成.这里打开export QT_DEBUG_PLUGINS=1,查看如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Got keys from plugin meta data ("cocoa")
    QFactoryLoader::QFactoryLoader() checking directory path "/Applications/MyApp.app/Contents/MacOS/platforms" ...
    Cannot load library /Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib: (dlopen(/Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib, 133): no suitable image found. Did find:
    /Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib: code signature in (/Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.)
    QLibraryPrivate::loadPlugin failed on "/Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib" : "Cannot load library /Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib: (dlopen(/Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib, 133): no suitable image found. Did find:\n\t/Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib: code signature in (/Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.)"
    qt.qpa.plugin: Could not load the Qt platform plugin "cocoa" in "" even though it was found.
    This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

    Available platform plugins are: cocoa.

    Abort trap: 6

  • 如上所示,在OSX下出现的Could not load the Qt platform plugin是因为文件未签名造成的.使用下面方法尝试处理.

    1
    ~$ codesign -f -s "Mac Developer: 你的开发者邮箱" /usr/local/opt/*/lib/*.dylib

签名问题

  • 检验签是否正确

    1
    2
    3
    ~$ spctl -a -t exec -vv /Applications/MyApp.app
    /Applications/MyApp.app: nested code is modified or invalid

  • 查看具体签名错误详情

    1
    2
    3
    4
    5
    ~$ codesign --verify --deep --verbose dmg_root/MyApp.app
    dmg_root/MyApp.app: nested code is modified or invalid
    In subcomponent: /Users/user/myapp-desktop/build-myappqt-Desktop_x86_darwin_generic_mach_o_64bit-Release/dmg_root/MyApp.app/Contents/Frameworks/QtWebEngineCore.framework
    file modified: /Users/user/myapp-desktop/build-myappqt-Desktop_x86_darwin_generic_mach_o_64bit-Release/dmg_root/MyApp.app/Contents/Frameworks/QtWebEngineCore.framework/Versions/Current/Helpers/QtWebEngineProcess.app

  • 签名后,检验将要打包的bundle目录签名情况,直到出现下面这样正确为止.

    1
    2
    3
    4
    ~$ codesign --verify --deep --verbose dmg_root/MyApp.app
    dmg_root/MyApp.app: valid on disk
    dmg_root/MyApp.app: satisfies its Designated Requirement

  • 如果按上述签名成,但是其它机器上安装成功,运行时确崩溃了,有些系统会有DiagnosticReports,有些是直接闪退.下面DiagnosticReports的错误,关键信息是EXC_BAD_ACCESS (Code Signature Invalid),__TEXT字段处是指向libcrypto.1.1,可以对libcrypto.1.1路径的文件进行签名校验查看.用户程序crash出错的路径是在/Users/<username>/Library/Logs/DiagnosticReports下面.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Time Awake Since Boot: 12000 seconds

System Integrity Protection: enabled

Crashed Thread: 0 Dispatch queue: com.apple.main-thread

Exception Type: EXC_BAD_ACCESS (Code Signature Invalid)
Exception Codes: 0x0000000000000032, 0x0000000106f3a000
Exception Note: EXC_CORPSE_NOTIFY

Termination Reason: Namespace CODESIGNING, Code 0x2

kernel messages:

VM Regions Near 0x106f3a000:
shared memory 0000000106f36000-0000000106f3a000 [ 16K] r--/r-- SM=SHM
--> mapped file 0000000106f3a000-0000000106f3c000 [ 8K] r--/r-- SM=PRV Object_id=4f872dd9
__TEXT 0000000106f3d000-0000000107165000 [ 2208K] r-x/rwx SM=COW /Applications/MyApp.app/Contents/Frameworks/libcrypto.1.1.dylib

Application Specific Information:
dyld: in dlopen()
/Applications/MyApp.app/Contents/Plugins/platforms/libqcocoa.dylib

  • 下面要是目标程序的未完整签名造成的.__TEXT指向当前系统的/usr/lib/dyld.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type: EXC_BAD_ACCESS (Code Signature Invalid)
Exception Codes: 0x0000000000000032, 0x0000000109bed000
Exception Note: EXC_CORPSE_NOTIFY

Termination Reason: Namespace CODESIGNING, Code 0x2

kernel messages:

VM Regions Near 0x109bed000:
shared memory 0000000109be5000-0000000109bed000 [ 32K] r--/r-- SM=SHM
--> mapped file 0000000109bed000-0000000109da9000 [ 1776K] r--/r-- SM=PRV Object_id=4f872dd9
__TEXT 000000010a61a000-000000010a6ac000 [ 584K] r-x/r-x SM=COW /usr/lib/dyld
  • OSX编译链接的错误问题, 是因为缺少了这个架构的库文件
    1
    2
    3
    4
    5
    6
    7

    Undefined symbols for architecture x86_64:
    "_iconv_ostream_create", referenced from:
    -exported_symbol[s_list] command line option
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

OSX命令行操作

重启服务

1
2
lcy@lcys-iMac-Pro ~ % sudo launchctl stop com.openssh.sshd
lcy@lcys-iMac-Pro ~ % sudo launchctl start com.openssh.sshd
  • 或者
1
2
lcy@lcys-iMac-Pro ~ %  sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist
lcy@lcys-iMac-Pro ~ % sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist

使用apple脚本开启远程管理(VNC桌面访问)

1
2
3
4
5
6
7
8
#!/bin/zsh
osascript -e "do shell script \"
/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -allowAccessFor -allUsers -privs -all
/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -clientopts -setvnclegacy -vnclegacy yes
/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -clientopts -setvncpw -vncpw 1234test
/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -restart -agent -console
/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate
\" with administrator privileges"
  • osascript是调起一个图形授权窗口,类似于终端的sudo,在Windows下就类似是UAC窗体,在Linux下就是调用pkexec获取sudo权限.

Command Line 修改配置(defaults)

  • 枚举出所有的可配置域.

    1
    2
    3
    sudo defaults domains
    com.apple.AppleMultitouchMouse, com.apple.AppleMultitouchTrackpad, com.apple.CoreBrightness, com.apple.CoreGraphics, com.apple.CrashReporterSupportHelper, com.apple.MobileAsset, com.apple.SSMenuAgent, com.apple.SoftwareUpdate, com.apple.UserAccountUpdater, com.apple.WirelessRadioManager.debug, com.apple.airplay, com.apple.awdd.persistent, com.apple.bluetoothd, com.apple.corecaptured, com.apple.coreduetd, com.apple.das.fairscheduling, com.apple.driver.AppleBluetoothMultitouch.mouse, com.apple.driver.AppleBluetoothMultitouch.trackpad, com.apple.driver.AppleHIDMouse, com.apple.dt.xcodebuild, com.apple.icloud.findmydeviced, com.apple.icloud.searchpartyd, com.apple.java.util.prefs, com.apple.loginwindow, com.apple.mediaremote, com.apple.mediaremoted, com.apple.rtcreporting, com.apple.security.ctkd-db, com.apple.systempreferences, com.apple.systemstats.microstackshot, com.apple.tailspin, com.apple.universalaccess, com.apple.xpc.activity2, com.oracle.javadeployment, systemmigrationd

  • 查看一个域的配置.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ~$ sudo defaults export com.apple.systempreferences -
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    <key>AttentionPrefBundleIDs</key>
    <dict>
    <key>com.apple.preferences.softwareupdate</key>
    <integer>1</integer>
    </dict>
    </dict>
    </plist>

  • 查看一个文件的配置.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    ~$ sudo defaults export /Library/Preferences/com.apple.RemoteManagement.plist -
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    <key>-bool</key>
    <string>no</string>
    <key>ARD_AllLocalUsers</key>
    <true/>
    <key>ARD_AllLocalUsersPrivs</key>
    <integer>1073742079</integer>
    <key>AllowSRPForNetworkNodes</key>
    <false/>
    <key>DisableKerberos</key>
    <false/>
    <key>LoadRemoteManagementMenuExtra</key>
    <true/>
    <key>ScreenSharingReqPermEnabled</key>
    <false/>
    <key>VNCLegacyConnectionsEnabled</key>
    <true/>
    <key>allowInsecureDH</key>
    <true/>
    </dict>
    </plist>
  • 读取域内的一个键值

    1
    2
    sudo defaults read /Library/Preferences/com.apple.RemoteManagement.plist ARD_AllLocalUsers
    1
  • 写入一个键值

    1
    sudo defaults write /Library/Preferences/com.apple.RemoteManagement.plist RestoreMachineState -bool no

keychain密码访问SUDO

查找OSX的服务运行参数

1
2
~$ launchctl list | grep "RemoteDesktop"
66152 -9 com.apple.RemoteDesktop.agent
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
~$ launchctl print system/com.apple.remotemanagementd
com.apple.remotemanagementd = {
active count = 0
copy count = 0
one shot = 0
path = /System/Library/LaunchDaemons/com.apple.remotemanagementd.plist
state = waiting

program = /System/Library/PrivateFrameworks/RemoteManagement.framework/remotemanagementd
default environment = {
PATH => /usr/bin:/bin:/usr/sbin:/sbin
}

environment = {
XPC_SERVICE_NAME => com.apple.remotemanagementd
}

domain = com.apple.xpc.launchd.domain.system
minimum runtime = 10
exit timeout = 5
runs = 0
successive crashes = 0
last exit code = (never exited)

semaphores = {
provides events => 1
}

event triggers = {
com.apple.remotemanagement.cloudConfigAvailable => {
keepalive = 0
service = com.apple.remotemanagementd
stream = com.apple.distnoted.matching
monitor = com.apple.UserEventAgent-System
descriptor = {
"Name" => "CPCloudConfigIsMDMv2Notification"
}
}
}

endpoints = {
"com.apple.remotemanagementd" = {
port = 0x1d703
active = 0
managed = 1
reset = 0
hide = 0
}
"com.apple.aps.remotemanagementd.http.apns-dev" = {
port = 0x1d803
active = 0
managed = 1
reset = 0
hide = 0
}
"com.apple.aps.remotemanagementd.http.apns-prod" = {
port = 0x18303
active = 0
managed = 1
reset = 0
hide = 0
}
}

dynamic endpoints = {
}

pid-local endpoints = {
}

instance-specific endpoints = {
}

event channels = {
"com.apple.distnoted.matching" = {
port = 0x18403
active = 0
managed = 1
reset = 0
hide = 0
}
}

sockets = {
}

instances = {
}

spawn type = background
spawn role = (null)
jetsam priority = 3
jetsam memory limit (active, soft) = 15 MB
jetsam memory limit (inactive, soft) = 15 MB
jetsamproperties category = daemon
jetsam thread limit = 32
cpumon = default

properties = {
partial import = 0
launchd bundle = 0
xpc bundle = 0
keepalive = 0
runatload = 0
low priority i/o = 0
low priority background i/o = 0
dataless file mode = 0
legacy timer behavior = 0
exception handler = 0
multiple instances = 0
supports transactions = 1
supports pressured exit = 1
supports idle hysteresis = 0
enter kdp before kill = 0
wait for debugger = 0
app = 0
system app = 0
creates session = 0
inetd-compatible = 0
inetd listener = 0
abandon process group = 0
one-shot = 0
event monitor = 0
penalty box = 0
pended non-demand spawn = 0
role account = 0
launch only once = 0
system support = 0
app-like = 0
inferred program = 0
joins gui session = 0
joins host session = 0
parameterized sandbox = 0
resolve program = 0
abandon coalition = 0
high bits aslr = 0
extension = 0
nano allocator = 0
no initgroups = 0
start on fs mount = 0
endpoints initialized = 1
is copy = 0
disallow all lookups = 0
system service = 1
protected by submitter = 0
}
}

谢谢支持

  • 微信二维码:

安装

  • Debian 安装
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    ~$ sudo apt-get remove docker docker-engine docker.io containerd runc
    ~$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

    ~$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

    ~$ echo \
    "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
    $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

    ~$ sudo apt-get update
    ~$ sudo apt-get install docker-ce docker-ce-cli containerd.io

Docker容器基本操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7ba1108b9f98 jenkinsci/jenkins "/sbin/tini -- /usr/l" 39 minutes ago Up 39 minutes 50000/tcp, 0.0.0.0:9090->8080/tcp jenkins
~$ docker exec -ti 7ba1108b9f98 /bin/bash #进入容器
jenkins@7ba1108b9f98:/$
jenkins@7ba1108b9f98:/$ exit
~$ docker exec --user root -ti 7ba1108b9f98 /bin/bash #进入容器,root用户.
root@7ba1108b9f98:/#

$ docker ps  
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
89abae910d39 gitlab/gitlab-ce "/assets/wrapper" 18 minutes ago Up 18 minutes 0.0.0.0:80->80/tcp, 443/tcp, 0.0.0.0:2222->22/tcp gitlab
7ba1108b9f98 jenkinsci/jenkins "/sbin/tini -- /usr/l" 2 hours ago Up 2 hours 50000/tcp, 0.0.0.0:9090->8080/tcp jenkins
~$ docker stop 89abae910d39 #停止容器
89abae910d39
~$ docker rm 89abae910d39 #删除除容器
89abae910d39
~$ docker rmi gitlab/gitlab-ce #删除镜像

~$ docker image prune -a #清除未使用的镜像,释放磁盤空间.

~$ docker system prune #清除更多的选项的资源.
  • 查看它的运行状态
1
2
3
4
5
6
7
~$ docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
91fca6eba694 dendrite_kafka 1.50% 357MiB / 31.27GiB 1.11% 1.6MB / 2.09MB 0B / 3.35MB 104
9600de970dfb docker_zookeeper_1 0.04% 84.32MiB / 31.27GiB 0.26% 48.6kB / 27.7kB 1.65MB / 803kB 83
6024799cf47c docker_monolith_1 0.68% 15.75MiB / 31.27GiB 0.05% 2.15MB / 1.69MB 877kB / 328kB 21
0446e52d719d docker_postgres_1 0.00% 50.26MiB / 31.27GiB 0.16% 138kB / 86.1kB 16.5MB / 12.3MB 15
8a986b075043 traefik_reverse-proxy_1 0.00% 23.53MiB / 31.27GiB 0.07% 49.8kB / 1.52MB 66.6MB / 0B 21

容器网络

  • 查看网络

    1
    2
    3
    4
    5
    ~$ docker network ls
    NETWORK ID NAME DRIVER SCOPE
    108d6f126660 bridge bridge local
    1f2d1f3f0ebf host host local
    b17831300bb4 none null local
  • 查看详情

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    docker network inspect bridge
    [
    {
    "Name": "bridge",
    "Id": "108d6f126660ffa74a81eebdb65ebf5e982cfcc0a0e982cdf832de602e462dca",
    "Created": "2020-11-18T09:42:07.001834136Z",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv6": true,
    "IPAM": {
    "Driver": "default",
    "Options": null,
    "Config": [
    {
    "Subnet": "172.17.0.0/16",
    "Gateway": "172.17.0.1"
    },
    {
    "Subnet": "2600:3c03:xx:x/64",
    "Gateway": "2600:3c03:xx:x1"
    }
    ]
    },
    "Internal": false,
    "Attachable": false,
    "Ingress": false,
    "ConfigFrom": {
    "Network": ""
    },
    "ConfigOnly": false,
    "Containers": {
    "3ca33d64a42243f5ac77dcf61eeb8262ff8f6a30e341b34a4f5352adc5f98ca9": {
    "Name": "ss-server",
    "EndpointID": "9230ae11d665b088d23ef939ee959a9ad512a2f3667106688f38e63f85f603a1",
    "MacAddress": "02:42:ac:11:00:02",
    "IPv4Address": "172.17.0.2/16",
    "IPv6Address": "2600:3c03::242:xx:x/64"
    },
    "893078d9926bd8f41d669975c48be945472feaad5daed23c937ce8ab517b5a18": {
    "Name": "trojan",
    "EndpointID": "0c3650579b8029b9ce940459a7ac795828cb76eaec331ac179ea9708adaba8ae",
    "MacAddress": "02:42:ac:11:00:03",
    "IPv4Address": "172.17.0.3/16",
    "IPv6Address": "2600:3c03::242:xx:x/64"
    }
    },
    "Options": {
    "com.docker.network.bridge.default_bridge": "true",
    "com.docker.network.bridge.enable_icc": "true",
    "com.docker.network.bridge.enable_ip_masquerade": "true",
    "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
    "com.docker.network.bridge.name": "docker0",
    "com.docker.network.driver.mtu": "1500"
    },
    "Labels": {}
    }
    ]

  • 创建网络

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
~$ docker network create --ipv6 --driver=bridge --subnet=172.20.0.0/24 --subnet=2600:3c03:1111::/64 --gateway=172.20.0.1 ipv6_bridge
7fa02d4275d7a5165ed4169161895d6ead1fc55a785b1d39bf0da129ec40cff8
docker network inspect ipv6_bridge
[
{
"Name": "ipv6_bridge",
"Id": "7fa02d4275d7a5165ed4169161895d6ead1fc55a785b1d39bf0da129ec40cff8",
"Created": "2020-11-19T05:15:23.263134245Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": true,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.20.0.0/24",
"Gateway": "172.20.0.1"
},
{
"Subnet": "2600:3c03:1111::/64"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]

  • 把现有的容器连接到新的网络
1
~$ docker network  connect ipv6_bridge <container>

代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
~$ sudo mkdir -p /etc/systemd/system/docker.service.d

# "HTTP_PROXY=socks5://127.0.0.1:1080" for socks5 proxy
~$ cat <<EOF >/etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://user01:password@10.10.10.10:8080/"
Environment="HTTPS_PROXY=https://user01:password@10.10.10.10:8080/"
Environment="NO_PROXY= hostname.example.com,172.10.10.10"
EOF

~$ systemctl daemon-reload
~$ systemctl restart docker
~$ systemctl show docker --property Environment
Environment=HTTP_PROXY=socks5://127.0.0.1:1080 HTTPS_PROXY=socks5://127.0.0.1:1080

使用HTTP与Docker交互

1
2
3
4
5
6
~$ curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" \
-d '{"Image": "alpine", "Cmd": ["echo", "hello world"]}' \
-X POST http://localhost/v1.41/containers/create
{"Id":"1c6594faf5","Warnings":null}

~$ curl --unix-socket /var/run/docker.sock -X POST http://localhost/v1.41/containers/1c6594faf5/start

配置存储驱动

  • Manage data in Docker
  • Docker支持多种存储驱动,默认是使用devicemapperloopback-lvm方式,它是零配置,但是性能差,不推荐在生产环境中使用.生产中建议使用direct-lvm的方式.默认的存储会有以下的警告:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
 docker info
Client:
Context: default
Debug Mode: false
Plugins:
app: Docker App (Docker Inc., v0.9.1-beta3)
buildx: Build with BuildKit (Docker Inc., v0.5.1-docker)

Server:
Containers: 7
Running: 5
Paused: 0
Stopped: 2
Images: 268
Server Version: 20.10.5
Storage Driver: devicemapper
Pool Name: docker-8:18-38141955-pool
Pool Blocksize: 65.54kB
Base Device Size: 107.4GB
Backing Filesystem: ext4
Udev Sync Supported: true
Data file: /dev/loop0
Metadata file: /dev/loop1
Data loop file: /home/michael/3TB-DISK/docker/devicemapper/devicemapper/data
Metadata loop file: /home/michael/3TB-DISK/docker/devicemapper/devicemapper/metadata
Data Space Used: 94.71GB
Data Space Total: 107.4GB
Data Space Available: 12.66GB
Metadata Space Used: 84.49MB
Metadata Space Total: 2.147GB
Metadata Space Available: 2.063GB
Thin Pool Minimum Free Space: 10.74GB
Deferred Removal Enabled: true
Deferred Deletion Enabled: true
Deferred Deleted Device Count: 0
Library Version: 1.02.155 (2018-12-18)
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 1
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc io.containerd.runc.v2 io.containerd.runtime.v1.linux
Default Runtime: runc
Init Binary: docker-init
containerd version: 05f951a3781f4f2c1911b05e61c160e9c30eaa8e
runc version: 12644e614e25b05da6fd08a38ffa0cfe1903fdec
init version: de40ad0
Security Options:
seccomp
[....]
WARNING: the devicemapper storage-driver is deprecated, and will be removed in a future release.
WARNING: devicemapper: usage of loopback devices is strongly discouraged for production use.
Use `--storage-opt dm.thinpooldev` to specify a custom block storage device.
  • 如果磁盘镜像文件太多了,如有如下错误:
    1
    2
    docker: Error response from daemon: devmapper: Thin Pool has 486 free data blocks which is less than minimum required 163840 free data blocks. Create more free space in thin pool or use dm.min_free_space option to change behavior.
    See 'docker run --help'.
  • 可以使用下面命令清除docker内的临时文件
    1
    ~$ docker system prune

Overlay2驱动

1
2
3
4
5
6
7
8
9
10
11
~$ sudo mkfs.xfs -n ftype=1 /dev/sdb1
meta-data=/dev/sdb1 isize=512 agcount=4, agsize=18310464 blks
= sectsz=4096 attr=2, projid32bit=1
= crc=1 finobt=1, sparse=1, rmapbt=0
= reflink=0
data = bsize=4096 blocks=73241856, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0, ftype=1
log =internal log bsize=4096 blocks=35762, version=2
= sectsz=4096 sunit=1 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
  • 配置daemon.json,参考daemon-configuration-file

    1
    2
    ~$ sudo systemctl stop docker
    ~$ echo '{ "storage-driver": "overlay2" }' | jq '.' | sudo tee /etc/docker/daemon.json
  • 重启

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    ~$ sudo systemctl start docker
    ~$ docker info
    Client:
    Context: default
    Debug Mode: false
    Plugins:
    app: Docker App (Docker Inc., v0.9.1-beta3)
    buildx: Build with BuildKit (Docker Inc., v0.5.1-docker)

    Server:
    Containers: 0
    Running: 0
    Paused: 0
    Stopped: 0
    Images: 0
    Server Version: 20.10.5
    Storage Driver: overlay2
    Backing Filesystem: xfs
    Supports d_type: true
    Native Overlay Diff: true
    Logging Driver: json-file
    Cgroup Driver: cgroupfs
    Cgroup Version: 1
    [...]
  • Export/Import容器

  • 这里是在原来的devicemapper驱动里的容器导出,再切换到overlay2驱动导入.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ~$ docker save sickcodes/docker-osx > ~/3TB-DISK/docker-osx.tar
    ~$ docker load < ~/3TB-DISK/docker-osx.tar
    e4f1ca1ca7a8: Loading layer [==================================================>] 731.1MB/731.1MB
    ee2075d8bcfb: Loading layer [==================================================>] 35.84kB/35.84kB
    a98393dc6c96: Loading layer [==================================================>] 59.95MB/59.95MB
    116b71590f7b: Loading layer [==================================================>] 166MB/166MB
    d3c6d5a7aa4e: Loading layer [==================================================>] 59.95MB/59.95MB
    6dd5cd2c75b5: Loading layer [==================================================>] 2.048kB/2.048kB
    908b86edf5d9: Loading layer [==================================================>] 2.56kB/2.56kB
    c706cc5ac18e: Loading layer [==================================================>] 6.144kB/6.144kB
    [...]
1
2
3
4
5
6
~$ for item in 6ffe5fbf69b7  92527f264cc9  a15038d35f57 d10b5c313d05; do
docker export $item > docker-export-${item}.tar ;
done
~$ for item in `ls docker-export*.tar`; do
docker import $item ;
done

使用multi-stage功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
FROM golang:1.16 AS builder
RUN go version

ARG upx_version=3.96
ARG GOPROXY

RUN go env -w GO111MODULE=on
RUN go env -w GOPROXY=https://goproxy.io,direct

COPY . /go/src/github.com/xindalcy/frp
WORKDIR /go/src/github.com/xindalcy/frp
#RUN set -x && \
# go get github.com/golang/dep/cmd/dep && \
# dep ensure -v

RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -ldflags="-w -s" -o bin/frps ./cmd/frps


SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends xz-utils && \
curl -Ls https://github.com/upx/upx/releases/download/v${upx_version}/upx-${upx_version}-amd64_linux.tar.xz -o - | tar xvJf - -C /tmp && \
cp /tmp/upx-${upx_version}-amd64_linux/upx /usr/local/bin/ && \
chmod +x /usr/local/bin/upx

RUN /usr/local/bin/upx -9 /go/src/github.com/xindalcy/frp/bin/frps

FROM scratch
COPY --from=builder /go/src/github.com/xindalcy/frp/bin/frps /go/bin/frps

EXPOSE 7001/tcp
EXPOSE 7500/tcp
EXPOSE 7001/udp
EXPOSE 7002/udp

VOLUME /etc/frp/

ENTRYPOINT ["/go/bin/frps","-c","/etc/frp/frps.ini"]
  • 上面这个脚本,演示如何在一个Dockerfile里实现分阶段创建镜像,最终的Docker镜像体积非常小,因为它是从scratch上构建的。

搭建基于DokkuPaaS平台

服务端安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# 参考位置 http://dokku.viewdocs.io/dokku/getting-started/install/debian/ 改编的文件
- name: 安装Dokku
hosts: DB001
become: yes
# user: root 这里可以直接用root,但是关闭root远程登录后要使用sudo.
tasks:
# 参照文档 https://docs.ansible.com/ansible/latest/modules/apt_module.html
- name: 更新并安装
apt:
name: ['apt-transport-https', 'wget']
allow_unauthenticated: yes
update_cache: yes

- name: 添加公钥
apt_key:
url: https://packagecloud.io/gpg.key
validate_certs: no
state: present

# 参考文档 https://docs.ansible.com/ansible/latest/modules/command_module.html#command-module
- name: 读取系统发行版本号
command: lsb_release -sc
register: result

# https://docs.ansible.com/ansible/latest/modules/stat_module.html?highlight=stat 读取文件的stat
- stat:
path: /etc/apt/sources.list.d/dokku_dokku.list
register: dokku_repo

# https://docs.ansible.com/ansible/latest/user_guide/playbooks_blocks.html
# 把几个任务组合起来,用条件判断.
- block:
# https://docs.ansible.com/ansible/latest/modules/get_url_module.html?highlight=get_url
- name: 下载安装脚本
get_url:
url: https://packagecloud.io/install/repositories/dokku/dokku/script.deb.sh
dest: /tmp/script.deb.sh
validate_certs: no
force: yes
mode: 0755

# https://docs.ansible.com/ansible/latest/modules/script_module.html
# 也可以从这里直接下载deb安装包. https://packagecloud.io/dokku/dokku/
- name: 运行安装Dokku脚本
command: bash /tmp/script.deb.sh
when: dokku_repo.stat.exists is not defined or dokku_repo.stat.size == 0

- name: 安装dokku
apt:
name: ['dokku']
allow_unauthenticated: yes
update_cache: yes

# https://docs.ansible.com/ansible/latest/modules/debconf_module.html
- name: unattended installation of dokku
debconf:
name: dokku
question: dokku/vhost_enable
value: 'true'
vtype: select

- name: 安装Dokku依赖
command: dokku plugin:install-dependencies --core
  • 安装完成后会启动一个http-server提供web方式的配置,浏览器输入服务器ip打开页面,输入公钥和域名(或者公网 IP)就 OK.

客户端安装

  • dokku-client这个客户端很久没有更新的了,不支持 python3.
  • 官方客户端,这里基于不同语言有比较全面的客户端介绍.
  • Deploying Django on Dokku
  • 这里使用官方的提供的客户端脚本,如下面所示,运行脚本前,先要确定几个重点,一是添加DOKKU_HOST环境变里,或者直接写入$HOME/.dokku/contrib/dokku_client.sh这个脚本里面.二是能使用公钥登录目标dokku服务器.
  • dokku服务器端加入一个可信的客户端公钥,操作如下:
1
2
3
4
5
6
7
8
9
# 列出本机加入的可信公钥
~$ dokku ssh-keys:list
SHA256:Lr2N48k+1UDb0IxxWm0AhI0fzpdpnEZtalGc+XXXXX NAME="admin1" SSHCOMMAND_ALLOWED_KEYS="no-agent-forwarding,no-user-rc,no-X11-forwarding,no-port-forwarding"
# 添加一个客户端的公钥
~$ sudo dokku ssh-keys:add admin2 /fullpath/id_rsa.pub
SHA256:diDyzHYBmugZoGkWw1RaqzGkLfdCUpmBOxXFnf/XXXX
~$ dokku ssh-keys:list
SHA256:Lr2N48k+1UDb0IxxWm0AhI0fzpdpnEZtalGc+Pf7Rvo NAME="admin1" SSHCOMMAND_ALLOWED_KEYS="no-agent-forwarding,no-user-rc,no-X11-forwarding,no-port-forwarding"
SHA256:diDyzHYBmugZoGkWw1RaqzGkLfdCUpmBOxXFnf/XXXX NAME="admin2" SSHCOMMAND_ALLOWED_KEYS="no-agent-forwarding,no-user-rc,no-X11-forwarding,no-port-forwarding"
  • 下载客户端仓库.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ~$ git clone git@github.com:dokku/dokku.git ~/.dokku

    # optional: make sure that the dokku_client.sh version matches your Dokku version
    ~$ cd ~/.dokku
    ~$ git checkout <tag/branch>

    # add the following to either your
    # .bashrc, .bash_profile, or .profile file
    ~$ alias dokku='$HOME/.dokku/contrib/dokku_client.sh'
  • 正常的客户端运行如下,与heroku的客户端命令极其相似.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    ~$ dokku
    Usage: dokku [--quiet|--trace|--rm-container|--rm|--force] COMMAND <app> [command-specific-options]

    Primary help options, type "dokku COMMAND:help" for more details, or dokku help --all to see all commands.

    Commands:

    apps Manage Dokku apps
    certs Manage Dokku apps SSL (TLS) certs
    checks Manage zero-downtime settings
    config Manages global and app-specific config vars
    docker-options Pass options to Docker the various stages of an app
    domains Manage vhost domains used by the Dokku proxy
    enter Connect to a specific app container
    events Show the last events (-t follows)
    git Manages the git integration for an app
    help Print the list of commands
    logs Output app logs
    network Manages network settings for an app
    nginx Interact with Dokku\'s Nginx proxy
    proxy Manage the proxy used by dokku on a per app
    ps List processes running in app container(s)
    repo Runs commands that interact with the app\'s repo
    run Run a command in a new container using the current application image
    scheduler-docker-local Manages the scheduler-docker-local integration for an app
    shell Spawn dokku shell
    ssh-keys Manage public ssh keys that are allowed to connect to Dokku
    storage Mount local volume / directories inside containers
    tags List all app image tags
    tar Deploy applications via tarball instead of git
    trace Enable dokku tracing
    url Show the first URL for an application (compatibility)
    urls Show all URLs for an application
    version Print dokku\'s version

    ~$ dokku plugin:list
    ! Deprecated: Please use plugin:list
    plugn: 0.3.0
    00_dokku-standard 0.14.1 enabled dokku core standard plugin
    20_events 0.14.1 enabled dokku core events logging plugin
    app-json 0.14.1 enabled dokku core app-json plugin
    apps 0.14.1 enabled dokku core apps plugin
    build-env 0.14.1 enabled dokku core build-env plugin
    certs 0.14.1 enabled dokku core certificate management plugin
    checks 0.14.1 enabled dokku core checks plugin
    common 0.14.1 enabled dokku core common plugin
    config 0.14.1 enabled dokku core config plugin
    docker-options 0.14.1 enabled dokku core docker-options plugin
    domains 0.14.1 enabled dokku core domains plugin
    enter 0.14.1 enabled dokku core enter plugin
    git 0.14.1 enabled dokku core git plugin
    logs 0.14.1 enabled dokku core logs plugin
    network 0.14.1 enabled dokku core network plugin
    nginx-vhosts 0.14.1 enabled dokku core nginx-vhosts plugin
    plugin 0.14.1 enabled dokku core plugin plugin
    proxy 0.14.1 enabled dokku core proxy plugin
    ps 0.14.1 enabled dokku core ps plugin
    repo 0.14.1 enabled dokku core repo plugin
    scheduler-docker-local 0.14.1 enabled dokku core scheduler-docker-local plugin
    shell 0.14.1 enabled dokku core shell plugin
    ssh-keys 0.14.1 enabled dokku core ssh-keys plugin
    storage 0.14.1 enabled dokku core storage plugin
    tags 0.14.1 enabled dokku core tags plugin
    tar 0.14.1 enabled dokku core tar plugin

部署Django工程实例

  • 链接:
  • 下面的环境基于Pyenv+Pipenv.Pyenv:python版本管理器.Pipenv:python包管理器,更好用的pip.
  • pyenv的一些基本操作.
  • pyenv安装的位置
    1
    2
    ~$ which pyenv
    /home/lcy/.pyenv/bin/pyenv
  • pyenv可提供的安装版本.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ~$ pyenv install --list
    Available versions:
    2.1.3
    2.2.3
    2.3.7
    2.4
    2.4.1
    2.4.2
    2.4.3
    2.4.4
    [...]
  • 本机已经安装的版本
    1
    2
    3
    4
    5
    6
    7
    ~$ pyenv versions
    system
    * 3.6.6 (set by /home/lcy/.python-version)
    3.6.6/envs/dokku-py3
    3.6.6/envs/py3dev
    dokku-py3
    py3dev
  • 本机默认使用的版本.
    1
    2
    ~$ pyenv version
    3.6.6 (set by /home/lcy/.python-version)
  • 为这当前版pyenv本安装pipenv
    1
    2
    ~$ pip install pipenv
    Collecting pipenv
  • 列出当前安装的包.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ~$ pip list
    Package Version
    ---------------- ----------
    autopep8 1.4
    certifi 2018.11.29
    pip 18.1
    pipenv 2018.11.26
    pycodestyle 2.4.0
    setuptools 39.0.1
    virtualenv 16.2.0
    virtualenv-clone 0.4.0
    yapf 0.23.0
  • 通过上述命令安装了pipenv,下面是它的一些基本操作.官方文档
  • 下面是创建python3的虚拟环境,也可以用pipenv --python 3.7指定具体的版本号.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    ~$ pipenv --three
    Creating a virtualenv for this project…
    Pipfile: /home/lcy/workspace/dokku-test/crm/Pipfile
    Using /home/lcy/.pyenv/versions/3.6.6/bin/python3.6 (3.6.6) to create virtualenv…
    ⠸ Creating virtual environment...Already using interpreter /home/lcy/.pyenv/versions/3.6.6/bin/python3.6
    Using base prefix '/home/lcy/.pyenv/versions/3.6.6'
    New python executable in /home/lcy/.local/share/virtualenvs/crm-GMqHkluo/bin/python3.6
    Also creating executable in /home/lcy/.local/share/virtualenvs/crm-GMqHkluo/bin/python
    Installing setuptools, pip, wheel...
    done.

    ✔ Successfully created virtual environment!
    Virtualenv location: /home/lcy/.local/share/virtualenvs/crm-GMqHkluo
    Creating a Pipfile for this project…
    # 查看环境位置.
    ~$ pipenv --venv
    /home/lcy/.local/share/virtualenvs/crm-GMqHkluo

    ~$ pipenv --py
    /home/lcy/.local/share/virtualenvs/crm-GMqHkluo/bin/python
  • 安装django依赖包.当前工程目录下的Pipfile.lock文件,就等同于传统的requirements.txt文件.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    ~$ pipenv install django django-toolbelt
    Installing django…
    Adding django to Pipfile\'s [packages]…
    ✔ Installation Succeeded
    Installing django-toolbelt…
    Adding django-toolbelt to Pipfile\'s [packages]…
    ✔ Installation Succeeded
    Pipfile.lock not found, creating…
    Locking [dev-packages] dependencies…
    Locking [packages] dependencies…
    ✔ Success!
    Updated Pipfile.lock (c14d8c)!
    Installing dependencies from Pipfile.lock (c14d8c)…
    🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 8/8 — 00:00:01
    To activate this project\'s virtualenv, run pipenv shell.
    Alternatively, run a command inside the virtualenv with pipenv run.
  • 列出安装包的的依赖.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ~$ pipenv graph
    django-toolbelt==0.0.1
    - dj-database-url [required: Any, installed: 0.5.0]
    - dj-static [required: Any, installed: 0.0.6]
    - static3 [required: Any, installed: 0.7.0]
    - django [required: Any, installed: 2.1.5]
    - pytz [required: Any, installed: 2018.9]
    - gunicorn [required: Any, installed: 19.9.0]
    - psycopg2 [required: Any, installed: 2.7.6.1]
  • 进入pipenv虚拟环境shell
    1
    2
    3
    ~$ pipenv shell
    Launching subshell in virtual environment…
    . /home/lcy/.local/share/virtualenvs/cms-uhqZcysp/bin/activate

创建Django的示例项目.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
~$ mkdir dokkutest && cd dokkutest
~$ pipenv --three
Creating a Pipfile for this project…
# 会在本机目录下生成一个Pipfile
~$ cat Pipfile
[[source]]
name = "pypi"
#url = "https://pypi.org/simple"
#使用阿里云源
url = "http://mirrors.aliyun.com/pypi/simple"
verify_ssl = true

# 使用阿里云源必需加这一行.
[install]
trusted-host = mirrors.aliyun.com

[dev-packages]

[packages]

[requires]
python_version = "3.6"
# 安装相应的包.
~$ pipenv install django django-toolbelt
~$ pipenv shell
~$ django-admin.py startproject dokkutest .
~$ echo "web: gunicorn dokkutest.wsgi" > Procfile
~$ echo "venv" > .gitignore
# 新建APP
~$ django-admin.py startapp webui
# 安装APP
~$ sed -i "/django.contrib.staticfiles/ a\ 'webui'," dokkutest/settings.py
# 如果不加这两行,就要设置 dokku config:set DISABLE_COLLECTSTATIC=1,不然会出错,强烈建议加下面一行.
~$ sed -i "/STATIC_URL/ a\STATIC_ROOT = os.path.join(BASE_DIR, 'static')" dokkutest/settings.py
# 本地合并
~$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
[....]
# 本的运行测度
$ python manage.py runserver 0.0.0.0:9000
Performing system checks...

System check identified no issues (0 silenced).
January 14, 2019 - 09:03:32
Django version 2.1.5, using settings 'dokkutest.settings'
Starting development server at http://0.0.0.0:9000/
Quit the server with CONTROL-C.
# 收集依赖包的列表,这里会收集当前虚环境的所有包,建议新建工程时新建一个新的虚拟环境,这样可以保证requirements.txt是最小的依赖列表.
~$ pip freeze -l > requirements.txt
# 添加Procfile文件.
~$ echo "web: gunicorn dokkutest.wsgi" > Procfile
# 指定python的版本
~$ echo "python-3.6.7" > runtime.txt
# 加入git版本管理,这里假设我的dokku服务器的<域名>地址是172.16.10.100
~$ git init
~$ git add .
~$ git commit -m 'first commit'
~$ git remote add dokku dokku@172.16.10.100:dokkutest
# push代码后,就触编译与发布.
~$ git push dokku master
Delta compression using up to 6 threads.
Compressing objects: 100% (29/29), done.
Writing objects: 100% (33/33), 8.11 KiB | 0 bytes/s, done.
Total 33 (delta 5), reused 0 (delta 0)
-----> Cleaning up...
-----> Building dokkutest from herokuish...
-----> Adding BUILD_ENV to build environment...
-----> Python app detected
Skipping installation, as Pipfile.lock hasn\'t changed since last deploy.
[....]
DOKKU_APP_RESTORE: 1
=====> Renaming container (b7192f0ff943) dreamy_pascal to dokkutest.web.1
=====> Application deployed:
http://172.16.10.100:51903 # 到此程序的窗口与宿主机的端口映射已经生成了.

To 172.16.10.100:dokkutest
* [new branch] master -> master

~$ dokku apps:list
=====> My Apps
dokkutest
# dokku 服务器里的docker对应的容器运行起来
~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b7192f0ff943 dokku/dokkutest:latest "/start web" 23 hours ago Up 23 hours dokkutest.web.1
# 端口映射OK
~$ netstat -tnlp
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:51903 0.0.0.0:* LISTEN -

# 应用在服务器的位置,一些配置文件与变量可以直接进入服务器里的相关app目录下去修改.
~$ tree -L 1 /home/dokku
/home/dokku
├── bazi
├── ENV
├── HOSTNAME
├── phpcms
├── VERSION
└── dokkutest

Dokku其它指南

  • 设置APP域名.如上面所述,app映射了一个很大端口值http://172.16.10.100:51903,只能通过IP+端口的方式访问,这有可能不能满足我们的实际应用需求,怎样在同一个IP里使用不同的域名访问不同的应用呢?或者说,同一个服务器里的应用都想通过80端口对外提供服务.这里就要通过nginx代理不同的域名.命令如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    ~$ dokku domains:help
    Usage: dokku domains[:COMMAND]

    Manage vhost domains used by the Dokku proxy.

    Additional commands:
    domains:add <app> <domain> [<domain> ...] Add domains to app
    domains:add-global <domain> [<domain> ...] Add global domain names
    domains [<app>] [DEPRECATED] Alternative for domains:report
    domains:clear <app> Clear all domains for app
    domains:disable <app> Disable VHOST support
    domains:enable <app> Enable VHOST support
    domains:remove <app> <domain> [<domain> ...] Remove domains from app
    domains:remove-global <domain> [<domain> ...] Remove global domain names
    domains:report [<app>] [<flag>] Displays a domains report for one or more apps
    domains:set <app> <domain> [<domain> ...] Set domains for app
    domains:set-global <domain> [<domain> ...] Set global domain names
  • dokkutest这个应用设置test.example.com这个域名,后面就可以通过个域名 80 端就能访问到这个应用了.

1
2
3
4
5
~$ dokku domains:test.example.com  dokkutest
[...]
=====> 734565b29c3d49d4e9ae129b79c8011353300f45380a4b1fdce0df9604c2d31b
=====> Application deployed:
http://test.example.com
  • 访问静态资源.其实上面的部署是一个基本的应用,做一个Restful API服务器是没有问题的.如果做成网页端,它的static下的静态资源是不能访问的.这里要用到一些其它包与设置.具体参照这里 Django and Static Assets.具体解决如下:
1
2
3
4
5
6
7
8
9
# 安装whitenoise
~$ pip install whitenoise
# 下面修改settings.py
MIDDLEWARE_CLASSES = (
# 放在最上层一行.
# https://warehouse.python.org/project/whitenoise/
'whitenoise.middleware.WhiteNoiseMiddleware',
# 添加这一行
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

Dokku插件应用

letsencrypt

1
2
3
4
# 安装
~$ sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
# 更新
~$ sudo dokku plugin:update letsencrypt
  • APP安装Lets'Encrypt,这里需要注意,这个app设置了三个域名,其中只有一个是在DNS上设置的h5.lcy.wiki,所以才会出现下面的错误.只要把其它两个域名从这个app中删除就可以了.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    ~$ dokku letsencrypt h5dev
    =====> Let\'s Encrypt h5dev
    -----> Updating letsencrypt docker image...
    [...]
    -----> Enabling ACME proxy for h5dev...
    -----> Getting letsencrypt certificate for h5dev...
    - Domain 'h5dev.www.lcy.wiki'
    - Domain 'h5.lcy.wiki'
    - Domain 'h5dev'
    [...]
    ACME server returned an error: urn:acme:error:malformed :: The request message was malformed :: Error creating new authz :: DNS name does not have enough labels

    Debugging tips: -v improves output verbosity. Help is available under --help.
    -----> Certificate retrieval failed!
    -----> Disabling ACME proxy for h5dev...
    done
    # 正常应该如下所示

    ~$ dokku domains:report h5dev
    =====> h5dev domains information
    Domains app enabled: true
    Domains app vhosts: h5.lcy.wiki

    ~$ dokku letsencrypt:ls
    -----> App name Certificate Expiry Time before expiry Time before renewal
    h5dev 2019-06-18 18:42:21 89d, 20h, 14m, 52s 59d, 20h, 14m, 52s

    # 自动刷新证书
    ~$ dokku letsencrypt:auto-renew h5dev
    h5dev still has 59d, 20h, 12m, 43s days left before renewal
  • 错误
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     dokku letsencrypt yfh5
    =====> Let's Encrypt yfh5
    -----> Updating letsencrypt docker image...
    0.1.0: Pulling from dokku/letsencrypt
    Digest: sha256:af5f8529c407645e97821ad28eba328f4c59b83b2141334f899xxxxxxxxxx
    Status: Image is up to date for dokku/letsencrypt:0.1.0
    docker.io/dokku/letsencrypt:0.1.0
    Done updating
    -----> Enabling ACME proxy for yfh5...
    -----> Getting letsencrypt certificate for yfh5...
    /var/lib/dokku/plugins/available/letsencrypt/functions: line 145: get_app_domains: command not found
    ^[[1;3Rdarkhttpd/1.12, copyright (c) 2003-2016 Emil Mikulic.
    listening on: http://0.0.0.0:80/
    You must set at least one -d/--vhost

    Debugging tips: -v improves output verbosity. Help is available under --help.
    -----> Certificate retrieval failed!
    -----> Disabling ACME proxy for yfh5...
    done

redis插件应用

  • dokku-redis
  • How to connect to redis with dokku and flask?
  • 安装插件,并创建数据库
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    ~$ sudo dokku plugin:install https://github.com/dokku/dokku-redis.git redis
    ~$ dokku redis:create dokku-redis
    ~$ dokku redis:info dokku-redis
    =====> Container Information
    # 这两行是映射到宿主机的实际目录下面.
    Config dir: /var/lib/dokku/services/redis/dokku-redis/config
    Data dir: /var/lib/dokku/services/redis/dokku-redis/data
    Dsn: redis://dokku-redis:df40bbae8555a06d52f937fd4072ad98ec6e58563f84686254b43ff946605e4c@dokku-redis-dokku-redis:6379
    Exposed ports: -
    Id: e535a815b6bdc6898c9e6615d2e3fe0dd7387598bc6795aaf0529ad998b2f114
    Internal ip: 172.17.0.8
    Links:
    Service root: /var/lib/dokku/services/redis/dokku-redis
    Status: running
    Version: redis:4.0.11
  • 连接redis与容器应用服务
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ~$ dokku redis:link dokku-redis  yfh5
    -----> Setting config vars
    REDIS_URL: redis://dokku-redis:df40bbae8555a06d52f937fd4072ad98ec6e58563f84686254b43ff946605e4c@dokku-redis-dokku-redis:6379
    -----> Restarting app yfh5
    -----> Releasing yfh5 (dokku/yfh5:latest)...
    [...]

    ~$ dokku redis:info dokku-redis
    [...]
    Internal ip: 172.17.0.8
    Links: yfh5
    Service root: /var/lib/dokku/services/redis/dokku-redis
    [...]
  • 添加到Django项目中用作 Sessiong Cache ,修改settings.py的内容如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    CACHES = {
    "default": {
    "BACKEND":
    "django_redis.cache.RedisCache",
    "LOCATION":
    "redis://dokku-redis:df40bbae8555a06d52f937fd4072ad98ec6e58563f84686254b43ff946605e4c@dokku-redis-dokku-redis:6379",
    "OPTIONS": {
    "DB":
    0,
    "PASSWORD":
    "df40bbae8555a06d52f937fd4072ad98ec6e58563f84686254b43ff946605e4c",
    "CONNECTION_POOL_KWARGS": {
    "max_connections": 65535
    },
    }
    }
    }

设置Settings.py

  • 链接:
  • 因为Django开发测试需要与数据库连接,且开发环境与生产(测试)部署的环境是不一样的,这里可以通过在settings.py判断系统环境变量来做出一些自动化.上面那个链很有参考意.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    # We should get this from the environment, never store them in git.
    # 为了安全建义不要SECRET_KEY直接写入settings.py,它会保存在git上面记录.可以使用 dokku config:set appname SECRET_KEY='xxxxxx'
    SECRET_KEY = os.environ.get("SECRET_KEY", 'secret')

    # Set DEBUG to False if the NODEBUG env var has been set.
    DEBUG = True if os.environ.get("NODEBUG") is None else False

    # Set the allowed hosts based on the environment.
    ALLOWED_HOSTS = ["web", "localhost"] if os.environ.get("NODEBUG") is None else [".yourdomain.com"]

    if os.environ.get("IN_DOCKER"):
    # Stuff for when running in Docker-compose.
    # 使用Docker-compose会有IN_DOCKER这个环境变量

    CELERY_BROKER_URL = 'redis://redis:6379/1'
    CELERY_RESULT_BACKEND = 'redis://redis:6379/1'

    DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': "postgres",
    'USER': 'postgres',
    'PASSWORD': 'password',
    'HOST': "db",
    'PORT': 5432,
    }
    }
    elif os.environ.get("DATABASE_URL"):
    # Stuff for when running in Dokku.

    # Parse the DATABASE_URL env var.
    USER, PASSWORD, HOST, PORT, NAME = re.match("^postgres://(?P<username>.*?)\:(?P<password>.*?)\@(?P<host>.*?)\:(?P<port>\d+)\/(?P<db>.*?)$", os.environ.get("DATABASE_URL", "")).groups()

    DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.postgresql_psycopg2',
    'NAME': NAME,
    'USER': USER,
    'PASSWORD': PASSWORD,
    'HOST': HOST,
    'PORT': int(PORT),
    }
    }

    CELERY_BROKER_URL = os.environ.get("REDIS_URL", "") + "/1"
    CELERY_RESULT_BACKEND = os.environ.get("REDIS_URL", "") + "/1"
    else:
    # Stuff for when running locally.

    CELERY_TASK_ALWAYS_EAGER = True
    DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
    }

Mysql插件应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
~$ sudo dokku plugin:install https://github.com/dokku/dokku-mysql.git mysql
# 创建数据库服务
~$ sudo dokku mysql:create dyt
Waiting for container to be ready
=====> MySQL container created: dyt
=====> Container Information
Config dir: /var/lib/dokku/services/mysql/dyt/config
Data dir: /var/lib/dokku/services/mysql/dyt/data
Dsn: mysql://mysql:42b0d88fb443bab7@dokku-mysql-dyt:3306/dyt
Exposed ports: -
Id: 45171e69490d59524728846297870ca3010d0066e9972f00448b95bf8bbe86d2
Internal ip: 172.17.0.10
Links: -
Service root: /var/lib/dokku/services/mysql/dyt
Status: running
Version: mysql:5.7.12
# 把应用与数库服务连接起来
~$ sudo dokku mysql:link dyt phpenroll
-----> Setting config vars
DATABASE_URL: mysql://mysql:42b0d88fb443bab7@dokku-mysql-dbname:3306/dyt
-----> Restarting app phpenroll

# 备价与恢复
~$ dokku mysql:export [db_name] > [db_name].dump
~$ dokku mysql:import [db_name] < [db_name].dump
# 进入数据库
~$ dokku mysql:connect dyt
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| dyt |
+--------------------+
2 rows in set (0.00 sec)

# 注意,dokku 创建的数据服务,里面只有一个与服务名相同的数据库,同时也不能通过mysql命令进去创建新的数据库,用户与授权.

Persistent Storage

  • 参考链接
  • 这里需要在主机上先建一个目录,供给容器内挂载,官方推荐是/var/lib/dokku/data/storage,这里可以是其它文件系统目录,
    • 如:cephfs,nfs等.关于volume与主机共享数据使用,也可以参考http://dokku.viewdocs.io/dokku/advanced-usage/docker-options/.
    • 如: dokku docker-options:add node-js-app deploy,run "-v /var/log/node-js-app:/app/logs"
      1
      2
      ~$ sudo dokku plugin:install storage
      ~$ dokku storage:mount node-js-app /var/lib/dokku/data/storage/node-js-app:/storage
  • 为了配合Linux的权限,需要把storage下的node-js-app目录设置成chown -R 32767:dokku node-js-app权限.

常见的错误

1
2
3
~$ -----> Python app detected
! Requested runtime (python-3.6.7) is not available for this stack (heroku-16).
! Aborting. More info: https://devcenter.heroku.com/articles/python-support
  • 如果出现上述错误,请重新提交.

与 WebPack 集成

谢谢支持

  • 微信二维码:

处理问题要流程

binutils工具

  • 查看动态库内的函数符号.
1
aarch64-linux-gnu-readelf --dyn-syms /lib/aarch64-linux-gnu/libssl.so.1.0.0  | grep "TLSv1_2_method"

查看程序链接动态库的依赖.

  • 查看当前系统的程序链接动态库的依赖,可以使用ldd这个工具,ldd -u可以直接列出无法链接到的库名.如果是在交叉编译环境下可以使用
    对应<CROSS_COMPILE>-readelf读取,使用如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
~$ aarch64-linux-gnu-readelf -d jtagd | grep "NEEDED"
0x0000000000000001 (NEEDED) Shared library: [libccl_ver.so]
0x0000000000000001 (NEEDED) Shared library: [libSafeString.so]
0x0000000000000001 (NEEDED) Shared library: [libboost_unit_test_framework.so.1.59.0]
0x0000000000000001 (NEEDED) Shared library: [libboost_program_options.so.1.59.0]
0x0000000000000001 (NEEDED) Shared library: [libboost_system.so.1.59.0]
0x0000000000000001 (NEEDED) Shared library: [libboost_filesystem.so.1.59.0]
0x0000000000000001 (NEEDED) Shared library: [libboost_serialization.so.1.59.0]
0x0000000000000001 (NEEDED) Shared library: [libboost_regex.so.1.59.0]
0x0000000000000001 (NEEDED) Shared library: [libnsl.so.1]
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgomp.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]

程序长时间运行,无stdout输出的问题

  • 可以使用strace <program>方法运行它,查看它做了那些动作.对于正在运行的程序可以使用strace -p <PID>通过attatch它的
    PID来查看它运行的详情.如果只想查看它的网络相关的调用,可以使用如下命令过虑掉其它信息干扰:
1
2
3
4
5
6
7
8
9
strace -e trace=network jtagconfig
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=26660, si_uid=1000, si_status=0, si_utime=0, ssi_stime=0} ---
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3
setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_LINGER, {l_onoff=1, l_linger=10}, 8) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(1309), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
recvfrom(3, "", 2, 0, NULL, NULL) = 0
recvfrom(-1, 0x1b066ac, 2, 0, NULL, NULL) = -1 EBADF (Bad file descriptor)
  • GLIBC的兼容问题
1
2
https://stackoverflow.com/questions/2856438/how-can-i-link-to-a-specific-glibc-version
https://stackoverflow.com/questions/4032373/linking-against-an-old-version-of-libc-to-provide-greater-application-coverage/5977518
  • 查看 core dump file

  • 下面错误处理,是没设置正的运行环境变量, 设置export LC_ALL=C就可以解决.

    1
    2
    : Gtk-WARNING **: Locale not supported by C library.
    Using the fallback 'C' locale.

谢谢支持

  • 微信二维码: