构建一个轻量级的嵌入式虚拟平台,开发工程用板stm32 picoc解释器,大量自定义函数,sarm拓展,lwip移植,nes模拟器移植,系统优化,等等技术的融合

来源:互联网 发布:科来网络 编辑:程序博客网 时间:2024/06/07 23:31



让嵌入式想java一样一处编写到处运行

第一次写博客,其实接触嵌入式已经快两年了,从开始学51单片机的时候,怀着满腔的热情。写出了点亮第一个流水灯代码的时候那个无比的激动,到后面自己做许多有趣的东西(比如光立方,电子时钟,无线通讯等等),刚开始连单片机知识一点也不了解,c语言写的很烂的时候,到后面开始慢慢的学着别人写代码,经过了两年的时光,,, 现在我觉得我应该证明我自己。于是我决定写一篇做了快一个月的东西,分享给大家,同时大家相互的学习,互相的进步。

在学习stm32的时候,当时是犹如大海找针一样的学习,完全不知道重哪儿开始,后面找到了刘凯的视频,发现视频讲的很全面,于是就花了15天的时间,专心的学习,晚上专研到2,3点,当时很穷,买的开发板也是淘宝上最便宜的那种,所以资料少的可怜。自己在写程序的时候也总是想自己把所有的代码全部都写出来,这期间走了不少的弯路,造了不少的轮子,这里就不细说了,后面在谈,下面我来介绍一下这个平台把:


起初想到这个想法的时候,完全是起源与mtk手机上的一个冒泡开发实验系统,在这套系统上移植一个一个picoc的嵌入式c语言解释器,我就在想能不能在嵌入式上也跑上这个解释器,在嵌入式上运行许多的应用程序,其他的嵌入式芯片只需要移植我这个平台就可以了,到目前为止,项目的函数的构建已经完成了一大半,只有网络与对话框等没有完成,还存在一定的bug

这个轻量级的嵌入式虚拟平台,开发工程用板stm32 picoc解释器,大量自定义函数,sarm拓展,lwip移植,nes模拟器移植,系统优化,等等技术的融合

在这个虚拟平台上,不仅完成了按键事件的结构,还支持触屏接口,支持page页面,button的创建等等


下面列出完成的功能:

完成了字库的驱动,可以加载任意的字库,一个字库的简单管理。、

完成了字库读取优化,字库第一次从sd卡读取到ram时会保存,第二次就会自动的去ram读取,不会在读写sd卡了

完成了unciode 码到gb2312码的转换,能够在内部自动的转换

完成了菜单的创建,菜单的创建采用链表管理,不受长度的限制,

完成了button的创建,button做的比较简单,能狗进行事件的回调(回调函数),颜色设置,内容设置等(只支持触屏)

完成了page页面的管理,能够创建任意多的页面,可以将button等加入到页面中,button就收到了page的管理,page的释放,将释放掉button

完成了软定时器,用户可以创建任意多个软定时器,定时器由回调函数返回结果。、

完成了sram的拓展,实现动态内存的管理

完成了lwip的移植,运行链接网络,测试服务器成功(socket为实现)

完成了file文件的扫描,能够直接运行应用程序。

完成了bmp图片解码,自己花了几天时间写的bmp图片解码,支持8bit 16bit 24bit图片解码(1,2,4,想做的还没来的急)

完成了bmp565纯数据格式的显示(速度很快),做界面最爱

完成了txt文字的显示,可以字节写一个小说阅读器啥的。

完成了nes模拟器的移植,能够运行40kb一下的游戏(本来想移植一个支持全部游戏的,觉得麻烦)

完成了屏幕缓冲区的设置,能够通过宏开关打开或关闭屏幕缓存(这个玩意可是暂用150kb的ram)

完成了gpio口到picoc的添加,能够在应用程序中直接控制gpio


今天就将这么多了,都说没图没真相,今天太晚了,明天上图。


下面我一一的讲解:、

picoc解释器:

Picoc C语言解释器的STM32平台移植
Picoc是google开源代码项目中看到的一个项目,其初衷貌似是要做一个在小的嵌入设备上的C解释器。它的核心代码只有3500行左右,可读性不错,虽然没有实现完整的ISO C标准,基本的C运行库还是具备了。
picoc代码上看,基本有如下几块:lex词法解析,table一个基本数据结构(用于存放变量),是个字符串hash表,heap管理内存分配(包括了stack frame的实现), type做类型管理(基本型别和程序自定义的struct,typedef等),expression做表达式解析,variable变量管理分配释放栈帧。
picoc的定位是一个解释器,它的解析和代码运行是在同一块代码块里做

  • PicoC是一个非常小的C解释器的脚本。它最初是作为一个无人机的飞行系统板上的脚本语言。它也非常适合于其他机器人,嵌入式和非嵌入式应用。
  • 核心的C源代码是大约4500行代码。它并不打算成为一个完整的ISO C实现的,但它拥有所有的必需品。在编译时,只需要几K的代码空间也很不遗余力的数据空间。这意味着,在小型嵌入式设备,它可以很好地工作。这也是一个有趣的例子,如何创建一个非常小的语言实现,同时仍保持代码的可读性。
  • picoc已经过测试的x86-32,x86-64的的PowerPC,ARM,以UltraSPARC,HP-PA和Blackfin处理器上,并很容易地移植到新的目标。


