Confusion between Arduino and PIC, Which one is better for learning?

bogosort

Joined Sep 24, 2011
696
Unfortunately web programming and hardware level programming have nothing to do with each other.
There is of course a sense in which it is true that embedded programming and web development are vastly different domains, but there is also a very important sense in which both are similar: solving problems algorithmically using logic. Yes, domain-specific knowledge is often essential to solving specific types of problems, but programming itself is a systematic, generalized method of problem solving.

Fundamentally, programming is about learning how to break down big problems into little problems that can be solved with a handful of computational instructions, organized in such a way that the desired result is achieved. The logic of this organization -- looping, conditional branching, etc. -- is the same whether you are banging UART bits or dynamically updating CSS style directives. Effective programming goes further, recognizing that different organizational approaches can lead to code with vastly different performance, maintainability, and reliability properties. Perhaps ironically, I've noticed that web developers tend to be far more attuned than embedded developers to these design considerations and principles. This is probably because all of the abstraction in the web world (which embedded types tend to scoff at) comes with a steep price in code complexity, and so software architecture and management is a more pressing concern for web devs.
 

geekoftheweek

Joined Oct 6, 2013
1,429
Assembly languages are not machine code.
Assembly languages are textual representations of the actual processor instructions that all other languages get converted into when the program is compiled.

C gets converted into the very same instructions, but it all happens behind the scenes.

If you look at the hex or binary of any compiled program and decompile it what you will end up with is an assembly language file containing the instructions specific to the processor. Arduino, PIC, STM, Intel, AMD, you name it.
 
Last edited:

nsaspook

Joined Aug 27, 2009
16,436
People are making a false equivalence between assembly languages and the "byte level" hardware knowledge required for effective embedded programming. Embedded programming is all about interfacing with peripherals, which requires a solid understanding of bus protocols, data formats, and peripherals at the register level. Assembly language not required. On the processor side, we need to understand its memory interface, how pins are addressed, how interrupts are handled, etc. We learn all this stuff by reading datasheets, not by learning an assembly language.

Knowing an assembly language is neither necessary nor sufficient for being an effective embedded programmer.

When I was in school we had to design our own 8-instruction single-cycle processor, with datapath and ALU, implement a toy assembly language for it, and then write a program in it to do some simple task like calculate Fibonacci numbers. Great way to really get a sense of how a CPU works, but definitely not the only way.
I'm not making a false equivalence between assembly languages and the "byte level" hardware knowledge. I also designed my own 16 instruction single-cycle processor in school from the SAP instructional series. Saying Knowing an assembly language is neither necessary nor sufficient for being an effective embedded programmer is true but being a better embedded programmer is really the rational. That's why assembly is still a formal training course.
Course syllabus for ICS312

https://henricasanova.github.io/ics312_spring2021/morea/GettingStarted/ics312_intro.pdf
 
Last edited:

nsaspook

Joined Aug 27, 2009
16,436
Assembly languages are not machine code.
You're far to smart to take those words literally. I'm also not advocating coding in assembly. I am advocating learning how the machine runs machine code. As a learning step to being a better embedded programmer it's a wise step IMO to have those types for programming patterns in your mental picture of the task.

What can I say, I'm a hardware guy since birth that needs to programming skills for X hardware engineering task and mainly sees programming as a necessary evil for the task instead of a vocation.
 
Last edited:

bogosort

Joined Sep 24, 2011
696
Assembly languages are textual representations of the actual processor instructions that all other languages get converted into when the program is compiled.

C gets converted into the very same instructions, but it all happens behind the scenes.

If you look at the hex or binary of any compiled program and decompile it what you will end up with is an assembly language file containing the instructions specific to the processor. Arduino, PIC, STM, Intel, AMD, you name it.
Assembly languages are "high-level" compared to the machine code they assemble to. It's not just being able to use mnemonics instead of numbers, all modern assembly languages have high-level abstractions and conveniences like symbolic identifiers, addressing shortcuts, flexible number representations, and macros. If what you claim were true, then there would necessarily be a one-to-one mapping between any assembly program and the assembled machine code. But that's clearly not the case -- you can produce the same x86 machine code using gas or nasm, but the two assembly programs won't look anything alike.
 

bogosort

Joined Sep 24, 2011
696
Saying Knowing an assembly language is neither necessary nor sufficient for being an effective embedded programmer is true but being a better embedded programmer is really the rational. That's why assembly is still a formal training course.
I'm just saying that people are overrating the value of assembly. I'm definitively not saying that learning assembly is valueless.
 

geekoftheweek

