User avatar
Z80 Refugee
Posts: 358
Joined: Sun Feb 09, 2014 1:53 pm

What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 1:43 pm

The RPi is a teaching resource for programming, right?

Physical computing is a good model for teaching programming, because it rewards by making things happen (lights flash, motors move, whatever), right?

What bothers me is that these student programmers really don't get to know anything about what they are doing, because they simply call up predefined libraries to do the "heavy lifting" of waggling GPIO pins, with no visibility of the code that is operating in the background.

Yes, clearly you need an easy way in, but that could be provided by explicitly pasting in pre-written (rather than pre-compiled) functions. Students would then be free to modify these or write their own versions.

The point is that if they were to design their own hardware, they would be unable to program it to do something until somebody else wrote them a library call.

Back in the days I was designing peripheral circuits for computer systems, naturally stuff got done by putting data registers on a bus and writing or reading into/out of those registers (the output of a register would be logic levels which acted on further circuits to control their operation, and returning status information came back by reading other registers). The software department tasked an "engineer" to write their interface routines to control my hardware, so I provided a design specification for what all the bits in all the registers did, and the bus addresses at which to access them. All standard stuff.

The problem was that this "software engineer" didn't know what I/O was. Oh yes, he could code a pretty interface in Visual Basic that worked with standard OS GUI calls, but when it came to addressing specific registers and bit twiddling he hadn't a clue. I tried to explain that if you want to change just one bit in an 8-bit register you read it, XOR it with a mask to change just the relevant bit, then write the result back, but I just got a blank look. The software department fixed the problem by swapping out the defective unit.

That's what I'm worried about here. People are being spoon-fed by hiding the details inside libraries, and learning little or nothing other than to expect instant gratification.
Military and Automotive Electronics Design Engineer (retired)

For the best service: make your thread title properly descriptive, and put all relevant details in the first post (including links - don't make us search)!

User avatar
topguy
Posts: 4860
Joined: Tue Oct 09, 2012 11:46 am
Location: Trondheim, Norway

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 2:14 pm

The RPi is a teaching resource for programming, right?
With a very wide age range. Your argument might have some value for students of higher education. But 7-12 year olds dont care about registers, and just want to see the LED blink. If you push too much detail on them you will kill the programming interest of many of them.

And you can dig below the library calls on a Pi to discover what goes on underneath the hood. Much easier than on a PC, and I believe that is the point, you can do it, but are not forced to do it.

User avatar
The Traveler
Posts: 361
Joined: Sat Oct 21, 2017 3:48 pm

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 2:17 pm

People with a curious nature may want to learn more about the inner workings later on as they gain knowledge and experience. I think it's important that folks have the desire to learn more and that will lead them on.

I never "spoon feed". My own approach is generally to point them to relevant links on the web and encourage them to research for themselves first then return with some evidence of their efforts.
Retired IT professional, C programmer and "beardie weirdie".
RPi interests: Developing an Infinite Improbability Drive
“Thinking outside of the box allows you to get rewards outside of your reach.” Matshona Dhliwayo

User avatar
scruss
Posts: 1800
Joined: Sat Jun 09, 2012 12:25 pm
Location: Toronto, ON
Contact: Website

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 2:47 pm

Z80 Refugee wrote:
Tue Jul 17, 2018 1:43 pm
… People are being spoon-fed by hiding the details inside libraries
If you look at this post along with the plethora of "Raspberry Pi is too hard" or "Raspberry Pi is too complicated" or "What do I do with this Raspberry Pi?" posts, it's fairly clear that one just can't please everybody.

I know you're looking for a lower-level board, based on your previous experience. But maybe most people don't need to know how hardware registers work these days. Maybe learning "the hard way" will put a lot of people off? The hardware details will still be there for those interested to learn them.
‘Remember the Golden Rule of Selling: “Do not resort to violence.”’ — McGlashan.

scotty101
Posts: 3101
Joined: Fri Jun 08, 2012 6:03 pm

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 2:49 pm

The Raspberry Pi is a very complex starting point for dealing with registers and low-level peripherals.

My own learning route for microcontroller/processors was the following;
Seconday School (Ages 14-17): PBASIC for BASIC STAMP, Assembly for PIC16F84A,
University: Assembly for 68HC12, Cross Compiled C code for 68HC12.
Since then: Mainly cross compiled C for either ATMEGA or PIC devices.

Early on I was able to learn the basics of programming with decisions, assignment, iteration/repetition without having to worry about low level details.
Then later progressing on to an Assembly language with a very small instruction set and very few peripherals before moving on to a more complex microcontroller with a larger instruction set and having to configure the peripherals by looking at the datasheets.

None of these were nearly as complex as the processor on the Raspberry Pi, but they gave a gentle learning curve towards it.
If you throw someone in with the complexity of the Pi's instruction set and peripherals on day 1 they will sink and never come back again.
Computers are no longer as simple as the ZX80 was...
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 20494
Joined: Sat Jul 30, 2011 7:41 pm

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 2:59 pm

This is down to the teaching, not the libraries.

If you want to teach low level register stuff, you get your students to write the library itself. They can use the existing code as a example, replicate, modify etc. AFter all, a huge amount of SW engineering nowadays is looking at others code and fixing/modifying it.

If you want to teach GPIO concepts and driving other devices, then the libraries are fine.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Please direct all questions to the forum, I do not do support via PM.

User avatar
PeterO
Posts: 4243
Joined: Sun Jul 22, 2012 4:14 pm

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 3:11 pm

Q: What Does Hiding the Details of I/O in Library Calls Teach?
A: Abstraction.

PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),Aeromodelling,1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

