Adding LUA tutorials: lua_calls_C1 - lua_calls_C5

Adding blinker demo: lua_blink_led
This commit is contained in:
Carlos Camargo 2010-09-06 20:24:53 -05:00
parent acf516e22d
commit 7d9b7b803c
29 changed files with 1049 additions and 0 deletions

10
lua/examples/Makefile Normal file
View File

@ -0,0 +1,10 @@
DIRS = lua_blink_led lua_calls_C1 lua_calls_C2 lua_calls_C3 lua_calls_C4 lua_calls_C5
all:
for n in $(DIRS); do $(MAKE) -C $$n || exit 1; done
upload:
for n in $(DIRS); do $(MAKE) -C $$n upload || exit 1; done
clean:
for n in $(DIRS); do $(MAKE) -C $$n clean || exit 1; done

View File

@ -0,0 +1,27 @@
CC = mipsel-openwrt-linux-gcc
CXX = mipsel-openwrt-linux-g++
OPENWRT_BUILD_DIR = /home/cain/Embedded/ingenic/sakc/build/openwrt-xburst/staging_dir/target-mipsel_uClibc-0.9.30.1
INCLUDE = -I. -I$(OPENWRT_BUILD_DIR)/usr/include/
WARNINGS = -Wcast-align -Wpacked -Wpadded -Wall
CCFLAGS = ${INCLUDE} ${DEBUG} ${WARNINGS} -std=c99 -fPIC
LDFLAGS = -L$(OPENWRT_BUILD_DIR)/usr/lib -llua -ldl
DEBUG = -O3 -g0
NANO_PATH = root@192.168.254.101:
TARGET = sram_gpio_lib
COMMON_SOURCES = jz47xx_gpio.c jz47xx_mmap.c sram_gpio_wrap.c
COMMON_OBJECTS = $(COMMON_SOURCES:.c=.o)
$(TARGET): $(COMMON_OBJECTS)
$(CC) $(CCFLAGS) $(LDFLAGS) -shared $(COMMON_OBJECTS) -o $(TARGET).so
.c.o:
$(CC) -c $(CCFLAGS) $< -o $@
upload: $(TARGET)
scp $(TARGET).so test_gpio.lua $(NANO_PATH)
clean:
rm -f *.o $(TARGET).so

View File

