LinuxCNC / linuxcnc

LinuxCNC controls CNC machines. It can drive milling machines, lathes, 3d printers, laser cutters, plasma cutters, robot arms, hexapods, and more.
http://linuxcnc.org/
GNU General Public License v2.0
1.73k stars 1.13k forks source link

Write hal module in c language linuxcnc with proper permissions on Rpi4 and Fedora IOT #2993

Closed nomi-ramzan closed 3 weeks ago

nomi-ramzan commented 3 weeks ago

Here are the steps I follow to reproduce the issue:

  1. Install linuxcnc following This in Fedora IOT RPi 4
  2. install halmodule using halcompile sudo halcompile --install mymodule.c
  3. launch linuxcnc

Description

PS: I know this is not the right place But I already tried all other platforms and did not get any solution.

I am writing module which uses spi interface and BCM2835 I set all permissions joined required groups cnc root wheel kmem video audio users input render rtkit realtime sys adm tty mem systemd-network kvm. Now my problem is BCM2835 driver is using /dev/mem device which required root permission. And If I run linuxcnc as sudo linuxcnc user then linuxcnc is refusing to run as root user.

module code

#include "rtapi.h"   /* RTAPI realtime OS API */
#include "rtapi_app.h" /* RTAPI realtime module decls */
#include "hal.h"   /* HAL public API decls */

#include "bcm2835.h"
#include "bcm2835.c"

int bcm2835_init_local(void)
{
  // ... above code See bcm2835.c bcm2835_init() for details code
  int memfd = open("/dev/mem", O_RDWR | O_SYNC);
  // ...
  // Values are mapmem('gpio', 25165824, 3, -33554432);
  printf("mapmem('gpio', %d, %d, %d);\n", bcm2835_peripherals_size, memfd, bcm2835_peripherals_base);
  // ERROR: bcm2835_init: gpio mmap failed: Operation not permitted
  bcm2835_peripherals = mapmem("gpio", bcm2835_peripherals_size, memfd, bcm2835_peripherals_base);
  // ...
  // This line is not setting the value 
  bcm2835_spi0 = bcm2835_peripherals + BCM2835_SPI0_BASE/4;
}
int rtapi_app_main(void)
{
  if (!bcm2835_init_local())
  {
    rtapi_print_msg(RTAPI_MSG_ERR, "bcm2835_init failed. Try run with root privlages.\n");
    return -1;
  }

  if (!bcm2835_spi_begin())
  {
    rtapi_print_msg(RTAPI_MSG_ERR, "bcm2835_spi_begin failed. Try run with root privlages.\n");
    return -1;
  }
}

This is what I expected to happen:

Set correct values of bcm2835_peripherals and other variables of type volatile uint32_t *

bcm2835_gpio = bcm2835_peripherals + BCM2835_GPIO_BASE/4;
bcm2835_pwm  = bcm2835_peripherals + BCM2835_GPIO_PWM/4;
bcm2835_clk  = bcm2835_peripherals + BCM2835_CLOCK_BASE/4;
bcm2835_pads = bcm2835_peripherals + BCM2835_GPIO_PADS/4;
bcm2835_spi0 = bcm2835_peripherals + BCM2835_SPI0_BASE/4;
bcm2835_bsc0 = bcm2835_peripherals + BCM2835_BSC0_BASE/4;
bcm2835_bsc1 = bcm2835_peripherals + BCM2835_BSC1_BASE/4;
bcm2835_st   = bcm2835_peripherals + BCM2835_ST_BASE/4;
bcm2835_aux  = bcm2835_peripherals + BCM2835_AUX_BASE/4;
bcm2835_spi1 = bcm2835_peripherals + BCM2835_SPI1_BASE/4;

This is what happened instead:

This error is coming bcm2835_init: gpio mmap failed: Operation not permitted

Information about my hardware and software:

andypugh commented 3 weeks ago