jahboater
Posts: 2930
Joined: Wed Feb 04, 2015 6:38 pm

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 4:26 pm

The pigpio library web page contains many useful examples.

http://abyz.me.uk/rpi/pigpio/examples.h ... ted%20code

In particular, take a look at the "Minimal GPIO Access" which is a simple C program providing basic GPIO stuff - at the lowest level.

User avatar
Paeryn
Posts: 2146
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 4:50 pm

Z80 Refugee wrote:
Tue Jul 17, 2018 1:43 pm
What bothers me is that these student programmers really don't get to know anything about what they are doing, because they simply call up predefined libraries to do the "heavy lifting" of waggling GPIO pins, with no visibility of the code that is operating in the background.
...
That's what I'm worried about here. People are being spoon-fed by hiding the details inside libraries, and learning little or nothing other than to expect instant gratification.
By extension of your argument your student programmers shouldn't even have the luxury of an OS, after all an OS can be seen as essentially a set of predefined libraries that does all the heavy lifting of managing multiple tasks for multiple users concurrently, managing I/O, dealing all the hardware blocks etc.

Being able to use libraries is essential, it allows a programmer to concentrate on the task at hand without having to worry about how the system accomplishes it. Also it allows your program to be compiled for and run on totally different hardware that you have no knowledge about (so long as it provides the same libraries).
She who travels light — forgot something.

User avatar
Z80 Refugee
Posts: 358
Joined: Sun Feb 09, 2014 1:53 pm

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 4:59 pm

I'm completely happy with all those comments... if the programming were confined to a self-contained unit. As soon as it's not, you end up with the situation I was faced with: somebody who thinks they're a whizz kid programmer but has no knowledge of the fundamentals.

Yes, no problem with libraries etc etc, but at some point (not too late on) expose them to actually controlling a GPIO pin raw so they know what's in a library call.
Military and Automotive Electronics Design Engineer (retired)