项目地址,有文档和源码:
GOOGLE https://code.google.com/p/picoc/
GitHub  https://github.com/larryhe/tiny-c-interpreter
SVN 地址,貌似还有人在开发当中,但是只有 win32版本可以编译过去,变化比较大...
# Non-members may check out a read-only working copy anonymously over HTTP.
svn checkout http://picoc.googlecode.com/svn/trunk/ picoc-read-only

以及我已经完成的函数列表:

#ifndef MRC_BASE_H
#define MRC_BASE_H


/*
本文件只相当于帮助文件,没有任何实际意义,也就是说在这里增加或修改定义不会有任何效果
如果你需要增加定义,请定义在其他文件中,要使用以下所有接口请在你的代码中增加“#include "base.h"”


请不要将此文件改名为其他文件名后包含在你的代码中!否则可能会导致系统异常!!!
*/






//系统版本,由于软件的更新,可能会造成有些函数、宏、类型等不一致而导致运行出错
//建议在源码中判断系统版本是否相同
#define _VERSION 1001


/*
此文件为系统内部简单封装的MRP函数实现了MRPAPI库<mrc_base.h>的部分功能
*/
typedef  unsigned short     uint16;      //有符号16bit整型
typedef  unsigned long int  uint32;      //无符号32bit整型
typedef  long int           int32;       //有符号32bit整型
typedef  unsigned char      uint8;       //无符号8bit整型
typedef  signed char        int8;        //有符号8bit整型
typedef  signed short       int16;       //有符号16bit整型


//下面四项为大部分系统函数的返回值,没有在系统内定义,如果需要这些宏定义请在其他头文件中定义
#define MR_SUCCESS  0    //成功
#define MR_FAILED   -1    //失败
#define MR_IGNORE   1     //不关心
#define MR_WAITING  2     //异步(非阻塞)模式


#define NULL (void*)0
#define TRUE 1
#define FALSE 0
#define SCRW  //系统内部宏,值为屏幕宽
#define SCRH  //系统内部宏,值为屏幕高




//基本按键值(未定义的其他按键也可以使用,但需知道其键值)
enum {  
   _0,           //按键 0
   _1,           //按键 1
   _2,           //按键 2
   _3,           //按键 3
   _4,           //按键 4
   _5,           //按键 5
   _6,           //按键 6
   _7,           //按键 7
   _8,           //按键 8
   _9,           //按键 9
   _STAR,        //按键 * 10
   _POUND,       //按键 # 11
   _UP,          //按键 上 12
   _DOWN,        //按键 下  13
   _LEFT,        //按键 左 14
   _RIGHT,       //按键 右  15
   _SLEFT=17,    //按键 左软键
   _SRIGHT,      //按键 右软键
   _SEND,        //按键 接听键
   _SELECT       //按键 确认/选择(若方向键中间有确认键,建议设为该键)
};


//基本事件(其他事件需自己定义)
enum {
    KY_DOWN, //按键按下
    KY_UP,       //按键释放
    MS_DOWN, //鼠标按下
    MS_UP,     //鼠标释放
    MN_SLT, //菜单选择
    MN_RET, //菜单返回
    MR_DIALOG, //对话框
    MS_MOVE=12   //鼠标移动
};


enum {
    DLG_OK,         //对话框/文本框等的"确定"键被点击(选择)
    DLG_CANCEL  //对话框/文本框等的"取消"("返回")键被点击(选择)
};


enum
{
    SEEK_SET,             //从文件起始开始
    SEEK_CUR,             //从当前位置开始
    SEEK_END             //从文件末尾开始
};
enum
{
    IS_FILE=1,      //文件
    IS_DIR=2,      //目录
    IS_INVALID=8,  //无效(非文件、非目录)
};


typedef struct {
    uint16            x;
    uint16            y;
    uint16            w;
    uint16            h;
}rectst;


typedef struct {
    uint8            r;
    uint8            g;
    uint8            b;
}colorst;




/********************************C库函数********************************/


/*该函数功能与printf函数相似,区别是本函数的输出
信息将打印在print.txt文件中(与mrpapi有点区别)*/
void printf(const char *format,...);


//申请内存接口,注意!必须严格管理申请的内存,以防内存泄漏!系统不会为你检查申请的内存的使用情况
void* malloc(int size);


//释放由malloc申请的内存
void free(void *address);


//由src所指内存区域复制count个字节到dest所指内存区域。src和dest所指内存区域不能重叠,函数返回指向dest的指针。
void *memcpy(void *dest, void *src, unsigned int count)


//由src所指内存区域复制count个字节到dest所指内存区域。src和dest所指内存区域可以重叠,但复制后dest内容会被更改。
void *memmove(void *dest, const void *src, unsigned int count);


//把src所指由NULL结束的字符串复制到dest所指的数组中。src和dest所指内存区域不可以重叠,且dest必须有足够的空间来容纳src的字符串。
char *strcpy(char *dest,char *src);


//将字符串src中最多n个字符复制到字符数组dest中,它并不像strcpy一样遇到NULL就开始复制,而是等凑够n个字符才开始复制。
char *strncpy(char *dest, char *src, int32 n);


//把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'。src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
char *strcat(char *dest,char *src);


//把src所指字符串的前n个字符添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'。src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
char *strncat(char *dest,char *src,int n);


//比较内存区域buf1和buf2的前count个字节。
int memcmp(void *buf1, void *buf2, unsigned int count);


