弱性能穿戴设备App化之Lua For STM32

今年穿戴设备突然火起来......穿戴设备与概念未爆发前的电子产品不同于“可联网”和“支持app”,使得一个封闭的小玩意可以加入多人的想象,屌丝的想象力很丰富的说....

穿戴设备目前分为"屌丝“和”高富帅“两档配置,所谓”屌丝”配置也就是弱得装不上android,未来一段时间内,手表和手环都以“屌丝”配置为主,例如pebble和sony手表以arm cortex m3芯,不过"高富帅"geek watch用上android....

吹完水,就说本文的重点,如何让弱性能设备支持app,也就是把lua移植到stm32.....本文代码可以到这里(http://download.csdn.net/detail/hellogv/5721915)下载。

手上的板子是STM32F103RCT6 FLASH 256K RAM 48K,配置低得勉强跑得动Lua。开发环境是IAR For ARM 6.4,以后也方便使用eclipse cdt,移植重点:


1.下载lua:http://www.lua.org/download.html,本文用Lua 5.2.2;


2.把/lua/src里的文件全部copy到IAR for STM32 工程;


3.在IAR for STM32 模版工程,workspace下面新建lua文件夹,添加所有源文件:



4. 修改工程配置





5.把lua.c和luac.c 从工程中删除,否则编译过程中会提示 Error[Li006]: duplicate definitions for "main";


6.修改stm32f10x_flash.icf,否则编译通过,运行会提示内存不足:
define symbol __ICFEDIT_size_cstack__   = 0x00008000;
define symbol __ICFEDIT_size_heap__     = 0x00002000;


除了移植之后,本文程序还通过计算运算耗时,通过循环加法运算对比luc跟c在运算效率上的对比,源码如下:

  1. #include "stm32f10x_conf.h"  
  2. #include "stm32f10x_lib.h"  
  3. #include "stm32f10x_systick.h"  
  4. #include <math.h>  
  5. #include "lua.h"  
  6. #include "lauxlib.h"  
  7. #include "lualib.h"  
  8.   
  9. void RCC_Init(void) {  
  10.     /* 定义枚举类型变量 HSEStartUpStatus */  
  11.     ErrorStatus HSEStartUpStatus;  
  12.   
  13.     /* 复位系统时钟设置 */  
  14.     RCC_DeInit();  
  15.     /* 开启 HSE */  
  16.     RCC_HSEConfig (RCC_HSE_ON);  
  17.     /* 等待 HSE 起振并稳定 */  
  18.     HSEStartUpStatus = RCC_WaitForHSEStartUp();  
  19.     /* 判断 HSE 起是否振成功,是则进入if()内部 */  
  20.     if (HSEStartUpStatus == SUCCESS) {  
  21.         /* 选择 HCLK(AHB)时钟源为SYSCLK 1分频 */  
  22.         RCC_HCLKConfig (RCC_SYSCLK_Div1);  
  23.         /* 选择 PCLK2 时钟源为 HCLK(AHB)1分频 */  
  24.         RCC_PCLK2Config (RCC_HCLK_Div1);  
  25.         /* 选择 PCLK1 时钟源为 HCLK(AHB)2分频 */  
  26.         RCC_PCLK1Config (RCC_HCLK_Div2);  
  27.         /* 设置 FLASH 延时周期数为2 */  
  28.         FLASH_SetLatency (FLASH_Latency_2);  
  29.         /* 使能 FLASH 预取缓存 */  
  30.         FLASH_PrefetchBufferCmd (FLASH_PrefetchBuffer_Enable);  
  31.         /* 选择锁相环(PLL)时钟源为 HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */  
  32.         RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);  
  33.         /* 使能 PLL */  
  34.         RCC_PLLCmd (ENABLE);  
  35.         /* 等待 PLL 输出稳定 */  
  36.         while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)  
  37.             ;  
  38.         /* 选择 SYSCLK 时钟源为 PLL */  
  39.         RCC_SYSCLKConfig (RCC_SYSCLKSource_PLLCLK);  
  40.         /* 等待 PLL 成为 SYSCLK 时钟源 */  
  41.         while (RCC_GetSYSCLKSource() != 0x08)  
  42.             ;  
  43.     }  
  44.   
  45.     /* 使能各个用到的外设时钟 */  
  46.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA,  
  47.             ENABLE);  
  48. }  
  49.   
  50. void GpioInit(void) {  
  51.     /* 定义 GPIO 初始化结构体 GPIO_InitStructure */  
  52.     GPIO_InitTypeDef GPIO_InitStructure;  
  53.   
  54.     /* 设置 USART1 的Tx脚(PA.9)为第二功能推挽输出功能 */  
  55.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  
  56.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
  57.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  58.     GPIO_Init(GPIOA, &GPIO_InitStructure);  
  59.   
  60.     /* 设置 USART1 的Rx脚(PA.10)为浮空输入脚 */  
  61.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  
  62.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
  63.     GPIO_Init(GPIOA, &GPIO_InitStructure);  
  64. }  
  65.   
  66. void UsartInit(void) {  
  67.     /* 定义 USART 初始化结构体 USART_InitStructure */  
  68.     USART_InitTypeDef USART_InitStructure;  
  69.     /* 定义 USART 初始化结构体 USART_ClockInitStructure */  
  70.     USART_ClockInitTypeDef USART_ClockInitStructure;  
  71.   
  72.     USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;  
  73.     USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;  
  74.     USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;  
  75.     USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;  
  76.     USART_ClockInit(USART1, &USART_ClockInitStructure);  
  77.   
  78.     USART_InitStructure.USART_BaudRate = 9600;  
  79.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;  
  80.     USART_InitStructure.USART_StopBits = USART_StopBits_1;  
  81.     USART_InitStructure.USART_Parity = USART_Parity_No;  
  82.     USART_InitStructure.USART_HardwareFlowControl =  
  83.             USART_HardwareFlowControl_None;  
  84.     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  
  85.     USART_Init(USART1, &USART_InitStructure);  
  86.   
  87.     /* 使能 USART1 */  
  88.     USART_Cmd(USART1, ENABLE);  
  89. }  
  90.   
  91. /******************************************************************************* 
  92.  * 函数名          : fputc 
  93.  * 函数描述     : 将printf函数重定位到USATR1 
  94.  * 输入参数     : 无 
  95.  * 输出结果     : 无 
  96.  * 返回值      : 无 
  97.  *******************************************************************************/  
  98. int fputc(int ch, FILE *f) {  
  99.     USART_SendData(USART1, (u8) ch);  
  100.     while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)  
  101.         ;  
  102.     return ch;  
  103. }  
  104.   
  105. const char LUA_SCRIPT[] = "function loop_add(a, b,t)            "  
  106.         "   local sum = 0                   "  
  107.         "   for i = 1, t do          "  
  108.         "       sum = sum + a + b           "  
  109.         "   end                             "  
  110.         "   return sum                      "  
  111.         "end                                "  
  112.         "                                   ";  
  113.   
  114. u32 c_loop_add(int a,int b,int t){  
  115.   u32 result=0,i=0;  
  116.   for(i=0;i<t;i++){  
  117.     result = result + a+ b;  
  118.   }  
  119.   return result;  
  120. }  
  121.   
  122. int use_lua_add(lua_State *L, const char *func_name, int x, int y, int t) {  
  123.     int sum;  
  124.     /*装载脚本*/  
  125.     lua_getglobal(L, func_name);  
  126.     /* 第一个参数 */  
  127.     lua_pushnumber(L, x);  
  128.     /* 第二个参数 */  
  129.     lua_pushnumber(L, y);  
  130.     /* 第三个参数 */  
  131.     lua_pushnumber(L, t);  
  132.     /* 调用函数,告知有三个参数,一个返回值 */  
  133.     lua_call(L, 3, 1);  
  134.     /* 得到结果 */  
  135.     sum = (int) lua_tointeger(L, -1);  
  136.     lua_pop(L, 1);  
  137.     return sum;  
  138. }  
  139.   
  140. /** 
  141.  * 开始计算耗时,不适合太耗时的计算 
  142.  */  
  143. void start_calculate_time() {  
  144.     SysTick_CLKSourceConfig (SysTick_CLKSource_HCLK_Div8); //(8*9000)*1000=72MHz  
  145.     SysTick_SetReload(0xFFFFFF); //校准值,开始后不断递减  
  146.     SysTick_CounterCmd (SysTick_Counter_Enable); // 启动SysTick定时器  
  147.   
  148. }  
  149.   
  150. /** 
  151.  * 停止计算耗时,不适合太耗时的计算 
  152.  */  
  153. u32 stop_calculate_time() {  
  154.     SysTick_CounterCmd (SysTick_Counter_Disable); // 关闭SysTick定时器  
  155.     u32 result = 0xFFFFFF - SysTick_GetCounter(); //得到时间差  
  156.     SysTick_CounterCmd (SysTick_Counter_Clear); //清0  
  157.     result = result / 9000; //除以9000->result的单位为ms  
  158.     return result;  
  159.   
  160. }  
  161. int main() {  
  162.     RCC_Init();  
  163.     GpioInit();  
  164.     UsartInit();  
  165.   
  166.     lua_State *L = luaL_newstate();  
  167.     if (L == NULL)  
  168.         printf("cannot create state: not enough memory");  
  169.   
  170.     luaopen_base(L); //48kb内存紧张,用luaL_openlibs加载所有模块,会自动退出  
  171.   
  172.     luaL_dostring(L, LUA_SCRIPT);  
  173.   
  174.     int i;  
  175.     for (i = 10000; i < 90000; i=i + 30000) {   
  176.                 //----计算lua循环加运算的耗时  
  177.         start_calculate_time();  
  178.         int sum = use_lua_add(L, "loop_add", 1, 1, i);  
  179.         u32 duration = stop_calculate_time();  
  180.         printf("lua %d", i);  
  181.         printf(" frequency duration(ms): %d\r\n", duration);  
  182.                 //----计算c循环加运算的耗时  
  183.                 start_calculate_time();  
  184.         sum = c_loop_add(1, 1, i);  
  185.         duration = stop_calculate_time();  
  186.         printf("c %d", i);  
  187.         printf(" frequency duration(ms): %d\r\n", duration);  
  188.                   
  189.     }  
  190.     // 关闭虚拟机  
  191.     lua_close(L);  
  192.   
  193.         while(1){};  
  194.       
  195. }  

lua和C的循环加法运算耗时通过串口输出,简单的lua程序跟C程序效率比是1:100,而 lua运算量越大,与C程序效率差距就越小
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值