For the best service: make your thread title properly descriptive, and put all relevant details in the first post (including links - don't make us search)!

jahboater
Posts: 2930
Joined: Wed Feb 04, 2015 6:38 pm

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 5:13 pm

Z80 Refugee wrote:
Tue Jul 17, 2018 4:59 pm
Yes, no problem with libraries etc etc, but at some point (not too late on) expose them to actually controlling a GPIO pin raw so they know what's in a library call.
Like this? Or do you mean "raw" to be assembler or even bare metal?

Code: Select all

*
   minimal_gpio.c
   2016-04-30
   Public Domain
*/

/*
   gcc -o minimal_gpio minimal_gpio.c
   sudo ./minimal_gpio
*/

#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>

static volatile uint32_t piModel = 1;

static volatile uint32_t piPeriphBase = 0x20000000;
static volatile uint32_t piBusAddr = 0x40000000;

#define SYST_BASE  (piPeriphBase + 0x003000)
#define DMA_BASE   (piPeriphBase + 0x007000)
#define CLK_BASE   (piPeriphBase + 0x101000)
#define GPIO_BASE  (piPeriphBase + 0x200000)
#define UART0_BASE (piPeriphBase + 0x201000)
#define PCM_BASE   (piPeriphBase + 0x203000)
#define SPI0_BASE  (piPeriphBase + 0x204000)
#define I2C0_BASE  (piPeriphBase + 0x205000)
#define PWM_BASE   (piPeriphBase + 0x20C000)
#define BSCS_BASE  (piPeriphBase + 0x214000)
#define UART1_BASE (piPeriphBase + 0x215000)
#define I2C1_BASE  (piPeriphBase + 0x804000)
#define I2C2_BASE  (piPeriphBase + 0x805000)
#define DMA15_BASE (piPeriphBase + 0xE05000)

#define DMA_LEN   0x1000 /* allow access to all channels */
#define CLK_LEN   0xA8
#define GPIO_LEN  0xB4
#define SYST_LEN  0x1C
#define PCM_LEN   0x24
#define PWM_LEN   0x28
#define I2C_LEN   0x1C
#define BSCS_LEN  0x40

#define GPSET0 7
#define GPSET1 8

#define GPCLR0 10
#define GPCLR1 11

#define GPLEV0 13
#define GPLEV1 14

#define GPPUD     37
#define GPPUDCLK0 38
#define GPPUDCLK1 39

#define SYST_CS  0
#define SYST_CLO 1
#define SYST_CHI 2

static volatile uint32_t  *gpioReg = MAP_FAILED;
static volatile uint32_t  *systReg = MAP_FAILED;
static volatile uint32_t  *bscsReg = MAP_FAILED;

#define PI_BANK (gpio>>5)
#define PI_BIT  (1<<(gpio&0x1F))

/* gpio modes. */

#define PI_INPUT  0
#define PI_OUTPUT 1
#define PI_ALT0   4
#define PI_ALT1   5
#define PI_ALT2   6
#define PI_ALT3   7
#define PI_ALT4   3
#define PI_ALT5   2

void gpioSetMode(unsigned gpio, unsigned mode)
{
   int reg, shift;

   reg   =  gpio/10;
   shift = (gpio%10) * 3;

   gpioReg[reg] = (gpioReg[reg] & ~(7<<shift)) | (mode<<shift);
}

int gpioGetMode(unsigned gpio)
{
   int reg, shift;

   reg   =  gpio/10;
   shift = (gpio%10) * 3;

   return (*(gpioReg + reg) >> shift) & 7;
}

/* Values for pull-ups/downs off, pull-down and pull-up. */

#define PI_PUD_OFF  0
#define PI_PUD_DOWN 1
#define PI_PUD_UP   2

void gpioSetPullUpDown(unsigned gpio, unsigned pud)
{
   *(gpioReg + GPPUD) = pud;

   usleep(20);

   *(gpioReg + GPPUDCLK0 + PI_BANK) = PI_BIT;

   usleep(20);
  
   *(gpioReg + GPPUD) = 0;

   *(gpioReg + GPPUDCLK0 + PI_BANK) = 0;
}

int gpioRead(unsigned gpio)
{
   if ((*(gpioReg + GPLEV0 + PI_BANK) & PI_BIT) != 0) return 1;
   else                                         return 0;
}

void gpioWrite(unsigned gpio, unsigned level)
{
   if (level == 0) *(gpioReg + GPCLR0 + PI_BANK) = PI_BIT;
   else            *(gpioReg + GPSET0 + PI_BANK) = PI_BIT;
}

void gpioTrigger(unsigned gpio, unsigned pulseLen, unsigned level)
{
   if (level == 0) *(gpioReg + GPCLR0 + PI_BANK) = PI_BIT;
   else            *(gpioReg + GPSET0 + PI_BANK) = PI_BIT;

   usleep(pulseLen);

   if (level != 0) *(gpioReg + GPCLR0 + PI_BANK) = PI_BIT;
   else            *(gpioReg + GPSET0 + PI_BANK) = PI_BIT;
}

/* Bit (1<<x) will be set if gpio x is high. */

uint32_t gpioReadBank1(void) { return (*(gpioReg + GPLEV0)); }
uint32_t gpioReadBank2(void) { return (*(gpioReg + GPLEV1)); }

/* To clear gpio x bit or in (1<<x). */

void gpioClearBank1(uint32_t bits) { *(gpioReg + GPCLR0) = bits; }
void gpioClearBank2(uint32_t bits) { *(gpioReg + GPCLR1) = bits; }

/* To set gpio x bit or in (1<<x). */

void gpioSetBank1(uint32_t bits) { *(gpioReg + GPSET0) = bits; }
void gpioSetBank2(uint32_t bits) { *(gpioReg + GPSET1) = bits; }

unsigned gpioHardwareRevision(void)
{
   static unsigned rev = 0;

   FILE * filp;
   char buf[512];
   char term;
   int chars=4; /* number of chars in revision string */

   if (rev) return rev;

   piModel = 0;

   filp = fopen ("/proc/cpuinfo", "r");

   if (filp != NULL)
   {
      while (fgets(buf, sizeof(buf), filp) != NULL)
      {
         if (piModel == 0)
         {
            if (!strncasecmp("model name", buf, 10))
            {
               if (strstr (buf, "ARMv6") != NULL)
               {
                  piModel = 1;
                  chars = 4;
                  piPeriphBase = 0x20000000;
                  piBusAddr = 0x40000000;
               }
               else if (strstr (buf, "ARMv7") != NULL)
               {
                  piModel = 2;
                  chars = 6;
                  piPeriphBase = 0x3F000000;
                  piBusAddr = 0xC0000000;
               }
               else if (strstr (buf, "ARMv8") != NULL)
               {
                  piModel = 2;
                  chars = 6;
                  piPeriphBase = 0x3F000000;
                  piBusAddr = 0xC0000000;
               }
            }
         }

         if (!strncasecmp("revision", buf, 8))
         {
            if (sscanf(buf+strlen(buf)-(chars+1),
               "%x%c", &rev, &term) == 2)
            {
               if (term != '\n') rev = 0;
            }
         }
      }

      fclose(filp);
   }
   return rev;
}

/* Returns the number of microseconds after system boot. Wraps around
   after 1 hour 11 minutes 35 seconds.
*/

uint32_t gpioTick(void) { return systReg[SYST_CLO]; }


/* Map in registers. */

static uint32_t * initMapMem(int fd, uint32_t addr, uint32_t len)
{
    return (uint32_t *) mmap(0, len,
       PROT_READ|PROT_WRITE|PROT_EXEC,
       MAP_SHARED|MAP_LOCKED,
       fd, addr);
}

int gpioInitialise(void)
{
   int fd;

   gpioHardwareRevision(); /* sets piModel, needed for peripherals address */

   fd = open("/dev/mem", O_RDWR | O_SYNC) ;

   if (fd < 0)
   {
      fprintf(stderr,
         "This program needs root privileges.  Try using sudo\n");
      return -1;
   }

   gpioReg  = initMapMem(fd, GPIO_BASE,  GPIO_LEN);
   systReg  = initMapMem(fd, SYST_BASE,  SYST_LEN);
   bscsReg  = initMapMem(fd, BSCS_BASE,  BSCS_LEN);

   close(fd);

   if ((gpioReg == MAP_FAILED) ||
       (systReg == MAP_FAILED) ||
       (bscsReg == MAP_FAILED))
   {
      fprintf(stderr,
         "Bad, mmap failed\n");
      return -1;
   }
   return 0;
}

main()
{
   int i;

   if (gpioInitialise() < 0) return 1;

   for (i=0; i<54; i++)
   {
      printf("gpio=%d tick=%u mode=%d level=%d\n",
         i, gpioTick(), gpioGetMode(i), gpioRead(i));
   }

   for (i=0; i<16; i++)
   {
      printf("reg=%d val=%8X\n",
         i, bscsReg[i]);
   }
}

User avatar
Paeryn
Posts: 2146
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 5:34 pm

Z80 Refugee wrote:
Tue Jul 17, 2018 4:59 pm
I'm completely happy with all those comments... if the programming were confined to a self-contained unit. As soon as it's not, you end up with the situation I was faced with: somebody who thinks they're a whizz kid programmer but has no knowledge of the fundamentals.

Yes, no problem with libraries etc etc, but at some point (not too late on) expose them to actually controlling a GPIO pin raw so they know what's in a library call.
That will teach them how to control a GPIO pin on (for example) the RPi, not necessarily how to control a GPIO pin on any random device so they need to know how to read hardware documentation as well so they are able to work to the particular hardware's implementation. Whilst we do need programmers that can deal with low-level implementations there are always going to be a lot that never go anywhere near low-level.
She who travels light — forgot something.

User avatar
bensimmo
Posts: 3222
Joined: Sun Dec 28, 2014 3:02 pm
Location: East Yorkshire

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 5:37 pm

It's also like saying why teach them Python, when you could teach them the lower level C to start with or why not just start with machine code.

It depends how you look at programming and what you want them to achieve.
In primary and secondary you are teaching them the language(s), sequence and logic and ability to make their own choices and use their imagination.

They are fully allowed to go further than that, but it will probably be University where they teach that sort of specific stuff if they have an interest in it.

hippy
Posts: 3786
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 5:48 pm

Z80 Refugee wrote:
Tue Jul 17, 2018 4:59 pm
Yes, no problem with libraries etc etc, but at some point (not too late on) expose them to actually controlling a GPIO pin raw so they know what's in a library call.
Why though?

I see the important thing being to provide people with the means of achieving what they want to achieve and if they want to go further then that is up to them.

I don't see that a programmer should understand or even care what a library is doing any more than a car mechanic should know how the jack they use to raise a vehicle actually works.

Should people writing web servers likewise have to understand the entire TCP/IP stack, NIC interfacing, and what's electrically going on at the link layer ? That is not information which is either useful nor important for the task they are actually undertaking.

I am one of those people who really does like to know how everything works behind the scenes and equally why. But I can understand not everyone else does; they want to know enough to get a job done and that's it, and that's fair enough. The main thing is to allow them to go further, dig deeper, if they wish.

That said I personally don't think anyone can truly call themselves a software engineer unless they have invented their own programming language, written a compiler for that, and have also designed their own CPU :mrgreen:

User avatar
Burngate
Posts: 5441
Joined: Thu Sep 29, 2011 4:34 pm
Location: Berkshire UK
Contact: Website

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 5:56 pm

Many years ago, I got taught a bit about computers & programming on an OU course using a teletype logged in to a remote mainframe.
That taught me some of the fundamentals, but nothing about what went on inside a computer, nor how that mainframe handled multiple users.
Getting and playing with a Windows box didn't help, and a Mac was even worse.
It wasn't until I bought a RISC PC that I got some inkling about the innards - the ARM is nice and simple compared with Intel etc. chips, and RISC-OS gives you a chance to see what's actually happening. Linux seems to me to be a step backwards in that respect, though is complicated enough to do useful stuff and open enough to be able to work out what's going on.

Somewhat earlier, I learnt to drive a car - which pedal did what, and how to avoid hitting too many things - but that level of knowledge wasn't enough when my diesel car ran its tank dry.
I now know enough about cars to be able to say Nikolaus August Otto should have been strangled at birth, and anything other than V6 is clunky.
But it took a lot of studying to get there.

Heater
Posts: 9840
Joined: Tue Jul 17, 2012 3:02 pm

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 7:26 pm

Z80 Refugee,
The software department fixed the problem by swapping out the defective unit.
That is ambiguous. Did they swap out your defective hardware or the defective software engineer?
As soon as it's not, you end up with the situation I was faced with: somebody who thinks they're a whizz kid programmer but has no knowledge of the fundamentals.
I first got the chance to program anything in 1972. In BASIC, using a teletype connected to a far away main frame. No low level details for me there. As useless as BASIC is it was a good first introduction to programming. Luckily we were also taught assembler during that course, only on a simulator though.

Luckily I was also into electronics and the new fangled digital logic as a hobby, so by the time Z80's and such arrived on the scene I was quite prepared for all that assembler bit twiddling and register bashing.

As for the Pi, it's not so simple anymore. This is about the simplest standalone example of access the GPIO pins on the Pi :

Code: Select all

//
//  How to access GPIO registers from C-code on the Raspberry-Pi
//  Example program
//  15-January-2012
//  Dom and Gert
//  Revised: 15-Feb-2013
 
 
// Access from ARM Running Linux
 
#define BCM2708_PERI_BASE        0x20000000
#define GPIO_BASE                (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
 
 
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
 
#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)
 
int  mem_fd;
void *gpio_map;
 
// I/O access
volatile unsigned *gpio;
 
 
// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
#define OUT_GPIO(g) *(gpio+((g)/10)) |=  (1<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
 
#define GPIO_SET *(gpio+7)  // sets   bits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0
 
#define GET_GPIO(g) (*(gpio+13)&(1<<g)) // 0 if LOW, (1<<g) if HIGH
 
#define GPIO_PULL *(gpio+37) // Pull up/pull down
#define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock
 
void setup_io();
 
void printButton(int g)
{
  if (GET_GPIO(g)) // !=0 <-> bit is 1 <- port is HIGH=3.3V
    printf("Button pressed!\n");
  else // port is LOW=0V
    printf("Button released!\n");
}
 
int main(int argc, char **argv)
{
  int g,rep;
 
  // Set up gpi pointer for direct register access
  setup_io();
 
  // Switch GPIO 7..11 to output mode
 
 /************************************************************************\
  * You are about to change the GPIO settings of your computer.          *
  * Mess this up and it will stop working!                               *
  * It might be a good idea to 'sync' before running this program        *
  * so at least you still have your code changes written to the SD-card! *
 \************************************************************************/
 
  // Set GPIO pins 7-11 to output
  for (g=7; g<=11; g++)
  {
    INP_GPIO(g); // must use INP_GPIO before we can use OUT_GPIO
    OUT_GPIO(g);
  }
 
  for (rep=0; rep<10; rep++)
  {
     for (g=7; g<=11; g++)
     {
       GPIO_SET = 1<<g;
       sleep(1);
     }
     for (g=7; g<=11; g++)
     {
       GPIO_CLR = 1<<g;
       sleep(1);
     }
  }
 
  return 0;
 
} // main
 
 
//
// Set up a memory regions to access GPIO
//
void setup_io()
{
   /* open /dev/mem */
   if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
      printf("can't open /dev/mem \n");
      exit(-1);
   }
 
   /* mmap GPIO */
   gpio_map = mmap(
      NULL,             //Any adddress in our space will do
      BLOCK_SIZE,       //Map length
      PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
      MAP_SHARED,       //Shared with other processes
      mem_fd,           //File to map
      GPIO_BASE         //Offset to GPIO peripheral
   );
 
   close(mem_fd); //No need to keep mem_fd open after mmap
 
   if (gpio_map == MAP_FAILED) {
      printf("mmap error %d\n", (int)gpio_map);//errno also set!
      exit(-1);
   }
 
   // Always use volatile pointer!
   gpio = (volatile unsigned *)gpio_map;
 
 
} // setup_io
That is a lot more than a few I/O instructions on a Z80. There are a lot of concepts in there to deal with, the C language for a start, macros, memory mapping etc.

