欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

lua移植到STM32F4全过程

程序员文章站 2022-06-04 09:56:54
...

lua移植到STM32F4全过程

 

基于之前了解到的Lua脚本开发功能,尝试过多次都没有很认真的做打底。之前的尝试都没能很好的应用到自己的工程里。

elua东西太多并且是在linux下编译的,我很不适应,当然liunx涉及的不深。

本次移植的条件及目标:

本次的目标是能精简移植最纯洁版的lua框架,能够实现多文件(.lua)的联合调用 require / dofile。

开发工具:Keil V5.29

硬件平台:STM32F4探索者开发版

移植下来发现lua和平台真的关系不大,就内存上面我还没搞懂他需要多少合适。

单纯加入了一个测试lib,具体编译空间MAP如下:

    Total RO  Size (Code + RO Data)               157208 ( 153.52kB)
    Total RW  Size (RW Data + ZI Data)             36904 (  36.04kB)
    Total ROM Size (Code + RO Data + RW Data)     157256 ( 153.57kB)

工作内容有:

1、lua库移植

2、FatFs文件系统的移植

3、多文件.lua的相互调用测试测试

这次捣鼓花了3天的时间,对lua语言和和lua库的函数库有初步了解。整个过程就不是很顺利,几经自闭。

程序源码会附件提供大家学习,以免大家少走弯路。欢迎下载。

下载链接:https://download.csdn.net/download/ai5945fei/12630346

 

整体参考博客,在此感谢给了很多的帮助

https://blog.csdn.net/zlm_space/article/details/50379980

 

工程整体能容:

lua移植到STM32F4全过程

移植步骤:

到gethub下载lua源码,当前使用版本 This is Lua 5.4.0, released on 18 Jun 2020.

解压并添加到自己的工程里,除lua.c和luac.c外全部添加。

添加后编译会出现几个未定义的函数,可以找到并实现一个空函数,实际用到的时候再补充。

不用文件的话不出意外都能跑起来。

大概描述一下几个地方,方便以后快速上手。

1、添加预编译LUA_32BITS

lua移植到STM32F4全过程

2、注意此处不打勾

文件系统重定向

lua移植到STM32F4全过程

3、这里坑我比较久

#pragma import(__use_no_semihosting) 

不加入这一句会出现一个很郁闷的问题。程序进入DEBUG模式时能正常运行,真机运行就崩溃起不来。

 

lua移植到STM32F4全过程

 

4、lua搜索路径

根据自己挂载的路径修改lua搜索路径,主要提供 require查找文件。dofile默认可以查找到当前路径,可以不需要设置该路径。reuqire不行,需要指定。

lua移植到STM32F4全过程

5、在此处添加自己的驱动

lua移植到STM32F4全过程

lua移植到STM32F4全过程

6、文件系统配置

文件系统我使用的是系统RAM,分配了10k空间。自己可随意调整为内部FLASH或者存储卡等存储介质。

#define FF_MIN_SS		1024 // 扇区大小

lua移植到STM32F4全过程

7、注意屏蔽掉fputc的实现 

int fputc(int ch, FILE *f)该函数就不需要在外部实现,会造成发送混乱。重定向的功能已经在stdio.c里面实现了。

8、这几个实现文件系统的必要文件

lua移植到STM32F4全过程

收尾

至此,没有什么要特别注意的了。附上main.c文件,是不是你需要的东西,自行评估。

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
#include "key.h"
#include "string.h"
//ALIENTEK 探索者STM32F407开发板 实验4
//串口通信实验 -库函数版本
//技术支持:www.openedv.com
//淘宝店铺:http://eboard.taobao.com
//广州市星翼电子科技有限公司
//作者:正点原子 @ALIENTEK

#include "lua.h"

#include "lauxlib.h"
#include "lualib.h"

#include <ff.h>
static FATFS fatfs;

//文件系统挂
static int file_system_init(void)
{
    char buffer[FF_MIN_SS];
    FRESULT fr;

    fr = f_mount(&fatfs, "0:/", 1); // 挂载磁盘
    if (fr == FR_OK)
    {
        printf("f_mount OK!\n");
        return 1;
    }
    if (fr == FR_NO_FILESYSTEM)
    {
        // 若磁盘没有格式化, 则格式化磁盘
        fr = f_mkfs("0:/", FM_FAT, 0, buffer, sizeof(buffer));
        if (fr == FR_OK)
        {
            printf("Disk is formatted!\n");
            return 1;
        }
        else
        {
            printf("Disk cannot be formatted! fr=%d\n", fr);
            return 0;
        }
    }
    else
    {
        printf("f_mount error! fr=%d\n", fr);
        return 0;
    }
}