// 比较字符串s1和s2。
// 返回值:
// 当s1<s2时,返回值<0
// 当s1=s2时,返回值=0
// 当s1>s2时,返回值>0
int strcmp(const char *s1,const char * s2);


//串比较,比较字符串str1和str2的前maxlen个字符。
int strncmp(char *str1, char *str2, int maxlen);


//从buf所指内存区域的前count个字节查找字符ch,当第一次遇到字符ch时停止查找。
//如果成功,返回指向字符ch的指针;否则返回NULL。
void *memchr(void *buf, char ch, unsigned count);


// 将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值, 块的大小由第三个参数指定。
// 这个函数通常为新申请的内存做初始化工作, 其返回值为指向s的指针。
void *memset(void *s, int ch, unsigned n);


// 计算字符串s的长度。
uint32 strlen(char *s);


/*
在母串str1中查找指定字符串str2的第一次出现位置,不比较结束符NULL。


参数说明:
str1      [IN]          欲查找串所在的母串
str2      [IN]          欲查找串
返回值:
NULL         在母串str1内未查找到子串str2;
非NULL       母串str1中第一次出现子串str2的位置指针
*/
char *strstr(char *str1, char *str2);


// 将字串格式化。(与mrpapi有点区别)
char *sprintf(char *str, char *format, ...);


//将数字字符串转化为整数,如“1234”转化为1234。
int atoi(const char *nptr);


// 将字符串转换成无符号长整型数。一开始会扫描参数nptr字符串,跳过前面的空格字符串,直到遇上数字或正负符号才开始做转换,再遇到非数字或字符串结束时('')结束转换,并将结果返回。若参数endptr不为NULL,则会将遇到不合条件而终止的nptr中的字符指针由endptr返回。
uint32 strtoul(const char *nptr,char **endptr,int base);




/*
查找一个字符串在另一个字符串中最后一次出现的位置,并返回从字符串中的这个位置起, 一直到字符串结束的所有字符。
参数说明:
str     [IN]          欲查询字符的母串
c       [IN]          查询字符
返回值:
非NULL:   返回母串src中首次出现字符c的子串指针;
NULL:     母串src中不存在字符c。
*/
char *strrchr(char *str, char c);


// 计算unicode字符串s的长度,结束符为:“\0\0”。
int32 wstrlen(char *s);
/********************************C库函数结束****************/




/*******************************入口函数*********************/
/*
应用初始化函数
该函数在应用初始化期间被mythroad平台调用,可以在这个
函数中进行全局变量的初始化等工作。
返回值:
0  应用初始化成功
-1      应用初始化失败
*/
int init(void);


/*
应用事件函数
该函数在应用运行期间,每当mythroad平台收到事件时被调用
输入:
code:
      code的可能取值如下:
enum {
      KY_DOWN, //按键按下
      KY_UP,       //按键释放
      MS_DOWN, //鼠标按下
      MS_UP,     //鼠标释放
      MS_MOVE=12   //鼠标移动
};


p0:
   当code为KY_DOWN或KY_UP时,p0的可能取值如下:
//基本按键值(未定义的其他按键也可以使用,但需知道其键值)
enum {  
   _0,           //按键 0
   _1,           //按键 1
   _2,           //按键 2
   _3,           //按键 3
   _4,           //按键 4
   _5,           //按键 5
   _6,           //按键 6
   _7,           //按键 7
   _8,           //按键 8
   _9,           //按键 9
   _STAR,        //按键 *
   _POUND,       //按键 #
   _UP,          //按键 上
   _DOWN,        //按键 下
   _LEFT,        //按键 左
   _RIGHT,       //按键 右
   _SLEFT=17,    //按键 左软键
   _SRIGHT,      //按键 右软键
   _SEND,        //按键 接听键
   _SELECT       //按键 确认/选择(若方向键中间有确认键,建议设为该键)
   };


当code为鼠标事件时,p0为屏幕的x坐标;p1为屏幕的y坐标;
其他事件各参数值请参考MRPAPI
返回值:
0  操作成功
-1 操作失败
*/
int event(int code, int p0, int p1);


/*
应用暂停函数
该函数在应用被暂停时(有电话等事件暂停应用)
被mythroad平台调用。


返回值:
0  操作成功
-1 操作失败
*/
int pause(void);


/*
该函数在应用恢复运行时被mythroad平台调用。


返回值:
0  操作成功
-1 操作失败
*/
int resume(void);


////////////////////////////以上为平台必需实现的入口函数//////////////////////////////
/*
以mode方式打开文件,如果文件不存在,根据mode值
判断是否创建之。


输入:
filename 文件名
mode 文件打开方式
     mode取值
1 //以只读的方式打开文件。
2  //以只写的方式打开文件。(这个方式可能被实现为与4相同的操作)
4  //以读写的方式打开文件。
8  //如果文件不存在,创建
该文件,该参数不会单独出现
,只能与其他值一同出现(使
用"或"运算)
mode可能的取值:
a、 前三个参数的其中一个
b、 前三个参数的其中一个和8的"或"值
返回:
非 0       文件句柄
0           失败
*/
int32 open(const char* filename,  uint32 mode);


/*
关闭文件。
输入:
f 文件句柄
返回:
0 成功
-1 失败
*/
int32 close(int32 f);


/*
取得文件类型信息。
输入:
filename 文件名
返回:
      IS_FILE     1//是文件
      IS_DIR      2//是目录
      IS_INVALID  8//文件不存在,或既不是文件也不是目录
*/
int32 filestate(const char* filename);


