Transplant lua interpreter in single chip microcomputer

1. Basic development environment

The development environment is based on the Wildfire STM32 development board.

The Lua interpreter version tested before is 5.4.2.

Download the lua resource package from the official website. The download address is as follows:

https://www.lua.org/

https://github.com/rjpcomputing/luaforwindows/releases

lua: Lua domestic mirror (gitee.com)‍

1f415694b1643573c448af9b9678487b.png

Two, transplant Lua interpreter

1. Unzip the downloaded Lua, delete the lua.c and luac.c (if any) files in the source file.

2. Create a new stm32 project

3. Add Lua source code to the project

Copy the Lua source file to the project

807418b271bfaa51cd05b3e55848e1f4.png

add header file

451aa165037e7d3753914b9ca707e803.png

Change part of the loslib.c file 

  1. Comment the if(L) exit(status) in the os_exit(lua_State * L) function, and add the status=status statement.

    4c3f1d8a72ce433e091c02d0082137f6.png

2. Add time(time_t *time) and system(const char *string)

e96f41cbc9d3d57cd16a5a1f8dbafe34.png

The above was changed because of the Use MicroLIB mode.

static int os_exit (lua_State *L) {
  int status;
  if (lua_isboolean(L, 1))
    status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE);
  else
    status = (int)luaL_optinteger(L, 1, EXIT_SUCCESS);
  if (lua_toboolean(L, 2))
    lua_close(L);
  //if (L) exit(status);  /* 'if' to avoid warnings for unreachable 'return' */
  status=status;
  return 0;
}


time_t time(time_t *time)
{
    return 0;
}


int system(const char * string)
{
    return 0;
}

Three, Lua use test

  1. write test code

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


static int lua_led_on(lua_State *L)
{
    LED1( ON );       
    return 1;
}
static const struct luaL_Reg mylib[]=
{
     {"led_on",lua_led_on},
     {NULL,NULL}
};


const char LUA_SCRIPT_GLOBAL_ON[] =" \
    while 1 do\
    led_on() \
    end";
    
 int main(void)
{


    SystemClock_Config();


    LED_GPIO_Config();
    
    LED1( ON );       // 亮
    HAL_Delay(1000);
    LED1( OFF );      // 灭
    HAL_Delay(1000);
    
    lua_State *L;
    L = luaL_newstate(); //建立Lua运行环境
    luaopen_base(L);//注册基础函数(此函数要屏蔽luaL_setfuncs(L, base_funcs, 0);)
    luaL_setfuncs(L, mylib, 0);//注册自定义函数
    luaL_dostring(L, LUA_SCRIPT_GLOBAL_ON);
    
    while(1)
    {    
    }    
}
/**
  ******************************************************************************
  * @file    main.c
  * @author  fire
  * @version V1.0
  * @date    2017-xx-xx
  * @brief   GPIOÊä³ö--ʹÓù̼þ¿âµãÁÁLEDµÆ
  ******************************************************************************
  * @attention
  *
  * ʵÑéƽ̨:Ò°»ð  STM32 F407 ¿ª·¢°å 
  * ÂÛ̳    :http://www.firebbs.cn
  * ÌÔ±¦    :http://firestm32.taobao.com
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx.h"
#include "./led/bsp_led.h"


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


static void SystemClock_Config(void);

#if 1

static int lua_led_delay_ms(lua_State *L)
{
//    int i=0xFFFFF;
//	while(i--)
//    {
//        ;;
//    }
//    //HAL_Delay(1000);
    HAL_Delay(1000);
	return 1;
}
static int lua_led_on(lua_State *L)
{
    LED1( ON );			 // ÁÁ 
    lua_led_delay_ms(L);
    LED1( OFF );
    lua_led_delay_ms(L);
    //HAL_GPIO_TogglePin(GPIOG,GPIO_PIN_7);
    return 1;
}
static int lua_led_off(lua_State *L)
{
    LED1( OFF );		  // Ãð
    return 1;
}

static const struct luaL_Reg mylib[]=
{
     {"led_on",lua_led_on},
     {NULL,NULL}
};

const char LUA_SCRIPT_GLOBAL_ON[] =" \
    while 1 do\
    led_on() \
    end";
const char LUA_SCRIPT_GLOBAL_OFF[] =" \
    led_off() \
    end";

const char LUA_SCRIPT_GLOBAL_TEST[] =" \
    while 1 do\
    led_on() \
    led_delay()\
    led_off() \
    led_delay()\
    end";


void BEEP_GPIO_Config(void)
{		
    /*¶¨ÒåÒ»¸öGPIO_InitTypeDefÀàÐ͵ĽṹÌå*/
    GPIO_InitTypeDef  GPIO_InitStruct;
    /*¿ªÆôBEEPÏà¹ØµÄGPIOÍâÉèʱÖÓ*/
    __GPIOG_CLK_ENABLE();
    /*Ñ¡ÔñÒª¿ØÖƵÄGPIOÒý½Å*/															   
    GPIO_InitStruct.Pin = GPIO_PIN_7;	
    /*ÉèÖÃÒý½ÅµÄÊä³öÀàÐÍΪÍÆÍìÊä³ö*/
    GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;  
    /*ÉèÖÃÒý½ÅΪÉÏÀ­Ä£Ê½*/
    GPIO_InitStruct.Pull  = GPIO_PULLUP;
    /*ÉèÖÃÒý½ÅËÙÂÊΪ¸ßËÙ */   
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; 
    /*µ÷Óÿ⺯Êý£¬Ê¹ÓÃÉÏÃæÅäÖõÄGPIO_InitStructure³õʼ»¯GPIO*/
    HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);	
   
    HAL_GPIO_WritePin(GPIOG,GPIO_PIN_7,0);
}