@ -0,0 +1,122 @@
/*
JZ47xx GPIO at userspace
Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <jz47xx_gpio.h>
#include <jz47xx_mmap.h>
#define JZ_GPIO_BASE 0x10010000
int
jz_gpio_as_output (JZ_PIO * pio, unsigned int o)
{
pio->PXFUNC = (1 << (o));
pio->PXSELC = (1 << (o));
pio->PXDIRS = (1 << (o));
return 0;
}
void
jz_gpio_as_input (JZ_PIO * pio, unsigned int o)
{
pio->PXFUNC = (1 << (o));
pio->PXSELC = (1 << (o));
pio->PXDIRC = (1 << (o));
}
void
jz_gpio_as_irq (JZ_PIO * pio, unsigned int o)
{
pio->PXFUNC = (1 << (o));
pio->PXSELS = (1 << (o));
pio->PXDIRC = (1 << (o));
}
int
jz_gpio_set_pin (JZ_PIO * pio, unsigned int o)
{
pio->PXDATS = (1 << (o));
return 0;
}
int
jz_gpio_clear_pin (JZ_PIO * pio, unsigned int o)
{
pio->PXDATC = (1 << (o));
return 0;
}
void
jz_gpio_out (JZ_PIO * pio, unsigned int o, unsigned int val)
{
if (val == 0)
pio->PXDATC = (1 << (o));
else
pio->PXDATS = (1 << (o));
}
unsigned int
jz_gpio_get_pin (JZ_PIO * pio, unsigned int o)
{
return (pio->PXPIN & (1 << o)) ? 1 : 0;
}
int
jz_gpio_as_func (JZ_PIO * pio, unsigned int o, int func)
{
switch (func)
{
case 0:
pio->PXFUNS = (1 << o);
pio->PXTRGC = (1 << o);
pio->PXSELC = (1 << o);
pio->PXPES = (1 << o);
return 1;
case 1:
pio->PXFUNS = (1 << o);
pio->PXTRGC = (1 << o);
pio->PXSELS = (1 << o);
pio->PXPES = (1 << o);
return 1;
case 2:
pio->PXFUNS = (1 << o);
pio->PXTRGS = (1 << o);
pio->PXSELC = (1 << o);
pio->PXPES = (1 << o);
return 1;
}
return 0;
}
JZ_PIO *
jz_gpio_map (int port)
{
JZ_PIO *pio;
pio = (JZ_PIO *) jz_mmap (JZ_GPIO_BASE);
pio = (JZ_PIO *) ((unsigned int) pio + port * 0x100);
return pio;
}

View File

@ -0,0 +1,84 @@
/*
JZ47xx GPIO at userspace
Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef __jz47xx_gpio_h__
#define __jz47xx_gpio_h__
#define JZ_GPIO_PORT_A 0
#define JZ_GPIO_PORT_B 1
#define JZ_GPIO_PORT_C 2
#define JZ_GPIO_PORT_D 3
typedef volatile unsigned int JZ_REG; /* Hardware register definition */
typedef struct _JZ_PIO
{
JZ_REG PXPIN; /* PIN Level Register */
JZ_REG Reserved0;
JZ_REG Reserved1;
JZ_REG Reserved2;
JZ_REG PXDAT; /* Port Data Register */
JZ_REG PXDATS; /* Port Data Set Register */
JZ_REG PXDATC; /* Port Data Clear Register */
JZ_REG Reserved3;
JZ_REG PXIM; /* Interrupt Mask Register */
JZ_REG PXIMS; /* Interrupt Mask Set Reg */
JZ_REG PXIMC; /* Interrupt Mask Clear Reg */
JZ_REG Reserved4;
JZ_REG PXPE; /* Pull Enable Register */
JZ_REG PXPES; /* Pull Enable Set Reg. */
JZ_REG PXPEC; /* Pull Enable Clear Reg. */
JZ_REG Reserved5;
JZ_REG PXFUN; /* Function Register */
JZ_REG PXFUNS; /* Function Set Register */
JZ_REG PXFUNC; /* Function Clear Register */
JZ_REG Reserved6;
JZ_REG PXSEL; /* Select Register */
JZ_REG PXSELS; /* Select Set Register */
JZ_REG PXSELC; /* Select Clear Register */
JZ_REG Reserved7;
JZ_REG PXDIR; /* Direction Register */
JZ_REG PXDIRS; /* Direction Set Register */
JZ_REG PXDIRC; /* Direction Clear Register */
JZ_REG Reserved8;
JZ_REG PXTRG; /* Trigger Register */
JZ_REG PXTRGS; /* Trigger Set Register */
JZ_REG PXTRGC; /* Trigger Set Register */
JZ_REG Reserved9;
JZ_REG PXFLG; /* Port Flag Register */
JZ_REG PXFLGC; /* Port Flag clear Register */
} JZ_PIO, *PJZ_PIO;
int jz_gpio_as_output (JZ_PIO * pio, unsigned int o);
void jz_gpio_as_input (JZ_PIO * pio, unsigned int o);
int jz_gpio_set_pin (JZ_PIO * pio, unsigned int o);
int jz_gpio_clear_pin (JZ_PIO * pio, unsigned int o);
void jz_gpio_out (JZ_PIO * pio, unsigned int o, unsigned int val);
unsigned int jz_gpio_get_pin (JZ_PIO * pio, unsigned int o);
int jz_gpio_as_func (JZ_PIO * pio, unsigned int o, int func);
JZ_PIO *jz_gpio_map (int port);
#endif

View File