/*
写文件
输入:
f 文件句柄
p 待写入数据存放地址
l 待写入数据长度
返回:
      >0                   确切写入的字节数
      -1      失败
*/
int32 write(int32 f,void *p,uint32 l);


/*
读取文件的内容到指定的缓冲。
输入:
f 文件句柄
p 文件缓存地址
l 缓冲长度
返回:
      >=0                确切读取的字节数
      -1      失败
*/
int32 read(int32 f,void *p,uint32 l);






/*
设置文件指针。
输入:
f 文件句柄
pos 文件指针位置
method 可能的取值为:
   SEEK_SET, 
   SEEK_CUR, 
   SEEK_END
返回:
      0  成功
      -1   失败
*/
int32 seek(int32 f, int32 pos, int method);


/*
取得文件长度。
输入:
filename 文件名 
返回:
      >=0   文件长度
      -1   失败/文件不存在
*/
int32 getlen(const char* filename);


/*
删除文件。
输入:
filename 文件名
返回:
      0  成功
      -1   失败
*/
int32 remove(const char* filename);


/*
文件重命名。
输入:
oldname 旧文件名
newname 新文件名
返回:
      0  成功
      -1   失败
*/
int32 rename(const char* oldname, const char* newname);


/*
创建目录。
输入:
name 目录名
返回:
      0  成功
      -1   失败
*/
int32 mkdir(const char* name);


/*
删除目录(必需为空目录)
输入:
name 目录名
返回:
      0  成功
      -1   失败
*/
int32 rmdir(const char* name);


/*
准备搜索name指定的目录,当dsm调用该函数后,系统
初始化一个目录搜索,并返回第一个目录搜索的结果
,每当dsm调用一次findnext函数,系统返回下一个
该目录下的文件或一级子目录名。该函数只返回查找
句柄。当name为空字符串""时(注意name指向空串,但
name不是NULL),搜索Mythroad平台引擎的文件当前目录。
如:若手机以"/dsmdata/"作为Mythroad平台引擎的文件当前
目录,当name为空字符串时,搜索目录"/dsmdata"。
例:一个目录下有文件:"a.bmp"、"b.mrp";目录"data",则
mr_c_findStart返回查找句柄和"a.bmp"/handle,紧接着的findnext
返回"b.mrp"/0、"data"/0和XX(无效)/-1。
输入:
name 目录名
len 缓冲区大小
输出:
buffer  缓冲区,用于存放查找成功时第一个文件名或一级
            子目录名
返回:
      >0                  查找句柄,供findnext、findstop函数使用
      -1      失败
*/
int32 findstart(const char* name, char* buffer, uint32 len);


/*
取得一个目录搜索的结果。将结果放置于buffer中。当
目录中的结果都遍历过后,返回-1。
这里需要注意的是,使用findnext获得的子目录可
能是"."和".."。
输入:
   search_handle 调用findstart时返回的查找句柄
   len 缓冲区大小
输出:
   buffer  缓冲区,用于存放查找成功时文件名或一级子目录名
返回:
      0  搜索成功
      -1   搜索结束或搜索失败
*/
int32 findnext(int32 search_handle, char* buffer, uint32 len);


/*
目录搜索结束。中止一个findstart开启的目录搜索。
输入:
search_handle        调用findstart时返回的查找句柄
返回:
      0  成功
      -1   失败
*/
int32 findstop(int32 search_handle);


/********************************绘图接口********************************/


/*
将指定文本绘制于屏幕指定位置。
输入:
pcText:         待显示的字符串
x, y:             待显示的文本左上角x, y
r, g, b:          字体颜色r,g,b,r,g,b的取值范围:0~255,下同。
is_unicode:    是否是unicode,TRUE(1)表示使用unicode编码,FALSE(0)表
                     示使用GB2312编码。
font:              字体大小,可能的值是   
                        0 小字体
                        1 常规字体
                        2 大字体
返回值:
   0  操作成功
   -1      操作失败
*/
int32 dtext(char* pcText, int16 x, int16 y, uint8 r, uint8 g, uint8 b, int is_unicode, uint16 font);


/*
与函数dtext功能相似,不同点在于dtext将
显示的字符限制在左上角为(x, y),宽高为(w, h)
的矩形范围之内。
1936及其之后版本中:不自动换行时可以显示半个字
符。
1935版本无法显示半个字符。
输入:
pcText:         待显示的字符串
x, y:             待显示的文本左上角x, y
rect:            显示的字符限制范围(MRPAPI并不是以指针传递)
color:          字体颜色(MRPAPI并不是以指针传递)
font:              字体大小,可能的值是   
                        0 小字体
                        1 常规字体
                        2 大字体
flag:可以取如下的值,也可以是这些值的相加:
         1 //是否使用UNICODE码, 网络字节序
         2 //是否自动换行
返回值:
    指示出在屏幕上第一个未完整显示字符的索引,
该索引是Text的unicode索引值。即使函数使用gb输入字
符串,函数返回的索引值也是根据该字符串转换为
unicode串后的索引值。若所有字符都能完整显示,则
返回该字串转换为unicode串后的长度。
*/
int32 dtextex(char* pcText, int16 x, int16 y, rectst *rect, colorst *color, int flag, uint16 font);


