8月没有太多学习,还在玩NUCLEO-F401RE,没玩透。
至于如何玩蛇(Python),我是用了一个开源的框架?组件?作者称为“跨平台的超轻量级嵌入式 Python 引擎”——Pikapython。
今天分享一下关于移植的做法,如果各位觉得没什么内容或者简单,请轻拍。
步骤一:用STM32CubeMX建立一个工程
-
打开STM32CubeMX后通过“ACCESS TO BOARD SELECTOR”
-
选择 NUCLEO-F401RE
-
进入 Project Manager 选项卡
- 设定
Project Name ,我设置成 STM32F401RE_Nucleo_PikaPython_Keil
- 设定
Toolchain/IDE 为 MDK-ARM (使用Keil)
- 设定
Minimum Heap Size 为 0x4000 (16K 的堆空间),设定Minimum Stack Size 为 0x1000 (4K 的栈空间)
- 建议设置:进入
Code Generator 子选项卡,勾选 Generate peripheral initalization as a pair of '.c/.h' files per peripheral
-
点击右上角 GENERATE CODE 完成工程创建
步骤二:移植前工作
由于需要使用库函数,准确来说是使用库函数重定向至串口,使用串口交互,所以需要先做串口重定向。
此处有个坑,本来用STM32CubeIDE报错才改为用MDK的,MDK莫名其妙的定义了 __GUNC__ ,导致我直接网上拷来的重定向函数有问题。也是参考网上教程改成 #if defined ( __GNUC__ ) && !defined (__clang__) 即可,由于不想用 MicroLib ,搜了一下,需要避免使用半主机模式,胡乱咔咔的复制一通,得到下面的代码,顺便把fgetc 也实现了。
//STM32F401RE
#if !defined(__MICROLIB)
//#pragma import(__use_no_semihosting) //AC5
__asm(".global __use_no_semihosting\n\t"); //AC6
void _sys_exit(int x) //避免使用半主机模式
{
x = x;
}
//__use_no_semihosting被要求使用,但是_ttywrch被定义为空函数
void _ttywrch(int ch) //该函数是在半主机模式下使用的,所以要对函数 _ttywrch 覆写
{
// 什么都不做,只是为了满足要求
ch = ch;
}
FILE __stdout;
FILE __stdin;
#endif
#if defined ( __GNUC__ ) && !defined (__clang__)
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
while((USART2->SR & 0X40) == 0);
USART2->DR = (uint8_t) ch;
return ch;
}
int fgetc(FILE* f)
{
uint8_t ch = 0;
while(HAL_UART_Receive(&huart2, &ch, 1, 0) != HAL_OK);
return ch;
}
编译下载,测试一下 printf 反正能用了,至于哪部分有用,哪部分没用,后面再看了(基础不扎实的心虚)。
由于需要使用Pikapython的Shell(REPL),所以需要实现一个函数 __platform_getchar ,用于Pikapython获取输入的字符,由于是使用串口,而上面已经实现了fgetc ,所以适配后的代码如下:
char __platform_getchar(void)
{
return getchar();
}
至此,移植的前提已经具备。
移植
- 在工程下,建立文件夹,名称随意,我设置为
PikaScript
- 下载文件包管理工具到上述目录中,打开官网PikaPython®,点击包管理器,然后点击点击下载包管理器即可
- 建立
requestment.txt ,最少需要两个模块,pikascript-core 和 PikaStdLib`,输入文档中各占一行,然后保存
- 建立
main.py 文件,简单的引入标准库import PikaStdLib 和打印个Hello World,print("Hello World")
- 双击打开包管理器,进入自动下载所需文件,并且自动编译
- 将
PikaScript 文件夹里包含子目录里的C文件全部加入到工程中,并把对应的目录加入到编译头文件的查找路径。
- 在
main.c 中加入#include "pikascript.h"
- 在
main 函数初始化结束后增加一句PikaObj* pikaMain = pikaScriptInit(); 即可完成移植,接上串口,复位一下就能看到信息了
- 如果要进行REPL交互,要在上述步骤建立
pikaMain 对象后,添加一句pikaScriptShell(pikaMain); 即可通过脚本进行交互
|