Arguably that is far too much to stick in the face of a beginner to programming.

ejolson
Posts: 1898
Joined: Tue Mar 18, 2014 11:47 am

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 8:45 pm

bensimmo wrote:
Tue Jul 17, 2018 5:37 pm
It's also like saying why teach them Python, when you could teach them the lower level C to start with or why not just start with machine code.
The difficulty with frameworks and subroutine libraries is they tend to be so over engineered that they make simple things like toggling GPIO pins appear much more complicated than they really are.

There is both a natural and historical progression from machine code to higher level languages. Note that BBC Basic allowed inline assembler but Python does not. If the goal is to gain enough understanding for a student to use what he or she learned later in life, it is more important to build a solid foundation than to focus on the high-level and glamorous. While starting with applied differential equations in kindergarten is impressive, such an approach may not lead to as much useful competency in the long term as starting with counting and arithmetic.

You can teach about the foundations--memory addresses, registers, CPUs, data and input output devices--in an abstract way; however, these ideas become easier to understand when illustrated with a little bit of assembly language or C programming. An adult might find such languages boring and difficult. It is even more boring and difficult to memorize the definition of a memory address and reproduce it on a quiz. Moreover, as demonstrated by Simon's book, C is not difficult.

User avatar
Z80 Refugee
Posts: 358
Joined: Sun Feb 09, 2014 1:53 pm

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 11:00 pm