/*
函数从右往左显示文本,相应的最右边显示的文本最
后一个字符;并且,该函数不支持自动换行。
函数不支持GB
输入:
pcText:         待显示的字符串
x, y:             待显示的文本右上角x, y
rect:            显示的字符限制范围(MRPAPI并不是以指针传递)
color:          字体颜色(MRPAPI并不是以指针传递)
font:              字体大小,可能的值是   
                        0 小字体
                        1 常规字体
                        2 大字体
flag:          无效;保留该参数仅为了统一
返回值:
    指示出在屏幕上第一个未完整显示字符的索引(字节),
该索引是Text的unicode索引值。若所有字符都能完整
显示,则返回该字串转换为0。
*/
int32 dtextright(char* pcText, int16 x, int16 y, rectst *rect, colorst *color, int flag, uint16 font);


/*
将gb字符串转换为Unicode字符串,并申请一片内存保
存Unicode字符串,将Unicode字符串的指针返回。
输入:
cp: 输入的gb字符串
err:填NULL;若err为非NULL,则在转换出错时err返回出
          错字符的索引
输出:
err:若err为非NULL,则在转换出错时err返回出错字符
             的索引
size:输出的Unicode字符串长度
返回:
    NULL        转换出错
    其他    Unicode字符串指针
*/
uint16* c2u(char *cp, int32 *err, int32 *size);




/*
获取字符串的显示宽度和高度。(MRPAPI原名为mrc_textWidthHeight)
输入:
pcText:         待显示的字符串
is_unicode:    是否是unicode,TRUE(1)表示使用unicode编码,FALSE(0)表
                     示使用GB2312编码。
font:              字体大小,可能的值是   
                        0 小字体
                        1 常规字体
                        2 大字体
输出:
w:字符串的显示宽度
h:字符串的显示高度
返回:
    0  操作成功
    -1      操作失败
*/
int32 textwh(char* pcText, int is_unicode, uint16 font, int32* w, int32* h);




/*
仅处理Unicode字符串输入
返回待显示字符串若显示在宽为w的区间里,
需要的行数;
pcText:         待显示的字符串
font:              字体大小,可能的值是   
                        0 小字体
                        1 常规字体
                        2 大字体
w                  待显示宽度
 返回:
    -1      操作失败
    其他           字符串行数
*/
int32 unitextrow(uint16* pcText, uint16 font, int32 w);






/*
绘制矩形于指定区域。
输入:
x,y,w,h: 位置
r,g,b     绘制颜色
*/
void drect(int16 x, int16 y, int16 w, int16 h, uint8 r, uint8 g, uint8 b);


/*
绘制线段。
输入:
x1,y1,x2,y2: 起末点位置
r,g,b          绘制颜色
*/
void dline(int16 x1, int16 y1, int16 x2, int16 y2, uint8 r, uint8 g, uint8 b);


/*
在屏幕的指定位置绘制点。
输入:
x, y           绘制点的位置
nativecolor 点的颜色。(R:G:B = 5:6:5)
*/
void dpoint(int16 x, int16 y, uint16 nativecolor);


/*
在屏幕的指定位置绘制点。
输入:
x, y           绘制点的位置
r,g,b          绘制颜色
*/
void dpointex(int16 x, int16 y, int32 r, int32 g, int32 b);


/*
使用指定的颜色清除屏幕。
输入:
r,g,b          绘制颜色
*/
void cls(int32 r, int32 g, int32 b);


/*
刷新屏幕指定的区域。该函数的功能是将mythroad屏幕
缓冲指定的区域刷新到屏幕上。
输入:
x, y, w, h       屏幕指定的区域(左上角为(x,y),宽高
                        为(w,h))
*/
void ref(int16 x, int16 y, uint16 w, uint16 h);


/*
将屏幕的左上角x,y,宽高为w,h的矩形区域内的r,g,b分别
增强perr/256, perg/256, perb/256倍。
若perr=256, perg=0, perb=0,将只保留矩形区域内的红色;若
perr=perg= perb=128,将使矩形区域内产生一种半透明的效
果。
输入:
x,y,w,h 屏幕位置。
perr, perg, perb r,g,b变化的数值。
*/
void effsetcon(int16 x, int16 y, int16 w, int16 h, int16 perr, int16 perg, int16 perb);








/********************************本地化UI接口********************************/


/*
创建一个菜单,并返回菜单句柄,title是菜单的标题。


输入:
title 菜单的标题,unicode编码,网络字节序。
num 菜单项的数目


返回:
      正整数   菜单句柄
      -1   失败
*/
int32 menucreate(const char* title, int16 num);


/*
    在菜单里设置一个菜单项,参数index是该菜单项的
    序号,当用户选中某个菜单项时,把index号通过
    event函数发送到应用中。


输入:
menu  菜单的句柄
text 菜单项的名字,使用unicode编码,网络字节序。
index    菜单项的index号(从0开始)


返回:
      0  成功
      -1   失败
*/
int32 menuset(int32 menu, const char *text, int32 index);


/*
显示菜单。当菜单显示时,如果用户选择了菜单上
的某一项,系统将构造Mythroad应用消息,通过
event函数传送给Mythroad应用,消息代码为MN_SLT,
参数1为该菜单项的index。如果用户选择
了退出该菜单,系统将构造Mythroad应用消息,通过
event函数传送给Mythroad应用,消息代码为MN_RET。


输入:
menu 菜单的句柄


返回:
      0  成功
      -1   失败
*/
int32 menushow(int32 menu);