@ -0,0 +1,64 @@
/*
* JZ47xx GPIO lines
*
* Written 2010 by Andres Calderon andres.calderon@emqbit.com
*/
#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <jz47xx_mmap.h>
void *
jz_mmap (off_t address)
{
int fd;
void *pio;
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC)) == -1)
{
fprintf (stderr, "Cannot open /dev/mem.\n");
return 0;
}
pio = (void *) mmap (0, getpagesize (), PROT_READ | PROT_WRITE, MAP_SHARED, fd, address);
if (pio == (void *) -1)
{
fprintf (stderr, "Cannot mmap.\n");
return 0;
}
return pio;
}
void *
jz_fpga_map (off_t address)
{
int fd;
void *fpga;
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC)) == -1)
{
fprintf (stderr, "Cannot open /dev/mem.\n");
return 0;
}
fpga = (void *) mmap (0, FPGA_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, address);
if (fpga == (void *) -1)
{
fprintf (stderr, "Cannot mmap.\n");
return 0;
}
return fpga;
}

View File

@ -0,0 +1,17 @@
/*
* JZ47xx GPIO lines
*
* Written 2010 by Andres Calderon andres.calderon@emqbit.com
*/
#ifndef __jz47xx_mmap_h__
#define __jz47xx_mmap_h__
#include <sys/mman.h>
#define FPGA_SIZE (1 << 15)
void *jz_mmap (off_t address);
void *jz_fpga_map (off_t address);
#endif

View File