const char LUA_SCRIPT_HELLO[] = " \
print('this is hello.lua')\
gloabl_param = 'this is gloabl param' \
function say_hello()\
	print('this is function:say hello')\
end	\
";

const char LUA_SCRIPT_GLOBAL[] = "  \
print('this is main.lua') \
off = 500     \
on = 500       \
require('module')\
print(module.constant)\
print('into while')\
while true do \
 led.led_on() \
 led.delay(off)    \
 led.led_off()        \
 led.delay(on)      \
end";


const char LUA_SCRIPT_GLOBAL_STR[] = "  \
print('this is main.lua') \
off = 500     \
on = 500       \
print('into while')\
while true do \
 led.led_on() \
 led.delay(off)    \
 led.led_off()        \
 led.delay(on)      \
end";

const char LUA_SCRIPT_MODULE[] = " \
module ={}  \
module.constant='这是一个模块常量'\
return module";

void file_write_string(const char *filename,const char *strdata)
{
    FILE *fp = NULL;

    fp = fopen(filename, "w");
    if(fp)
    {
        fputs(strdata, fp);
        fclose(fp);
        printf("file %s create success\r\n",filename);
    }
    else
    {
        printf("file %s create err\r\n",filename);
    }
}

static void file_create_test(void)
{
    file_write_string("main.lua",LUA_SCRIPT_GLOBAL);
    file_write_string("hello.lua",LUA_SCRIPT_HELLO);
    file_write_string("module.lua",LUA_SCRIPT_MODULE);
}

FRESULT scan_files(char *path)
{
    FRESULT res; //定义结果对象
    DIR dir; //定义目录对象
    UINT i; //定义变量
    static FILINFO fno; //定义静态文件信息结构对象
    res = f_opendir(&dir, path); //打开目录,返回状态 和 目录对象的指针
    char pathBuff[256]; //定义路径数组
    if (res == FR_OK) //打开成功
    {
        for (;;) //遍历
        {
            res = f_readdir(&dir, &fno); //读取目录,返回状态 和 文件信息的指针
            if (res != FR_OK || fno.fname[0] == 0)
                break; //若打开失败 或 到结尾,则退出

            if (fno.fattrib & AM_DIR) //是目录
            {
                i = strlen(path); //获取原目录长度
                sprintf(&path[i], "/%s", fno.fname); //将新目录添加在原目录后面
                printf("是目录::%s\r\n", path);
                res = scan_files(path); //将新目录进行递归调用
                if (res != FR_OK)
                    break; //打开失败则退出
                path[i] = 0;
            }
            else
            {
                printf("是文件:%s/%s\r\n", path, fno.fname); //是文件
                //strcpy(pathBuff, fno.fname); //将文件目录存储起来
            }
        }
    }
    else
    {
        printf("失败 - %s", &res); //打开失败
    }
    f_closedir(&dir); //关闭目录
    return res; //返回状态
}

int main(void)
{
    uart_init(115200);

    delay_init(168);                                //延时初始化

    LED_Init();                                     //初始化与LED连接的硬件接口

    file_system_init();//加载文件系统

    file_create_test();//创建lua脚本文件

    scan_files("0:");

    lua_State *L  = luaL_newstate();

    if (L == NULL)
    {
        printf("LUA ERR\r\n");
    }
    else
    {
        printf("Lua init ok\r\n");

        luaL_openlibs(L);//加载Lua库

				//重复写文件测试
        file_write_string("autorun.lua","print('autorun file <1>  2')");

        luaL_dofile(L,"autorun.lua");

        file_write_string("autorun.lua","print('autorun file <2> s ')");

        luaL_dofile(L,"autorun.lua");
			
        luaL_dofile(L, "main.lua");
    }

    printf("exit\r\n");
}


运行结果:

led灯正产闪烁

lua移植到STM32F4全过程

其他:

启动文件再执行 __main 和 mian()函数之间会执行 __rt_entry函数,还函数会加载和执行

_sys_open 函数,配置STDIN  STDOUT STDERR等相关初始化工作。

 

 

 

相关标签: lua STM32 STM32F4