/*
释放菜单。


输入:
menu 菜单的句柄


返回:
      0  成功
      -1   失败
*/
int32 menudel(int32 menu);


/*
刷新菜单显示。


输入:
menu 菜单的句柄


返回:
      0  成功
      -1   失败
*/
int32 menuref(int32 menu);


/*
创建一个对话框,并返回对话框句柄。当对话框显
示时,如果用户按了对话框上的某个键,系统将构
造Mythroad应用消息,通过event函数传送给Mythroad应
用,消息类型为MR_DIALOG,参数为该按键的ID。
"确定"键ID为:0;"取消"键ID为:1。


输入:
title 对话框的标题,unicode编码,网络字节序。
text 对话框内容,unicode编码,网络字节序。
type 对话框类型:
      0:对话框有"确定"键。
      1:对话框有"确定"和"取消"键。
      2:对话框有 "返回"键。


返回:
      正整数   对话框句柄
      -1   失败
*/
int32 dlgcreate(const char * title, const char * text, int32 type);


/*
释放对话框。


输入:
dialog  对话框的句柄


返回:
      0  成功
      -1   失败
*/
int32 dlgdel(int32 dialog);


/*
刷新对话框的显示。


输入:
dialog 对话框的句柄
title 对话框的标题,unicode编码,网络字节序。
text 对话框内容,unicode编码,网络字节序。
type 若type为-1,表示type不变。
对话框类型:
      0:对话框有"确定"键。
      1:对话框有"确定"和"取消"键。
      2:对话框有 "返回"键。


返回:
      0  成功
      -1   失败
*/
int32 dlgref(int32 dialog, const char * title, const char * text, int32 type);


/*
创建一个文本框,并返回文本框句柄。文本框用来
显示只读的文字信息。文本框和对话框并没有本质
的区别,仅仅是显示方式上的不同,在使用上它们
的主要区别是:对话框的内容一般较短,文本框的
内容一般较长,对话框一般实现为弹出式的窗口,
文本框一般实现为全屏式的窗口。也可能在手机上
对话框和文本框使用了相同的方式实现。
文本框和对话框的消息参数是一样的。当文本框显
示时,如果用户选择了文本框上的某个键,系统将
构造Mythroad应用消息,通过event函数传送给Mythroad
平台,消息类型为MR_DIALOG,参数为该按键的ID。
"确定"键ID为:0;"取消"键ID为:1。


输入:
title 文本框的标题,unicode编码,网络字节序。
text 文本框内容,unicode编码,网络字节序。
type 文本框类型:
      0:文本框有"确定"键。
      1:文本框有"确定"和"取消"键。
      2:文本框有 "取消/返回"键。


返回:
      正整数   文本框句柄
      -1   失败
*/
int32 textcreate(const char * title, const char * text, int32 type);


/*
释放文本框。


输入:
text 文本框的句柄


返回:
      0  成功
      -1   失败
*/
int32 textdel(int32 text);


/*
刷新文本框显示。


输入:
handle 文本框的句柄
title 文本框的标题,unicode编码,网络字节序。
text 文本框内容,unicode编码,网络字节序。


返回:
      0  成功
      -1   失败
*/
int32 textref(int32 handle, const char * title, const char * text);


/*
创建一个编辑框,并返回编辑框句柄。编辑框用来
显示并提供用户编辑文字信息。text是编辑框显示的
初始内容。
当编辑框显示时,如果用户选择了编辑框上的某个
键,系统将构造Mythroad应用消息,通过event函数
传送给Mythroad应用,消息类型为MR_DIALOG,参数
为该按键的ID。"确定"键ID为:0;"取消
"键ID为:1。


输入:
title 编辑框的标题,unicode编码,网络字节序。
text 编辑框的初始内容,unicode编码,网络字节序。
type 输入法类型:
      0: 任何字符
      1: 数字
      2: 密码,用"*"显示
max_size 最多可以输入的字符(unicode)个数,这里每一
                个中文、字母、数字、符号都算一个字符。
返回:
      正整数   编辑框句柄
      -1   失败
*/
int32 editcreate(const char * title, const char * text, int32 type, int32 max_size);


/*
释放编辑框。


输入:
edit 编辑框的句柄


返回:
      0  成功
      -1   失败
*/
int32 editdel(int32 edit);


/*
获取编辑框内容,unicode编码。调用者若需在编辑框
释放后仍然使用编辑框的内容,需要自行保存该内
容。该函数需要在编辑框释放之前调用。


输入:
edit 编辑框的句柄


返回:
      非NULL       编辑框的内容指针,unicode编码。
      NULL            失败
*/
char* editget(int32 edit);


/********************************其他接口********************************/
/*
退出应用,应用调用该函数通知mythroad,应用将要退出。
*/
void exit(void);


/*
获取系统时间,单位毫秒。系统时间可以以Mythroad平
台引擎启动之前的任意时刻为起始时间,返回从起
始时间到目前经过的毫秒数。例如这个函数可能返
回的是系统启动后经过的毫秒数。
返回:
     单位毫秒的系统时间
*/
int32 getuptime(void);




/*
获取系统日期时间。
mr_datetime格式如下(由于不常用,所以需要自己定义这个结构!):
typedef struct
{
   uint16 year;                 //年
   uint8  month;                //月
   uint8  day;                  //日
   uint8  hour;                 //时,24小时制
   uint8  minute;               //分
   uint8  second;               //秒
}mr_datetime;


输出:
datetime 日期时间


返回:
      0  成功
      -1   失败
*/
int32 getdatetime(mr_datetime* datetime);