@ -0,0 +1,59 @@
/*
JZ47xx test gpio
Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com
Carlos Camargo cicamargoba@unal.edu.co
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <stdio.h>
#include <unistd.h>
#include "jz47xx_gpio.h"
//#define TEST_PORT JZ_GPIO_PORT_C
//#define TEST_PIN 17
int
main (int argc,char *argv[])
{
int TEST_PORT, TEST_PIN;
if(argc != 3){
fprintf(stderr,"\nUsage: %s TEST_PIN_PORT(A=0, B=1, C=2, D=3) TEST_PIN \n",argv[0]);
}
TEST_PORT = 17;
TEST_PIN = 17;
JZ_PIO *pio = jz_gpio_map (TEST_PORT);
if (!pio)
return -1;
jz_gpio_as_output (pio, TEST_PIN);
int tg = 1;
while (1)
{
jz_gpio_out (pio, TEST_PIN, tg);
printf ("[%d]", jz_gpio_get_pin (pio, TEST_PIN));
fflush (stdout);
usleep (500 * 1000);
tg = !tg;
}
return 0;
}

View File

@ -0,0 +1,63 @@
#include <jz47xx_gpio.h>
#include <jz47xx_mmap.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
const char *metaname = "mine.JZ_PIO"; // associated with userdata of type Point*
static int jz_gpio_as_output_wrap(lua_State *L) {
JZ_PIO *pio = (JZ_PIO *)lua_touserdata(L,1);
luaL_checkudata(L, 1, metaname); // check argument type
int b = luaL_checkint(L, 2);
lua_pushnumber(L, (lua_Number)jz_gpio_as_output(pio, b));
return 1;
}
static int jz_gpio_set_pin_wrap(lua_State *L) {
JZ_PIO *pio = luaL_checkudata(L, 1, metaname); // check argument type
int b = luaL_checkint(L, 2);
lua_pushnumber(L, (lua_Number)jz_gpio_set_pin(pio, b));
return 1;
}
static int jz_gpio_clear_pin_wrap(lua_State *L) {
JZ_PIO *pio = luaL_checkudata(L, 1, metaname); // check argument type
int b = luaL_checkint(L, 2);
lua_pushnumber(L, (lua_Number)jz_gpio_clear_pin(pio, b));
return 1;
}
static int point_new_wrapper(lua_State *L) { // get Lua to allocate an initialize a Point*
//create user data and associate metable with it
JZ_PIO *pio = jz_gpio_map (JZ_GPIO_PORT_C);
lua_pushlightuserdata(L,pio);
luaL_getmetatable(L, metaname);
lua_setmetatable(L, -2);
return 1;
}
static const struct luaL_reg functions[] = {
{"jz_gpio_as_output", jz_gpio_as_output_wrap},
{"jz_gpio_set_pin", jz_gpio_set_pin_wrap},
{"jz_gpio_clear_pin", jz_gpio_clear_pin_wrap},
{"point_new", point_new_wrapper},
{ NULL, NULL}
};
//This is the init function that will be called when you require 'mylib'
int luaopen_sram_gpio_lib(lua_State *L) {
luaL_newmetatable(L, metaname);
//pop 1 elements from the statck .. why?? to pop the newmetatable that is useless.
//
//lua_pop(L, 1);
//replace luaL_openlib
luaL_register(L, "sram_gpio_lib", functions);
return 1;
}

View File

@ -0,0 +1,23 @@
package.cpath = "./?.so"
require "sram_gpio_lib"
function pulse()
sram_gpio_lib.jz_gpio_set_pin(pio,17)
delay_s(1)
sram_gpio_lib.jz_gpio_clear_pin(pio,17)
delay_s(1)
end
function delay_s(delay)
delay = delay or 1
local time_to = os.time() + delay
while os.time() < time_to do end
end
pio=sram_gpio_lib.point_new()
sram_gpio_lib.jz_gpio_as_output(pio,17)
for i=0,5,1 do
pulse()
end

View File

@ -0,0 +1,23 @@
CC = mipsel-openwrt-linux-gcc
CXX = mipsel-openwrt-linux-g++
OPENWRT_BUILD_DIR = /home/cain/Embedded/ingenic/sakc/build/openwrt-xburst/staging_dir/target-mipsel_uClibc-0.9.30.1
INCLUDE = -I. -I$(OPENWRT_BUILD_DIR)/usr/include/
WARNINGS = -Wcast-align -Wpacked -Wpadded -Wall
CCFLAGS = ${INCLUDE} ${DEBUG} ${WARNINGS} -std=c99 -fPIC
LDFLAGS =
DEBUG = -O3 -g0
NANO_PATH = root@192.168.254.101:
TARGET = fromlua
$(TARGET): $(TARGET)
$(CC) $(CCFLAGS) -o $(TARGET).so -shared $(TARGET).c
.c.o:
$(CC) -c $(CCFLAGS) -o $@
upload: $(TARGET)
scp $(TARGET).so top1.lua $(NANO_PATH)
clean:
rm -f *.o $(TARGET).so

View File

@ -0,0 +1,29 @@
Examples from http://www.wellho.net/mouth/1844_Calling-functions-in-C-from-your-Lua-script-a-first-HowTo.html
The first two lines of the Lua code tell Lua to REPLACE the library path with .so files in the current directory. This is great for testing but you'll want to also consider library directories in a real live program.
package.cpath = "./?.so"
require "fromlua"
The C function who's name is the same as the required module, preceeded by luaopen_ is run as the module is requireed,
int luaopen_fromlua ( lua_State *L) {
....
}
and it defines a Map which tells the interface the names of various Lua function calls, and the equivalent function name that that map to in C.
static const luaL_reg Map [] = {
{"dothis", myCfunc},
{NULL,NULL} } ;
In this case, the lua function dothis maps to the C function myCfunc.
The map is then registered with Lua, into a table named as the second parameter to the luaL_register call.
luaL_register(L, "cstuff", Map);
We've now defined where the library is to be found, loaded it, and told Lua about it. All that remains is for us to call the function from the Lua. All functions called in this way return a static int ( the number of values returned) and take as a parameter a Lua stack pointer - although in this first example we return nothing (0) and do nothing with the Lua stack passed in - we just print "lua SIE's Test" to show we're here. And indeed the code runs like this:

View File

@ -0,0 +1,15 @@
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include <stdio.h>
static int myCfunc ( lua_State *L) {
printf ("lua SIE's Test\n");
return 0; }
int luaopen_fromlua ( lua_State *L) {
static const luaL_reg Map [] = {
{"dothis", myCfunc},
{NULL,NULL} } ;
luaL_register(L, "cstuff", Map);
return 1; }

Binary file not shown.

View File

@ -0,0 +1,23 @@
CC = mipsel-openwrt-linux-gcc
CXX = mipsel-openwrt-linux-g++
OPENWRT_BUILD_DIR = /home/cain/Embedded/ingenic/sakc/build/openwrt-xburst/staging_dir/target-mipsel_uClibc-0.9.30.1
INCLUDE = -I. -I$(OPENWRT_BUILD_DIR)/usr/include/
WARNINGS = -Wcast-align -Wpacked -Wpadded -Wall
CCFLAGS = ${INCLUDE} ${DEBUG} ${WARNINGS} -std=c99 -fPIC
LDFLAGS =
DEBUG = -O3 -g0
NANO_PATH = root@192.168.254.101:
TARGET = luapassing
$(TARGET): $(TARGET)
$(CC) $(CCFLAGS) -o $(TARGET).so -shared $(TARGET).c
.c.o:
$(CC) -c $(CCFLAGS) -o $@
upload: $(TARGET)
scp $(TARGET).so top2.lua $(NANO_PATH)
clean:
rm -f *.o $(TARGET).so

View File

@ -0,0 +1,29 @@
Examples from http://www.wellho.net/mouth/1844_Calling-functions-in-C-from-your-Lua-script-a-first-HowTo.html
The code is very similar, but you'll notice six additions - in the Lua:
a) We have added a parameter to the call to dothis in the Lua
b) We have added an assignment to collect a return value from the C
summat = cstuff.dothis(value)
c) We have printed out these values
print ("Values in Lua now",value, summat)
and in the C:
d) We have used lua_tonumber to collect a numeric value that was passed from the Lua to the C; you'll note that all such numbers are treated as doubles. The parameter "1" indicates 1 down - i.e. top of - the state stack.
double trouble = lua_tonumber(L, 1);
e) We have performed a calculation (representative of something being done in the C code) and pushed the result of this back onto the Lua state stack so that it can be picked up once we have returned from the C to the Lua
lua_pushnumber(L, 16.0 - trouble);
f) We have changed return 0 into return 1 to indicate that one result is being returned.
return 1; }

View File

@ -0,0 +1,19 @@
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include <stdio.h>
static int myCfunc ( lua_State *L) {
printf ("lua SIE's test\n");
double trouble = lua_tonumber(L, 1);
lua_pushnumber(L, 16.0 - trouble);
return 1; }
int luaopen_luapassing ( lua_State *L) {
static const luaL_reg Map [] = {
{"dothis", myCfunc},
{NULL,NULL} } ;
luaL_register(L, "cstuff", Map);
return 1; }

View File

@ -0,0 +1,7 @@
package.cpath = "./?.so"
require "luapassing"
print("hello")
value = 10
summat = cstuff.dothis(value)
print ("It's run da C code!")
print ("Values in Lua now",value, summat)

View File

@ -0,0 +1,23 @@
CC = mipsel-openwrt-linux-gcc
CXX = mipsel-openwrt-linux-g++
OPENWRT_BUILD_DIR = /home/cain/Embedded/ingenic/sakc/build/openwrt-xburst/staging_dir/target-mipsel_uClibc-0.9.30.1
INCLUDE = -I. -I$(OPENWRT_BUILD_DIR)/usr/include/
WARNINGS = -Wcast-align -Wpacked -Wpadded -Wall
CCFLAGS = ${INCLUDE} ${DEBUG} ${WARNINGS} -std=c99 -fPIC
LDFLAGS =
DEBUG = -O3 -g0
NANO_PATH = root@192.168.254.101:
TARGET = candy
$(TARGET): $(TARGET)
$(CC) $(CCFLAGS) -o $(TARGET).so -shared $(TARGET).c
.c.o:
$(CC) -c $(CCFLAGS) -o $@
upload: $(TARGET)
scp $(TARGET).so top3.lua $(NANO_PATH)
clean:
rm -f *.o $(TARGET).so

View File

@ -0,0 +1,22 @@
Examples from http://www.wellho.net/mouth/1844_Calling-functions-in-C-from-your-Lua-script-a-first-HowTo.html
If you may with to pass a table from your Lua script into a C function, so that the C function can make use of a value from the table code like this:
stuff = {hotel = 48, hq = 404, town = 1}
....
summat = extratasks.dothis(stuff)
This isn't as easy as just passing a value, since the size of a table can vary, and Lua's dynamic memory allocation doesn't sit well, in a simple interface, with C's static model. The "trick" is to tackle it within the C code by using function calls to get (and if necessary) reset values from the table - with the data required by those function calls being processed via the Lua stack.
/* Looking up based on the key */
/* Add key we're interested in to the stack*/
lua_pushstring(L,"hq");
/* Have Lua functions look up the keyed value */
lua_gettable(L, -2 );
/* Extract the result which is on the stack */
double workon = lua_tonumber(L,-1);
/* Tidy up the stack - get rid of the extra we added*/
lua_pop(L,1);
That code retrieves the "hq" value from the table that's been passed in (called stuff in my Lua example above) and stores it into a C variable called workon ... objective achieved!

