yuhuo1989 发表于 2015-5-12 21:11:30

分享一个在linux app层调用/dev/mem来控制WORK_LED的方法

如下代码完全由本人编写,亲自验证通过的,大家欢迎交流~通过这种方法不光可以控制指示灯哦~
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 = {"test", "wr", "rd"};
char g_acCMD_ExtendWord = {"openmem", "closemem"};
char g_acCMD_Word;

/* 内存设备相关*/
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, cTmp);

// printf("\r\naa:");
// printf(g_acCMD_Word);

ucWordCnt++;
}

return ucWordCnt;
}


uchar CMD_MatchWord(char *cCmdSrc, char cCmdDes[])
{
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))
{
break;
}
// printf("\r\nbb:");
// printf(cCmdDes);
}

if (CMD_PRIMY_NUM == ucIndex)
{
ucIndex = INVALID_UCHAR;
}

return ucIndex;
}

int main (void)
{
int i;
char cCmd = {0};
char cOutBuf = {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, g_acCMD_PrimyWord) ;
switch(ucCmdPrimyIndex)
{
case 0:
{
if (ucCmdWordCnt == 4)
{
ucCmdExtendIndex = CMD_MatchWord (g_acCMD_Word, g_acCMD_ExtendWord) ;
if (0 == ucCmdExtendIndex)
{
sscanf(g_acCMD_Word, "%x", &uiAddr);
sscanf(g_acCMD_Word, "%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, 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, "%x", &uiAddr);
sscanf(g_acCMD_Word, "%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, "%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 #



yuhuo1989 发表于 2015-5-12 21:14:04

这代码段存放直接把我的空格搞没了:o,大家将就着看吧

yuhuo1989 发表于 2015-5-12 21:19:19

实际界面操作部分信息也没有,我晕~还不能重新编辑吗?
实际界面操作:
shell@rk3288:/data/local/test #
shell@rk3288:/data/local/test #
shell@rk3288:/data/local/test # ./test                                       
hello my test
<WSF>
<WSF>
<WSF>
<WSF>test openmem ff7f0000 100
Command : test initmem addr:0xff7f0000,len:0x100
<WSF>
<WSF>
<WSF>
<WSF>
<WSF>rd 4
read address 0xb6fcb004
Command : read addr:0xb6fcb004,data:0xf
<WSF>wr 4 1
Command : write addr:0xb6fcb004,data:0x1
<WSF>
<WSF>wr 4 f
Command : write addr:0xb6fcb004,data:0xf
<WSF>
<WSF>

zhansb 发表于 2015-5-13 08:45:33

支持原创{:3_48:}
编辑在“收藏 评分”按钮下面

busybee 发表于 2015-5-13 17:57:37

Android 下也有个类似命令 /system/xbin/io,源码在 external/io 里。

bartfj 发表于 2016-11-21 11:04:35

busybee 发表于 2015-5-13 17:57
Android 下也有个类似命令 /system/xbin/io,源码在 external/io 里。
用io写寄存器时会出现panic, 是存在这样的问题吗

[ 1229.428037] Unhandled fault: imprecise external abort (0x1c06) at 0xb6f12000
[ 1229.428152] Internal error: : 1c06 [#1] PREEMPT SMP ARM
[ 1229.440116] Modules linked in: mali_kbase
[ 1229.444054] CPU: 3 PID: 1345 Comm: io Not tainted 3.10.0 #139
[ 1229.449675] task: dc353f00 ti: dbb54000 task.ti: dbb54000
[ 1229.454975] PC is at klist_remove_lock+0x3f1364d0/0x4
[ 1229.459902] LR is at 0xb6f91de0
[ 1229.462984] pc : [<ffff0008>]    lr : [<b6f91de0>]    psr: 60070093
[ 1229.462984] sp : dbb55ff8ip : 00000000fp : b6fd3f98
[ 1229.474229] r10: 00001000r9 : 00000000r8 : b6f12000
[ 1229.479348] r7 : 00000006r6 : b6f12001r5 : 00000002r4 : b6f12001
[ 1229.485743] r3 : 00000001r2 : 00000002r1 : b6f12000r0 : 00000003
[ 1229.492145] Flags: nZCvIRQs offFIQs onMode SVC_32ISA ARMSegment user
[ 1229.499220] Control: 10c5387dTable: 1bb6006aDAC: 00000015
[ 1229.504842]
[ 1229.504842] PC: 0xfffeff88:
[ 1229.509017] ff88******** ******** ******** ******** ******** ******** ******** ********
[ 1229.517034] ffa8******** ******** ******** ******** ******** ******** ******** ********
[ 1229.525050] ffc8******** ******** ******** ******** ******** ******** ******** ********
[ 1229.533066] ffe8******** ******** ******** ******** ******** ******** ea0003ff ea000465
[ 1229.541082] 0008e59ffff0 ea000443 ea000422 ea000481 ea000400 ea000480 e7fddef1 e7fddef1
[ 1229.549099] 0028e7fddef1 e7fddef1 e7fddef1 e7fddef1 e7fddef1 e7fddef1 e7fddef1 e7fddef1
[ 1229.557115] 0048e7fddef1 e7fddef1 e7fddef1 e7fddef1 e7fddef1 e7fddef1 e7fddef1 e7fddef1
[ 1229.565131] 0068e7fddef1 e7fddef1 e7fddef1 e7fddef1 e7fddef1 e7fddef1 e7fddef1 e7fddef1
[ 1229.573151]
[ 1229.573151] SP: 0xdbb55f78:
[ 1229.577326] 5f7800000001 dbb54000 00000000 c00ee8a0 00000001 000ff7f0 00000003 000ff7f0
[ 1229.585343] 5f9800000001 ffff0008 60070093 ffffffff dbb55fe4 c000d598 00000003 b6f12000
[ 1229.593359] 5fb800000002 00000001 b6f12001 00000002 b6f12001 00000006 b6f12000 00000000
[ 1229.601375] 5fd800001000 b6fd3f98 00000000 dbb55ff8 b6f91de0 ffff0008 60070093 ffffffff
[ 1229.609392] 5ff800000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1229.617408] 601800000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1229.625424] 603800000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1229.633441] 605800000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1229.641467] Process io (pid: 1345, stack limit = 0xdbb54238)
[ 1229.647008] Stack: (0xdbb55ff8 to 0xdbb56000)
[ 1229.651275] 5fe0:                                                       00000000 00000000
[ 1229.659292] Code: bad PC value
[ 1229.662276] ---[ end trace 0a7cc0b8a18886f2 ]---
[ 1229.666792] Kernel panic - not syncing: Fatal exception
[ 1229.671921] CPU0: stopping
[ 1229.674565] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G      D      3.10.0 #139
[ 1229.681508] [<c0013ec4>] (unwind_backtrace+0x0/0xe0) from [<c001176c>] (show_stack+0x10/0x14)
[ 1229.689854] [<c001176c>] (show_stack+0x10/0x14) from [<c0012f9c>] (handle_IPI+0x154/0x2c8)
[ 1229.697952] [<c0012f9c>] (handle_IPI+0x154/0x2c8) from [<c0008558>] (gic_handle_irq+0x54/0x5c)
[ 1229.706395] [<c0008558>] (gic_handle_irq+0x54/0x5c) from [<c000d600>] (__irq_svc+0x40/0x70)
[ 1229.714559] Exception stack(0xc0c07f08 to 0xc0c07f50)
[ 1229.719519] 7f00:                   c0c07f50 000004e0 e0a576b5 00000122 c1f162e0 00000000
[ 1229.727537] 7f20: e0a5015b 00000122 c0c18fd8 c0c06000 c0c18fe8 00000000 35c09c4f c0c07f50
[ 1229.735544] 7f40: c0079850 c05b4e58 600f0013 ffffffff
[ 1229.740520] [<c000d600>] (__irq_svc+0x40/0x70) from [<c05b4e58>] (cpuidle_enter_state+0x54/0xec)
[ 1229.749131] [<c05b4e58>] (cpuidle_enter_state+0x54/0xec) from [<c05b505c>] (cpuidle_idle_call+0x16c/0x27c)
[ 1229.758592] [<c05b505c>] (cpuidle_idle_call+0x16c/0x27c) from [<c000e750>] (arch_cpu_idle+0x8/0x38)
[ 1229.767461] [<c000e750>] (arch_cpu_idle+0x8/0x38) from [<c0078c14>] (cpu_idle_loop+0x1b8/0x224)
[ 1229.775985] [<c0078c14>] (cpu_idle_loop+0x1b8/0x224) from [<c0078c8c>] (freezing_slow_path+0x0/0x80)
[ 1229.784932] [<c0078c8c>] (freezing_slow_path+0x0/0x80) from [<ffffffff>] (0xffffffff)
[ 1229.792593] CPU2: stopping
[ 1229.795245] CPU: 2 PID: 0 Comm: swapper/2 Tainted: G      D      3.10.0 #139
[ 1229.802180] [<c0013ec4>] (unwind_backtrace+0x0/0xe0) from [<c001176c>] (show_stack+0x10/0x14)
[ 1229.810524] [<c001176c>] (show_stack+0x10/0x14) from [<c0012f9c>] (handle_IPI+0x154/0x2c8)
[ 1229.818622] [<c0012f9c>] (handle_IPI+0x154/0x2c8) from [<c0008558>] (gic_handle_irq+0x54/0x5c)
[ 1229.827065] [<c0008558>] (gic_handle_irq+0x54/0x5c) from [<c000d600>] (__irq_svc+0x40/0x70)
[ 1229.835231] Exception stack(0xde8bff30 to 0xde8bff78)
[ 1229.840185] ff20:                                     de8bff78 000004e0 e0a576b5 00000122
[ 1229.848208] ff40: c1f282e0 00000000 e0189fb2 00000122 c0c18fd8 de8be000 c0c18fe8 00000000
[ 1229.856219] ff60: 35c09c4f de8bff78 c0079850 c05b4e58 600f0013 ffffffff
[ 1229.862722] [<c000d600>] (__irq_svc+0x40/0x70) from [<c05b4e58>] (cpuidle_enter_state+0x54/0xec)
[ 1229.871335] [<c05b4e58>] (cpuidle_enter_state+0x54/0xec) from [<c05b505c>] (cpuidle_idle_call+0x16c/0x27c)
[ 1229.880798] [<c05b505c>] (cpuidle_idle_call+0x16c/0x27c) from [<c000e750>] (arch_cpu_idle+0x8/0x38)
[ 1229.889664] [<c000e750>] (arch_cpu_idle+0x8/0x38) from [<c0078c14>] (cpu_idle_loop+0x1b8/0x224)
[ 1229.898189] [<c0078c14>] (cpu_idle_loop+0x1b8/0x224) from [<c0078c8c>] (freezing_slow_path+0x0/0x80)
[ 1229.907125] CPU1: stopping
[ 1229.909776] CPU: 1 PID: 0 Comm: swapper/1 Tainted: G      D      3.10.0 #139
[ 1229.916710] [<c0013ec4>] (unwind_backtrace+0x0/0xe0) from [<c001176c>] (show_stack+0x10/0x14)
[ 1229.925053] [<c001176c>] (show_stack+0x10/0x14) from [<c0012f9c>] (handle_IPI+0x154/0x2c8)
[ 1229.933153] [<c0012f9c>] (handle_IPI+0x154/0x2c8) from [<c0008558>] (gic_handle_irq+0x54/0x5c)
[ 1229.941595] [<c0008558>] (gic_handle_irq+0x54/0x5c) from [<c000d600>] (__irq_svc+0x40/0x70)
[ 1229.949761] Exception stack(0xde8bdf30 to 0xde8bdf78)                                                               
[ 1229.954716] df20:                                     de8bdf78 000004e0 e0a578fc 00000122                           
[ 1229.962739] df40: c1f1f2e0 00000000 dfa4fcab 00000122 c0c18fd8 de8bc000 c0c18fe8 00000000                           
[ 1229.970751] df60: 35c09c4f de8bdf78 c0079850 c05b4e58 600f0013 ffffffff                                             
[ 1229.977252] [<c000d600>] (__irq_svc+0x40/0x70) from [<c05b4e58>] (cpuidle_enter_state+0x54/0xec)
[ 1229.985866] [<c05b4e58>] (cpuidle_enter_state+0x54/0xec) from [<c05b505c>] (cpuidle_idle_call+0x16c/0x27c)
[ 1229.995328] [<c05b505c>] (cpuidle_idle_call+0x16c/0x27c) from [<c000e750>] (arch_cpu_idle+0x8/0x38)
[ 1230.004195] [<c000e750>] (arch_cpu_idle+0x8/0x38) from [<c0078c14>] (cpu_idle_loop+0x1b8/0x224)
[ 1230.012720] [<c0078c14>] (cpu_idle_loop+0x1b8/0x224) from [<c0078c8c>] (freezing_slow_path+0x0/0x80)
[ 1230.021652] CRU:
[ 1230.023469] 00000000: 00000007 9fff0047 0fff0024 00000008 00000001 9fff0025 0fff0012 00000008
[ 1230.031820] 00000020: 00000007 9fff00c5 00000000 00000008 00000007 9fff00c5 0fff0014 00000008
[ 1230.040177] 00000040: 00000b00 9fff0270 0fff0138 00000008 00005111 00000000 00000000 00000000
[ 1230.048534] 00000060: 00004031 0000b108 00000003 00000200 00008100 00008100 00008585 00010014
[ 1230.056891] 00000080: 01885091 01885091 0000a101 00002745 00004345 00008a00 00000200 00000200
[ 1230.065250] 000000a0: 00000200 0bb8ea60 00010014 00010014 00010014 00000910 00000900 001f05dc
[ 1230.073606] 000000c0: 00001703 0000078c 00000040 00000301 00000242 00000342 00004141 00004041
[ 1230.081963] 000000e0: 00004141 00000505 00008042 00008f8f 00000000 00000631 00001ee5 00008307
[ 1230.090319] 00000100: 00001200 00010014 00004141 00000000 00000000 00000000 00000000 00000000
[ 1230.098675] 00000120: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.107031] 00000140: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.115392] 00000160: 00001000 0000ff00 00003d60 0000faf0 00004f80 0000aefd 0000fbe0 0000c12b
[ 1230.123749] 00000180: 00000fa4 00000000 0000080d 000005cc 00000000 0000fe84 00000000 0000c01e
[ 1230.132105] 000001a0: 0000017f 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.140462] 000001c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.148820] 000001e0: 00000000 00000000 00000000 00640064 00000004 00000000 00000002 00000000
[ 1230.157177] 00000200: 00000002 00000000 00000002 00000000 00000002 00000000 00000004 000004e0
[ 1230.165534] 00000220: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.173891] 00000240: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.182248] 00000260: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.190606] 00000280: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.198963] 000002a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.207321] 000002c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.215678] 000002e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.224036] 00000300: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.232393] 00000320: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.240751] 00000340: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.249108] 00000360: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.257465] 00000380: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.265823] 000003a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.274181] 000003c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.282538] 000003e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1230.290899] 00000400: 00000007 9fff0047 0fff0024 00000008 00000001 9fff0025 0fff0012 00000008
[ 1230.299239] Rebooting in 5 seconds..DDR Version 1.00 20150318
页: [1]
查看完整版本: 分享一个在linux app层调用/dev/mem来控制WORK_LED的方法