在嵌入式C函数中记录问题

huangapple go评论86阅读模式
英文:

Issue logging within an embedded C function

问题

以下是翻译好的部分:

"Is there a way to get the device that calls the embedded function? Do I need to pass the device pointer into fib()?"

"我想要从嵌入的C函数中记录日志。"

英文:

I'd like to generate logging messages from within a C function embedded in a DML method. Take the example code below where the fib() function is called from the write() method of the regs bank. The log methods available to C all require a pointer to the current device.

Is there a way to get the device that calls the embedded function? Do I need to pass the device pointer into fib()?

dml 1.2;
device simple_embedded;
parameter documentation = "Embedding C code example for"
    + " Model Builder User's Guide";
parameter desc = "example of C code";

extern int fib(int x);

bank regs {
    register r0 size 4 @0x0000 {
        parameter allocate = false;
        parameter configuration = "none";
        method write(val) {
            log "info": "Fibonacci(%d) = %d.", val, fib(val);
        }

        method read() -> (value) {
            // Must be implemented to compile            
        }
       
    }
}

header %{
int fib(int x);
%}

footer %{
int fib(int x) {
    SIM_LOG_INFO(1, mydev, 0, "Generating Fibonacci for %d", x); 
    if (x < 2) return 1;
    else return fib(x-1) + fib(x-2);
}
%}

I want to log from an embedded C function.

答案1

得分: 2

I solved this by passing the Simics conf_object_t pointer along to C. Just like implied in the question.

So you would use:

int fib(conf_object_t *mydev, int x) {
    SIM_LOG_INFO(1, mydev, 0, "Generating Fibonacci for %d", x); 
}

And

method write(val) {
    log "info": "Fibonacci(%d) = %d.", val, fib(dev.obj,val);
}
英文:

I solved this by passing the Simics conf_object_t pointer along to C. Just like implied in the question.

So you would use:

int fib(conf_object_t *mydev, int x) {
    SIM_LOG_INFO(1, mydev, 0, "Generating Fibonacci for %d", x); 
}

And

        method write(val) {
            log "info": "Fibonacci(%d) = %d.", val, fib(dev.obj,val);
        }

答案2

得分: 1

Jakob的回答是对的,如果您的目的是将一些计算卸载到C代码中(这在许多情况下是有意义的,比如当功能由库实现时)。

但是,如果您只是想要向要求函数指针的API传递回调函数,那么更容易的方法是在DML中保留实现,并使用方法引用,例如:

method init() {
    SIM_add_notifier(obj, trigger_fib_notifier_type, obj, &trigger_fib,
                     &dev.regs.r0.val);
}

method trigger_fib(conf_object_t *_, lang_void *aux) {
    value = *cast(aux, uint64 *);
    local int result = fib(value);
    log info: "result: %d", result;
}

method fib(int x) -> (int) {
    log info: "Generating Fibonacci for %d", x; 
    if (x < 2) return 1;
    else return fib(x-1) + fib(x-2);
}
英文:

Jakob's answer is the right one if your purpose is to offload some computations to C code (which makes sense in many situations, like when functionality is implemented by a lib).

However, if you just want a way to pass a callback to an API that asks for a function pointer, then it is easier to keep the implementation within DML and use a method reference, like:

method init() {
    SIM_add_notifier(obj, trigger_fib_notifier_type, obj, &trigger_fib,
                     &dev.regs.r0.val);
}

method trigger_fib(conf_object_t *_, lang_void *aux) {
    value = *cast(aux, uint64 *);
    local int result = fib(value);
    log info: "result: %d", result;
}

method fib(int x) -> (int) {
    log info: "Generating Fibonacci for %d", x; 
    if (x < 2) return 1;
    else return fib(x-1) + fib(x-2);
}

huangapple
  • 本文由 发表于 2023年2月8日 09:17:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/75380519.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定