View File

@ -0,0 +1,67 @@
/* This is the third (of three) examples of calling from
a Lua script to a C library. In this example, we have
registered multiple C functions with the Lua, and we have
also passed in a table which is intrinically much harder
to handle as it doesn't map directly to a C type. */
#include "lua.h"
#include "lauxlib.h"
#include <stdio.h>
/* The peardrop function is called with a single
numeric parameter, and it returns a number */
static int peardrop ( lua_State *L) {
printf ("lua SIE's test\n");
double trouble = lua_tonumber(L, 1);
lua_pushnumber(L, 16.0 - trouble);
return 1;
}
/* The humbug function is called with a TABLE as
its parameter (or it should be!). It extracts the
element with the key "hq", and returns 123 more
than that number (the sum added is just done to
demonstrate the C doing something! */
static int humbug ( lua_State *L) {
printf ("Enter humbug function\n");
/* Is it a table? */
if (lua_istable(L,-1)) {
printf("Table passed to humbug\n");
/* Looking up based on the key */
/* Add key we're interested in to the stack*/
lua_pushstring(L,"hq");
/* Have Lua functions look up the keyed value */
lua_gettable(L, -2 );
/* Extract the result which is on the stack */
double workon = lua_tonumber(L,-1);
/* Tidy up the stack - get rid of the extra we added*/
lua_pop(L,1);
/* We can now use the result */
lua_pushnumber(L, workon + 123.0 );
} else {
printf("Not a Table passed to humbug\n");
lua_pushnumber(L, 12.0 );
}
return 1;
}
/* This registers "dothis" and "dothat" with Lua, so that when
they're called they run the humbug and peardrop functions respectively */
int luaopen_candy ( lua_State *L) {
static const luaL_reg Map [] = {
{"dothis", humbug},
{"dothat", peardrop},
{NULL,NULL}
} ;
/* dothis and dothat are put in the extratasks table */
luaL_register(L, "extratasks", Map);
return 1;
}

