telink script tool
工具介绍
telink script tool
为了快速进行产品原型验证,我们开发了一套脚本系统。系统中,telink script tool作为一款windows端工具,通过UART接口并配合支持相同交互协议的目标板(协议开源且易移植),可实现脚本编辑、文件交互、UART收发、断点控制等功能。其系统框图如下:
快速体验
Rocket板快速体验
快速体验固件只适用于泰凌B91系列的芯片,采用Rocket板套件则只需用type-c连接底板和电脑即可,若采用的是非Rocket板,只需将UART0_TX_PB2、UART0_RX_PB3通过USB转UART模块连接到电脑端。
1、使用泰凌的下载器将快速体验固件下载到芯片。固件烧录可采用工具 BDT 或者 Web BDT 。
2、下载工具telink_script_tool,工具中自带了个示例脚本,其主要功能:每隔1秒打印采集到数据并翻转LED,每隔5秒定时器产生一次中断,按下拨轮按键可控制板子上的彩灯显示。
3、Rocket板上采用的USB转UART信号的芯片为CH340E,请事先安装CH340E驱动。用Type-C线连接Rocket板的USB_UART口和电脑,在工具主界面处点击端口按钮,选择对应的端口号后点击设置,然后点击连接按钮。
4、点击全下按钮,等待全部下载完毕提示(下载过程约五秒左右),若中途卡住了,可再次点击全下按钮。
5、观察Rocket板现象是否跟预期一样,可点击终端按钮查看串口打印的数据。
工具使用
Windows APP
工具主界面如下图所示,1号区域按钮用于系统设置,2号区域按钮用于与开发板进行交互,3号区域为文件列表区,4号区域为文件编辑区,5号区域为日志显示窗口。
系统操作
单击发送区的文件,文件编辑区会加载该文件内容,我们可以在编辑区内进行脚本的编辑,也可以右键进行新增或者重命名文件。
1号区域内的按键功能简介如下 端口:弹框配置端口和波特率,需点击弹框内设置按钮完成设定 连接:与设定的UART端口进行连接/断开 刷新:刷新文件列表 保存:将编辑区内的文件进行保存(切换选择文件时也会自动保存) 清空:清空下方的log窗口内容 文档:打开浏览器访问在线文档 关于:工具由Qt构建,显示Qt相关的license 设置:默认模式下的部分功能设置是禁止的。设置选项的状态是重启保存的,正常用默认模式即可。 其中log等级选项用于设置日志显示窗口处的打印等级,文件选项用于匹配文件列表和文件编辑区语法高亮
工具的project文件夹下,send为发送区的文件夹,receive为接收区文件夹,stytle.qss为用户自定义皮肤样式表,config.ini为系统配置文件,配置文件中将mode值改为root,然后重启应用就可解锁更多的设置权限,这时可设置灰色区选项,但需对应的修改芯片处代码用以匹配。
操作板子
2号区域按钮用于与开发板进行交互,在UART连接成功后才可以进行操作。其功能简介如下 ⬆️ 读取:将开发板内的脚本文件和断点描述文件都读至project/receive目录下,点击接收区文件列表可以在工具的编辑区内查看文件内容
⤵️ 下载:单击发送列表内的文件后点击下载,会将该文件下载到开发板内 ⤵️ 全下:将project/send目录下的所有脚本文件和断点描述文件都下载至开发板内 ❌ 删除:单击文件列表,删除对应电脑端的文件。若勾选了系统设置中的选项:"连同板内文件一起删除",则在删除接收列表内的文件时也会尝试删除板内同名文件 🐞 断点:将project/send目录下的断点描述文件都下载至开发板内。断点的介绍看下文中的"断点使用"章节 🚫 清除:将电脑端断点描述文件清空,并删除开发板内的断点描述文件 🔁 复位:将UART的RST信号拉低100毫秒后再拉高,Rocket将CH340E_RST连接到了芯片复位引脚上,该信号会触发芯片硬件复位 终端:点击后会出现弹窗。在脚本运行时,跟开发板通过UART进行交互。弹窗界面如下:1号区域为UART数据接收区,2号区域为功能按钮,3号区域内有三个子区域
单条发送:在输入框内输入数据,点击2号区域内的发送数据按钮,可以将数据发送给开发板
断点控制:除了rts复位,其余功能只有在断点停留时才可生效
按钮名称 | 按钮功能 |
---|---|
继续运行 | 跳过停留处的断点继续往下运行 |
全速运行 | 取消所有断点,全速运行 |
打印断点 | 打印所有断点信息 |
取消断点 | 取消停留处的断点 |
内核状态 | 程序读取CSR寄存器和PC值,并打印出来 |
执行脚本 | 执行按钮下发的输入框内的脚本 |
rts复位 | 将UART的RST信号拉低100毫秒后再拉高 |
读写数据:在断点停留时,才可以进行此项操作。先选择要读取的对象:Core/Flash/Analog,再输入地址和长度,最后点击读取/写入按钮
脚本编写
以lua脚本为例,用户需编写main.lua脚本,参考示例脚本实现setup、loop函数。如果要实现中断功能,需编写irq.lua脚本并实现irq_entry函数,这三个函数在程序中的调用逻辑如下所示
// 中断处理函数
void xxx_irq_handler(void){
// 清除中断标志位
clear_irq_state;
// 调用lua脚本中的函数irq_entry,并将该中断号传递给该函数
call_lua_one_par("irq_entry",IRQ_NUMBER);
}
void main() {
// 系统初始化
sys_init();
// 调用lua脚本中的初始化函数
call_lua_function("setup");
while (1) {
// 调用lua脚本中的loop函数
call_lua_function("loop");
}
}
用户可以下载其他名称的lua脚本到芯片中,并在main.lua中引入这些文件并使用其中的功能(示例代码中有体现)。
断点使用
为了方便开发者进行调试,系统实现了简易的断点功能。需要注意的是在中断函数里打断点是不会生效的。具体使用步骤如下: 1、勾选/取消断点:点击代码行号右侧可以勾选此处断点,再次点击可以取消此处断点。日志窗口处会有断点提示,并且系统会将断点信息同步写入电脑端的断点配置文件中。
2、点击主界面中的"断点"/"全下"按钮可以将电脑端的断点配置文件下载进开发板内。点击"清除"按钮可清空电脑端断点配置文件,并删除开发板内的断点配置文件。开发板每次上电都会先读取并解析断点配置文件,并按配置运行。
3、点击主界面中的"终端"按钮,在断点停留时可进行一系列操作。这里的操作不会影响开发板内的断点配置文件。
接口列表
示例工程中将接口放在了my_lua_reg.c处,这些接口可在脚本文件中调用,接口的描述如下 1、Rocket板相关:
接口原型 | 接口功能 | 调用示范 |
---|---|---|
rocket_init() | 初始化板子上的器件 | rocket_init() |
rocket_oled_cls() | 清空OLED屏幕 | rocket_oled_cls() |
rocket_oled_cls_y(Y) | OLED屏幕一共六行,清空第Y和Y+1行 | rocket_oled_cls_y(0) |
rocket_oled_show_str(x,y,string) | 在屏幕上显示字符串,字符串行高为2,x∈[0,127] y∈[0,6] string为字符串 | rocket_oled_show_str(0,0,"hello world") |
rocket_sht30_read() | 读取温湿度数据,返回值为两个float | temp,humi = rocket_sht30_read() |
lua_rocket_adc_read() | 读取ADC采集到的电压值和计算到的R13阻值,返回值为两个int | vol,r13 = rocket_adc_read() |
rocket_lis2dh_read() | 读取三轴加速度器数据,返回值为三个int | x,y,z = rocket_lis2dh_read() |
rocket_button_read() | 读取按键数据,返回一个int,返回0代表没有按键按下,返回1、2、3分别代表左、中、右键按下 | button_value = rocket_button_read() |
rocket_ws2812b_set(color) | 设置彩灯颜色,color为int型,数据格式为GRB,如0xff0000代表Green色 | rocket_ws2812b_set(0xff0000) |
2、读写相关:
接口原型 | 接口功能 | 调用示范 |
---|---|---|
analog_write_reg8(addr,data) | 往模拟寄存器地址addr处写入一个字节的数据data | analog_write_reg8(0x12,0x34) |
analog_write_reg16(addr,data) | 往模拟寄存器地址addr处写入半个字的数据data | analog_write_reg16(0x12,0x3456) |
analog_write_reg32(addr,data) | 往模拟寄存器地址addr处写入一个节的数据data | analog_write_reg32(0x12,0x12345678) |
analog_write_reg8_buff(addr,buff,len) | 往模拟寄存器地址addr处写入一组字节数据buff,len为写入的长度,不能大于1024 | buff = {} buff[1] = 0x12 buff[2] = 0x34 buff[3] = 0x56 buff[4] = 0x78 analog_write_reg8_buff(0x12,buff,4) |
analog_read_reg8(addr) | 从模拟寄存器地址addr处读取一个字节的数据 | data_8 = analog_read_reg8(0x12) |
analog_read_reg16(addr) | 从模拟寄存器地址addr处读取半个字的数据 | data_16 = analog_read_reg16(0x12) |
analog_read_reg32(addr) | 从模拟寄存器地址addr处读取一个字的数据 | data_32 = analog_read_reg32(0x12) |
analog_read_reg8_buff(addr,len) | 从模拟寄存器地址addr处读取一组字节数据buff,len为读取的长度,其不能大于1024 | buff={} buff,read_len = analog_read_reg8_buff(0x12,20) |
与之类似的读写接口如下,见名之意,它们操作的对象为SRAM何寄存器。
write_sram8、write_sram16、write_sram32
write_sram8_buff、write_sram16_buff、write_sram32_buff
read_sram8、read_sram16、read_sram32
read_sram8_buff、read_sram16_buff、read_sram32_buff
write_reg8、write_reg16、write_reg32
read_reg8、read_reg16、read_reg32
3、GPIO相关:
接口原型 | 接口功能 | 调用示范 |
---|---|---|
gpio_function_en(PAD_NUM) | 将引脚PAD_NUM设置为GPIO功能,PAD号为字符串类型 | gpio_function_en('PB6') |
gpio_function_dis(PAD_NUM) | 关闭引脚PAD_NUM的GPIO功能 | gpio_function_dis('PB6') |
gpio_output_en(PAD_NUM) | 打开PAD_NUM输出功能 | gpio_output_en('PB6') |
gpio_output_dis(PAD_NUM) | 关闭PAD_NUM输出功能 | gpio_output_dis('PB6') |
gpio_input_en(PAD_NUM) | 打开PAD_NUM输入功能 | gpio_input_en('PB6') |
gpio_input_dis(PAD_NUM) | 关闭PAD_NUM输入功能 | gpio_input_dis('PB6') |
gpio_high(PAD_NUM) | 设置PAD_NUM输出高 | gpio_high('PB6') |
gpio_low(PAD_NUM) | 设置PAD_NUM输出低 | gpio_low('PB6') |
gpio_toggle(PAD_NUM) | 翻转PAD_NUM的输出 | gpio_toggle('PB6') |
gpio_set_up_down_res(PAD_NUM,mode) | 设置PAD_NUM模拟上下拉,mode取值为0-3,0:浮空,1:上拉1M,2:下拉100K 3:上拉10K | gpio_set_up_down_res('PB6',1) |
gpio_set_irq(PAD_NUM,IQR_TYPE) | 设置GPIO_IRQ中断,IQR_TYPE为触发模式,取值为0-3,0:上升沿,1:下降沿,2:高电平 3:低电平 | gpio_set_irq('PD1',1) |
gpio_set_gpio2risc0_irq(PAD_NUM,IQR_TYPE) | 设置IRQ_RISC0中断,IQR_TYPE为触发模式,取值为0-3,0:上升沿,1:下降沿,2:高电平 3:低电平 | gpio_set_gpio2risc0_irq('PD2',1) |
gpio_set_gpio2risc1_irq(PAD_NUM,IQR_TYPE) | 设置IRQ_RISC1中断,IQR_TYPE为触发模式,取值为0-3,0:上升沿,1:下降沿,2:高电平 3:低电平 | gpio_set_gpio2risc1_irq('PD3',1) |
4、其他:
接口原型 | 接口功能 | 调用示范 |
---|---|---|
SYS_DEBUG_EN() | 开启断点功能 | SYS_DEBUG_EN() |
print_riscv_reg() | 打印程序读取到的CSR寄存器和PC值 | print_riscv_reg() |
core_interrupt_enable() | 打开全局总中断 | mstatus = core_interrupt_enable() |
core_interrupt_disable() | 关闭全局总中断 | core_interrupt_disable() |
core_restore_interrupt(mstatus) | 由传入值恢复全局中断 | core_restore_interrupt(mstatus) |
get_mem_perused() | 获取动态内存使用率 | value = get_mem_perused() |
set_timer0_cycle(ms) | 设置定时器0的定时周期(毫秒) | set_timer0_cycle(1000) |
set_timer1_cycle(ms) | 设置定时器1的定时周期(毫秒) | set_timer1_cycle(1000) |
delay_us(us) | 延时函数(us) | core_restore_interrupt(10) |
delay_ms(ms) | 延时函数(ms) | delay_ms(10) |
固件构建
固件构建
快速体验中使用到的固件里面的接口是固定且有限的。用户可下载源码自己进行二次开发。
用户可以在源码下的my_lua_reg.c处增加自己想要的接口,也可以直接将源码直接移植到其他平台。
针对泰凌的B91系列芯片,在工程目录下我们提供了生成lib库的参考脚本,可将生成的lib库加载到自己工程里进行编译产生固件。在Telink IoT Studio的设置中将tlua_lib.a和数学库加进去,并将文件夹lua_interface和telink_lua_lib中相关头文件加入工程,初始化和主循环中调用lib库中的两个接口
#include "lua_interface/my_lua_reg.h"
#include "lua_interface/my_lua_interface.h"
#include "telink_lua_lib/lua/lua_extend.h"
void user_init()
{
telink_lua_lib_init(lua_lib,&lua_interface);
}
void main_loop(void)
{
while(1){
telink_lua_main_loop();
}
}
在中断函数处调用Lua的irq_entry函数,示例如下
_attribute_ram_code_sec_noinline_ void gpio_irq_handler(void)
{
gpio_clr_irq_status(FLD_GPIO_IRQ_CLR);
c_call_lua_one_par("irq_entry",IRQ25_GPIO);
}