/*
获取系统所剩余的内存数


返回:
      系统所剩余的内存数,单位字节
*/
uint32 getmemremain(void);


/*
启动手机震动。


输入:
ms             震动持续的时间,单位毫秒


返回:
      0     成功
      -1         失败
*/
int32 shake(int32 ms);


/*
取得系统的总共内存大小
*/
int32 getsysmem(void);






/*
从指定的mrp文件中读取指定的文件。实际使用mrc_readFileFromMrpEx
输入:
packname     mrp文件名
filename        欲读取文件的文件名
*filebuf          读取文件的输出缓冲
                    当文件以压缩形式存放时,若:
                    *filebuf==NULL,则函数申请一片空间存放返回的文件
                    *filebuf!=NULL,这时函数使用*filebuf指向的空间存放
                           返回的文件内容
*filelen          当*filebuf!=NULL、文件以压缩形式存放时,指出
                    *filebuf指向的空间大小,若该空间大小不足以
                    存放解压以后的文件,则函数返回失败
lookfor          指出函数的操作形式:
                    0:    读取mrp中文件的内容,并通过*filebuf和*filelen
                               返回该内容;当*filebuf==NULL时,返回的内存
                               需要调用者释放;
                    1:    仅仅查找mrp中是否存在该文件,并不读取
                               文件内容
                    2:    当mrp文件位于ROM或RAM中时,读取欲读取文
                                件的原始内容,即使文件进行了压缩也
                                不进行解压,返回的内存不需要释放;
                                当mrp文件位于文件系统中时,等同于
                                lookfor==0
                    3:    以强检查的方式读取mrp中文件的内容,由于
                               lookfor==0的方式读取文件时,文件是否压缩
                               的判断是自适应的,所以不能完全保证文件
                               的正确性;lookfor==3时会强制约定文件进行了
                               压缩,并进行强检查。当*filebuf==NULL时,返回
                               的内存需要调用者释放;
                     4:与3相同,不同在于使用malloc8分配内存;
                     5:仅通过filelen返回文件长度;


输出:
*filebuf         当lookfor==0、2、3时返回文件内容指针
*filelen         当lookfor==0、2、3时返回文件内容长度


返回:
      0   成功,当lookfor==1时表示文件存在
      -1       失败


(近日发现有部分代码在使用readFileFromMrpEx函数时,
对结果的判断仅使用了filebuf(判断是否为NULL),而忽略
了函数的返回值。
      在这里提醒:readFileFromMrpEx函数在操作失败时,返回
      值是失败,但filebuf的值是未定义(也就是说,可能是
      NULL,也可能不是NULL),这里必须使用函数返回值进
      行结果判断,使用filebuf进行判断是不保险的。)free释放
*/
int32 readfilefrommrp(char* packname, const char* filename, 
               uint8 ** filebuf, int32 *filelen, int32 lookfor);




/*
输入:
data     文件内容指针
filelen          文件内容长度
*/
void freefiledata(void* data, int32 filelen);


/*
释放由原始内存申请方式申请的空间。
输入:
add     指针
size   长度
*/
void freeorigin(void* add, int32 size);




/////////////////////以下接口并不是定义在mrc_base.h文件中,但为了使用方便而统一定义在本系统中//////////////////////////
// 以下函数定义在mrc_exb.h文件中
/*
原函数名:mrc_unicodeToGb2312 
输入:
将unicode编码的字符串转成gb2312编码
input:需要转换的unicode字符串
input_len:需要转换的unicode字符串长度,单位字节数
output:转换成功以后的gb2312编码字符串存放缓冲区,
缓冲区的内存由应用调用者提供并管理、释放。
注意:该输出缓冲区必须使用malloc分配处理的空间,否则手机可能会出现重启。
output_len:output缓冲区的长度,单位字节数


返回:
    MR_SUCCESS 转换成功
    MR_FAILED   转换失败


*/
int32 u2c(uint8* input, int32 input_len, uint8** output, int32* output_len);




int32  runmrp(char * mrp_name,char* filename);


/*
原函数名称:mrc_GetParentPath
功能:获取当前运行MRP所在父目录,返回的BUFF指针空闲时需程序员手动释放
参数:void
返回值:char*  父目录路径指针
   NULL  获取失败
*/
char* getparentpath(void);




// 随机数种子,利用getuptime得到的系统运行时间做为种子,可以保证rand不重复。
void sand(uint32 seed);


// 随机数发生器。
uint32 rand(void);


/*
发送短信
pNumber 电话号码,ASCII码 
pContent 消息内容,ASCII码或Unicode码,由flags参数决定 
flags              0~2bit:编码类型
                   0: ASCII码
                   1: Unicode码, 网络字节序。
                   3bit:是否隐藏状态报告
                   1:隐藏状态报告
                   0:不隐藏状态报告
                   4bit:是否隐藏发送结果(成功/失败)提示
                   1:隐藏
                   0:不隐藏
                   5~31 bit:保留 
成功启动返回MR_SUCCESS,失败返回MR_FAILED, 未准备好返回MR_IGNORE
*/
int32 sms(char* pNumber, char*pContent, int32 flags);


