查看: 329|回复: 0

扩展库开发记录

[复制链接]

0

主题

0

帖子

24

积分

注册会员

Rank: 2

积分
24
发表于 2023-5-13 20:51:59 | 显示全部楼层 |阅读模式
本帖最后由 x789o 于 2023-5-13 23:05 编辑

因为天问STC15系统库未提供需要的选项和更丰富的功能,第三方库占用FLASH空间较大,需要自行用C语言实现。将其进一步封装成“图形编程”所用的库,对促进分享和社区的发展都是有利的。坛中已有高人记载了图形界面的主要操作流程,但对“预处理”、“执行等代码生成的解释尚不详细。因此,我在摸索出扩展库创建流程的同时,也在此简要记录扩展库开发的常用代码,希望对同有需要的朋友带来帮助。

一、新建库

点击“天问Block”软件左下角的“添加扩展”,点击顶部最后一个按钮“新建库”,即可打开库编辑窗口。在这里,“图形编程”所用的一个个图形积木块被称为一个个“模块”。通过“删除”按钮可以删除一个模块。目前没有一键清空功能,如果后续需要开发多个扩展库,可以点击“生成库”按钮保存一个干净的自定义库作为模板。

当前的“生成库”按钮中的配置会在下次打开库编辑窗口时丢失,因此每隔一段时间应重新点击“生成库”按钮导出一次,后续可通过“导入库”-“导入本地库”恢复,以防写好的库名称和说明丢失。在生成库的窗口中,还需要点击“XML文件编辑”旁边的“编辑”按钮,点击“导入编辑区代码”,以确保模块内容被正常配置。点击“天问Block”软件左下角的“添加扩展”,点击顶部“用户库”按钮,再点击“本地导入”,即可导入生成的库进行测试。目前暂未发现更简单的同步调试方案,而且自定义扩展库总是在下方,希望后续这些问题能得到改善。

每拼上一个模块,天问Block就会在必要的位置生成对应的代码。自定义扩展库是配置每个模块的过程。相比于每个模块本身的显示方式,每个模块的输入参数、“在哪里生成什么代码”更加重要。接下来将介绍这些内容。

二、模块输入参数

模块输入是在图形编程时可指定的内容,这些内容通常会影响生成的代码。

1、“输入”

“输入”定义了在模块右侧能够嵌合的图形模块的类型和数量,共有三种形式。“假输入”没有任何可以接收模块的凹槽,只能在模块本身上填写内容。“值输入”在右侧定义一个小凹槽,可以接收一个值,每添加一个“值输入”,小凹槽增加一个。“语句输入”在右侧定义一个大凹槽,可以接收多条语句,通常用于定义函数体。

“输入”下方还定义有两种连接方式,尝试一下即可明白。

2、“领域”

“领域”是嵌入在模块“输入”中可修改的内容。

3、“输入”和“领域”对应的变量

“输入”和“领域”部分的每个可配置内容都对应了一个变量,以便在下方的代码生成中使用。其中:

“值输入”对应的变量名为“value_名称”,“语句输入”对应的变量名为“statements_名称”;

“领域”中,文本、数字、角度、下拉、选项、颜色、变量对应的变量名分别为“text_名称”、“number_名称”、“angle_名称”、“dropdown_名称”、“checkbox_名称”、“colour_名称”、“variable_名称”。

这里的“名称”在库编辑窗口提示为“套接字”,我觉得使用“名称”更加直观。所有名称都是小写的。

三、生成代码

“生成代码”是模块对应C代码的生成器,用JavaScript实现,在库编辑窗口的右下角可以查看。可以利用高级编程方法计算需要配置的数值,如使用“整数变量.toString()”、“小数变量.toFixed(小数点位数)”将数字转换为字符串进行拼接。

即使一个文件中的函数不全被使用,SDCC编译器不能像GCC那样自动剔除未用到的部分。如果一股脑儿导入全部库代码,所有函数都会得到保留,就会使得编译后的体积增大。因此,对于小容量的单片机,生成的代码应根据模块的输入参数自动配置,有效利用图形编程模式自动维护字符模式代码的不同部分,而不需要在运行阶段动态判断。通常直接套入文本代码无法达成此目的,而需要通过库编辑窗口的两种“自定义代码”实现。

1、预处理代码

“预处理代码”共有5类,格式分别如下:

宏定义:Blockly.Arduino.definitions_['define_宏名'] = '#define 宏名 宏体'

头文件:Blockly.Arduino.definitions_['include_头文件名'] = '#include "myLib/xxx.h"'

变量定义:Blockly.Arduino.definitions_['var_declare_变量定义语句'] = '变量类型 变量名;'

类定义:Blockly.Arduino.definitions_['var_declare_类定义语句'] = '类名 实例名(类参数);'

初始化(setup函数中添加的内容):Blockly.Arduino.setups_['初始化名称_init'] = '初始化语句;'

因此,实际上的预处理代码只有2类,并且模块的共同内容(由字典的键决定)在字符模式中只会被生成一遍。通过“自定义行”,可以将字符串与“输入”和“领域”对应的变量拼接,动态生成代码。如果减小体积是很重要的目的,可以根据将用到的功能函数的具体实现作为预处理代码行,而无需包含C文件,甚至头文件。

2、执行代码

若执行代码不为空,则执行代码会被放置到如下代码段中:

  1. var code = 内容;
  2. return code;
复制代码

其中,“内容”是手动设置的“自定义代码”框中的内容,或者其他字符串拼接的框中的内容。最后得到的类型需要是字符串类型。如果内容具有多行,可以使用``括起来形成模板字符串,实现自由换行。当然也可以使用'内容1\n内容2\n内容3'的形式,或['内容1','内容2','内容3'].join('\n')的形式。

四、总结

根据以上记录,可以将写好的C库包装为图形模块。

以上记录仅供参考,若有不到之处,还请包涵。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|好好搭搭在线 ( © 好好搭搭在线 浙ICP备19030393号-1 )

GMT+8, 2024-4-25 01:45 , Processed in 0.326238 second(s), 23 queries .

Powered by Discuz!

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表