如下代码完全由本人编写,亲自验证通过的,大家欢迎交流~通过这种方法不光可以控制指示灯哦~
APP代码:
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/mman.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
/* 数据类型*/
#define INVALID_UCHAR 0xff
#define FALSE 0
#define TRUE 1
#define uchar unsigned char
#define ushort unsigned short
#define uint unsigned int
#define ulong unsigned long
/* 命令行相关宏定义*/
#define CMD_BUF_LEN 32
#define CMD_LOGO "<WSF>"
#define OUTPUT_BUF_LEN 64
#define CMD_PRIMY_NUM 3
#define CMD_EXTEND_NUM 2
#define CMD_WORD_MAX 10
#define CMD_LEN 20
char g_acCMD_PrimyWord[CMD_PRIMY_NUM][CMD_LEN] = {"test", "wr", "rd"};
char g_acCMD_ExtendWord[CMD_EXTEND_NUM][CMD_LEN] = {"openmem", "closemem"};
char g_acCMD_Word[CMD_WORD_MAX][CMD_LEN];
/* 内存设备相关*/
typedef struct MEM_DeviceInfo
{
int fd;
int *map_VirAddr;
int *map_PhyAddr;
int memlen;
int flag;
}MEM_INFO_S;
MEM_INFO_S g_stMemInfo = {0};
uchar MEM_InitDevice(int phyaddr, int len)
{
int fd;//文件句柄
uchar *map_base = NULL;
/* 未打开MEM设备则打开*/
if (0 == g_stMemInfo.fd)
{
/* 打开mem设备*/
fd = open("/dev/mem", O_RDWR|O_SYNC);
if (fd == -1)
{
printf("ERROR: Open mem device failed!\r\n");
return FALSE;
}
g_stMemInfo.fd = fd;
}
/* 映射虚拟地址*/
map_base = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, g_stMemInfo.fd, phyaddr);
if (MAP_FAILED == map_base)
{
perror("mmap");
printf("ERROR: mmap mem device failed!\r\n");
return FALSE;
}
// printf("mmap virtual address 0x%x\r\n", map_base);
g_stMemInfo.map_VirAddr = (int *)map_base;
// g_stMemInfo.map_PhyAddr = (int *)phyaddr;
g_stMemInfo.memlen = len;
g_stMemInfo.flag = TRUE;
return TRUE;
}
void MEM_ReleaseDevice(void)
{
if (TRUE == g_stMemInfo.flag)
{
/* 释放虚拟地址*/
munmap( g_stMemInfo.map_VirAddr, g_stMemInfo.memlen);
g_stMemInfo.flag = FALSE;
}
/* 关闭文件*/
close(g_stMemInfo.fd);
memset(&g_stMemInfo, 0, sizeof(g_stMemInfo));
}
uchar CMD_GetWord(char *cCmd)
{
char *cString, *cTmp;
char cDelims[] = " ";
uchar ucWordCnt = 0;
int mapAddr = 0;
// cString = ltrim(cCmd);
cString = cCmd;
// printf("\r\nget:");
// printf(cString);
memset(g_acCMD_Word, 0, sizeof(g_acCMD_Word)) ;
while (ucWordCnt < CMD_WORD_MAX)
{
if (0 == ucWordCnt)
{
cTmp = strtok(cString, cDelims);
}
else
{
cTmp = strtok(NULL, cDelims);
}
if (NULL == cTmp)
{
break;
}
strcpy(g_acCMD_Word[ucWordCnt], cTmp);
// printf("\r\naa:");
// printf(g_acCMD_Word[ucWordCnt]);
ucWordCnt++;
}
return ucWordCnt;
}
uchar CMD_MatchWord(char *cCmdSrc, char cCmdDes[][CMD_LEN])
{
char *cString;
uchar ucIndex = INVALID_UCHAR;
// cString = ltrim(cCmdSrc);
// cString = rtrim(cCmdSrc);
cString = cCmdSrc;
for (ucIndex = 0; ucIndex < CMD_PRIMY_NUM; ucIndex++)
{
if (0 == strcmp (cString, cCmdDes[ucIndex]))
{
break;
}
// printf("\r\nbb:");
// printf(cCmdDes[ucIndex]);
}
if (CMD_PRIMY_NUM == ucIndex)
{
ucIndex = INVALID_UCHAR;
}
return ucIndex;
}
int main (void)
{
int i;
char cCmd[CMD_BUF_LEN] = {0};
char cOutBuf[OUTPUT_BUF_LEN] = {0};
uchar ucCmdWordCnt = 0;
uchar ucCmdPrimyIndex = 0, ucCmdExtendIndex = 0;
uint uiAddr, uiData, uiLen;
uint *pTmp = NULL;
printf ("hello my test\r\n");
printf(CMD_LOGO);//打印命令logo
while(1)
{
gets (cCmd);//获取输入命令
ucCmdWordCnt = CMD_GetWord(cCmd);
if (ucCmdWordCnt > 0)
{
ucCmdPrimyIndex = CMD_MatchWord (g_acCMD_Word[0], g_acCMD_PrimyWord) ;
switch(ucCmdPrimyIndex)
{
case 0:
{
if (ucCmdWordCnt == 4)
{
ucCmdExtendIndex = CMD_MatchWord (g_acCMD_Word[1], g_acCMD_ExtendWord) ;
if (0 == ucCmdExtendIndex)
{
sscanf(g_acCMD_Word[2], "%x", &uiAddr);
sscanf(g_acCMD_Word[3], "%x", &uiLen);
if (FALSE == MEM_InitDevice (uiAddr, uiLen))
{
break;
}
printf("Command : test initmem addr:0x%x,len:0x%x\r\n", uiAddr, uiLen);
}
}
else if (ucCmdWordCnt == 2)
{
ucCmdExtendIndex = CMD_MatchWord (g_acCMD_Word[1], g_acCMD_ExtendWord) ;
if (1 == ucCmdExtendIndex)
{
MEM_ReleaseDevice ();
printf("Command : test close mem\r\n");
}
}
else
{
printf("ERROR: Cmd invaild!\r\n");
}
break;
}
case 1:
{
if (ucCmdWordCnt == 3)
{
sscanf(g_acCMD_Word[1], "%x", &uiAddr);
sscanf(g_acCMD_Word[2], "%x", &uiData);
if (TRUE == g_stMemInfo.flag)
{
if (uiAddr <= g_stMemInfo.memlen)
{
uiAddr = (long)g_stMemInfo.map_VirAddr + uiAddr;
pTmp = (uint *)uiAddr;
*pTmp = uiData;
}
printf("Command : write addr:0x%x,data:0x%x\r\n", uiAddr, *pTmp);
break;
}
printf("ERROR: Device not be opened!\r\n");
}
else
{
printf("ERROR: Cmd invaild!\r\n");
}
break;
}
case 2:
{
if (ucCmdWordCnt == 2)
{
sscanf(g_acCMD_Word[1], "%x", &uiAddr);
if (TRUE == g_stMemInfo.flag)
{
if (uiAddr <= g_stMemInfo.memlen)
{
uiAddr = (long)g_stMemInfo.map_VirAddr + uiAddr;
printf("read address 0x%x\r\n", uiAddr);
pTmp = (uint *)uiAddr;
uiData = *pTmp;
}
printf("Command : read addr:0x%x,data:0x%x\r\n", uiAddr, uiData);
break;
}
printf("ERROR: Device not be opened!\r\n");
}
else
{
printf("ERROR: Cmd invaild!\r\n");
}
break;
}
default:
{
printf("ERROR: Cmd invaild!\r\n");
break;
}
}
}
printf(CMD_LOGO);//打印命令logo
// sprintf(cOutBuf, "%s\r\n", cCmd);//打印输入字符串
// printf(cCmd);
/* 清缓存*/
memset (cCmd, 0, CMD_BUF_LEN);
// memset (cOutBuf, 0, OUTPUT_BUF_LEN);
}
return 0;
}
Makefile代码:
all = test
objects = testmem.o
CC = arm-linux-gnueabihf-gcc
$(all):$(objects)
$(CC) -static -o $(all) $(objects)
$(objects):%.o:%.c
$(CC) -c [ DISCUZ_CODE_13 ]lt; -o $@
clean:
rm -f *.o $(all) *~
实际界面操作:
<blockquote>shell@rk3288:/data/local/test #