 Just gonna get going here in a couple minutes, so sit tight. Make sure all the streams are streaming. Say hi to folks as they drop in. Oh, and I remembered I didn't. Restream chats. Offscreen here. Hope everybody's having a good Friday. Or if you're watching this later, thank you. And I hope you're having a good weekend. Tum, tum, tum. Tum, tum, tum, tum. Hi, DVD. Welcome, welcome, welcome. Hopefully my voice is better than last week. Hello, Biada. Hello, The Guide. We'll get started in just a little bit here. Hi, Sam on Discord. Hello, Tim. If folks on YouTube want to join our Discord server, you can go to the URL adafru.it slash discord. The advantage of that is that it sticks around all the time. We can have a great time all week long, not just when we're streaming here. Happy Friday, sunny Friday. Although you can't see the bird poop on my window. I came in one day and I was like, oh, a bird hit my window. I'll have to figure out how to clean it. Hi, Yonderbox. Welcome, welcome, welcome. Some new names. That's awesome. Okay, well, let's get started. Oh, and you know what? I think DCD is gone today. Thank you, let me know. So no time codes today. Although I may be all, if they're major things, I'll go back and add them. Okay, so let's get started. Hello, everyone. Welcome if you're new here. If you're not, thanks for coming back. Hello, Dharma42, stoked to be here. Welcome. So my name is Scott. I work on circuit Python for Adafruit. Circuit Python is an open source version of Python designed for little tiny computers called microcontrollers. This one is Raspberry Pi Pico. But this is the headers version, where the headers come installed for you. And the SWD ports brought out differently, which I think we might use today. So this is an example. This chip here is 133 megahertz. Has a 256K RAM. A little tiny chip that has a whole computer inside of it. All for like 50 cents a chip. This board is like six bucks-ish. So it's really easy to get into. It's great to get started with. Adafruit, the folks that pay me the channel you're watching. They are an open source software and hardware company based out of New York City. I work remotely. I'm in Seattle for them. They also make development boards. This one's called the Clue. And this one's just packed with sensors and a screen and all that. And then the microcontroller on here is under this metal canister there. So that's a little bit about me. If you want to support me, you like this stream. You like the hardware that we make. You can go to Adafruit.com and purchase stuff there. As I said a little bit before, there's two chats on the side here. I was getting it wrong. One is the Discord server, which is our chat server that is around all the time. So people can hang out all week. You can get help with all sorts of different things. And it's well-moderated, so all that. To join to the Discord, you can go to the URL, adafru.id-discord. And we also have the YouTube chat down here. Right here. I'm happy to see folks in there as well. So this is a deep dive. I do it pretty much every Friday here at 2 p.m. Pacific for two hours usually, two to four. Next week I will not be here, but Foamy Guy is going to fill in for me. So there will be a deep dive next week, but it won't be me. I will be in Portland if all goes well. I've taken a long weekend with the fam down in Portland. And yeah. So deep dives are really just whatever I'm working on, whatever I'm interested in, has to do with CircuitPython, has to do with Embedded. And I'm happy, happy, happy to take questions. So if you have questions about Embedded, CircuitPython, all sorts of things, feel free to drop them in the chat whenever. We've had lots of good tangents that have come, kind of brain-dumped what I know about things and really hopefully taught some people some stuff. So if you have questions, feel free to drop them there. A couple of folks I didn't say hello to yet. Dharma42 is on the Discord. Fede2 says hi from Costa Rica. Hamzlabs says hi, Scott. It was cloudy here in Buffalo for the eclipse. At least I got to see the one in 2017 under clear skies. Nice. I saw the 2017 one, but I was not in totality here in Seattle. But I did go outside and look at all the funny-shaped shadows. That's the thing that I remember the most about it. And Tyeth says hello. Hey, all. Hi, Dexter. So happy to take questions, like I said. My plan here is to, so I'm in a little bit of a lame duck period because I'm going to be gone on Friday next week, and then I'm going to a conference all next week that is here in Seattle. It's the Zephyr Development Summit slash the Embedded Open Source Software Summit. Hey, that's a good idea, Tyeth. Pretty QR code. I trust that that's correct. So I won't be doing a whole lot of work on CircuitPython next week, and I've wrapped up the USB host work on the Max 3421. That's checked in. That'll go out in the next 911 beta. I assume it's going to be a beta. Dan's been doing pretty much all the releasing. So that'll be out with that. I got it working on Espressif and Raspberry Pi and SAMD. The thing I think that we did last week on the stream where we refactored it was the way to go. It really helped. That was kind of what got me over the hump and got it working. That's checked in. I had this few days where I didn't have a lot to do. The next thing that's on my list or my radar is BLE support on the ESP32 S3 in particular, but I think the C1s will come with that as well. But that's a huge piece of work. So that's kind of something I got to start the whole week with and just really get my brain into there. So I had a few days, I didn't want to do it before I go off to this conference, and having something kind of like lower priority if I have some downtime during the conference will be nice too. So what I've been working on is if folks don't know that I've had this desire to get CircuitPython building with Clang. So Clang is a C compiler that it's C-Lang, Clang. It's a C compiler that is part of the larger LLVM project. So the LLVM project originated with Apple, I think. And it was really to create a compiler tool kit, compiler creation tool kit that was more liberally licensed so it's not a GPL licensed piece of software. And the reason that big companies like Apple have interest in that is because big companies are a little scared of the GPL because they want to be able to protect some code and keep it private. So you get a lot of big players working in the LLVM space, including Google. I was there a decade ago now, which is kind of weird to me. I'm not just fresh out of Google, but there was a process where they switched from GCC to Clang and one of the early reasons to move to Clang is that the error messages were better. So Clang is part of this LLVM project and there's a lot of tooling that is built on top of that as well. So one of them is Clang D, which is a language server for C. And I guess maybe I'll start there. Language servers were kind of introduced by VS Code, I think, but it's a standard protocol for getting autocomplete information from a separate server so that an editor can use it. So I've been playing around with some of that stuff. And so there's so much really good tooling in the LLVM ecosystem that I'd really like to get CircuitPython, not building everything in Clang, because the thing that's prevented me from switching ages ago, I've tracked it for years, actually. If you look in my abandoned branches on GitHub, you'll see that every major version of Clang, I kind of want to see where it's at. And it really doesn't match RMGCC's code size. So code size is like a critical thing, especially on the SAMD21 port. And frankly, if the code size is bigger, we can't switch to it. But I really would want to migrate that way. And I think I've mentioned before, I've actually dabbled in modifying Clang to work better for us, in particular for marking code that needs to run when Flash is unavailable and doing that smarter than everyone does it now. And so I really would like to at least have CircuitPython kind of maintain its ability to be built under Clang, even if we don't fully switch to it. So I have this goal of mine that I set myself to switch the RP2040 or make at least the RP2040 port built with Clang. And the reason that that's a better target than the SAMD is that it's not as critical for code size. So code size is not as critical, so we have a little bit more room to play. So that's why the RP2040 is more interesting than the SAMD. And then we're not doing a lot of work on the SAMD now either. So I've got this embedded build branch. I showed this on Show and Tell, but I'm actually going to merge it with my Clang 18 branch too. Where do I want to start? Any questions about that? Fede too posted pictures of a partial eclipse. Could you tell with the shadows that it was that shape? So maybe I should show... I set up my... Oh, desktop. I've set up Sublime Text to work better for me. And if you've been watching this stream, you know I've been having this cursor bug, and it's fixed. Somebody fixed... Oh yeah, Sam, you're going to be excited. So I found somebody... I poked somebody enough on the Kwin side. So Kwin is the window manager compositor for KDE, which is what I use here. And I poked to the right person or dumped it in the right chat that somebody... And it turns out there is actually a Kwin bug where GTK... The translation between Qt and GTK is causing some issues. So there's this fix that somebody did. Vlad, Serojny, a Kwin developer fixed this bug for me. And I've actually patched it. So I have... I'm running a patched version of Kwin. But it fixes the Sublime Text issue I've been seeing, and it actually does impact other apps like Firefox as well. So it's very cool. It's just like this one thing that was moved from one location to another. But it fixes the issue. It's been awesome. So thanks to Vlad for fixing that bug for me. I don't know... I don't think it's been released yet because it was just merged in. So I'm patching it right now. It's like obviously not a huge change. So I just have a patched version of the package build that Arch builds for me. So yeah, if you see... I won't have that cursor bug anymore, which is great. I'm also now getting smarter help from the compiler or from ClangD. So you can see here that it's doing analysis saying, hey, frozen mod is not used directly. And that's coming from ClangD here. So this is kind of in the ecosystem of LLVM. ClangD is what's known as a language server, I think. ClangD is giving sublime text this information about this file. And I should just quickly go into how I have that set up. So that's cool. But what's even cooler is that I've turned on this thing where it's called inlay hints. So I don't actually have this size colon written in my code. But I can have ClangD emit these into sublime text so it labels all the parameters. Sometimes you'll see in C code that people will add comments, especially if there's a lot of different things. But you can have it automatically do it for you. And that's amazing and awesome. So that's been really cool. And I'll show how I... One thing I had to do to get that working in just a minute. Yeah, these hints are cool. They are not on by default. So I did have to change the language server settings for that. But I was thinking back to working in Bordenit where I'm initializing an e-ink display. And it's like 20 different parameters. And it gets really hard as the types get mixed. So that's cool. So this is auto analysis of imports. And you can see, oh, this import is used for these things. Now, there's one huge caveat. And that's that all of these analytics are done for specific board that you were building. So these analytics happen after all of the preprocessing is done. So that's why you see an underscore here, but not here. It's like whatever board I was building wasn't using Wi-Fi, for example. So you kind of have to be aware of the boundaries of what this stuff is knowing. But then the other thing that I've got is I also set up co-pilot. So this thing that popped up on the left here is GitHub co-pilot, which is like the AI code assistant thing. And because I do a bunch of open source stuff, they give me access for free, which is cool. So I didn't have to pay for it. And I have actually been using it a bit. It is quite nice for small. I'm using it as a fancy or auto-complete, but I am finding it somewhat helpful. So you'll see that. Not only a bit of a start to know. When the max, which is very little here, was very cloudy. Okay. Mark says we had cloud here, but lighten up. I can still see it pretty clearly. I got surprisingly clear video with eclipse glasses over my iPhone 15. Nice. Fed A2 says I did forget to do a Memento times lab. So my bad. Hits are very cool. Very readable. Ty says, now that's a feature I need needed and reminding about, and particularly really what it's called. VS Code for some languages, but not all, but never remember it was there. It's called inlay. Inlay hinting, I think is what it's called. Inlay. Inlay hints. Yeah. And I actually like, I was looking at sea lion. It's been a good week for my supply and text uses. That bug got fixed. And now like I figured it out a bit better how I want to use it. But yeah. So they're called inlay hints. And they do need to be turned on. Let's see what ClangD says it is. Teach your editor C plus plus. ClangD understands your C plus plus code and adds smart features to your editor. Code completion, compile errors, go to definition and more. It is a language server that can work with many editors via a plugin. Yeah. The inlay hints were like quite nice. The copilot stuff is pretty cool too. So to get this working in circuit Python, it needs to have this compile commands JSON. And that is, it's tricky to get. I'm here. I was building an atmos samd board. I don't know where the board name is. But it's this file that basically captures all of the different things that the commands that were run to do a build. So this is for atmos samd. Let's just reset it up. Ports raspberry pi. Because I want to do some rp2040 stuff. So I'm actually going to remove compile commands. And then there's this tool called bear. And bear capture, like it sniffs whatever make is doing something like that. So, oh, you do have to do clean. I was doing the DVI one for the 20 for the USB host stuff. But then there's this bear program that you can run. You have to do a clean because it only will capture the commands that were actually run. So if you have it cleaned, you won't get all their commands. Luckily, like doing a full build is real quick. Anyway, and then I think I do have to like close my editor to get that. So I'm just going to close sublime. Yeah, bear. Once I figured out how bear worked and worked, I didn't realize that you gave bear the like the make command. At first I was actually like trying to add bear in front of every compile statement. So I was having to modify make files. But this actually works a lot better. It actually works, which is great. Okay, so now if we open sublime text back up and I don't know how we can test it. It's annotated everything again. So it is running. And then if I look at compile commands, it's now doing pico stuff. So yeah, what may happen is that you may find that like you wander off the files that you taught it how to compile. So let's see if we do like we switched to Raspberry Pi, but what if we open a sandy file, like sandy background. See it has all these warnings because it doesn't know. It doesn't know enough to help me out. Like there's a few things that were compiled before that it does know about. But see here, you can see like this one got labeled, but these others didn't get labeled. So there's like there is a limitation to it because it is a board mismatch. There's not a good way to handle this. I googled it briefly and couldn't certain looked for it briefly to figure out how to do that. So that's really cool. So this is kind of part of my motivation to get us at least building in the Clang world. So I want to let's see where we are at building with Clang. It'll be overwritten by OK. Or maybe let me fix this thing first. So one of the really good commit message. I'm known for my good commit messages. Okay, and it's asking me for my PGP key. So I'm just going to go off them. Sorry, I'm just I'm unlocking my password manager for getting my GPG key. I got to fix that. I could set it up to sign my commits with scratch X and scratch Y memory regions. Four kilobytes each. What are they used for? I think I forget which order they're in. We set aside the higher one for PIO USB and the DVI stuff. One way you could look is in here. But the memory map file is the place to look. So RP 2040, that's the one we just built. Now if we look for a scratch. Okay, so Y becomes before X in this case. So scratch Y here has a dummy stack in it. It doesn't have anything else. So that's where a circuit by the most artist stack. And then scratch X. Oh, neither of them have anything in them. Yeah, I don't think for this build they don't have anything. Let's build a DVI. But yeah, generally there's a few. There's some code that needs to run for DVI output. And we'll kind of copy that in the scratch Y so that it can be fixed there. Oh, you know what? I fixed this. What am I based on? I should be based. Yeah, I don't need that anymore. There's my block commit. Yeah, generally the second core has its separate stack as well. So I think in scratch Y, that's where we put it. So one of them is kind of used for a circuit by them. One of them is used for the second core code if we have it. Yeah, so here scratch X now is this big. So it's got TMDS, which is like the lower level encoding for DVI. It has data and functions in there for that. And then scratch Y is empty still. Maybe the PIO USB stuff doesn't go there. But yeah, sometimes it's used for the DVI stuff. Okay, so I wanted to switch to Clang 18. And I actually, I'm going to do the same rebase and try to get this up to date as well. And I wanted to get this switched. When did I split these off? Get rebase abort. Yeah, I know. Get log. I thought I did that. I thought I split them apart. Or maybe it's a different Clang 18 branch. This is a ref log. So this is, did I do it on my laptop? I thought I did split them apart. No, this is also trying to haunt you. So I was, I had started, what computer was I on? It might have been my laptop. Let me get my laptop. I do this sometimes. I do work, but I forget to push it. I haven't done my anti-static stuff yet. So I'm zapping everything. Like I can feel the chair is like, static-y. You can just see what my, I might have changed it to a different branch. Oh yeah. So it did do the state of, okay. So that's, okay. So yeah, I did the Clang changes I wanted it to on here. So let me just push those. Sorry. I'll be at my back on my desk in just a second. We'll pull those down and start there. I basically like, I started doing the Clang 18 switch and then I wanted to try the hauntra stuff. But I now decided that that's kind of too much in one go. Like switching everything to a whole new build system. So the plan that I'm thinking right now is I will use the make system that we currently have except I need pico libc. So I have a Python script that'll build pico libc that we can call from, that we can call from the make files, which is what I'm getting at. We're getting two. Do, do, do, do, do, do, do. We'll see how that goes. Okay. So now that I pushed that, let me do get pull tan new Clang 18. And it grabbed another one. And I think I could just do get reset hard. Tan new Clang 18. There's nothing here I want. And I'll just delete that directory. Okay. So now if I do make, does this do Clang for me? Yes, it does. That's why it fails. Okay. So it's trying to build stage two using Clang here. And it's unable to link it because these things are not available. So these are interesting. So I didn't add these on the command line. At least they don't think so. These are like three, three libraries, the libc, libm, which is math, and then the Clang RT, which is Clang runtime. These are three libraries that the linker by default will try to link against. So what we need to do is we need to get in the make file. I want to get to the point where we need our libc and then we'll kind of merge the two things that I've been working on. So in the make file, the way that I'm doing it is there's a new flag. So micro pi build Clang. And then if we're building Clang, we're doing this. If not, we're doing that. Oh, see, this is me experimenting with building Clang RT built-in's arm directly, which we're not there yet. See, there was a little copilot pop-up for boot two, boot two bin, boot two elf, stage two, boot two SC flags. That doesn't make sense. What is that? I don't feel like it should be SC flags. Oh, and it goes straight to elf. I can say if equal. See, it's trying to guess. But see, now it's right. If I'm doing Clang, then I want to do, that's not right, but no standard. So that's all copilot auto completion. I don't know if I do that. Oh, it overflowed by eight bytes. Arm EX IDX will not fit in region. So close. The SRAM, it's not fit in region SRAM by eight bytes. Beata says yep. Yep to what, Beata? I think the delay is bad enough. That doesn't make sense to me that it doesn't fit in SRAM. We could do it. You think OZ? 16 bytes. It always overflows by eight bytes. Boot stage two LD. What is that? SRAM 252. I don't know why it's trying to put Arm EX IDX. I think that's like unwind information, which I don't think we actually need. Okay, so there's only one SRAM region. So this is a case, I think, where it's just code size. Code size is like slightly too large now. Which is unfortunate. Function sections. Data sections. Do we get a map out of it? We're building here. We do get a map. See, but this map looks completely different than the GCC one. Is there like a hacky language version you haven't circumvented on like pirate to test builds where the RAM is too little by smidge? Where the language strings are shortened? No, usually what I'll do is just disable modules temporarily. Like ULAB. That gets me a lot more room. Virtual memory address. Logical memory address. Size. So I don't care if it's zero. Well, that's it. Arm EX IDX. Stage 2 boot. What am I? Am I actually doing the... It like exactly fits. What is it? Discard? I think we actually need it. David's last words. Is that what it is? Do we have read-only data? I never know the linker syntax. I was hoping it would auto-complete for me. Anchor script discard. Come on, search. There we go. Interesting. Hey, it worked. Oh, yes. And you know what, I think I fixed it. But I fixed it on that version that I didn't... I pushed it, but it's in a sub-module. And I fixed it in the sub-module. I fixed this twice. I fixed the... These are both problems in these sub-modules. I can fix them real quick. Because I remember what I did. One is in libPIOUSB. The other thing I can do is I can set it up so it links me straight there. SourcePIO. I can also just disable it, but if and if. So Clang doesn't know what to do. So this just tells Clang to ignore it. It's so nice having that bug fixed. I was hitting it all the time. In USB host. Oh, I did it in the wrong file. This is interesting. This is a fragment that's telling, like, forcing a file to be, like, optimized. Built with optimized flags. Which is not necessarily what you want. Oh, and then there's this inline thing. And the other thing I'm using more is this control P. It usually works pretty well. To get me the right file. So... Oh, that's right. Pecan compiler is not... Is it intermakefile? One thing to check things is you can just say error. Hello. Are we getting here or not getting here? We shouldn't get there. Oh, we didn't get there. We fixed other things. It's weird. Can that still be overloaded? The 03 is part of define if you want a differently optimized debug. I'm not sure. I don't think so. I think it will override it. Okay. So this is a tiny USB bug. And I remember finding this as well. There is a check. Tiny USB. Oh, what files it in? I think there's a compiler. TUSB compiler. That's what I want. And then I want fall through. Yeah. So if can you see is less than five. Clang actually has that. Not defined. Because we actually do want to mark it. So now we're back to having the inline problem. And we're also having this push options problem. It's not running just in a consistent order because I'm doing the dash J32. PIO USB.C. Fail. You didn't get that one right. Sam, let me know if you have to go early because I've got something to show you too. You're going to be excited about this PicoLib C stuff that I've been doing. So this other inline thing. This is a Pico SDK thing. I just like suggested some garbage. Huh. Still didn't work. Oh, you know what? I fixed these in PIO USB because it has duplicate inlines. PIO USB. So here's inline and force inline. It doesn't need both. The force inline includes an inline. Orange Crab FPGA experiment stuff. Yeah, that's fine. I just want to show you the PicoLib C stuff here. I'm hoping what happens is once I do these errors, it'll get to the link phase and when it links, it won't find PicoLib C. Orange Crab are cool. I think so too. PIO USB host and PIO USB also need this inline fix. All of these things that are being marked as no inline not in flash function, that's all caused by this executed place garbage unused function. So this is interesting. This is an exception that Clang is detecting or at least enabled and that GCC is not. So PIO USB 118. It's an example of what I would think it was a better attribute fall through. Yeah, this is a really floppy thing. I saw that I fixed this before too. The problem is that these are fixes in sub modules, which is why I keep having to fix them again. MFM and pool. Oh, it's just not here. That's what it is. All right. No such file or directory. Okay, so it's trying to link against a PicoLib C, but it's not the right directory. Okay, so let's... This is all changes elsewhere. I guess we changed the boot to fit. What I want to do is I want to get merge in my embedded build. Did it change there? Almost links. Sorry, I got all the max stuff too. Well, I got more than I thought. I guess I didn't rebase my Clang 18 update, so I got kind of a wonky way of doing it. Okay, so in my make file, I don't think I'm going to need all this stuff anymore. Let me rebuild, and I should actually do a Pico, because I was going to do this Pico with the SWD on it. Zoom, zoom. So I think I was talking about this last week, but the challenge... The challenge of... This is going to be a Cortex M0 plus. That's going to change. The challenge with... So Clang is really cool in that it can support both ARM and RISC-5 and stuff. You don't need... It can work with a lot more architectures. The problem is that the compiler assumes that you have built versions of MC and the runtime stuff for your specific architecture, and managing that is kind of a huge pain. Like finding something that's pre-built everything. So what I did is... I've made this Python Lib Pico Lib C, which I showed on show and tell. So this is a Python script that automatically figures out given a microcontroller name, it can figure out automatically what your CPU is and build for that. So if I do it for the RT-1011, it discovered that it is a Cortex M7. And now if I look in the build directory, I've got a Cortex M7 build directory here. It's built everything. If folks have other ARM microcontrollers, let me know and I'll see if it works. RP2040 doesn't actually work, but I'm going to fix that right now. It uses this thing called SimSysPacks to look up information about what CPU is there. You can also do dash C now. So if you wanted to do a Cortex M0 plus, target specific Lib C builder thing, that would be really cool. Ah, what's even cooler? You know there is a core called the Hazard3. That's a RISC-5 core and it works too. So now if we do a list build, we'll have a Hazard3 and we get our libraries there for that specific RISC-5 version. I should say that the ARM stuff is built with ARM GCC, but the RISC-5 stuff is using Clang. It's in my circuit Python repo under the embedded build branch. I intend on splitting it out as a library but I'm trying not to get ahead of myself. So let me show you this file. It's the one that I had open here. So this is me thinking ahead to breaking this out as a tool. So actually let me start from the bottom and go work my way up. So what I'm imagining is that you'll be able to say, hey, if you're just running this file, you call this thing embedded build or whatever we decide to call it on this function that's local to ignore everything above here. So imagine that build picolib C has this build function that takes in a CPU, which a CPU would be a type provided by that library and artifacts would be a type provided by that library. It figures out source directory. It figures out some Python stuff. It sets up build path and then it creates a mason file. So picolib C is traditionally built with mason and ninja. So I'm capturing that here. So I'm just running two commands. I'm running mason and I'm running ninja. Mason gets, I wanted some easy way of capturing like this specific setup for it. So turning off semi-hosting, turning off tests, turning off multilib and just giving it a cross file, which is how mason does cross compilation, source directory and build path. So you do that. It configures everything with a ninja file and then you run ninja within that directory. And so this is all of what I kind of imagine is like the picolib C specific stuff. And then it's using this suit, will be a library at some point thing that can like figure out, oh, you take in a CPU. So no C flags, no nothing. You just say here, I want to build it for this CPU and then it calls create cross file and cross file knows how to do that. That is the file, this. Yep, that's correct. The build picolib C and it should be up to date until I fix it here. So now let's peel back that layer. One thing I'm imagining that I haven't done yet is that inspired by honcho and maybe I'll use honcho, I haven't decided, but this build function will actually return something immediately but then could be constructed into a build graph using async IO like honcho does. And then I have this helper function that says, hey, given the CPU create mason cross file and so you can see here I'm saying like, hey, if it's an arm one, then we're going to use the arm GCC. If it's risk five, we're going to use clang and here's some link flags and then we're going to return this and write it to a file for the cross file. And so that's what get is cross compiled and then if we peel back another layer, so how does embedded build work? Well, it takes in a function and then it actually inspects the signature of that function to say like, hey, if you take in a CPU, I'm going to, on the CLI, I'll add both dash C option if you want to give the CPU explicitly and then also if you take a CPU or a microcontroller in because I'm thinking further ahead when we use this to build, like circuit pipeline in the far future, like if you actually, there's more data you may want to incorporate like header file, header paths and linker script stuff if you gave it a microcontroller. So I split these two things out and say, oh, you can give it to the microcontroller instead and then if it's the parameter is microcontroller then we actually do that. We parse the arguments that we just dynamically added based on the function that we were given and then if we get a CPU, we get the CPU from a name. If we have a CPU directly, then we just use that. Otherwise, if we had the MCU, then we get it from the MCU and then we call the function with function arts. It's kind of tricky. Functions are first class things in Python, but it's kind of neat. So now we have like, okay, get CPU from name. So now we can say like, here's all the different names I want to support and in fact we can have aliases for Cortex M0. We took the lower version so capitalization doesn't, well, it has to be lowercase and we handle like floating point, not floating point as well. And then if we don't give it just a name of the CPU, we can then give it a microcontroller. So it might have a Cortex M4, but it may or may not have floating point for example. So like the microcontroller data knows whether it has the version that it has, has floating point or not. So, okay, you gave us a substring. We'll just look for it and we'll just look through all the part names and if all the parts match, we're okay. We figured out what we want. We can do this arm.fromPDSC function and then we can print out the C flags if we want. So now we have objects for each different type of, each different type of arm1 that I support right now and depending on the core, you'll have different function parameters and then that function parameters gets converted to like a, forget what I call it, microarchitecture and then the Boolean. So the armCPU takes an mCPU, which is GCC specific, but I think probably carries over easily to Clang as well. So to go full Clang, I would actually have to change this, but not quite there. And then here's the from PDFC. So look in the description for the core and just map between names and objects. And then for hazard three, it's a subtype of risk five and here's the extensions that it has. Unique ID is what we use in the file path, blah, blah, blah, and that's pretty much the whole file. But I've spent a lot of time thinking about in my ideal world, how would I build this thing? So that first build function is what we would actually have for PicoLib C and then everything above it would be something that we would actually have in a shared library. So if you have ideas for names, I think it's something boring and build embedded or embedded build would be the packaging. But right now I think it's just like, I'll just do it in one file. It's only 250 lines-ish right now. There's something I needed to fix on this. Oh, I want to add the ability to changing the build directory. So I do want to be able to say, to integrate into our existing build system, I do want to be able to have this output to like the build-boredname location. So that was one thing I wanted to do. You know, I did start doing that. We have new CPU and then output directory. Oh, you know what we can do is, let's make this a... Have you thought about trying to group the configs into more of a dictionary type data structure rather than spread out between functions? I'm not sure what you mean. I'm thinking of being able to compare between more stuff fitting on the screen at the same time. Oh, just to have it more dense. Well, part of the reason that I wanted to do separate classes for every core is because I do actually want it to be human-accessible. Like you might... In your build, you may just say, I'm only building for this core and then you want to be able to use that, right? Because in a world where everything is in this style, like the board build would call this with the CPU and it may know that it's Cortex-M0+, it doesn't necessarily have to do that lookup stuff. Actually, maybe before I go down this rabbit hole too far, because it's built, let's just see if we can get it going. So instead of doing this... Yeah, I meant to print it out. Okay, so build Cortex-M0+, let's just see if we can get it working. This is going to be top. Maybe it's more interesting to just get it working. Okay, let's see if it links. It couldn't find picolibc.h. I thought it would be there. Yeah, it's there. iSystem. Oh, there's a dash instead of a details. Can I just fix that? Oh, it's not in picolibc either. I haven't moved it yet, but I do want to see if it... Okay, so this is the same problem we saw before where the compiler is assuming that here... Okay, so what we're going to do is, if we're building and playing, we're going to go here and we're also going to add no standard lib. You might find that we need the compiler RT stuff as well. It should be fun. But I kind of want to do the same thing with that that I did for... Yeah. Huh. So synthio, heap start, heap end, canoe, thumb, one case, u, q, i. Oh. So this is actually building... So this might be due to a mismatch in... Like we built libc, or new libc with GCC, but we're trying to link it with Clang now. So I think maybe what we should try here is let's make this always use... Let's try to just always use Clang. Remove build, cn0 plus. There we go. Oh yeah, this is fun. I've had this before. Clang.comilePrograms. That's not true. If you go and then go to this file, it will tell you. It compiles some things to check. So it's saying unsupported option for mCPU, argument unutilized because target is not provided. So if we go to... So this is where it gets a little tricky because I have... I want to support both. So I really need to do compiler. Okay, let's do class GCC compiler. Else... I want to have like version detection and stuff for this. Or paths. So maybe I just say compiler and then compiler to create mason file. See, like I'm trying to think about how I would do this generically, but I'm also trying to not get too far ahead of myself either. It's a balancing act. That's okay. Oh, I wouldn't make... Good try, copilot. That's not what I want. Ooh, that is what I want though. See? Oh, that's not what I want. It's stripping the prefix. Almost got me. That's all rough stuff. I'll type it out. You think I can get it here? That looks right. See? Isn't that cool? That's pretty wild. So now we go here. Oh, and we take in a compiler. And we... Yeah, you folks that are already using copilot are like, yeah, it is cool. I think it's complaining that for the top level compiler it doesn't have it. That's okay. It's really just a base class. And then... So we need... I wonder what target we need. If compiler is instance or clang, then we need to flags.append. That's not right. Target. That's right, I think. Armed on eABA. See? Yeah, that's interesting. Hey. Ta-da! Okay, so that worked. Now we go back. Let's clean for good measure and try again. I guess we didn't need to clean because we were already doling phase. Although it'll bring in a different header file. Okay. So it's still wondering undefined symbols heap and heap start. And then there's these two synthio things, but I'm tempted to just turn synthio off. Because I think those are things that are in compiler RT. Which I think we could just ignore. But heap end and heap start. I wonder why we're pulling those in. Like sbreak and break. I wonder if we could get away with not having those either. I think they're memory allocation related, which we don't want. Yeah, break and sbreak are basic memory management system calls used in Unix and Unix like operating systems. I wonder if we can... PicoLibc has a bunch of... Building options. I wonder if we could just turn it off. But if we should... It's possible we don't... We shouldn't need it if we're not calling anything that needs it. Include PicoLib bits for TLS and sbreak support. TLS is thread local storage. So let's try... In our PicoLibc... In our actual PicoLibc stuff. Let's just do dash D. PicoLib is false. And see if we... All of these configs that I'm just adding plainly could be things that are added to the function signature of that build call. Where I imagine that the wrapper would automatically know that it needs to add a bool. It's inspired by Typer. But Typer does some weird stuff and I thought, Oh, how do you handle this case where you want a complex type? Like a C. That's kind of why I ended up here. So the header changes, that's why everything's recompiling. And now it's looking for... Nanomalloc is still trying to look for sbreak. And there's this eAbiReadTP that it's missing too. I don't know if we can put it in a straight up, don't malloc anything mode. That's not the end of the world. Small footprint nanomalloc implementation. I don't really want that though. Because we have our own malloc. It doesn't make sense to me why it's not giving a reference trace. Let's turn off synth.io and just see if that goes away. And then we can allow it to do the memory allocation stuff. It's just not a good idea. We already managed memory ourselves. We don't need... How can I do it without malloc? Like if I turn it off. TeniStandard.io true. It still has the original NewLiveStandard.io bits and those still work. But depend on posic.io functions from the underlying system and perform many malloc calls over time. They're only relevant in that context. Raspberry Pi boards. I guess I could say if we're building a micro with Clang then turn it off. I think that'll work. If everybody's quiet, did I just lose all of you? Looks like I lost most people. That's fine. So it's missing synth.io now because we need to clean and make again. Like what is using nanomalloc? That's what I want to know. Sam says I'm still here. Okay, well the synth.io stuff worked. I really don't want to use malloc. And I wish that this was telling me why nanomalloc was needed. Hi, Yanni. Bruce is here. Ty says it's a sign of being deep in the weeds. It is. We're an hour and a half into the stream too. I get it. I got to run off right afterwards because we're planning on going to my dad's house. Debugging gets a certain rhythm. Yeah, it's true. So the question is why do we need malloc? Like if it was being GC'd then why don't we even care? Although maybe we're not doing function sections? Is it possible we're not building with function sections? How do we check that? I think it does, but LLVM, object jump. What is it? Is it object jump that shows you sections? Or is it NM? I can never remember. I need to try the like command line chat GPT thing. Like what command do I run to show sections? Read Elf. S, vertex M0. New line. Type CA. There is a text.ctan. Looks like it does have function sections. It would just be .txt if it didn't. Yeah, I don't want the larger version either. We're going to have some example code of a config builder system that works vaguely like CSS. Oh, I've been there. Dictionary where architecture defaults can be inherited and specialized by MCU config. I've been there. Look at the nvm.toml. I wrote this tool called cascade.toml. We actually use it, but I don't think we want it. I had a discussion with Dan about all this build stuff and he was like, why do we need Toml? Why do we need a data language? Why don't we just do Python everywhere? And I'm like, I think that's quite wise thinking more and more about it. Python has good APIs and people discount that. People really like Python, but then they just like don't use the APIs boundaries at all. And I was like, what are you doing? Use your APIs because you get all this cool autocomplete stuff. Okay, so are we getting a, oh, you know what? Does this file include references? I don't know. I don't think the map file, I think the map file for clang is actually just a map. It won't tell me why I need something. Like what is trying to pull in as a weak Python program, what kind of APIs are we talking about implementing here to add autocomplete? I'm thinking just like function, function calls and objects, instead of all these like complicated data structures, like one thing I'm less of a fan of with Hancho is like, there's also this like template config system where it's like, oh, this object is just like any bag of keys, right? Like any key value pairs and like that's super powerful, but it's also like totally bespoke and undocked. Like it has no way to document what the keys are. So, yeah, that's one thing I'm in particular thinking of and even with like the cascade.toml stuff like, and then the data.toml stuff is like, eh, that's right, Python code, it's fine, especially if you're in this model where like all my build system is going to be in Python. I don't know. Okay, so this is not telling me what I need to know. I'm surprised that it's not giving me like it's saying like, hey, sbreak is being referenced by Malik sbreak aligned, even though I turned sbreak off, but I don't want it. Like what am I calling that is using without Malik? Can I get it in a phase without Malik? That's not Malik. Right, that's not Malik as in your talk about it, but somehow I'm pulling in Malik. How am I pulling in Malik? I wouldn't have these errors if I didn't need Malik, right? Like this AEABI readTP is referenced by Malik and see Alec, but it doesn't kind of go another step and say like, and Malik is needed by. I think there's a way to do it. I'll be dump symbol references trace trace symbol. It needs revision is not merged in. I think that is what it is though. I'll be trace symbol dash Y. Okay, so if I go in here, make file, let's just cheat it and we'll go right in. This is the link command. Pico time. Pico time time. Oh, has a reference to Malik. Why is that see Alec has a reference to Malik too, but Pico time time. See Pico underscore time as in STK not. Not Pico lib C. That's not confusing at all Malik. Malik alarm pull create. And there's a see Alec there too. Let me fix this. It's kind of weird that it doesn't like PIO USB host has a reference to it. So if I turn off PIO, if I turn off USB host, will it go away? That worries me a little bit. It shouldn't be doing that. We got to clean and rebuild again. And I don't need to see the steps anymore. Any questions? We got about 20 minutes left and then I'm going to get out of here. Stir to L needs this A E A B I read TP. That must be thread local. I wonder if the thread local. I wonder if we undo the Pico lib C change. Maybe the thread local stuff is okay. I need to do that. Oh, I've done it anyway. It's gigantic. How do you think that is overflowed by 700,000 bytes? Oh no. Are we not GCing sections? Yeah, it's right there. We shouldn't be doing function sections. This will not fit in region. It's a little too large. I don't know why boot 2 is overflowing as well. It's like it didn't line up. I got to commit this soon so I can get out of here. Boot 2 padded and checked some is this. It should fit exactly. It shouldn't overflow by like that. That is what we want. 256. It's 256 but it says it will not fit in region flash firmware. I wonder if region flash firmware is not the right size. Firmware size is 1020k. I wonder if it's, this is probably a linker script problem. If I copy that and then say, where's my linker script? I think it's generated. No, it's here. I bet it's zero. It probably doesn't know how to do that. I didn't need to clean. I don't know how we're going to fix that. Hey, there we go. Do we see if it runs? Let's do the Pico. We might have to turn off those two. Synthio and PIO USB or the USB host is set up. I suspect I will need to turn it off. It would be cool if I, you know what, let me cut this. Then we can do it in here. Do I have Synthio? What I can do is default it to that. See if that works. Does my bit rate drop when I compile? That didn't work. Didn't I clean it? I did. Oh, I need the inverse of it. That's annoying. Optionally, you know what? I guess I could just do this. I don't know if it's going to be confused or unhappy with that. Do, do, do, do, do, sunny day. Going to be a nice walk home. Got to get packed. Go catch a ferry. All right, it built. Do we think it runs? I am curious actually to see how different the size is between the two. We're also building it at OS, but there is an OZ. We may not even be building OS, actually, which is why this is interesting for Clang support. Let me plug in my Pico. This is a fresh Pico. I took it right out of the anti-static foam. I have not used it for anything. This one I may want. Where's my other? I've been doing more debugger work. I have my J-Link hooked up to my Pi badge. I've seen my tiny... I have two USB cables of each type. Two micro USB cables and two... I have one here that's plugged in to my Pico probe. Where did my other one go? There it is. I'm going to hold boot select down. Start address. Oh, output size. Yeah, that output size does look crazy, doesn't it? I wonder how big the UF2 is. That's probably because there's some... Yeah, good call. I think the... People actually... Tithe is actually watching. Yeah, 513 megabytes. Good eye, good eye. So that's bad. It should not be that big. It should be more like 2 or 3, I think. But my guess is that it's a memory region that is being marked as load when it shouldn't. So we're starting it a thousand. Let's look at the make file. UF2. Here's the start address. Firmware.bin is probably also gigantic. Yeah, 257. He said that Pico was a full computer. Yeah. Catch a ferry, yeah. One that carries boats. A ferry boat. Okay, so how do we create the bin file? So this dash R is probably excluding something. And I bet that there is another section that we need to exclude for Clang. And the firmware map should tell us, is it just .data? No, we want to look at the load address. We want data. We're probably including... Like there's .bss. Is it possible that we have .bss in there? Maybe. See, like we excluded DTCM, BSS, but maybe not BSS. Maybe it's been marked wrong. I don't know if I need to clean or not. So I'm going to clean to be on the safe side. The start offset is huge. The reason the start offset is that, is that's just where flash memory is mapped into the memory map space of it. Okay, so we didn't... I guess we can look at... I'll read Alpha again, but on... So it's one of these. Address, address, address, info. There's a flag that matters. I don't know which one it is. See, this is not showing load address. It would be... Maybe it's this DTCM data. We want that too. I don't know why this isn't showing... There's TBSS. X for execute. So I think it's... I can't get Octenna. All right, I'm going to get out of here soon, but... Let's just open... I'm going to look at the file. Raspberry Pi, Raspberry Pi. Good eye. Because I think it's 256 megs. So this is IMX. And you're done with the bottom of the file. 0006540. Set for the fact that that is offset. So let's... I think there's a way to set... Set base address is... What did we say it was? I never know whether it's meta... Okay, so this... What this tells us is that it's going through this address so 6540. What is .txt in there? And now what we can do is we can look in our map file and see 6540. Hmm. I mean, that is BSS. Weird. In my experience, it's some random section. Oh, yeah. No. It's in the middle of BSS. Hmm. This looks... Oh, TBSS is at 654C. I bet that's it. So for now, let's just do TBSS. This will be the last thing we do today. That's my guess. Thank you all so much. It's been a pleasure. A lot more fun. Oh, it's still giant. Hmm. It's something in there. It was also... Sorry, I jinxed myself. Initialized. Try one more thing. Thank you all. This has been another deep dive. Thanks to Tim for doing next week. If you want to support me, you can go to Adafruit.com, purchase hardware there. Join the Discord server if you want to chat with us outside of this time. You can go to the URL, A-D-A-A-F-R-U-I-T slash Discord. It's a much more reasonable size now. It was uninitialized that was set up wrong. So we'll have to figure out why that is. Yeah. I'm Scott. And let me go... Thanks everybody for hanging out. It was wonderful to see you. Have a great weekend. Support me at Adafruit.com. Discord, A-D-A-F-R-U-I-T slash Discord. And we'll do some window. I'm going to go outside and get out of here. Oh, I have to commit this stuff too. So check, I will push this to my Clang 18 branch. Okay?