elcritch / nesper

Program the ESP32 with Nim! Wrappers around ESP-IDF API's.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Compile error: Unknown type name 'esp_timer' when calling createTimer()

aboisvert opened this issue · comments

When setting up a timer in my code:

    proc timerSetup() =
      let timerHandle = createTimer(timerTriggered, nil, ESP_TIMER_TASK, "HVAC_TIMEOUT")
      check: esp_timer_start_periodic(timerHandle, TIMEOUT.toMicros.uint64)

I get a compile error while running make:

/root/.nimble/pkgs/nesper-#0.5.0/nesper/timers.nim:17:25: error: unknown type name 'esp_timer'
/root/.nimble/pkgs/nesper-#0.5.0/nesper/timers.nim:17:223: error: unknown type name 'esp_timer'; use 'struct' keyword to refer to the type
/root/.nimble/pkgs/nesper-#0.5.0/nesper/timers.nim:17:279: error: unknown type name 'esp_timer'; use 'struct' keyword to refer to the type
/root/.nimble/pkgs/nesper-#0.5.0/nesper/timers.nim:17:366: error: 'esp_timer' undeclared (first use in this function)
/root/.nimble/pkgs/nesper-#0.5.0/nesper/timers.nim:17:376: error: expected expression before ')' token
/root/.nimble/pkgs/nesper-#0.5.0/nesper/timers.nim:17:472: error: expected expression before ')' token
../main/nimcache/@mhvac_controller.nim.c:153:25: error: unknown type name 'esp_timer'
/project/main/hvac_controller.nim:99:79: error: unknown type name 'esp_timer'; use 'struct' keyword to refer to the type
make: *** [build] Error 2

Any idea why compilation is failing?

Odd, looks like it's not importing the header for the esp timer. What branch of nesper are you using and what esp-idf version?

I'm using the Docker container from the Nesper repository, which relies on ESP-IDF 4.0

from espressif/idf:release-v4.0

and I'm using the 0.5.0 tag for Nesper:

requires "https://github.com/elcritch/nesper#0.5.0"

The weird thing I've noticed is that $IDF_PATH/components/esp_common/include/esp_timer.h from ESP-IDF 4.0 in the container differs from the nesper/tests/c_headers/esp_timer.h file contained in the Nesper repository.

% diff -c $IDF_PATH/components/esp_common/include/esp_timer.h ~/git/nim/nesper/tests/c_headers/esp_timer.h
*** components/esp_common/include/esp_timer.h	2021-01-04 15:32:48.187474654 -0800
--- /home/boisvert/git/nim/nesper/tests/c_headers/esp_timer.h	2020-12-30 17:55:51.620577474 -0800
***************
*** 47,52 ****
--- 47,72 ----
  extern "C" {
  #endif
  
+ 
+ struct esp_timer {
+     uint64_t alarm;
+     uint64_t period;
+     union {
+         esp_timer_cb_t callback;
+         uint32_t event_id;
+     };
+     void* arg;
+     const char* name;
+     size_t times_triggered;
+     size_t times_armed;
+     uint64_t total_callback_run_time;
+     struct  {
+         struct esp_timer *le_next;	/* next element */
+         struct esp_timer **le_prev;	/* address of previous next element */
+     } list_entry;
+ };
+ 
+ 
  /**
   * @brief Opaque type representing a single esp_timer
   */

This explains the compilation error but doesn't explain why there is a difference.

In the container, the esp_timer struct is defined in $IDF_PATH/components/esp_common/src/esp_timer.c. Weird.

It's an odd piece. I'll check it out this weekend. It may require some header file fiddling. I've run into similar before and it's not too hard to resolve but I need my desktop to pull open the entire esp-idf project to find the headers.

Cool, thanks for the response! I've tried mucking around with the headers but didn't get things to work yet. I'm no C/C++ expert, but if I can learn how you tackle this issue, I can probably help with other similar cases in the future.

Think it's fixed now! Well, at least it compiles. It turned out the esp_timer needs to be a struct esp_timer on the Nim side.

In most of the imports from the esp-idf I've used the typedefed type which usually matches the C struct name. That means no struct is required and is how Nim's codegen works too. In this case, the esp-idf folks define the typedef as esp_timer_handle_t.

Here's how it's defined (

esp_timer_handle_t* = ptr esp_timer
):

type
  esp_timer_handle_t* = ptr esp_timer

For the C:

typedef struct esp_timer* esp_timer_handle_t;

To fix it:

type
  esp_timer* {.importc: "struct esp_timer", header: "esp_timer.h", bycopy.} = object
      ...

P.S. the fix is on the devel branch. You'll need to check it out from github directly with Nimble.

Thank you for the fix! I've confirmed compilation works for my app. I can't test if things work at runtime right now because I'm traveling and I don't have access to my ESP32 device. I'll test later but closing this issue since compilation succeeds.