Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions config/pikapython-capabilities.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,15 @@ profiles:
hardware-control:
roots: [binding.constants, binding.container-result, binding.mutable-buffer, binding.object-argument, binding.python-callable, builtin.container-construct, builtin.len, builtin.print, builtin.scalar-convert, call.defaults, call.keyword, call.reference, container.bytearray, container.dict, container.list, container.tuple, exception.finally, flow.loop, flow.pass, iter.builtin, iter.range, library.struct-basic, library.time-basic, literal.embedded-int, logic.short-circuit, machine.adc, machine.pin, machine.pwm, module.from-import, module.python, name.global, object.user-basic, op.augmented, op.bitwise, op.compare-basic, op.membership, op.numeric-basic, op.slice, op.subscript, runtime.frozen-program, runtime.gc, scope.global-statement, value.bool, value.bytes, value.float, value.none, value.string]
syntaxLevel: 6
pico2:
roots: [binding.constants, binding.container-result, binding.mutable-buffer, binding.object-argument, binding.python-callable, builtin.container-construct, builtin.len, builtin.print, builtin.scalar-convert, call.defaults, call.keyword, call.reference, container.bytearray, container.dict, container.list, container.tuple, exception.finally, flow.loop, flow.pass, iter.builtin, iter.range, library.struct-basic, library.time-basic, literal.embedded-int, logic.short-circuit, machine.adc, machine.pin, machine.pwm, module.from-import, module.python, name.global, object.user-basic, op.augmented, op.bitwise, op.compare-basic, op.integer, op.membership, op.numeric-basic, op.slice, op.subscript, repl.auto-indent, runtime.frozen-program, runtime.gc, scope.global-statement, value.bool, value.bytes, value.float, value.none, value.string]
syntaxLevel: 6
pico2-full:
roots: [assignment.unpack, binding.constants, binding.container-argument, binding.container-result, binding.mutable-buffer, binding.object-argument, binding.object-result, binding.python-callable, builtin.container-construct, builtin.embedded, builtin.help, builtin.len, builtin.print, builtin.scalar-convert, builtin.type, call.defaults, call.keyword, call.reference, call.variadic, container.bytearray, container.dict, container.list, container.tuple, exception.finally, flow.pass, iter.builtin, iter.range, library.aes, library.base64, library.binascii, library.fuzzypid, library.hashlib, library.hmac, library.http-client, library.json, library.math, library.modbus-codec, library.mqtt-client, library.os-basic, library.random, library.socket-basic, library.struct-basic, library.time-basic, library.unittest-basic, library.zlib, literal.embedded-int, logic.short-circuit, machine.adc, machine.pin, machine.pwm, module.from-import, module.python, object.class, object.user-basic, op.augmented, op.bitwise, op.compare-basic, op.complete, op.float, op.integer, op.membership, op.numeric-basic, op.slice, op.subscript, protocol.text-network, repl.auto-indent, runtime.frozen-program, runtime.frozen-source, runtime.gc, scope.global-statement, value.bool, value.bytes, value.float, value.int, value.none, value.string]
resourceLimits:
frontend:
functionCount: 192
syntaxLevel: 6
interactive-minimal:
roots: [builtin.print, call.positional, flow.branch, name.global, op.integer, repl.auto-indent, runtime.frozen-program]
syntaxLevel: 1
Expand Down
4 changes: 2 additions & 2 deletions packages/fuzzypid/fuzzypid_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ typedef struct {
int mf_parameters[PIKA_FUZZYPID_MF_PARAMETER_COUNT];
PikaFuzzyPidState pids[PIKA_FUZZYPID_DOF_LIMIT];
PikaFuzzyPidInference fuzzy[PIKA_FUZZYPID_DOF_LIMIT];
unsigned int mf_types[PIKA_FUZZYPID_DOF_LIMIT]
[PIKA_FUZZYPID_MAX_MF_TYPES];
uint32_t mf_types[PIKA_FUZZYPID_DOF_LIMIT]
[PIKA_FUZZYPID_MAX_MF_TYPES];
float fuzzy_outputs[PIKA_FUZZYPID_DOF_LIMIT]
[PIKA_FUZZYPID_MAX_FUZZY_OUTPUTS];
uint8_t directions[PIKA_FUZZYPID_DOF_LIMIT];
Expand Down
128 changes: 128 additions & 0 deletions project-templates/pico2/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
cmake_minimum_required(VERSION 3.19)

# Prefer an explicit environment/cache override, then the user's standard
# SDK location.
if(NOT PICO_SDK_PATH AND DEFINED ENV{PICO_SDK_PATH})
set(PICO_SDK_PATH "$ENV{PICO_SDK_PATH}" CACHE PATH
"Path to the Raspberry Pi Pico SDK")
endif()
if(NOT PICO_SDK_PATH AND EXISTS "$ENV{HOME}/pico-sdk")
set(PICO_SDK_PATH "$ENV{HOME}/pico-sdk" CACHE PATH
"Path to the Raspberry Pi Pico SDK")
endif()
if(NOT PICO_SDK_PATH)
message(FATAL_ERROR
"Pico SDK was not found; set PICO_SDK_PATH or PICO_SDK_PATH environment variable")
endif()

set(PICO_BOARD pico2 CACHE STRING "Pico board")
set(PICO_PLATFORM rp2350-arm-s CACHE STRING "Pico platform")
set(PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS 0 CACHE STRING
"Do not block startup while waiting for a USB CDC host")

include("${PICO_SDK_PATH}/external/pico_sdk_import.cmake")

project(pikapython_pico2 C CXX ASM)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
# The Pico SDK uses GNU inline assembly in its RP2350 runtime sources.
set(CMAKE_C_EXTENSIONS ON)

pico_sdk_init()

set(PIKA_GENERATED_DIR "${CMAKE_SOURCE_DIR}/pikapython-generated")
set(PIKA_SOURCE_MANIFEST "${PIKA_GENERATED_DIR}/source-manifest.json")
if(NOT EXISTS "${PIKA_SOURCE_MANIFEST}")
message(FATAL_ERROR
"Missing pikapython-generated/source-manifest.json; run pikapython-cli build --prebuild-only first")
endif()

file(READ "${PIKA_SOURCE_MANIFEST}" PIKA_MANIFEST_JSON)
string(JSON PIKA_SOURCE_COUNT LENGTH "${PIKA_MANIFEST_JSON}" sources)
if(PIKA_SOURCE_COUNT EQUAL 0)
message(FATAL_ERROR "PikaPython source manifest contains no sources")
endif()
math(EXPR PIKA_SOURCE_LAST "${PIKA_SOURCE_COUNT} - 1")
set(PIKA_SOURCES)
foreach(PIKA_INDEX RANGE 0 ${PIKA_SOURCE_LAST})
string(JSON PIKA_RELATIVE_SOURCE GET
"${PIKA_MANIFEST_JSON}" sources ${PIKA_INDEX})
if(PIKA_RELATIVE_SOURCE STREQUAL "pikapython-packages/socket/platform_socket.c")
continue()
endif()
if(PIKA_RELATIVE_SOURCE MATCHES "/")
set(PIKA_SOURCE_PATH "${CMAKE_SOURCE_DIR}/${PIKA_RELATIVE_SOURCE}")
else()
set(PIKA_SOURCE_PATH "${PIKA_GENERATED_DIR}/${PIKA_RELATIVE_SOURCE}")
endif()
if(NOT EXISTS "${PIKA_SOURCE_PATH}")
message(FATAL_ERROR "PikaPython source is missing: ${PIKA_RELATIVE_SOURCE}")
endif()
list(APPEND PIKA_SOURCES "${PIKA_SOURCE_PATH}")
endforeach()

string(JSON PIKA_INCLUDE_COUNT LENGTH
"${PIKA_MANIFEST_JSON}" includeDirectories)
set(PIKA_INCLUDE_DIRECTORIES)
if(PIKA_INCLUDE_COUNT GREATER 0)
math(EXPR PIKA_INCLUDE_LAST "${PIKA_INCLUDE_COUNT} - 1")
foreach(PIKA_INDEX RANGE 0 ${PIKA_INCLUDE_LAST})
string(JSON PIKA_RELATIVE_INCLUDE GET
"${PIKA_MANIFEST_JSON}" includeDirectories ${PIKA_INDEX})
list(APPEND PIKA_INCLUDE_DIRECTORIES
"${CMAKE_SOURCE_DIR}/${PIKA_RELATIVE_INCLUDE}")
endforeach()
endif()

add_executable(pico2-firmware
firmware/main.c
firmware/platform.c
firmware/platform_socket.c
${PIKA_SOURCES}
)

target_include_directories(pico2-firmware PRIVATE
firmware
${PIKA_INCLUDE_DIRECTORIES}
)

target_compile_definitions(pico2-firmware PRIVATE
PIKA_FRONTEND_MODULE_LIMIT=32u
PIKA_FRONTEND_FUNCTION_LIMIT=128u
PIKA_FRONTEND_CLASS_LIMIT=16u
PIKA_FRONTEND_IDENTIFIER_BYTE_LIMIT=63u
PIKA_FRONTEND_SYMBOL_LIMIT=128u
PIKA_FRONTEND_PARAMETER_LIMIT=16u
PIKA_FRONTEND_ARGUMENT_LIMIT=16u
PIKA_FRONTEND_COLLECTION_ELEMENT_LIMIT=64u
PIKA_FRONTEND_EXCEPTION_HANDLER_LIMIT=16u
PIKA_RUNTIME_VALUE_LIMIT=64u
PIKA_REPL_MAX_LINE_BYTES=256u
PIKA_REPL_MAX_BLOCK_BYTES=4096u
PIKA_REPL_MAX_HISTORY_ENTRIES=8u
PIKA_REPL_MAX_HISTORY_BYTES=1024u
PIKA_REPL_MAX_CODE_BYTES=16384u
PIKA_REPL_MAX_OUTPUT_BYTES_PER_COMMAND=2048u
PIKA_REPL_MAX_TRACEBACK_FRAMES=8u
)

target_compile_options(pico2-firmware PRIVATE
-Wall
-Wextra
-ffunction-sections
-fdata-sections
)

target_link_libraries(pico2-firmware PRIVATE
pico_stdlib
hardware_adc
hardware_pwm
)

pico_enable_stdio_usb(pico2-firmware 1)
pico_enable_stdio_uart(pico2-firmware 0)
pico_set_program_name(pico2-firmware "PikaPython Pico 2")
pico_set_program_description(pico2-firmware
"PikaPython v2 on Raspberry Pi Pico 2")
pico_add_extra_outputs(pico2-firmware)
33 changes: 33 additions & 0 deletions project-templates/pico2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Raspberry Pi Pico 2 ARM

该模板面向 Raspberry Pi Pico 2(RP2350A、ARM Secure Cortex-M33),使用
`~/pico-sdk` 中的 Pico SDK 2.3.0 或兼容版本构建。目标固定为
`rp2350-arm-s`;USB CDC 是默认的 PikaPython 输出和 REPL 传输,
`machine.Pin`、`machine.ADC` 和 `machine.PWM` 映射到 Pico SDK 的 GPIO、ADC 和 PWM。

## 构建

复制模板后执行:

```bash
pikapython-cli install
pikapython-cli build --prebuild-only
pikapython-cli build
```

如果 SDK 不在 `~/pico-sdk`,设置 `PICO_SDK_PATH` 或在 CMake 配置时传入
`-DPICO_SDK_PATH=/absolute/path/to/pico-sdk`。构建输出位于
`.pikapython/build/pico2/`,其中 `pico2-firmware.uf2` 可拖放到 Pico 2 的
`RPI-RP2` 启动盘。

首次启动后打开 USB CDC 串口即可看到 `main.py` 输出和 `>>>` 提示符。按 Ctrl-D
结束 REPL;固件随后保持运行。

## 支持边界

- 固件架构:RP2350A ARM Secure Cortex-M33。*RISCV 并未提供支持*
- SDK 后端:GPIO、ADC、PWM、时间、睡眠、临界区和 USB CDC。
- PikaPython:默认使用 `pico2-full` capability,可安装模板列出的全部包。
- 网络:socket、MQTT、HTTP 包可参与构建;Pico 2 本身没有网络控制器,网络操作
需要额外的 lwIP/外部网络硬件后端。
- 输出:`.elf`、`.bin`、`.hex` 和 `.uf2` 均生成在 `.pikapython/build/pico2/`。
38 changes: 38 additions & 0 deletions project-templates/pico2/firmware/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <string.h>

#include "pico/stdlib.h"

#include "pika_application.h"
#include "pika_platform.h"
#include "pikapython_modules.h"

static void pika_pico2_fail(const char* message) {
(void)pika_platform_write(message, strlen(message));
for (;;) {
tight_loop_contents();
}
}

int main(void) {
PikaStatus status;

stdio_init_all();
status = pikaPythonInit();
if (status != PIKA_STATUS_OK) {
static const char message[] = "PikaPython init failed\r\n";
pika_pico2_fail(message);
}

#if PIKA_REPL_ENABLE
status = pikaPythonRepl();
if (status != PIKA_STATUS_OK) {
static const char message[] = "PikaPython REPL failed\r\n";
pika_pico2_fail(message);
}
#endif

pika_application_stop();
for (;;) {
tight_loop_contents();
}
}
Loading