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.
- Z80 Refugee
- Posts: 358
- Joined: Sun Feb 09, 2014 1:53 pm
What Does Hiding the Details of I/O in Library Calls Teach?
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)!
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)!
Re: What Does Hiding the Details of I/O in Library Calls Teach?
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.The RPi is a teaching resource for programming, right?
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.
- The Traveler
- Posts: 403
- Joined: Sat Oct 21, 2017 3:48 pm
Re: What Does Hiding the Details of I/O in Library Calls Teach?
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.
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.
RPi interests: Coding an Infinite Improbability Drive. In C.
Old Assembler programmers don't die. They just disassemble.
Old Assembler programmers don't die. They just disassemble.
Re: What Does Hiding the Details of I/O in Library Calls Teach?
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.Z80 Refugee wrote: ↑Tue Jul 17, 2018 1:43 pm… People are being spoon-fed by hiding the details inside libraries
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.
Pronouns: he/him
Pronouns: he/him
Re: What Does Hiding the Details of I/O in Library Calls Teach?
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...
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
Pi Interests: Home Automation, IOT, Python and Tkinter
Re: What Does Hiding the Details of I/O in Library Calls Teach?
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.
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.
Contrary to popular belief, humorous signatures are allowed.
I've been saying "Mucho" to my Spanish friend a lot more lately. It means a lot to him.
Contrary to popular belief, humorous signatures are allowed.
I've been saying "Mucho" to my Spanish friend a lot more lately. It means a lot to him.
Re: What Does Hiding the Details of I/O in Library Calls Teach?
Q: What Does Hiding the Details of I/O in Library Calls Teach?
A: Abstraction.
PeterO
A: Abstraction.
PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson
Re: What Does Hiding the Details of I/O in Library Calls Teach?
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.
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.
Re: What Does Hiding the Details of I/O in Library Calls Teach?
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.Z80 Refugee wrote: ↑Tue Jul 17, 2018 1:43 pmWhat 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.
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.
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!
- 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?
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.
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)!
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)!
Re: What Does Hiding the Details of I/O in Library Calls Teach?
Like this? Or do you mean "raw" to be assembler or even bare metal?Z80 Refugee wrote: ↑Tue Jul 17, 2018 4:59 pmYes, 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.
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]);
}
}
Re: What Does Hiding the Details of I/O in Library Calls Teach?
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.Z80 Refugee wrote: ↑Tue Jul 17, 2018 4:59 pmI'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.
She who travels light — forgot something.
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!
Re: What Does Hiding the Details of I/O in Library Calls Teach?
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.
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.
Re: What Does Hiding the Details of I/O in Library Calls Teach?
Why though?Z80 Refugee wrote: ↑Tue Jul 17, 2018 4:59 pmYes, 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.
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

- Burngate
- Posts: 6401
- Joined: Thu Sep 29, 2011 4:34 pm
- Location: Berkshire UK Tralfamadore
- Contact: Website
Re: What Does Hiding the Details of I/O in Library Calls Teach?
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.
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.
Re: What Does Hiding the Details of I/O in Library Calls Teach?
Z80 Refugee,
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 :
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.
That is ambiguous. Did they swap out your defective hardware or the defective software engineer?The software department fixed the problem by swapping out the defective unit.
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.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.
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
Arguably that is far too much to stick in the face of a beginner to programming.
Memory in C++ is a leaky abstraction .
Re: What Does Hiding the Details of I/O in Library Calls Teach?
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.
- 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?
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)!
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)!
- 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?
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)!
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)!
Re: What Does Hiding the Details of I/O in Library Calls Teach?
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.Z80 Refugee wrote: ↑Tue Jul 17, 2018 11:41 pmOk, 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).
That's before you get to what happens if/when a subsequent RPi uses different hardware that doesn't work the same way?
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).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.
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.
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!
- 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?
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.
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.
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.
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?
The student would learn a reality of programming life: you can't necessarily run the same code on a different version of the kit!
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".
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)!
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)!
Re: What Does Hiding the Details of I/O in Library Calls Teach?
Z80 Refugee,
Writing to an I/O port could be as simple as :
Toggling an I/O port could be as simple as:
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.
Many things...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?
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
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
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.
Memory in C++ is a leaky abstraction .
Re: What Does Hiding the Details of I/O in Library Calls Teach?
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.
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.
Re: What Does Hiding the Details of I/O in Library Calls Teach?
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?
Re: What Does Hiding the Details of I/O in Library Calls Teach?
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.Z80 Refugee wrote: ↑Wed Jul 18, 2018 8:07 amI 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?
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.