我正在尝试直接访问嵌入式Linux项目的物理内存,但我不确定如何最好地为我的内容指定内存.
如果我定期启动我的设备,并访问/ dev/mem,我可以轻松地读取和写入我想要的任何地方.但是,在这里,我正在访问可以轻松分配给任何进程的内存; 这是我不想做的
我的/ dev/mem代码是(所有错误检查等删除):
mem_fd = open("/dev/mem", O_RDWR));
mem_p = malloc(SIZE + (PAGE_SIZE - 1));
if ((unsigned long) mem_p % PAGE_SIZE) {
mem_p += PAGE_SIZE - ((unsigned long) mem_p % PAGE_SIZE);
}
mem_p = (unsigned char *) mmap(mem_p, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, mem_fd, BASE_ADDRESS);
Run Code Online (Sandbox Code Playgroud)
这很有效.但是,我想使用其他人无法触及的记忆.我已经尝试通过使用mem = XXXm启动来限制内核看到的内存量,然后将BASE_ADDRESS设置为高于该值(但低于物理内存),但它似乎并不是一致地访问相同的内存.
根据我在网上看到的内容,我怀疑我可能需要一个使用ioremap()或remap_pfn_range()(或两者兼而有之)的内核模块(可以),但我完全不知道如何; 有人可以帮忙吗?
编辑:我想要的是一种总是访问相同物理内存(比如,1.5MB)的方法,并将该内存放在一边,以便内核不会将其分配给任何其他进程.
我正在尝试重现我们在其他操作系统中的系统(没有内存管理),我可以通过链接器在内存中分配一个空间,并使用类似的方式访问它
*(unsigned char *)0x12345678
Run Code Online (Sandbox Code Playgroud)
EDIT2:我想我应该提供更多细节.此内存空间将用于RAM缓冲区,以用于嵌入式应用程序的高性能日志记录解决方案.在我们拥有的系统中,在软重启期间没有什么可以清除或扰乱物理内存.因此,如果我向物理地址X写入一个位并重新启动系统,则重新启动后仍将设置相同的位.这已经在运行VxWorks的完全相同的硬件上进行了测试(这种逻辑在不同平台上的Nucleus RTOS和OS20上也很好用,FWIW).我的想法是通过直接解决物理内存在Linux中尝试相同的事情; 因此,每次启动时都必须获得相同的地址.
我应该澄清这是针对内核2.6.12和更新的.
EDIT3:这是我的代码,首先是内核模块,然后是用户空间应用程序.
要使用它,我用mem = 95m启动,然后insmod foo-module.ko,然后mknod mknod/dev/foo c 32 0,然后运行foo-user,它会死掉.在gdb下运行表明它在赋值时死了,虽然在gdb中,我无法取消引用从mmap获得的地址(虽然printf可以)
FOO-的module.c
#include <linux/module.h>
#include <linux/config.h>
#include <linux/init.h>
#include …Run Code Online (Sandbox Code Playgroud) 我正在使用我在Linux中的Direct Memory Access上发布的驱动程序将一些物理ram映射到用户空间地址.但是,我无法使用GDB来查看任何地址; 即,x 0x12345678(其中0x12345678是mmap的返回值)失败,并显示错误"无法访问地址0x12345678处的内存".
有没有办法告诉GDB可以查看这个内存?或者,我在mmap中可以做些什么(在foo_mmap的调用或实现),它将允许它访问这个内存?
请注意,我不是在询问/ dev/mem(如在那里的第一个片段中),而是关于通过ioremap(),virt_to_phys()和remap_pfn_range()获取的内存的mmap
不是一个具有所有静态成员/方法的类是一种单例设计模式吗?有这样的课程有什么不利之处吗?详细解释会有所帮助.
有没有办法让VIM继续将格式应用于用作折叠标题的行?
例如,我有以下代码:
int foo(int a, int b) {
int c;
....
}
Run Code Online (Sandbox Code Playgroud)
折叠后,我看到:
+-- 4 lines: int foo(int a, int b) {----------------------------
Run Code Online (Sandbox Code Playgroud)
但是,整行都按照"折叠"类突出显示.有没有办法禁用它,所以我继续看到语法突出显示?
[举一个简单的例子,这不是那么重要,但我也在查看大数据文件时使用折叠,而且格式化对我来说更重要]
通常在查看vim中的日志文件时,我会使用标记突出显示有趣的行.在某些时候,我希望能够将所有有趣的行(或者所有标记的行或标记列表)复制到寄存器或其他文件中(这并不重要;目标是便于撰写摘要).我无法找到任何内置的方法来做到这一点; 是不是可能在vim?
我想这可能是一个相当简单的功能; 可能看起来像这样,但我的vimscript能力非常弱:
for cur_mark in list_of_marks
goto mark
yank current line and append to register
Run Code Online (Sandbox Code Playgroud)
有没有人写过他们可以指出的类似的东西?
谢谢
编辑:我在https://github.com/mikeage/vim-yankmarks上发布了已接受的解决方案
我有以下设置:
mkdir /1
mkdir /1/2
mkdir /1/2/3
ln -s /1/2/3 /1/3
Run Code Online (Sandbox Code Playgroud)
如果我这样做cd /1/3,那么pwd,我明白了/1/3.如果我使用pwd -P,我可以得到/1/2/3或pwd -L强迫/1/3.
在VIM中,我正在寻找一种方法来获得/1/3.
如果我打开一个文件/1/3/foo.txt,并使用类似的东西fnamemodify(bufname(winbufnr(0)), ':p:h'),它会返回/1/2/3.
我怎么能告诉它给我相同的目录pwd呢?
我正在将一些代码从BSD套接字移植到Winsock,我不知道如何处理下面的情况.
我的原始应用程序在stdin和网络套接字上运行select:
FD_SET(sock, &fd);
FD_SET(0, &fd);
...
if (select(..., &fd, ... )...)
Run Code Online (Sandbox Code Playgroud)
试图在Winsock中运行它会产生错误10038(WSAENOTSOCK),这是有道理的,因为Linux(stdin)中的文件句柄0不是Windows中的套接字(更确切地说:SOCKET类型).
有没有一种简单的方法将此测试移植到Windows套接字?
考虑下面的程序
char str[5];
strcpy(str,"Hello12345678");
printf("%s",str);
Run Code Online (Sandbox Code Playgroud)
运行此程序时会出现分段错误.
但是当strcpy被替换为以下时,程序运行正常.
strcpy(str,"Hello1234567");
Run Code Online (Sandbox Code Playgroud)
所以问题是当尝试复制到str超过5个字符长度的任何其他字符串时它应该崩溃.
那么为什么它不会因为"Hello1234567"崩溃而只会崩溃为"Hello12345678",即长度为13或超过13的字符串.
该程序在32位机器上运行.
我有一些代码(它是wordpress插件的一部分),它接受一个文本字符串,并给出date()的格式说明符,并尝试将其解析为包含小时,分钟,秒,日,月,年的数组.
目前,我使用以下代码(请注意strtotime与01/02/03之类的东西非常不可靠)
// $format contains the string originally given to date(), and $content is the rendered string
if (function_exists('date_parse_from_format')) {
$content_parsed = date_parse_from_format($format, $content);
} else {
$content = preg_replace("([0-9]st|nd|rd|th)","\\1",$content);
$content_parsed = strptime($content, dateFormatToStrftime($format));
$content_parsed['hour']=$content_parsed['tm_hour'];
$content_parsed['minute']=$content_parsed['tm_min'];
$content_parsed['day']=$content_parsed['tm_mday'];
$content_parsed['month']=$content_parsed['tm_mon'] + 1;
$content_parsed['year']=$content_parsed['tm_year'] + 1900;
}
Run Code Online (Sandbox Code Playgroud)
这实际上运作得相当好,似乎处理了我抛出的每一个组合.
然而,最近有人给了我24 ??????, 2010.这是2010年11月24日的俄语[日期格式为j F, Y],它被解析为年份= 2010年,月份= null,日期= 24.
是否有任何我可以使用的功能知道如何将11月和Ноябрь翻译成11?
编辑:
运行print_r(setlocale(LC_ALL, 0));回报C.切换回strptime()似乎可以解决问题,但文档警告:
在内部,此函数调用系统的C库提供的strptime()函数.此功能可以在不同的操作系统上表现出明显不同的行为.在PHP 5.3.0及更高版本中,建议使用不受这些问题影响的date_parse_from_format().
是date_parse_from_format()正确的API,如果是这样,我如何让它识别语言?
我有一个故意执行除以零的程序(并将结果存储在一个易变的变量中),以便在某些情况下停止.但是,我希望能够禁用此暂停,而无需更改执行除零的宏.
有什么方法可以忽略它吗?
我试过用了
#include <signal.h>
...
int main(void) {
signal(SIGFPE, SIG_IGN);
...
}
Run Code Online (Sandbox Code Playgroud)
但它仍然会消息"浮点异常(核心转储)".
我实际上并没有使用该值,因此我并不关心分配给变量的内容; 0,随机,未定义......
编辑:我知道这不是最便携的,但它适用于在许多不同操作系统上运行的嵌入式设备.默认的暂停动作是除以零; 其他平台需要不同的技巧来强制看门狗引发重启(例如禁用中断的无限循环).对于PC(linux)测试环境,我想在不依赖断言之类的情况下禁用除零时停止.
我想在C中构建一个Morse解码器(最终是一个编码器).我想使用音频端口作为输入,并在端口上对输入电压进行采样.
如何使用C读取Windows中麦克风音频端口的电压?
我正在寻找一个C代码的声明,给出文件名和亚麻的开始.
当然,我不能只是采取行,因为我可以有类似的东西:
foo(i,
j, "this is ); \
", k);
Run Code Online (Sandbox Code Playgroud)
如例子所示,我也不能寻找下);一个,这将使它相当简单.
那里有什么东西,大概是在CPAN上,它会自动执行此操作吗?
如果我可以先通过缩进运行代码,我会让它允许无限制的行长度,然后只取这条线,但如果我这样做,我会丢失行号!
我一直在我的网站上运行我的大部分PHP应用程序,在fastcgi后端,由NGINX提供服务.我有一个新的应用程序,似乎很好地与Apache集成; 例如,它严重依赖于动态编写的.htaccess文件.我正在努力修改它以与NGINX本地工作,但还没有准备好.与此同时,我将把NGINX代理连接到该路径直接连接到Apache,并让Apache处理它.
但是,我的内存限制为VPS,我宁愿不为NGINX(带有自己的APC缓存)运行一组PHP-CGI进程,而为Apache运行另一组PHP(使用更多内存用于其 APC缓存).有没有人有幸在两者之间分享PHP?
mod_ fcgid似乎不支持使用已经运行的服务器,所以我尝试了mod_ fastcgi.这似乎最初起作用,但吸收了相当多的内存(承诺 - 它正在增长,而不仅仅是静态).更糟糕的是,我无法在我的apache配置中使用DirectoryIndex行来使用mod_fastcgi!
我补充道
AddHandler php5-fastcgi .php
FastCgiExternalServer /var/www -host 127.0.0.1:9000
到我的Apache配置,并处理所有.php页面,但像http://example.com/foo/这样的路径不服务器/foo/index.php!如果我删除FastCgiExternalServer,它确实找到index.php,但当然只是将其显示为文本.
我假设它是因为DirectoryIndex是在FastCgiExternalServer之后处理的,但我不知道如何更改它.