Heater wrote:
Tue Jul 17, 2018 7:26 pm
That is ambiguous. Did they swap out your defective hardware or the defective software engineer?
I can make a light flash without any help from software. The only light software can flash without help from hardware is a simulation of one.
Military and Automotive Electronics Design Engineer (retired)

For the best service: make your thread title properly descriptive, and put all relevant details in the first post (including links - don't make us search)!

User avatar
Z80 Refugee
Posts: 358
Joined: Sun Feb 09, 2014 1:53 pm

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Tue Jul 17, 2018 11:41 pm

Ok, memory mapping and address translation complicates things, but that aside: what makes the RPi I/O any worse than any other memory mapped hardware accessed with a bit of bitblitting? A library call to do the address mapping and maybe some initialisation would paper over the variability between RPi versions, but then surely some peeks and pokes would be enough? If not, there's something severely lacking (I'm not counting the special functions here, just the plain I/O).
Military and Automotive Electronics Design Engineer (retired)

For the best service: make your thread title properly descriptive, and put all relevant details in the first post (including links - don't make us search)!

User avatar
Paeryn
Posts: 2146
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Wed Jul 18, 2018 1:25 am

Z80 Refugee wrote:
Tue Jul 17, 2018 11:41 pm
Ok, memory mapping and address translation complicates things, but that aside: what makes the RPi I/O any worse than any other memory mapped hardware accessed with a bit of bitblitting? A library call to do the address mapping and maybe some initialisation would paper over the variability between RPi versions, but then surely some peeks and pokes would be enough? If not, there's something severely lacking (I'm not counting the special functions here, just the plain I/O).
So you've gone from "don't hide any details in library calls" to "let's hide most of the details in library calls". Since you've put the hardware specific (and/or complex) mapping and initialisation into a library (not forgetting arbitration - you don't want multiple processes trying to set the same registers where one is expecting the state to be how it set it whilst another has jumped in and changed things half way through) you might as well go the whole hog and put the actual I/O functions in there and have a complete library that can be used to abstract the whole process.

That's before you get to what happens if/when a subsequent RPi uses different hardware that doesn't work the same way?
Z80 Refugee wrote: What bothers me is that these student programmers really don't get to know anything about what they are doing, because they simply call up predefined libraries to do the "heavy lifting" of waggling GPIO pins, with no visibility of the code that is operating in the background.
If people want to learn how to talk directly to hardware they can, the libraries for doing so are practically all open-source, anyone can look to see how they work if they want or need to, it's not as if the libraries are black-boxes whose inner workings are behind NDAs (not counting some inner workings of the SoC like the hardware video encoders/decoders which are handled by the VC4 rather than the ARMs).

Yes we need programmers who can write low-level code for specific hardware but the majority don't need to do that, surely it's just as important that we have programmers who can write code today that will compile and work without needing re-writes when the underlying hardware changes.

For beginner programmers, get them used to using libraries so they aren't bogged down with specifics, when they are comfortable (and interested) move on to teaching the different ways such libraries (and hardware) work.
She who travels light — forgot something.

User avatar
Z80 Refugee
Posts: 358
Joined: Sun Feb 09, 2014 1:53 pm

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Wed Jul 18, 2018 8:07 am

Yes, OK, I'm feeling my way here. I have a gut feeling that if the RPi is trying to take the mystery out of how computers are made to do things, there is still a big mystery in how they are made to do (physical) things.

Yes, maybe the libraries are not locked away from view, but they are still in a dark corner where nobody would look of their own volition. A means to bring some illumination to it, in the same way that illumination has been applied to coding in general, would be a good thing. It would provide an opportunity to understand what's happening. If anybody's following my posts on this forum, I am trying to illuminate the principles of electronics (mostly people seem to throw circuits together and keep their fingers crossed - the same as they are doing with software, but in hardware it has consequences). I think the "you can't break it, fill your boots" experimental attitude to software may be encouraging too lax an approach to hardware.
Paeryn wrote:
Wed Jul 18, 2018 1:25 am
(not forgetting arbitration - you don't want multiple processes trying to set the same registers where one is expecting the state to be how it set it whilst another has jumped in and changed things half way through)
I had not considered arbitration up to now... how is it handled? If I ran two user processes both toggling the same IO pin, what would happen?
Paeryn wrote:
Wed Jul 18, 2018 1:25 am
That's before you get to what happens if/when a subsequent RPi uses different hardware that doesn't work the same way?
The student would learn a reality of programming life: you can't necessarily run the same code on a different version of the kit!
Paeryn wrote:
Wed Jul 18, 2018 1:25 am
For beginner programmers, get them used to using libraries so they aren't bogged down with specifics
I have no problem with that, and I didn't intend to suggested different. What I am after is greater visibility of what's going on under the bonnet without having to go and look for it. At the moment there is a message "coding is easy", when I would prefer a message "coding is easy... but here's the work that has been done for you already".
Paeryn wrote:
Wed Jul 18, 2018 1:25 am
when they are comfortable (and interested) move on to teaching the different ways such libraries (and hardware) work.
That implies there is somebody guiding their education. Is there not a significant population who are just picking up the RPi as a hobby, unguided by anyone? How will they have a light shone on it unless the signposts are in the examples they follow?

If a library import was well-commented source code rather than compiled code, the steps needed to view what is under the hood would be simply to open the library file for reading.
Military and Automotive Electronics Design Engineer (retired)

For the best service: make your thread title properly descriptive, and put all relevant details in the first post (including links - don't make us search)!

Heater
Posts: 9840
Joined: Tue Jul 17, 2012 3:02 pm

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Wed Jul 18, 2018 8:17 am

Z80 Refugee,
Ok, memory mapping and address translation complicates things, but that aside: what makes the RPi I/O any worse than any other memory mapped hardware accessed with a bit of bitblitting?
Many things...

Writing to an I/O port could be as simple as :

Code: Select all

    li  r1, 0x01      // Get immediate value 1 into a register
    st  r1, io_port   // Write to I'/O port
Toggling an I/O port could be as simple as:

Code: Select all

    ld  r1, io_port   // Read I'/O port
loop:
    xor r1, 0x01      // Invert lowest bit
    st  r1, io_port   // Write to I'/O port
    jmp loop          // Repeat
In some pseudo assembler language. That is substantially less code than the C example I posted above. It is trivial to understand given an hour or so study of assembler language.

As noted, this is a lot harder on the Pi running Raspbian because one has to do all that memory mapping stuff to even get access to the IO port. But there is more:

1) We don't know the execution time of our code.

Raspbian can quite likely suspend execution of our loop and get the processor to do something else. For an indeterminate amount of time. Many posts on this forum have been about this problem. Extra work is required to prevent such interruptions of our code.

We might even need to take into account the variable execution time caused by the processors cache memory access patterns.

2) We need to be sure we have root access to even get to that port. Many posts here are questions about that.

3) Other bits of the port may be used by other processes, we had better be sure that is not causing problems.