Joined Oct 6, 2013
1,429
Assembly languages are "high-level" compared to the machine code they assemble to. It's not just being able to use mnemonics instead of numbers, all modern assembly languages have high-level abstractions and conveniences like symbolic identifiers, addressing shortcuts, flexible number representations, and macros. If what you claim were true, then there would necessarily be a one-to-one mapping between any assembly program and the assembled machine code. But that's clearly not the case -- you can produce the same x86 machine code using gas or nasm, but the two assembly programs won't look anything alike.
But the assembly programs are the actual processor instructions that are included in every microcontroller, processor, or whatever's datasheet that are used when programming in assembly language. It doesn't matter if nasm and gas produce the exact same code. What makes it machine code is the fact it is the actual instructions the processor uses which are the same instructions used to write assembly programs. PC's have lots more going on system wise that a microcontroller ever will and that will account for huge variations between C, gas, nasm, and the final result.

https://en.wikipedia.org/wiki/X86_instruction_listings -- this is what C, PHP, PERL, Java, BASIC, and so and and so on boil down to. The same thing used in assembly
 
Last edited:

nsaspook

Joined Aug 27, 2009
16,436
I'm just saying that people are overrating the value of assembly. I'm definitively not saying that learning assembly is valueless.
I'm saying it's valuable as a skill in the domain of embedded projects when things break, crash and burn. That debugger asm listing is going to drop you in a world hurt without some idea of assembly that you can use to grok the specific machine ops quickly.
 

Wolframore

Joined Jan 21, 2019
2,619
ok can we get back to the subject? A beginner would benefit from getting their feet wet using an Arduino. The reason why is because most of the difficult and challenging things are done for you. All you have to do it use their version of C to get something to blink... etc. You should dig deeper if you want to learn more.
 

MrChips

Joined Oct 2, 2009
35,020
Here is a specific example of how knowing asm helped.

I recently completed a job that required interfacing STM32 MCU with nRF24L01+ over SPI.

All of the code, including libraries is written in C. Presumably, the programmer does not need to know anything about asm.
The libraries failed to work and was transferring wrong data. The issue became evident after examining the disassembled code. Some parts of the C code was generating asm code that transferred 2 bytes while others were transferring 1 byte. Along with that, byte ordering was messed up. Knowing these two issues I was able to work around the problem by rewriting the libraries so that I could transfer exactly the number of bytes and byte order required. I did not have to write in assembler. I needed to have enough knowledge to know that the asm code was transferring the incorrect number of bytes.

That's an example of what an embedded engineer has to be capable of doing.
 

bogosort

Joined Sep 24, 2011
696
But the assembly programs are the actual processor instructions . . .
This is not true. For one thing, assemblers recognize pseudo-instructions like MOV, which are typically translated into two or more actual machine instructions. For another thing, assembly languages provide all kinds of syntactic sugar that are not directly translatable to machine code.

The point is that assembly languages, like C, provide a level of abstraction over the hardware. No one is denying that C provides a higher level of abstraction, but we shouldn't pretend that assembly languages don't provide their own abstractions. Machine code is completely unabstracted, necessarily so, as that is where the rubber meets the road.
 

geekoftheweek

Joined Oct 6, 2013
1,429
This is not true. For one thing, assemblers recognize pseudo-instructions like MOV, which are typically translated into two or more actual machine instructions. For another thing, assembly languages provide all kinds of syntactic sugar that are not directly translatable to machine code.
I have to confess I don't know much about say the x86 family and won't argue there is some conveniences in certain assemblers.
I can say every PIC program I've written has always been byte for byte exactly how I wrote it with macros expanded as expected, where expected, and everything else. I always define my own memory pointers, but even if I didn't the actual instruction part of the hex file would be the same byte for byte.
 

djsfantasi

Joined Apr 11, 2010
9,237
That's an example of what an embedded engineer has to be capable of doing.
Totally agree in that case... Having that level of understanding comes from experience. But you cannot expect a beginner to have that level of understanding. It comes from experience.

When I was a beginner, I learned FORTRAN first, on a 4K IBM 1130. And after one FORTRAN course, I wrote a program that could recognize basic 3D objects from a scan. I minimized memory so I could fit the scans and code in 4K. Without understanding assembly.

After that, I wrote my first assembly terminal emulator without training.

I’d lay a wager I could solve the same problem which you faced. With no assembly training. And I started with an ancient 3rd generation language.

I’m trying not to be argumentative. There are many paths to the same destination. That is my ONLY point.

This is likely (no promises) my last post on this thread. I see at least three different viewpoints and no understanding between them. So, we’ve devolved into argument rather than information.
 

geekoftheweek

Joined Oct 6, 2013
1,429
I'll stop here. @bogosort put some holes in long standing assumptions gained while trying to write my own OS years ago. I could get everything to work fine in 16 bit mode, but struggled to get 32 bit mode to work without faulting and resetting. Once that hurdle was crossed I found it really wasn't worth going further due to just how much work was involved to get basic stuff working. All in assembly.

