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.