A quick web search suggests that this message is not necessarily due to a permissions problem: https://forums.raspberrypi.com/viewtopic.php?t=106214

I think that you may need to follow the instructions here, on creating a group with the correct access: http://linuxcnc.org/docs/stable/html/drivers/hal_gpio.html

And, of course, you could consider simply using that driver....

I am going to close this issue as I do not think that it is a bug in LinuxCNC. I am happy to continue discussing it here, but don't want it to appear on the list of unfixed bugs.

nomi-ramzan commented 3 weeks ago

In this reference

http://linuxcnc.org/docs/stable/html/drivers/hal_gpio.html what is use of file 90-gpio-access ?

andypugh commented 3 weeks ago

It would help if the documentation explained that. It seems I forgot to say. It's a file that goes in /etc/udev/rules.d that cereates the gpio gruip and gives the right permissions to members of the gpio group.

nomi-ramzan commented 3 weeks ago

I created file /etc/udev/rules.d/90-gpio-access.rules then

sudo udevadm control --reload-rules
sudo udevadm trigger

then reboot and restart linuxcnc. same error still coming.

One more thing which I found is in driver 2835.c file this line if (geteuid() == 0 ) is giving id 0 which is root id but linuxcnc instance is running under user cnc with id 1000. When I run same module in fedora instance then above line is giving id 1000 and control is moving to else block to read /dev/gpiomem But There is no variable initialization ie bcm2835_spi0

Moreover I logged the values when I run module in linuxcnc official distribution I am getting these values

106: hal_malloc -1235466688...!!!
237: debug 0...!!!
268: /proc/device-tree/soc/ranges file done
273: base_address 0 
278: peri_size -33554432 
286: base_address RPi4 -33554432 
291: peri_size RPi4 25165824 
300: read buf done 
303: bcm2835_peripherals_base: -33554432 
304: bcm2835_peripherals_size: 25165824 
307: Overriding global value pud_type_rpi4: 0 to 1
313: read ranges file done 
324: geteuid() value is 0
333: rtapi_open_as_root(/dev/mem) PASSED 7
337: mapmem(gpio) return bcm2835_peripherals -1267073024, 1
339: mapmem(gpio) PASSED
345: bcm2835_gpio = -1264975872 , 606081088
346: bcm2835_pwm  = -1264926720 , 0
347: bcm2835_clk  = -1266020352 , 25453
348: bcm2835_pads = -1266024448 , 28781
349: bcm2835_spi0 = -1264959488 , 262144
350: bcm2835_bsc0 = -1264955392 , 0
351: bcm2835_bsc1 = -1258668032 , 0
352: bcm2835_st   = -1267060736 , 10
353: bcm2835_aux  = -1264889856 , 0
354: bcm2835_spi1 = -1264889728 , 0
390: return success 1

in Fedora IOT same execution values are

106:hal_malloc -1232057216...!!!
237:debug 0...!!!
262:/proc/device-tree/soc/ranges opened
268:/proc/device-tree/soc/ranges file done
273:base_address 0 
278:peri_size -33554432 
286:base_address RPi4 -33554432 
291:peri_size RPi4 25165824 
300:read buf done 
303:  bcm2835_peripherals_base: -33554432 
304:  bcm2835_peripherals_size: 25165824 
307:Overriding global value pud_type_rpi4: 0 to 1
313:read ranges file done 
324:geteuid() = 1000
360:open(/dev/gpiomem) instead of /dev/mem -1
370:open(/dev/gpiomem) PASSED 7
372:mapmem('gpio'...) 
  bcm2835_peripherals_size 25165824
  memfd: 7 
 bcm2835_peripherals_base: 0374:bcm2835_peripherals -1264648192
380:/dev/gpiomem read all done ok? 1
390:return success 1
andypugh commented 3 weeks ago

Did you remember to add the user who is running linuxcnc to the gpio group?

Does the hal_gpio driver work? (to separate out the permissions problems and possible issues with your own code)