一、基本开发环境
开发环境基于野火STM32开发板。
前测试的 Lua 解释器版本为 5.4.2。
官网下载lua资源包,下载地址如下:
https://www.lua.org/
https://github.com/rjpcomputing/luaforwindows/releases
lua: Lua 国内镜像 (gitee.com)
二、移植Lua解释器
1.下载的Lua解压,删除源文件中的的 lua.c 和 luac.c (如果有的话)文件。
2.新建stm32工程
3.工程添加Lua源码
将Lua源文件拷贝到工程
添加头文件
更改 loslib.c 文件下部分内容
-
将 os_exit(lua_State * L)函数中 if(L) exit(status)注释,并添加 status=status 语句。
2.添加 time(time_t *time)和 system(const char * string)
更改以上内容是因为使用了 Use MicroLIB 模式。
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;
}
三、Lua使用测试
-
编写测试代码
#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.下载,查看测试效果
实验现象,指示灯先亮后灭再常亮,符合预期。
欢迎关注个人公众号:嵌入式学习与实践
参考:
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