4.2. Interactive Run
PikaPython supports reading strings directly to run Python scripts, so to support interactive operation, you only need to make a serial port receiving driver.
4.2.1. Option 1: Read and run by byte (recommended)
4.2.1.1. Implement a blocking byte read function
Interactive operation requires a low-level interface __platform_getchar()
to read user input bytes. This interface is a weak function. Users need to implement a __platform_getchar()
in their own code. to override this weak function.
The weak function prototype is in PikaPlatform.c. If the user does not override it, an error will be reported when using the interactive runtime.
/* PikaPlatform.c */
PIKA_WEAK char __platform_getchar(void) {
__platform_printf("[error]: __platform_getchar need impaltment!\r\n");
while(1){
}
}
Users can directly implement a __platform_getchar()
in the main.c of the project.
If the platform itself supports getchar()
, you can directly access the platform’s getchar()
.
/* main.c */
char __platform_getchar(){
return getchar();
}
If the platform does not support it, you need to implement it yourself, pay attention to implement a blocking getchar()
, that is, when there is no serial input character, you need to use __platform_getchar()
waits, and returns a character if there is input.
E.g:
/* main.c */
char __platform_getchar(){
char res = 0;
while(rx_char == 0){
};
res = rx_char;
rx_char = 0;
return res;
}
4.2.1.2. Start PikaPython Shell and run pikaScriptShell() directly to start interactive operation.
pikaScriptShell()
The entry parameter is the root object of pika, and running pikaScriptInit()
will create a root object.
pikaScriptShell(pikaScriptInit());
4.2.1.3. Sample code
stm32g070cb: https://github.com/pikastech/pikascript/blob/master/bsp/stm32g070cb/Booter/main.c
rt-thread: https://github.com/pikastech/pikascript/blob/master/package/pikaRTThread/rt_pika.c
4.2.1.4. Precautions:
Kernel version needs to be at least v1.3.0
It is strongly recommended to use putty as a serial terminal.
4.2.2. Option 2: Run by byte input
The obj_runChar
kernel API can specify an object to execute a script with one byte of input.
You need to run obj_runCharInit()
before you can use obj_runChar
.
Example code.
PikaObj* pikaMain = pikaScriptInit();
obj_runCharInit(pikaMain);
while(1){
char ch = my_get_char();
obj_runChar(pikaMain, ch);
}
4.2.2.1. Caution.
Kernel version needs to be no less than v1.8.3
4.2.3. Option 3: Read and run the entire line
obj_run
kernel API can specify an object to execute a script, and use this API to execute a single-line or multi-line script.
The following is an example of the interactive running driver of CH32. This interactive running support is written in the main loop of the firmware and starts to execute after the pikaScriptInit()
initialization script is executed.
PikaObj *PikaMain = pikaScriptInit();
printf(">>>");
while(1)
{
if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET)
{
is_Rx_start = 1;
t_start = rt_tick_get();
rxCh = USART_ReceiveData(USART1);
if(rxCh < 128){
RxBuffer[RxCnt++] = rxCh;
}
}
if( (is_Rx_start == 1) && (rt_tick_get() - t_start > 10) ){
is_Rx_start = 0;
for(int i = 0; i< RxCnt; i ++)
{
USART_SendData(USART1, RxBuffer[i]);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)== RESET);
}
obj_run(PikaMain, RxBuffer);
printf(">>>");
memset(RxBuffer, 0, 256);
RxCnt = 0;
}
}
4.2.3.1. Driven Content
Poll to receive characters and store them in the buffer.
A reception is considered complete when no new characters are received for more than 10ms. Using the idle time to determine the completion of the transmission of the string can support interactive running of multi-line scripts. If you only need to run the single-numbered script, you can use the newline character
'\n'
to determine the end of the string reception. When running a single-line script, the'\n'
line break can be omitted, and a multi-line script needs to have a'\n'
line break. Newlines of the form"\r\n"
are also supported.Echo the received string after receiving.
Execute scripts using the
obj_run
kernel API. The specified object is the root object created by thepikaScriptInit()
init script, and the execution content is the received string.Clean up the receive buffer.
4.2.3.2. Notes:
Kernel version needs to be at least v1.2.6
When executing a multi-line script, you need to pass in a complete code block For example: the following script is a complete code block, especially the 4th line, which needs to have an indent of 0 to mark the end of the code block. and the last line needs to have a blank line, which means
print('the end')
with a newline at the end of the script.
while a < 10:
a = a + 1
print(a)
print('the end')
The following example is also possible
while a < 10:
a = a + 1
print(a)
The following example does not work
# Missing final newline
while a < 10:
a = a + 1
print(a)
# The content of the while block is missing
while a < 10:
4.2.4. Quit Interaction
Type exit()
to exit the interactive run.
4.2.5. Run temporary files
4.2.5.1. Run Python files
Using pikaStudio (recommended). Drag and drop Python files to run
Using other serial port tools (not recommended). Add
#!pika
to the first and last lines of the file you want to run, and then send the file directly through the serial port to run it. This file will be sent to RAM and run directly, and will be disabled after reboot. For example
#!pika
print('hello pikapython in file')
#!pika
Output.
>> #
=============== [code] ===============
print('hello pikapython in file')
=============== [code] ===============
hello pikapython in file
>>>>
Note that.
requires kernel version
>= v1.11.4
.The first and last line of the temporary file must be
#!pika
, otherwise it will be treated as a normal string.
__platform_getchar()
is needed not to be too slow, otherwise the file will fail to be sent, or you can try to slow down the serial port baud rate.
4.2.5.2. Run the bytecode file
Send the xxx.py.o bytecode file to run Output.
=============== [Code] ===============
[ Info] Bytecode size: 305
=============== [ RUN] ===============
hello pikapython in file
Note that.
requires kernel version
>= v1.11.6
.