View File

@ -0,0 +1,25 @@
--[[ This is a short (demonstration) piece of Lua
script which calls in some C functions from a file
called candy.c; the functions are accessed via a
table called extratasks (that's defines in the
C code) and called via the names dothis and dothat -
again defined in the candy.c file
]]
-- Setting up demo variables that will be passed to C
print("Lua code running ...")
stuff = {hotel = 48, hq = 404, town = 1}
-- Loading and calling the C
require "candy"
summat = extratasks.dothis(stuff)
somemore = extratasks.dothat(summat)
-- Lua code to show you the results
print ("... back into Lua code")
print ("Values in Lua now", summat, somemore)
print ("Table contains ...")
for k,v in pairs(stuff) do
print (k,v)
end

View File

@ -0,0 +1,15 @@
CC = mipsel-openwrt-linux-gcc
CXX = mipsel-openwrt-linux-g++
OPENWRT_BUILD_DIR = /home/cain/Embedded/ingenic/sakc/build/openwrt-xburst/staging_dir/target-mipsel_uClibc-0.9.30.1
INCLUDE = -I. -I$(OPENWRT_BUILD_DIR)/usr/include/
WARNINGS = -Wcast-align -Wpacked -Wpadded -Wall
CCFLAGS = ${INCLUDE} ${DEBUG} ${WARNINGS} -std=c99 -fPIC
LDFLAGS =
DEBUG = -O3 -g0
TARGET = candy
#luaavg:
# $(CXX) ${INCLUDE} -Wno-variadic-macros -fPIC luaavg.cc -llua -ldl -o luaavg
clean:
rm -f luaavg