The comparison between web programming and hardware programming sucked me in. The same in some ways (logic, structure, and general programming), but in terms of actual relevance to a microcontroller I thought it was weak.

PICs as well as others are a different story altogether.

Good luck all
 

bogosort

Joined Sep 24, 2011
696
The libraries failed to work and was transferring wrong data. The issue became evident after examining the disassembled code. Some parts of the C code was generating asm code that transferred 2 bytes while others were transferring 1 byte. Along with that, byte ordering was messed up. Knowing these two issues I was able to work around the problem by rewriting the libraries so that I could transfer exactly the number of bytes and byte order required. I did not have to write in assembler. I needed to have enough knowledge to know that the asm code was transferring the incorrect number of bytes.

That's an example of what an embedded engineer has to be capable of doing.
I'd argue that decompiling the code is an inefficient method of troubleshooting that issue. Probing the SPI bus would have revealed that an incorrect number of bytes were being transferred. Inspecting the C code itself would have also revealed the problem.
 

nsaspook

Joined Aug 27, 2009
16,436
I'd argue that decompiling the code is an inefficient method of troubleshooting that issue. Probing the SPI bus would have revealed that an incorrect number of bytes were being transferred. Inspecting the C code itself would have also revealed the problem.
It would be inefficient to decompile the entire code body randomly looking for the bug but that's seldom necessary because you can usually pinpoint the likely buggy sections quickly by hardware, memory or register interface transactions that correspond to C function calls or code.

It's only inefficient if you lack the knowledge and background to quickly understand the narrow scope of possible SPI related machine code sequences on the programming screen and then use that information to create the correct C coded sequencing.

'What is normal for the spider is chaos for the fly.'
 

bogosort

Joined Sep 24, 2011
696
It would be inefficient to decompile the entire code body randomly looking for the bug but that's seldom necessary because you can usually pinpoint the likely buggy sections quickly by hardware, memory or register interface transactions that correspond to C function calls or code.
If I'm writing the code to interface with a peripheral using an SPI library, and the peripheral doesn't seem to be responding, the first thing I'm doing is looking at what's going out the bus. Upon seeing incorrect behavior, I'd look at the library code (not the dissassembled output) and find the logic bug. I'd then curse myself for using an unvetted library and move on.

I suspect that's how most embedded programmers troubleshoot such things, which are bugs in logic, not hardware. And the logic -- whether written in C or assembly -- is the same either way. And the nice thing about debugging in C rather than assembly is that debugging C is a transferable skillset that's equally efficient on any architecture.
 

nsaspook

Joined Aug 27, 2009
16,436
If I'm writing the code to interface with a peripheral using an SPI library, and the peripheral doesn't seem to be responding, the first thing I'm doing is looking at what's going out the bus. Upon seeing incorrect behavior, I'd look at the library code (not the dissassembled output) and find the logic bug. I'd then curse myself for using an unvetted library and move on.

I suspect that's how most embedded programmers troubleshoot such things, which are bugs in logic, not hardware. And the logic -- whether written in C or assembly -- is the same either way. And the nice thing about debugging in C rather than assembly is that debugging C is a transferable skillset that's equally efficient on any architecture.
We all have our own ways of doing things.

If you're in the flow it's easy.
flow2.png
 
Last edited:

MrChips

Joined Oct 2, 2009
35,020
Let me see if I can explain this further.

The bug was neither in the C code library nor in the SPI hardware. The bug was in how the compiler converted from C to assembler. The fault was not the compiler either. The library was already vetted on another system. The fault was migrating from one machine to another. Some machine instructions transfer single bytes while others are fetching double bytes. Scoping the SPI would not have shed any light on the problem. I found the issue only by examining the disassembly code. Believe me, I have over 50 years experience in trouble shooting HW/SW embedded systems and I cannot think of any other way I would have unraveled this bug other than by the investigative probing that I did.
 

bogosort

Joined Sep 24, 2011
696
Let me see if I can explain this further.

The bug was neither in the C code library nor in the SPI hardware. The bug was in how the compiler converted from C to assembler. The fault was not the compiler either. The library was already vetted on another system. The fault was migrating from one machine to another. Some machine instructions transfer single bytes while others are fetching double bytes. Scoping the SPI would not have shed any light on the problem. I found the issue only by examining the disassembly code. Believe me, I have over 50 years experience in trouble shooting HW/SW embedded systems and I cannot think of any other way I would have unraveled this bug other than by the investigative probing that I did.
This was an extraordinary bug and so I'm intrigued! How was the hardware interfaced to the processor, was it memory-mapped? What system call did the library use to write the byte(s)? What data type? If the extra byte didn't get on to the bus, where did it go? Please provide more info as this sounds like a fascinating case study.
 
Top