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

%\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} 。