View File

@ -0,0 +1,6 @@
-- call a C++ function
avg, sum = average(10, 20, 30, 40, 50)
print("The average is ", avg)
print("The sum is ", sum)

View File

@ -0,0 +1,58 @@
#include <stdio.h>
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
/* the Lua interpreter */
lua_State* L;
static int average(lua_State *L)
{
/* get number of arguments */
int n = lua_gettop(L);
int sum = 0;
int i;
/* loop through each argument */
for (i = 1; i <= n; i++)
{
/* total the arguments */
sum += lua_tonumber(L, i);
}
/* push the average */
lua_pushnumber(L, sum / n);
/* push the sum */
lua_pushnumber(L, sum);
/* return the number of results */
return 2;
}
int main ( int argc, char *argv[] )
{
/* initialize Lua */
L = lua_open();
/* load Lua base libraries */
luaL_openlibs(L);
/* register our function */
lua_register(L, "average", average);
/* run the script */
luaL_dofile(L, "avg.lua");
/* cleanup Lua */
lua_close(L);
/* pause */
printf( "Press enter to exit..." );
getchar();
return 0;
}

View File

@ -0,0 +1,22 @@
CC = mipsel-openwrt-linux-gcc
CXX = mipsel-openwrt-linux-g++
OPENWRT_BUILD_DIR = /home/cain/Embedded/ingenic/sakc/build/openwrt-xburst/staging_dir/target-mipsel_uClibc-0.9.30.1
INCLUDE = -I. -I$(OPENWRT_BUILD_DIR)/usr/include/
WARNINGS = -Wcast-align -Wpacked -Wpadded -Wall
CCFLAGS = ${INCLUDE} ${DEBUG} ${WARNINGS} -std=c99 -fPIC
LDFLAGS = -L$(OPENWRT_BUILD_DIR)/usr/lib -llua -ldl
DEBUG = -O3 -g0
NANO_PATH = root@192.168.254.101:
TARGET = mylib
$(TARGET):
$(CC) $(CCFLAGS) $(LDFLAGS) -shared liba.c liba_wrapper.c -o $(TARGET).so
.c.o:
$(CC) -c $(CCFLAGS) -o $@
upload: $(TARGET)
scp $(TARGET).so test.lua $(NANO_PATH)
clean:
rm -f *.o $(TARGET).so

View File

@ -0,0 +1,40 @@
#include <stdio.h>
#include <string.h>
#include "liba.h"
#define ENTER do{printf("in %s \n" ,__FUNCTION__);}while(0);
void lib_a_f_1()
{
ENTER
}
int lib_a_f_2(int a , int b)
{
ENTER
return a * b ;
}
int lib_a_f_3(const char *s)
{
ENTER
return strlen(s);
}
int lib_a_f_4(Point *in_t)
{
ENTER
return in_t->a * in_t->b ;
}
int lib_a_f_5(Point *out_t)
{
ENTER
out_t->a = 20;
out_t->b = 30;
return 0;
}

View File

@ -0,0 +1,10 @@
typedef struct tagT{
int a ;
int b ;
}Point;
void lib_a_f_1(void);
int lib_a_f_2(int a, int b);
int lib_a_f_3(const char *s);
int lib_a_f_4(Point *in_t);
int lib_a_f_5(Point *out_t);

View File

