我正在尝试读取/写入FM24CL64-GTR FRAM通过地址上的I2C总线连接的芯片0b 1010 011.
当我试图写3个字节(数据地址2个字节,+数据一个字节)时,我得到一个内核消息([12406.360000] i2c-adapter i2c-0: sendbytes: NAK bailout.),以及写返回!= 3.参见下面的代码:
#include <linux/i2c-dev.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
int file;
char filename[20];
int addr = 0x53; // 0b1010011; /* The I2C address */
uint16_t dataAddr = 0x1234;
uint8_t val = 0x5c;
uint8_t buf[3];
sprintf(filename,"/dev/i2c-%d",0);
if ((file = open(filename,O_RDWR)) < 0)
exit(1);
if (ioctl(file,I2C_SLAVE,addr) < 0)
exit(2);
buf[0] = dataAddr >> 8;
buf[1] = dataAddr & 0xff;
buf[2] = val;
if (write(file, buf, 3) …Run Code Online (Sandbox Code Playgroud) 对于我的Programming 102类,我们被要求提供在Linux下编译和运行的C代码.我的硬盘驱动器上没有足够的空间来安装Linux和Windows,因此我使用cygwin编译我的程序.
我必须提供的最新程序编译并在cygwin下正常运行.它在Linux下编译很好,但执行中途会产生分段错误.我向给我们上课的研究生解释了这一点,他说cygwin的GCC版本允许编写和执行更粗糙的代码.
我通过谷歌找到的少数参考文献尚无定论.我找到的一个帖子说Linux下的seg故障原因是内存泄漏.为什么这不会影响cygwin版本?
我会使用大学的计算机,但我不能在他们身上使用Subversion,这会严重阻碍我的努力.(我是编码的新手,通常需要能够恢复到X修订版).
cygwin的GCC版本是否真的对它编译的代码更"松懈"?如果是这样,编码时是否有任何明显的问题需要注意?是否有任何替代方法可以编写将在Linux下运行的代码?
编辑
谢谢你的回复.我在原帖中没有明确表示:我的代码中有一个错误对我来说非常重要(我对编程很陌生,毕竟C语言真的很绿).我的TA暗示cygwin的GCC是一个不太可靠的编译器 - 比起在GNU/Linux下发现的代码要运行得更多.我发现这很奇怪,所以在互联网上搜索,但实际上找不到任何对这个事实的引用.
不仅仅是责怪编译器和我的代码,我想知道程序在Windows下运行并在Linux下崩溃的原因是什么.回复:在这方面说明了Windows/Linux下的不同内存管理器和堆/堆栈布局.
结论是cygwin的GCC和GNU/Linux一样"好",它是底层操作系统/纯粹的运气,我的错误程序运行在一个而不是另一个是非常正确的吗?
关于发布源代码,这是一个家庭作业,所以我更愿意自己找到问题,如果可能的话:)
编辑2
我接受了jalf的答案,因为它讨论了什么使程序在Windows下而不是在Linux下运行,这是我真正想知道的.感谢所有贡献的人,他们都是非常有趣和内容丰富的回复.
当我发现问题并修复它时,我会上传一个包含这个非工作版本的所有源代码的zip文件,万一有人好奇地看到我到底做了什么:)
编辑3
对于那些有兴趣看到代码的人,我发现了问题,这确实是由于指针.我试图从函数返回一个指针.我试图返回的指针正在函数内部声明,因此在函数执行后被销毁.问题代码在第22-24行注释掉.
随意嘲笑我的代码.
/**
* Returns array of valid searches based on current coordinate
*/
void determine_searches(int row, int col, int last_row, int last_col, int *active_search){
// define coordinate categories and related valid search directions
int Library0[] = {2, 3, 4, -1};
int Library1[] = {4, 5, 6, -1};
int Library2[] = {2, 3, 4, 5, 6, -1};
int Library3[] = {0, 1, 2, …Run Code Online (Sandbox Code Playgroud) sscanf(input_str, "%5s", buf); //reads at max 5 characters from input_str to buf
Run Code Online (Sandbox Code Playgroud)
但我需要使用%MACRO_SIZE而不是%5s
一个简单的解决方案是为它创建一个格式字符串
char fmt_str[100] = "";
snprintf(fmt_str, 100, "%%%ds", MACRO_SIZE);
sscanf(input_str, fmt_str, buf);
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来实现同样的目标?
出于某种原因,我的gcc安装似乎在其错误消息中打印了"a with a carat"字符代替所有%s,例如,
test.c:4: error: expected â, â, â, â or â before â token
Run Code Online (Sandbox Code Playgroud)
有没有人见过这个?(毋庸置疑,谷歌很难.)
(这是在Ubuntu 8.10上)
编辑:http://ubuntuforums.org/showthread.php?t = 252832 的人说要设置LC_MESSAGES = en_US,但这对我没有任何作用.
鉴于所有原始数据类型和对象都分配了内存,因此直观地容易想象指向这些类型的指针.
但是函数指针究竟指向哪里?鉴于指令被转换为机器代码并驻留在内存中,我们是否应该考虑它们指向与函数指令开头相对应的内存位置?
由于非法内存访问,我们在指针中面临许多错误.当函数指针指向数据存储器而不是指令存储器时,是否会发生错误?
是否每个.C或.cpp文件都应该有一个标题(.h)文件?
假设有以下C文件:
MAIN.C
Func1.C
Func2.C
Func3.C
其中,main()在MAIN.C文件.应该有四个头文件
Main.h
Func1.h
Func2.h
Func3.h
或者所有.C文件应该只有一个头文件?
什么是更好的方法?
我已经开始回顾回调了.我在SO上找到了这个链接: C中的"回调"是什么?它们是如何实现的? 它有一个很好的回调示例,它与我们在工作中使用的非常类似.但是,我试图让它工作,但我有很多错误.
#include <stdio.h>
/* Is the actual function pointer? */
typedef void (*event_cb_t)(const struct event *evt, void *user_data);
struct event_cb
{
event_cb_t cb;
void *data;
};
int event_cb_register(event_ct_t cb, void *user_data);
static void my_event_cb(const struct event *evt, void *data)
{
/* do some stuff */
}
int main(void)
{
event_cb_register(my_event_cb, &my_custom_data);
struct event_cb *callback;
callback->cb(event, callback->data);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道回调使用函数指针来存储函数的地址.但是我发现有些事情我不明白:
我有一个需要新功能的传统固件应用程序.应用程序的大小已经接近设备的有限闪存容量,并且少数新功能和变量将其推到了边缘.打开编译器优化可以解决这个问题,但客户对这样做很谨慎,因为它们过去曾导致过失败.那么,在重构C代码以产生较小的输出时,需要注意哪些常见的事情?
假设我有三个C静态库,比如libColor.a,它依赖于*libRGB.*a,而后者依赖于libPixel.a.据说库libColor.a依赖于库libRGB.a,因为libColor.a中有一些对libRGB.a中定义的符号的引用.如何将所有上述库组合到一个独立的新libNewColor.a中?
独立意味着新库应该定义所有符号.所以在链接时我只需要给出-lNewColor.新库的大小应该是最小的,即它不应该包含libRGB.a中的任何符号,libColor.a等不使用它.我在ar命令中使用了各种选项来试运气(用于创建和更新静态库/档案) ).