/*
功能:mrc_LCDCanSleep
打开、关闭LCD定时休眠功能。

输入:
char CanSleep=1 时,允许LCD定时休眠;
char CanSleep=0时,不允许LCD定时休眠。


输出:
MR_SUCCESS :成功
MR_FAILED  :失败
MR_IGNORE  : 不支持该功能
*/
int32 lcd(char CanSleep);






// 以下函数定义在mrc_bmp.h文件中//////////////////////////////////////




//取屏幕缓冲区的内存地址
uint16 *getscrbuf(void);


//设置屏幕缓冲区的内存地址
void setscrbuf(uint16 *ptr);


//获取屏幕缓冲区宽高
void getscrsize(int32 *w,int32 *h);


//设置屏幕缓冲区宽高
void setscrsize(int32 w, int32 h);




enum {
    BM_OR,          //SRC .OR. DST*   半透明效果
    BM_XOR,         //SRC .XOR. DST*
    BM_COPY,        //DST = SRC*      覆盖
    BM_NOT,         //DST = (!SRC)*
    BM_MERGENOT,    //DST .OR. (!SRC)
    BM_ANDNOT,      //DST .AND. (!SRC)
    BM_TRANS, //透明色不显示,图片的第一个象素(左上角的象素)是透明色
    BM_AND,         //DST AND SRC
    BM_GRAY,        //灰度绘图, 相当于BM_TRANSPARENT+灰度绘图:DST灰度 = 30%R + 59%G + 11%B图片序号
    BM_REVERSE      //反向绘图,相当于BM_TRANSPARENT+反向绘图(V1939)
};
/*
rop取值(系统没有预先定义这些宏):
#define TRANS_NONE 0x0000   没有进行转动和翻转; 
#define TRANS_ROT90 0x0100   90度转动; 
#define TRANS_ROT180 0x0200   180度转动; 
#define TRANS_ROT270 0x0300   270度转动; 
#define TRANS_MIRROR 0x0400   左右翻转; 
#define TRANS_MIRROR_ROT90 0x0500   左右翻转后90度转动; 
#define TRANS_MIRROR_ROT180 0x0600   左右翻转后180度转动; 
#define TRANS_MIRROR_ROT270 0x0700   左右翻转后270度转动。 
输入:
p        源图片指针
x,y     屏幕 显示位置
mw 图片的原始宽度,即完整宽度。
rop : (BM_TRANSPARENT 或BM_COPY(仅两项),其余模式默认BM_COPY处理) | (TRANS_NONE至TRANS_MIRROR_ROT270,不填
功能与mrc_bitmapshowEx相同)
sx,sy           源图片的起始位置
w,h             欲加载图片的宽高
transcolor : 透明色 (16bit),可以用MAKERGB宏将(r,g,b)转换为16bit的格式。


返回:
      MR_SUCCESS     成功
      MR_FAILED         失败
*/
int32 bmpshowflip(uint16* p, int16 x, int16 y, uint16 mw, uint16 w, uint16 h, uint16 rop, 
int16 sx, int16 sy, uint16 transcolor);




/*
mrc_aux.h文件中
读取mrp中一个文件的指定长度内容到指定空间。函数
读取文件filename的len长度的内容到buf指向的地址上,若
文件长度小于len,仅读取文件长度的内容,len被赋值
为实际读取的长度。


输入:
filename          文件名
buf                  读取的文件的保存空间
len                  期望读取长度


输出:
len                  实际读取长度


返回:
      0  成功
      -1   失败
*/
int32 readall(char* filename, char* buf, int32 *len);


void wap(char* wap);




/********************************定时器接口********************************/


/*
创建定时器


返回:
      非0     定时器句柄
      0          失败
*/
int32 timercreate(void);


/*
删除定时器


输入:
t           定时器句柄
*/
void timerdel(int32 t);


/*
停止定时器


输入:
t           定时器句柄
*/
void timerstop(int32 t);


/*
定时器回调函数(只是一种形式,在本系统无效)
输入:
data:
   启动定时器时传入的data参数。
*/
typedef void (*timerCB)(int32 data);


/*
启动定时器


输入:
t           定时器句柄
time      定时器时长,单位毫秒
data      定时器数据
f           定时器回调函数名(因为不支持函数指针且是解释运行,所以这里应该填入回调函数的函数名字符串)
loop      是否循环;0:不循环,1:循环


返回:
      0     成功
      -1         失败
*/
int32 timerstart (int32 t, int32 time, int32 data, char* f, int32 loop);




/*
更改定时器时长。


输入:
t           定时器句柄
time      定时器时长,单位毫秒


返回:
      0     成功
      -1         失败
*/
int32 timersettime(int32 t, int32 time);


///////////////////以下函数为系统扩展函数////////////////////


//显示一张图片
int img(char* filename, int x,int y);


/*
画渐变矩形
参数mode可以选以下值
enum E_SHAD_MODE (需要自己定义,或直接填入值)
{
    SHADE_UPDOWN, //从上到下
    SHADE_LEFTRIGHT, //从左到右
    SHADE_DOWNUP, //从下到上
    SHADE_RIGHTLEFT //从右到左
};
例如画一个红色到黄色渐变的矩形:
shaderect(0,0,176,220,0xff0000,0xffff00,SHADE_UPDOWN);
*/
void shaderect(int x, int y, int w, int h, int32 pixelA, int32 pixelB, int mode);


#endif
 


上面的内容有点多,不必完全看玩,明天接着更,大家期待哈

0 0
原创粉丝点击