As you say, we can hide much of this complexity in libraries and kernel drivers etc, but then why not go the whole hog and just give the user a function to do the job "gpio_out(port_bit, state)" or whatever. Reduce it to pretty much the good old fashioned PEEK and POKE of BASIC days.

User avatar
bensimmo
Posts: 3222
Joined: Sun Dec 28, 2014 3:02 pm
Location: East Yorkshire

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Wed Jul 18, 2018 8:38 am

One thing to consider is that it's fine to say the Foundation should be opening people eyes to the lower level work (and yes it would be good for those interested or a higher level computer engineering course, I would love to see them).
Also methods on each specific protocol, i2c, SPI, UART, pwm etc
From an electronics interfacing point of view or reading the spec sheets and understanding registers to get data from it.
But there are only so many in the company who probably know how and they are probably the ones building the next Pi.
So they still concentrate their efforts on getting people started with the RaspberryPi or programming.

The MagPi or HackSpace magazine and even the HelloWprd Education one (this is quite a different read) is often where this techy stuff would end up, so email them. I'm sure they are always looking for articles for them. Or start a website with this tech detail in it :-)

You do have to remember that the people interested at school level, that would have any interest and not be zoned out, is very small.

I'm all for it though, they make you sit through languages and other boring stuff many do not wish or care for, so let's make everyone learn some more interesting electronics and low level computing.