@ -0,0 +1,131 @@
#include "liba.h"
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
//glue the luaVm and the actually libary
static int lib_a_f_1_wrapper(lua_State * luaVM)
{
// no parameters , just call
lib_a_f_1();
return 0;
}
static int lib_a_f_2_wrapper(lua_State * L)
{
// no parameters , just call
int n = lua_gettop(L);
//error checking & return back to lua scripter
int a = lua_tonumber(L,1);
int b = lua_tonumber(L,2);
int r = lib_a_f_2(a ,b );
lua_pushnumber(L,r);
return 1;
}
static int lib_a_f_3_wrapper(lua_State * L)
{
// no parameters , just call
int n = lua_gettop(L);
//error checking & return back to lua scripter
const char *s = lua_tostring(L,1);
int r = lib_a_f_3(s);
lua_pushnumber(L,r);
return 1;
}
const char *metaname = "mine.Point"; // associated with userdata of type Point*
static int lib_a_f_4_wrapper(lua_State *L) {
Point *t = luaL_checkudata(L, 1, metaname); // check argument type
lua_pushnumber(L, (lua_Number)lib_a_f_4(t));
return 1;
}
static int point_new_wrapper(lua_State *L) { // get Lua to allocate an initialize a Point*
int a = luaL_checkint(L, 1);
int b = luaL_checkint(L, 2);
//create user data and associate metable with it
Point *t = lua_newuserdata(L, sizeof(*t));
luaL_getmetatable(L, metaname);
lua_setmetatable(L, -2);
t->a = a;
t->b = b;
return 1;
}
static int point_geta_wrapper(lua_State *L)
{
Point *t = luaL_checkudata(L, 1, metaname);
lua_pushnumber(L,t->a);
return 1;
}
static int point_getb_wrapper(lua_State *L)
{
Point *t = luaL_checkudata(L, 1, metaname);
lua_pushnumber(L,t->b);
return 1;
}
static int lib_a_f_5_wrapper(lua_State *L)
{
// Point *t = luaL_checkudata(L, 1, metaname); // check argument type
// lua_pushnumber(L, (lua_Number)lib_a_f_4(t));
Point t ;
lib_a_f_5(&t);
Point *r = lua_newuserdata(L,sizeof(*r));
luaL_getmetatable(L, metaname);
//It will Pops a table from the stack and
//sets it as the new metatable for the value at the given acceptable index.
//so , after this function , it is the userdata at the top of the stack.
lua_setmetatable(L, -2);
r->a = t.a;
r->b = t.b;
return 1;
}
static const struct luaL_reg functions[] = {
{"lib_a_f_1", lib_a_f_1_wrapper},
{"lib_a_f_2", lib_a_f_2_wrapper},
{"lib_a_f_3", lib_a_f_3_wrapper},
{"lib_a_f_4", lib_a_f_4_wrapper},
{"lib_a_f_5", lib_a_f_5_wrapper},
{"point_new", point_new_wrapper},
{"point_geta", point_geta_wrapper},
{"point_getb", point_getb_wrapper},
{ NULL, NULL}
};
//This is the init function that will be called when you require 'mylib'
int luaopen_mylib(lua_State *L) {
luaL_newmetatable(L, metaname);
//pop 1 elements from the statck .. why?? to pop the newmetatable that is useless.
//
//lua_pop(L, 1);
//replace luaL_openlib
{
lua_pop(L, 1);
luaL_newmetatable(L,metaname);
return 1;
}
luaL_register(L, "mylib", functions);
return 1;
}

View File

@ -0,0 +1,16 @@
package.cpath = "./?.so"
require "mylib"
--test1
mylib.lib_a_f_1()
--test2
assert(6==mylib.lib_a_f_2(2,3))
--test3
assert(5==mylib.lib_a_f_3("hello"))
--test4 : use userdata to pass structure
t=mylib.point_new(3,6)
assert(18 == mylib.lib_a_f_4(t))
--test5, return userdata
t=mylib.lib_a_f_5()
assert(600 == mylib.lib_a_f_4(t))
assert(mylib.point_geta(t) == 20)
assert(mylib.point_getb(t) == 30)