/**
  * @brief  Ö÷º¯Êý
  * @param  ÎÞ
  * @retval ÎÞ
  */
int main(void)
{
    /* ϵͳʱÖÓ³õʼ»¯³É168MHz */
    SystemClock_Config();

    /* LED ¶Ë¿Ú³õʼ»¯ */
    LED_GPIO_Config();
    //BEEP_GPIO_Config();
    
    LED1( ON );			 // ÁÁ 
    HAL_Delay(1000);
    LED1( OFF );		  // Ãð
    HAL_Delay(1000); 
    
 
#if 0
    lua_State *L;
    L = luaL_newstate(); //
    luaopen_base(L);
     lua_register(L, "led_on", lua_led_on);     
     lua_register(L, "led_off", lua_led_off);
     lua_register(L, "led_delay", lua_led_delay_ms);    
    
    while(1)
    {
        
        luaL_dostring(L, LUA_SCRIPT_GLOBAL_TEST);
    
    }  
    
#else    
    /* ¿ØÖÆLEDµÆ */
    while(1)
    {
        lua_State *L;
        L = luaL_newstate(); //
        luaopen_base(L);
        luaL_setfuncs(L, mylib, 0);
        luaL_dostring(L, LUA_SCRIPT_GLOBAL_ON);
        while(1);
    
    }   
#endif    
}

#else 
static int lua_led_on(lua_State *L)
{
	LED1( ON );
	return 1;
}
static int lua_led_off(lua_State *L)
{
	LED1( OFF );
	return 1;
}
 
static int lua_delay(lua_State *L)
{
	int num;
//	num= lua_tointeger(L, 1);
	HAL_Delay(500);
	return 1;
}

static const struct luaL_Reg mylib[]=
{
	{"led_on",lua_led_on},
	{"led_off",lua_led_off},
	{"delay",lua_delay},
	{NULL,NULL}
};


const char LUA_SCRIPT_GLOBAL[] ="  \
	off = 500     \
	on = 500       \
	while 1 do \
	led_on() \
	delay(on)    \
	led_off()        \
	delay(off)      \
	end";




/**
  * @brief  Ö÷º¯Êý
  * @param  ÎÞ
  * @retval ÎÞ
  */
int main(void)
{
    /* ϵͳʱÖÓ³õʼ»¯³É168MHz */
    SystemClock_Config();

    /* LED ¶Ë¿Ú³õʼ»¯ */
    LED_GPIO_Config();
    
    LED1( ON );			 // ÁÁ 
    HAL_Delay(1000);
    LED1( OFF );		  // Ãð
    HAL_Delay(1000); 
    
    /* ¿ØÖÆLEDµÆ */
    while(1)
    {
        lua_State *L;
        L = luaL_newstate(); //
        luaopen_base(L);
        luaL_setfuncs(L, mylib, 0);
        luaL_dostring(L, LUA_SCRIPT_GLOBAL);
        
        while(1);
    
    }    
}
#endif
/**
  * @brief  System Clock Configuration
  *         The system Clock is configured as follow : 
  *            System Clock source            = PLL (HSE)
  *            SYSCLK(Hz)                     = 168000000
  *            HCLK(Hz)                       = 168000000
  *            AHB Prescaler                  = 1
  *            APB1 Prescaler                 = 4
  *            APB2 Prescaler                 = 2
  *            HSE Frequency(Hz)              = 8000000
  *            PLL_M                          = 25
  *            PLL_N                          = 336
  *            PLL_P                          = 2
  *            PLL_Q                          = 7
  *            VDD(V)                         = 3.3
  *            Main regulator output voltage  = Scale1 mode
  *            Flash Latency(WS)              = 5
  * @param  None
  * @retval None
  */
static void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;

  /* Enable Power Control clock */
  __HAL_RCC_PWR_CLK_ENABLE();
  
  /* The voltage scaling allows optimizing the power consumption when the device is 
     clocked below the maximum system frequency, to update the voltage scaling value 
     regarding system frequency refer to product datasheet.  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  
  /* Enable HSE Oscillator and activate PLL with HSE as source */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 25;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    while(1) {};
  }
  
  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 
     clocks dividers */
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;  
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;  
  if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    while(1) {};
  }

  /* STM32F405x/407x/415x/417x Revision Z devices: prefetch is supported  */
  if (HAL_GetREVID() == 0x1001)
  {
    /* Enable the Flash prefetch */
    __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
  }
}

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

2. Download and view the test results

According to the experimental phenomenon, the indicator light turns on first, then turns off and then stays on, which is in line with expectations.

Welcome to pay attention to the personal public number: embedded learning and practice

reference:

https://www.gd32mcu.com/data/documents/userManual/AN019_CN_Rev1.0.pdf

https://blog.csdn.net/weixin_38728721/article/details/104068015

https://blog.csdn.net/weixin_41558887/article/details/101385077

https://www.armbbs.cn/forum.php?mod=viewthread&tid=94757

Guess you like

Origin blog.csdn.net/weixin_46158019/article/details/131238467