Arduino çiziminden C fonksiyonlarını nasıl çağırırım?


10

Bir Arduino kroki kullanarak C dosyalarında bulunan işlevleri çağırmak için bir yolu olup olmadığını bilmek istiyorum?

C dosyam bir işlevi bildirir ve tanımlar. Dağınık işlev tanımını Arduino çizimime koymaktan kurtarmak için, işlevi doğrudan çizimden çağırmak istiyorum.

Arduino ve C kullanarak bunu yapmanın standart bir yolu var mı? İşte taslak:

#include "crc16.h";

void setup(){

}

void loop(){

  CalculateCRC16("<09M", 4);

}

ve bu da kesilmiş C dosyası:

#include <stdio.h>
#include <stdint.h>

uint16_t crctable[256] =
{
    0x0000, 0x1189,.....



uint16_t // Returns Calculated CRC value
CalculateCRC16( // Call example CalculateCRC16("<09M", 4);
    const void *c_ptr, // Pointer to byte array to perform CRC on
    size_t len)        // Number of bytes to CRC
{

    uint16_t crc = 0xFFFF // Seed for CRC calculation
    const uint8_t *c = c_ptr;

    while (len--)
        crc = (crc << 8) ^ crctable[((crc >> 8) ^ *c++)];

    return crc;
}

Dosyanızın C ++ yerine C kullanması için bir neden var mı?
Peter Bloomfield

Aslında evet. Dosyayı C ++ kullanarak derlemeye çalıştığımda hatalar var, ancak C'de hatasız. Hata satırlardan kaynaklanıyor: const void *c_ptrve const uint8_t *c = c_ptr;. Hata iletisi, türler arasında geçersiz bir dönüşümden bahsediyor.
user_name

4
Lütfen hatayı oluşturan 2 kod dosyasını (veya basitleştirilmiş bir minimal sürümünü) kaydedebilir ve hata mesajını tam olarak kopyalayıp yapıştırabilir misiniz?
drodri

Hata mesajları çok hoş değil: In function uint16_t CalculateCRC16(uint16_t, const void*, size_t)': 46 invalid conversion from const void * '-const uint8_t*' In function int main()': 57 system' undeclared (first use this function) (Each undeclared identifier is reported only once for each function it appears in.)
kullanıcı_adı

Yanıtlar:


10

"C" # komutunu aşağıdaki gibi ekleyebilirsiniz:

extern "C"{
#include "crc16.h"
};

void setup(){
}

void loop(){
  CalculateCRC16("<09M", 4);
}

Ve crc16.h dosyası olabilir (bazı küçük düzeltmeler, #pragma bir kez, döküm):

#pragma once

#include <stdio.h>
#include <stdint.h>

uint16_t crctable[2] ={ 0x0000, 0x1189};

uint16_t CalculateCRC16( // Call example CalculateCRC16("<09M", 4);
    const void *c_ptr, // Pointer to byte array to perform CRC on
    size_t len)        // Number of bytes to CRC
{
    uint16_t crc = 0xFFFF; // Seed for CRC calculation
    const uint8_t *c = (const uint8_t *)c_ptr;

    while (len--)
        crc = (crc << 8) ^ crctable[((crc >> 8) ^ *c++)];

    return crc;
}

Teşekkürler, şimdi iyi çalışıyor. Pragmanın ihtiyacını açıklar mısınız?
user_name

1
Tabii, iyi bir uygulamadır, ancak örneğinizde gerekli değildir. Aynı başlık dosyasının bir derleme dosyasına iki kez dahil edilmesini önler. A.cpp -> (bh ve ch) ve bh-> ch'yi hayal edin. A.cpp derlerken ch içeriğini çoğaltacaktır. #Pragma bir kez bundan kaçınır. Ayrıca #ifndef _MY_FILE_H_INCLUDED #define _MY_FILE_H_INCLUDED koruma yönergeleri bunun için yaygındır. Bununla birlikte, Peter R. Bloomfield'ın işaret ettiği gibi, CalculateCRC16 uygulamasını bir cpp dosyasına koymak ve yalnızca başlık dosyasında bildirimi bırakmak daha iyi olabilir.
drodri

Tamam, kod gittikçe karmaşıklaştığında bir sorun haline geldiğini görebiliyorum. Tavsiye için teşekkürler.
user_name

4

* .Cpp dosyasına girebilmesi için CRC işleviniz kolayca C ++ 'ya dönüştürülebilir. Tek yapmanız gereken cişaretçinizi başlattığınızda açık bir oyuncu kadrosu kullanmaktır . İşte bunu yapmak için 'uygun' C ++ yolu:

const uint8_t *c = static_cast<const uint8_t*>(c_ptr);

Bununla birlikte, eski bir C tarzı oyuncu da işe yarayacaktı:

const uint8_t *c = (const uint8_t*)c_ptr;

Sorun, temel olarak C'nin işaretçileri türler arasında dolaylı olarak dönüştürmenize izin vermede biraz daha izin verici olabilmesidir. C ++ ile yapmak için, derleyiciye dönüşümün kasıtlı olduğunu açıkça belirtmeniz gerekir.


1

Evet, sadece açıklama satırını çiziminize kopyalayın:

extern "C" {
    void myfunction(int arg);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.