介绍
嵌入式脚本组件 (pikascript.com)
PikaScript是一个超轻量级的Python引擎,它可以在只有4KB RAM和32KB闪存的微控制器上运行。相比较流行的MicroPython,则需要至少16KB的RAM和256KB的空间存储代码。PikaScript具有完整的解释器,字节码和虚拟机架构。PikaScript支持裸机运行,而且支持Keil、IAR、rt-thread studio、segger embedded studio等IDE开发,零依赖,零配置,开箱即用,极易集成进已有的C工程。
移植
我是直接从官网下载了stm32g070cb的工程文件,在此基础上进行的移植。
首先,新建一个n32g4fr的keil工程,然后往工程里添加相关文件,细节如下图所示:
引入头文件路径
移植串口终端,用于脚本交互
主要是修改串口中断的处理函数
volatile static char rx_char = 0;
char UART1_RxBuff[RX_BUFF_LENGTH] = {0};
uint16_t UART1_RXBuff_offset = 0;
__attribute__((weak)) void __PIKA_USART1_IRQHandler(char rx_char) {}
void USART1_IRQHandler(void)
{
if(USART_GetIntStatus(USART1, USART_INT_RXDNE) != RESET)
{
rx_char = USART_ReceiveData(USART1);
__PIKA_USART1_IRQHandler(rx_char);
if(UART1_RXBuff_offset >= RX_BUFF_LENGTH)
{
UART1_RXBuff_offset = 0;
memset(UART1_RxBuff, 0, sizeof(UART1_RxBuff));
}
UART1_RxBuff[UART1_RXBuff_offset] = rx_char;
UART1_RXBuff_offset++;
if('\n' == rx_char)
{
if(MCU_Code_reciveHandler(UART1_RxBuff, UART1_RXBuff_offset))
{
goto line_exit;
}
line_exit:
UART1_RXBuff_offset = 0;
memset(UART1_RxBuff, 0, sizeof(UART1_RxBuff));
return;
}
}
}
修改flash读写代码,方便下载python脚本
由于n32g4fr不支持64位写,因此需要将flash写的代码修改成32位写
void MCU_Code_flashHandler(void)
{
if(!codeHeap.ena)
{
return;
}
if(uwTick - codeHeap.reciveTime < 200)
{
return;
}
MCU_Code_reciveHandler("\n\n", 2);
uint32_t FirstPage = 0, NbOfPages = 0;
uint32_t PageError = 0;
__IO uint32_t data32 = 0, MemoryProgramStatus = 0;
printf("==============[Programer]==============\r\n");
printf("[info]: Recived byte: %d\r\n", codeHeap.size);
printf("[info]: Programing... \r\n");
FLASH_Unlock();
FirstPage = GetPage(FLASH_SCRIPT_START_ADDR);
printf("startAddr: 0x%08X, page:%d\r\n",FLASH_SCRIPT_START_ADDR,FirstPage);
NbOfPages = GetPage(FLASH_SCRIPT_END_ADDR) - FirstPage + 1;
printf("endAddr: 0x%08X,number of pages: %d\r\n",FLASH_SCRIPT_END_ADDR,NbOfPages);
printf("[info]: Erasing flash... \r\n");
for(uint32_t i=0;i<NbOfPages;i++)
{
if (FLASH_COMPL != FLASH_EraseOnePage(FLASH_SCRIPT_START_ADDR+i*FLASH_PAGE_SIZE))
{
printf("[error]: Erase faild! \r\n");
while(1)
{
}
}
}
printf("[ OK ]: Erase flash ok! \r\n");
printf("[info]: Writing flash... \r\n");
uint32_t baseAddress = FLASH_SCRIPT_START_ADDR;
uint32_t writeAddress = 0;
uint64_t writeData64 = 0;
uint32_t writeData32 = 0;
while(writeAddress < codeHeap.size + 1)
{
writeData32 = 0;
for(int i = 3; i >= 0; i--)
{
char ch = codeHeap.content[writeAddress + i];
writeData32 = writeData32 << 8;
writeData32 += ch;
}
if (FLASH_COMPL == FLASH_ProgramWord(baseAddress + writeAddress, writeData32))
{
writeAddress = writeAddress + 4;
}
else
{
printf("[error]: Write flash faild. \r\n");
while(1)
{
}
}
}
FLASH_Lock();
printf("[ OK ]: Write flash ok! \r\n");
baseAddress = FLASH_SCRIPT_START_ADDR;
MemoryProgramStatus = 0x0;
printf("[info]: Checking flash... \r\n");
char* codeInFlash = (char*)baseAddress;
printf("\r\n");
printf("----[code in flash]-----\r\n");
for(int i = 0; i < strGetSize(codeHeap.content); i++)
{
if('\n' == codeHeap.content[i] && '\r' != codeHeap.content[i - 1])
{
fputc('\r', (FILE*)!NULL);
}
fputc(codeHeap.content[i], (FILE*)!NULL);
}
printf("----[code in flash]-----\r\n");
printf("\r\n");
if(!strEqu(codeInFlash, codeHeap.content))
{
printf("[error]: Check flash faild.\r\n");
printf("\r\n");
printf("\r\n\r\n");
printf("---------[code in heap]----------\r\n");
printf("\r\n");
for(int i = 0; i < strGetSize(codeHeap.content); i++)
{
if('\n' == codeHeap.content[i])
{
fputc('\r', (FILE*)!NULL);
}
fputc(codeHeap.content[i], (FILE*)!NULL);
}
printf("\r\n\r\n");
printf("---------[code in heap]----------\r\n");
while(1)
{
}
}
printf("[ OK ]: Checking flash ok! \r\n");
printf("[ OK ]: Programing ok! \r\n");
printf("[info]: Restarting... \r\n");
printf("==============[Programer]==============\r\n");
printf("\r\n");
NVIC_SystemReset();
}
经过以上的内容基本就修改完成了。
效果展示
源码
*附件:pikapython_n32g4fr.zip
|