B.Goode
Posts: 6451
Joined: Mon Sep 01, 2014 4:03 pm
Location: UK

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Wed Jul 18, 2018 9:30 am

If a library import was well-commented source code rather than compiled code, the steps needed to view what is under the hood would be simply to open the library file for reading.

Give or take the bit about "well-commented", isn't that the way that imported modules for use with Python work by default?

hippy
Posts: 3786
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: What Does Hiding the Details of I/O in Library Calls Teach?

Wed Jul 18, 2018 9:58 am

Z80 Refugee wrote:
Wed Jul 18, 2018 8:07 am
I have a gut feeling that if the RPi is trying to take the mystery out of how computers are made to do things, there is still a big mystery in how they are made to do (physical) things...

Is there not a significant population who are just picking up the RPi as a hobby, unguided by anyone? How will they have a light shone on it unless the signposts are in the examples they follow?
The disconnect seems to be between what the RPF and partners are providing for and what you think they should be providing for, what their goals are and what you believe they should be.

It's a lot like complaining driving instructors are not teaching car mechanics or vehicle engineering. That AstroPi and CubeSat ventures don't teach anyone about the problem of getting a payload up into space.

No, they don't. But that's not necessarily a problem.

Return to “General programming discussion”

Who is online

Users browsing this forum: No registered users and 1 guest