You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
252 lines
7.9 KiB
252 lines
7.9 KiB
%\begin{content}
|
|
\chapter{添加 micropython 解释器}
|
|
从 \href{http://svn.zmd.com/svn/一部软件库/公共模块/micropython-c6x}{micropython-c6x} SVN 仓库获取项目最新的源码。
|
|
|
|
在将源代码下的 \texttt{ports/c6x/lib/upy.c6x.ae66} 添加到 AppRun 工程下的 lib 目录。
|
|
并修改 module.cmd,添加一行:
|
|
\begin{minted}[bgcolor=lightgray!30,fontsize=\small]{c}
|
|
-l ../lib/upy.c6x.ae66
|
|
\end{minted}
|
|
%修改后的 module.cmd 内容如下:
|
|
%\begin{minted}[bgcolor=lightgray!30,fontsize=\scriptsize]{ini}
|
|
%-l ../lib/DrvUtils.lib
|
|
%-l ../lib/upy.c6x.ae66
|
|
%
|
|
%--diag_suppress=10068,10247
|
|
%--retain="*(.shellCommand)"
|
|
%
|
|
%SECTIONS
|
|
%{
|
|
% .module_section: fill=0x0 align=0x4{
|
|
% module_ver_start=.;
|
|
% *(.module_section)
|
|
% module_ver_end=.;
|
|
% }>DDR_RAM
|
|
%
|
|
% .dsp_cmd_section: fill = 0x0 align = 0x10 {
|
|
% __console_cmd_start = .;
|
|
% *(.dsp_cmd_section)
|
|
% __console_cmd_end = .;
|
|
% } > DDR_RAM
|
|
%
|
|
% .shell_command_section: fill = 0x0{
|
|
% _shell_command_start = .;
|
|
% *(.shellCommand)
|
|
% _shell_command_end = .;
|
|
% } > DDR_RAM
|
|
%}
|
|
%\end{minted}
|
|
|
|
\section{最小移植需求}
|
|
在 AppRun 工程中新建一个文件 mp\_port.c, 添加如下内容:
|
|
\begin{minted}[bgcolor=lightgray!30,fontsize=\scriptsize]{c}
|
|
#include <stdint.h>
|
|
/* {{{: console */
|
|
int mp_tic6x_console_readable()
|
|
{
|
|
return serialTstc();
|
|
}
|
|
|
|
int mp_tic6x_console_getc()
|
|
{
|
|
return serialGetc();
|
|
}
|
|
|
|
void mp_tic6x_console_putn(const char *str, size_t len)
|
|
{
|
|
while (len > 0) {
|
|
serialPutc(*str++);
|
|
--len;
|
|
}
|
|
}
|
|
/* }}} */
|
|
\end{minted}
|
|
也可以通过实现 uart 的接口(mp\_tic6x\_uart\_readable, mp\_tic6x\_uart\_putc, mp\_tic6x\_uart\_getc) 中的第一个参数(uart\_id) 为-1时的功能来作为 REPL 的console。
|
|
|
|
在 AppRun.c 中添加 micropython 解释器的代码:
|
|
\begin{minted}[bgcolor=lightgray!30,fontsize=\scriptsize]{c}
|
|
/* {{{: upy interpreter */
|
|
void mp_tic6x_repl(unsigned char *, int len);
|
|
#define GC_HEAP_SIZE 0x400000
|
|
static unsigned char gc_heap[GC_HEAP_SIZE];
|
|
|
|
void AppRun(void)
|
|
{
|
|
...
|
|
if (DNUM == 0) {
|
|
...
|
|
mp_tic6x_repl(gc_heap, GC_HEAP_SIZE);
|
|
...
|
|
}
|
|
}
|
|
/* }}} */
|
|
\end{minted}
|
|
这里 upy 的堆大小 GC\_HEAP\_SIZE 可根据实际需求进行修改。示例的代码中 0x400000 只起演示作用,不是硬性的大小限制。
|
|
|
|
\section{Flash 文件系统支持}
|
|
upy 库默认添加了 FAT 和 LFS 支持,可以在 mp\_port.c 添加如下类似代码,实现文件系统的支持:
|
|
\begin{minted}[bgcolor=lightgray!30,fontsize=\scriptsize]{c}
|
|
/* {{{ tic6x.Flash */
|
|
#define BLOCK_SIZE_BYTES (0x20000)
|
|
#define BPI_FLASH_REGBASE (0x70000000)
|
|
|
|
#ifndef MICROPY_HW_FLASH_STORAGE_BYTES
|
|
#define MICROPY_HW_FLASH_STORAGE_BYTES (0x200000)
|
|
#endif
|
|
#ifndef MICROPY_HW_FLASH_STORAGE_BASE
|
|
#define MICROPY_HW_FLASH_STORAGE_BASE (0x600000)
|
|
#endif
|
|
|
|
#define FLASH_START_ADDRESS (BPI_FLASH_REGBASE + MICROPY_HW_FLASH_STORAGE_BASE)
|
|
|
|
extern int norFlashFifoProgram(unsigned int nAddr, const unsigned char *pBuffer, unsigned int len);
|
|
|
|
int mp_tic6x_flash_get_part_size(int part_id, unsigned int *blocks, unsigned int *block_size)
|
|
{
|
|
int r = 0;
|
|
|
|
if (part_id == 0) {
|
|
*blocks = (MICROPY_HW_FLASH_STORAGE_BYTES) / BLOCK_SIZE_BYTES;
|
|
*block_size = BLOCK_SIZE_BYTES;
|
|
} else {
|
|
r = -1;
|
|
}
|
|
return (r);
|
|
}
|
|
|
|
int mp_tic6x_flash_read(int part_id, unsigned int sect_start, unsigned int sect_off,
|
|
void *buf, size_t size)
|
|
{
|
|
unsigned char *srcbuf = (unsigned char *)(FLASH_START_ADDRESS);
|
|
|
|
if (part_id != 0) {
|
|
return -1;
|
|
}
|
|
|
|
srcbuf += sect_start * BLOCK_SIZE_BYTES + sect_off;
|
|
memcpy(buf, srcbuf, size);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int mp_tic6x_flash_erase(int part_id, unsigned int block_start, unsigned int nblocks)
|
|
{
|
|
if (part_id != 0) {
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int mp_tic6x_flash_program(int part_id, unsigned int sect_start,
|
|
unsigned int offset_in_sect, const void *buf, unsigned int size)
|
|
{
|
|
int r = 0;
|
|
unsigned int lba;
|
|
|
|
if (part_id != 0) {
|
|
r = -1;
|
|
goto end;
|
|
}
|
|
|
|
lba = MICROPY_HW_FLASH_STORAGE_BASE + sect_start * BLOCK_SIZE_BYTES + offset_in_sect;
|
|
r = norFlashFifoProgram(lba, buf, size);
|
|
end:
|
|
return (r);
|
|
}
|
|
/* }}} */
|
|
\end{minted}
|
|
解释器在进入 REPL 之前,会先后自动运行文件系统上的名为 \textcolor{blue}{\texttt boot.py} 和 \textcolor{blue}{\texttt main.py} 的脚本文件。
|
|
|
|
\section{系统功能支持}
|
|
设置系统主频,复位和设备ID,可以在 mp\_port.c 中添加下列实现:
|
|
\begin{minted}[bgcolor=lightgray!30,fontsize=\scriptsize]{c}
|
|
/* {{{ machine.unique_id() */
|
|
int mp_tic6x_unique_id(uint8_t *buf, int len)
|
|
{
|
|
const char *board = getEnv("BOARD_INDEX");
|
|
|
|
if (board) {
|
|
size_t slen = strlen(board);
|
|
if (slen > len)
|
|
slen = len;
|
|
memcpy(buf, board, slen);
|
|
return (slen);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void sysReboot();
|
|
void mp_tic6x_hard_reset(void)
|
|
{
|
|
sysReboot();
|
|
}
|
|
|
|
unsigned int mp_tic6x_get_cpu_freq()
|
|
{
|
|
return 1250000000UL;
|
|
}
|
|
/* }}} */
|
|
\end{minted}
|
|
|
|
\section{符号表支持}
|
|
如果需要在 upy 支持直接调用程序的全局函数,可对 AppRun 工程做一点微小的修改来实现。
|
|
|
|
将 ports/c6x/include/symtbl.h 复制到 AppRun 的 h/user 目录下。
|
|
将 ports/c6x/lib/symgen目录下的 symgen.exe 和 symgen.lar 复制到 AppRun 的 bin 目录下,并在 该目录下新建一个空的名为 builtins.txt \label{sec:builtin} 的文件(该文件的用途后面再讲)。
|
|
将 ports/c6x/lib/symgen 下的 makefile.targets 文件复制到 AppRun 工程的最上面:
|
|
\begin{table}[H]
|
|
\centering
|
|
\begin{tabular}{lcl}
|
|
\toprule
|
|
{\bf upy 工程} & & {\bf AppRun 工程} \\
|
|
\midrule
|
|
ports/c6x/include/symtbl.h & -> & h/user/symtbl.h \\
|
|
ports/c6x/lib/symgen/symgen.exe & -> & bin/symgen.exe \\
|
|
ports/c6x/lib/symgen/symgen.lar & -> & bin/symgen.lar \\
|
|
ports/c6x/lib/symgen/makefile.targets & -> & makefile.targets \\
|
|
& new & bin/builtins.txt \\
|
|
\bottomrule
|
|
\end{tabular}
|
|
\caption{symbol 支持工程文件}
|
|
\end{table}
|
|
如果有需要从符号表中排除一些接口,可以在 AppRun 的bin目录,创建一个名为 symgen.excl 的文件,将不需要的符号添加到该文件,
|
|
每行一个符号名。
|
|
|
|
文件添加后,AppRun 工程的文件如下图所示:
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includegraphics[width=0.5\textwidth]{symgen}
|
|
\caption{symgen 文件位置}
|
|
\end{figure}
|
|
图中的 symgen.lar 是 symgen.lua 用 lz4.exe 压缩得到的:
|
|
\begin{minted}[bgcolor=lightgray!30,fontsize=\small]{bash}
|
|
lz4.exe -9 symgen.lua symgen.lar
|
|
\end{minted}
|
|
直接用 symgen.lua 文件也是可以的。
|
|
|
|
在 AppRun 工程上点击右键,分别选择 “Properties” => “Build” => “Behaviour”,将按下图红框所示进行配置:
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includegraphics[width=0.9\textwidth]{builder}
|
|
\caption{编译 appsym 目标}
|
|
\end{figure}
|
|
|
|
将添加了 micropython 解释器的工程最编译并烧写后,进入调试串口,看到如下类似打印:
|
|
\begin{minted}[bgcolor=lightgray!30,fontsize=\scriptsize]{python}
|
|
MicroPython ff67efa on 2022-07-20; C66xx with TIC6X
|
|
Type "help()" for more information.
|
|
>>>
|
|
\end{minted}
|
|
则移植成功。可以输入 help() 查看帮助,输入 help('modules') 查看所支持的 Python 模块。
|
|
|
|
%生成的 bootloader 文件是: \texttt{image/A/bootloader.bin} 。
|
|
|
|
|
|
%在项目源码工程的 Tools 目录下有适合本项目的交叉编译器 gcc-linaro-6.1.1-2016.08-x86\_64\_aarch64-linux-gnu.tar.xz。
|
|
%先将其解压到 U-Boot 源码目录,然后编译:
|
|
%\begin{minted}[bgcolor=lightgray!30,fontsize=\small]{c}
|
|
%> cd /path/to/ASAACFT2000M-BS1_BOOT
|
|
%> tar xvf gcc-linaro-6.1.1-2016.08-x86_64_aarch64-linux-gnu.tar.xz
|
|
%> ./run build u-boot
|
|
%\end{minted}
|
|
%生成的 bootloader 文件是: \texttt{image/A/bootloader.bin} 。
|
|
|