Sziasztok!
Van nekem egy Intel Galileo Gen2 vezérlőm, amin Yocto Linux fut. Erre a vezérlőre szabványos Arduino Shield-eket, lehet tenni.
Eddig minden rendben. Vettem hozzá egy MCP3201 ADC-t tartalmazó shield-et, ami SPI-n kommunikál(na) a vezérlővel.
A probléma, hogy az itt található forrásból fordított kernel modul a címben említett hibával tér vissza.
A parancs amit kiadok:
modprobe mcp320x
A dmesg sem sokkal bőbeszédűbb:
[ 5349.763606] mcp320x_driver: Unknown symbol mcount (err 0)
Ha jól értem kell a modprobe parancsnak plusz paraméter, de nem tudom, hogy milyen paraméter=érték (
) párosra van szüksége.parameter
=value
Találtam doksit is, de sokat segítene ha valaki tapasztaltabb meg tudná mondani, hogy tényleg csak a paraméterezést rontom el, vagy más a hiba? Plusz az is jól jönne, hogy hogyan paraméterezzem helyesen a modeprobe parancsot?
Az overaly nevezetű programmal elvileg egyszerű lenne a paraméterezés, viszont azt a Yocto linux polky verziójára nem találtam meg.
Szerk.:
Végül sikerült megoldani. :)
Újrafordítottam az imaget és hozzá a modult, így már működött. Tehát vl-nek volt igaza a hibával kapcsolatban. Köszönöm a segítséget!
Szerk II.:
Azért azt ideírom még, hogy ne legyen félrevezető: Sikerült továbbá 3.14-es kernellel fordítani, így csak egy sort kellett módosítani az eredeti kódon, az is csak egy include.
- 227 megtekintés
Hozzászólások
A dirver nincs véletlenül benne itt:
grep mcp /etc/modprobe.d/*
- A hozzászóláshoz be kell jelentkezni
Itt sajna nincs ilyesmi. :(
grep: /etc/modprobe.d/*: No such file or directory
- A hozzászóláshoz be kell jelentkezni
Ha jól értem kell a modprobe parancsnak plusz paraméter
Nem, a hibaüzenet nem ezt jelenti. Hanem azt, a megadott nevű függvény/változó hiányzik neki. Ennek vagy a kernelben, vagy egy másik modulban kéne definiálva lennie. Tehát vagy nem jó kernelhez sikerült fordítani (esetleg a kernel fordítási opciók nem stimmelnek), vagy egy másik modulra lenne szüksége.
- A hozzászóláshoz be kell jelentkezni
vagy egy másik modulra lenne szüksége
Igen. Kerdes hogy valamifele SPI host driver (peldaul barmi a /lib/modules/`uname -r`/kernel/drivers/spi/ alol) be van-e toltve? Ezen kivul elsore mas fuggoseget nem szurtam ki.
- A hozzászóláshoz be kell jelentkezni
Az SPI host driver be van töltve. Ezt én is kiszúrtam, ezek szerint jól.
- A hozzászóláshoz be kell jelentkezni
Akkor ha jól értem az mcount függvény/változó hiányzik neki?
A kernelem verziója 3.8.7-yocto-standard. Jó régi. De erről áttérni másra igen bajos...
Van esetleg valami ötlet, hogyan tudnám belevarázsolni az mcount függvényt/változót?
- A hozzászóláshoz be kell jelentkezni
Megnézed a forrását az mcountnak és belemasolod.
Aki másnak vermet ás, az stack pointer.
- A hozzászóláshoz be kell jelentkezni
Háttöö... az van, hogy a fordítás során azt gondolja, hogy a kernelben majd lesz ilyen függvény/változó, hiszen lefordult a modul. Aztán runtime már nem találja. Ha a fordításnál sincs ott a függvény/változó, akkor a fordításnál kéne hibát kapni. Ergó vagy egy modult be kellett volna tölteni, amit nem tettél meg, ezért hiányzik a függvény/változó, vagy a modult egy másik kernelhez sikerült fordítani, mint ami fut. Az egyezéshez nem elég, hogy ugyanaz legyen a kernelverzió, hanem a kernel confignak is egyeznie kell. Sőt, ha valaki más gcc verziót használ, abból is lehet galiba. Tehát ugyanaz a kernel forrás, ugyanazokkal a config opciókkal, ugyanazzal a gcc-vel.
- A hozzászóláshoz be kell jelentkezni
Szerintem itt én hibáztam korábban. Az eredeti kód nem fordult le és elkezdtem belerakni a hiányzó függvényeket... (Nem tudtam, hogy ebből baj lesz.)
Amit most csináltam javításként:
- Újra bemásoltam az eredeti kódot
- Hozzáadtam két plusz sort:
#include <linux/init.h> #include <linux/of.h>
Remélem ezzel nagy bajt nem okozok.
-
Nézem a hibákat és ötletem sincs hogy teszem bele a hiányzó függvényeket.
Ezek voltak pluszban még a régi kódban:/** * spi_message_init_with_transfers - Initialize spi_message and append transfers * @m: spi_message to be initialized * @xfers: An array of spi transfers * @num_xfers: Number of items in the xfer array * * This function initializes the given spi_message and adds each spi_transfer in * the given array to the message. */ static inline void spi_message_init_with_transfers(struct spi_message *m, struct spi_transfer *xfers, unsigned int num_xfers) { unsigned int i; spi_message_init(m); for (i = 0; i < num_xfers; ++i) spi_message_add_tail(&xfers[i], m); } /* * Create a contiguous bitmask starting at bit position @l and ending at * position @h. For example * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. */ #define GENMASK(h, l) \ (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) #define GENMASK_ULL(h, l) \ (((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h)))) extern unsigned int __sw_hweight8(unsigned int w); extern unsigned int __sw_hweight16(unsigned int w); extern unsigned int __sw_hweight32(unsigned int w); extern unsigned long __sw_hweight64(__u64 w); static void devm_iio_device_release(struct device *dev, void *res) { iio_device_free(*(struct iio_dev **)res); } /** * devm_iio_device_alloc - Resource-managed iio_device_alloc() * @dev: Device to allocate iio_dev for * @sizeof_priv: Space to allocate for private structure. * * Managed iio_device_alloc. iio_dev allocated with this function is * automatically freed on driver detach. * * If an iio_dev allocated with this function needs to be freed separately, * devm_iio_device_free() must be used. * * RETURNS: * Pointer to allocated iio_dev on success, NULL on failure. */ struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv) { struct iio_dev **ptr, *iio_dev; ptr = devres_alloc(devm_iio_device_release, sizeof(*ptr), GFP_KERNEL); if (!ptr) return NULL; /* use raw alloc_dr for kmalloc caller tracing */ iio_dev = iio_device_alloc(sizeof_priv); if (iio_dev) { *ptr = iio_dev; devres_add(dev, ptr); } else { devres_free(ptr); } return iio_dev; }
Mást nem nagyon találtam.. De ránézek majd még egyszer.
-
Itt van még pár fordítási hiba ami az eredeti kód + a 2. pontban lévő kód fordításakor keletkezett:
error: implicit declaration of function 'GENMASK' error: unknown field 'info_mask_separate' specified in initializer | MCP320X_VOLTAGE_CHANNEL_DIFF(0, 1), error: unknown field 'info_mask_shared_by_type' specified in initializer error: implicit declaration of function 'devm_iio_device_alloc' [-Werror=implicit-function-declaration] | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc)); | ^ error: implicit declaration of function 'spi_message_init_with_transfers' [-Werror=implicit-function-declaration] | spi_message_init_with_transfers(&adc->msg, | ^
Ezeket meg lehet oldani valahogy szabályosan?
Köszi a tanácsokat és a segítséget amúgy! :)
- A hozzászóláshoz be kell jelentkezni
modinfo mcp320x
filename: /lib/modules/5.0.0-31-generic/kernel/drivers/iio/adc/mcp320x.ko
license: GPL v2
description: Microchip Technology MCP3x01/02/04/08 and MCP3550/1/3
author: Oskar Andero
srcversion: 2132041D64E02EAE44E7397
alias: spi:mcp3553
alias: spi:mcp3551
alias: spi:mcp3550-60
alias: spi:mcp3550-50
alias: spi:mcp3301
alias: spi:mcp3208
alias: spi:mcp3204
alias: spi:mcp3202
alias: spi:mcp3201
alias: spi:mcp3008
alias: spi:mcp3004
alias: spi:mcp3002
alias: spi:mcp3001
depends: industrialio
retpoline: Y
intree: Y
name: mcp320x
vermagic: 5.0.0-31-generic SMP mod_unload
signat: PKCS#7
signer:
sig_key:
sig_hashalgo: md4
Szerintem ez nem paraméterezhető, viszont ez rendben van?
*** depends: industrialio
Szerk.: válaszolok magamnak: ha eltávolítom az industrialio modult, akkor ez van:
modprobe: ERROR: could not insert 'mcp320x': Unknown symbol in module, or unknown parameter
- A hozzászóláshoz be kell jelentkezni