Writing my first EFI application with gnu-efi [closed] - uefi

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I got an Alexa device and I’m using an esp8266 to get request from the echo dot.
I can wake on lan my Pc but it’s not enough. I have windows and Linux on my Pc so I thought “I need some code to run before boot so I can communicate with my esp8266 to know witch os should be booted”. So I started searching everywhere to find a solution and I think I’m really close to it. What I did was to put the efi-shell as main boot, let it execute the startup.nsh.
In this startup.nsh I want to start my efi application who can communicate with the esp8266.
Is this the right way to do this thing? Should I do something else?
The problem is that I can’t code this app. I can’t understand how to use protocols and which protocols are the solutions. The application should send a simple character to the esp to let it know that the computer is ready to get boot instruction. The esp should reply “1” for windows or “2” for Linux.
Can someone give me some advices for this task? Is it the right way or am I doing a lot of useless stuff? Maybe exists a better way

Here is a sample how to load and start an UEFI application with EDK2, porting it to gnu-efi should be an easy task, wrap all gBS-> calls with the uefi_call_wrapper.
Based on the response from the esp8266 you have to start the Linux or Windows loader application.
I posted an UDP sample as answer to your first question.
#include <Uefi.h>
#include <Library\UefiLib.h>
#include <Protocol\LoadedImage.h>
#include <Protocol\DevicePath.h>
#include <Library\DevicePathLib.h>
#ifndef LOG
#define LOG(fmt, ...) AsciiPrint(fmt, __VA_ARGS__)
#endif
#ifndef TRACE
#define TRACE(status) LOG("Status: '%r', Function: '%a', File: '%a', Line: '%d'\r\n", status, __FUNCTION__, __FILE__, __LINE__)
#endif
extern EFI_BOOT_SERVICES *gBS;
/*
Configuration
*/
static CHAR16 gFilePath[] = L"\\Tools\\Udp4Sample.efi";
EFI_STATUS
EFIAPI
UefiMain(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable)
{
EFI_STATUS Status;
EFI_LOADED_IMAGE *LoadedImageProtocol = NULL;
EFI_DEVICE_PATH_PROTOCOL *AppDevicePath = NULL;
EFI_HANDLE AppHandle = NULL;
/*
Step 1: Handle the LoadedImageProtocol of the current application
*/
Status = gBS->HandleProtocol(
ImageHandle,
&gEfiLoadedImageProtocolGuid,
&LoadedImageProtocol);
if (EFI_ERROR(Status)) {
TRACE(Status);
// Error handling
return Status;
}
/*
Step 2: Create a device path that points to the application, the application must be located on the same device (partition) as this one
*/
AppDevicePath = FileDevicePath(LoadedImageProtocol->DeviceHandle, gFilePath);
if (!AppDevicePath) {
TRACE(EFI_INVALID_PARAMETER);
// Error handling
return EFI_INVALID_PARAMETER;
}
/*
Step 3: Load the application
*/
Status = gBS->LoadImage(
FALSE,
ImageHandle,
AppDevicePath,
NULL,
0,
&AppHandle);
gBS->FreePool(AppDevicePath);
if (EFI_ERROR(Status)) {
TRACE(Status);
// Error handling
return Status;
}
/*
Step 4: Start the application
*/
Status = gBS->StartImage(
AppHandle,
NULL,
NULL);
if (EFI_ERROR(Status)) {
TRACE(Status);
// Error handling
return Status;
}
return EFI_SUCCESS;
}

Related

how to apply Nanomsg Protocol using Java NIO

I'm new the world of TCP / IP, Networking, Sockets etc.. during my internship I should replace the Nanomsg Library with java-only code. My supervisor has also sent me the following protocol and wants me to write a implement it: https://github.com/nanomsg/nanomsg/blob/master/rfc/sp-tcp-mapping-01.txt .
So here are some questions that still arise in my mind:
The written code should be executed once the connection has been established. do you have any suggestions how I can do this ? I have tried it but I am not sure if that will work, here is what I have done:
`public void connectionInitiation(AsynchronousSocketChannel connectReq, AsynchronousSocketChannel connectionPair) {
if(connectReq)
Future<Integer> writeBytes = connectReq.write(header);
writeBytes.get();
ByteBuffer receivedbytes = ByteBuffer.allocate(4);
Future<Integer> readBytes = connectionPair.read(receivedbytes);
header.flip();
receivedbytes.flip();
if (!header.equals(receivedbytes)) {
connectReq.close();
} else if (receivedbytes.get(6) != 0x00 || receivedbytes.get(7) != 0x00) {
connectReq.close();
} else {
System.out.println("Protocol Header is successfully verified.");
}
}`
this method comes right after the connection has been established.
He asked me to do this in a separated class, how can I do this ? ( sorry if the question is quiet dumb )
I apologize if the questions are not clear enough or if the answer is tooo obvious.... I still in the learning phase and want to make sure I grasped this in the right way.

STM32 Flash Erase fails with a "Programming Parallelism error" and "Programming Sequence error"

I have an application running on an STM32F4 which uses the STM32 HAL framework + FreeRTOS. I occasionally need to store some settings in flash during runtime and have written the following function to erase the data at my target address of 0x08060000UL (I believe this is SECTOR_6 of this particular MCU).
HAL_StatusTypeDef Flash::erase(uint32_t address)
{
HAL_StatusTypeDef status;
HAL_FLASH_Unlock(); // unlock the flash API
__disable_irq(); // disable all interrupts
vTaskSuspendAll(); // suspend all FreeRTOS tasks
FLASH_EraseInitTypeDef eraseConfig = {0};
uint32_t sectorError;
uint32_t flashError = 0;
eraseConfig.TypeErase = FLASH_TYPEERASE_SECTORS;
eraseConfig.Sector = this->getSector(address);
eraseConfig.NbSectors = 1;
eraseConfig.VoltageRange = FLASH_VOLTAGE_RANGE_3;
status = HAL_FLASHEx_Erase(&eraseConfig, &sectorError); // <---- FAILS HERE
if (status != HAL_OK)
{
flashError = HAL_FLASH_GetError();
}
status = HAL_FLASH_Lock();
xTaskResumeAll(); // resume all FreeRTOS tasks
__enable_irq(); // re-enable interrupts
return status;
}
The flashError variable ends up getting set to 6, which means the following two errors occurred during the call to HAL_FLASHEx_Erase()
#define HAL_FLASH_ERROR_PGS 0x00000002U /*!< Programming Sequence error */
#define HAL_FLASH_ERROR_PGP 0x00000004U /*!< Programming Parallelism error */
I can't be 100% sure, but I think this code worked fine prior to implementing FreeRTOS. Regardless, what kind of behavior might cause such an error? I thought disabling all ISRs as well as suspending all tasks (even though there is only one running during this operation) would cover me, but no combination of these attempts alleviates the error 🤷‍♂️.
Turns out I had to reset some peripheral flags prior to using the HAL Flash API. Why? I don't know, but clearing all the flags prior to using the API fixed my problem.
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGAERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGPERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGSERR);

RTOS μC/OS-II not running as expected

I'm using ST STM32F101xB and μC/OS-II, I was having external clock (HSE) on old board and it's running fine. We wanted to use internal clock (HSI) on new board, however, the RTOS (Appmaintask()) doesn't run using internal clock, i have changed my code as below, any idea what's wrong with the change:
void BSP_Init (void)
{
RCC_DeInit();
//RCC_HSEConfig(RCC_HSE_ON);
//RCC_WaitForHSEStartUp();
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1); // APB2 clock divide by 1 => 64MHz
RCC_PCLK1Config(RCC_HCLK_Div2); // APB1 clock divide by 2 => 32MHz
FLASH_SetLatency(FLASH_Latency_2);
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
//RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_8); // 64MHz
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_8);
RCC_PLLCmd(ENABLE);
RCC_LSEConfig(RCC_LSE_OFF);
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {
;
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while (RCC_GetSYSCLKSource() != 0x08) {
;
}
//Set the Vector Table base location at 0x08000000
//NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
// Need to finalize and arange priority for each interrupts in future,
// So that 1 interrupt wont blocks another interrupt.
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
}
void main()
{
INT8U err;
cpuObj = new Cstm32f10x();
BSP_Init();
BSP_IntDisAll(); /* Disable all ints until we are ready to accept them. */
OSInit();
err = OSTaskCreateExt (AppMainTask,
(void *)0,
(OS_STK *)&AppMainTaskStk[APP_MAIN_TASK_STK_SIZE-1],
APP_MAIN_TASK_PRIO,
APP_MAIN_TASK_ID,
(OS_STK *)&AppMainTaskStk[0],
APP_MAIN_TASK_STK_SIZE,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
OSStart(); // Start multitasking (i.e. give control to uC/OS-II)
}
void AppMainTask (void *p_arg)
{
OS_CPU_SysTickInit();
while(TRUE)
{
OSTimeDly(1);
}
}
Thanks.
Setting up of the PLL is normally performed in the CMSIS start-up code provided by ST/ARM. This code executes as part of the runtime environment start-up before main() is called. I recommend that you use this code for chip initialisation since static data initialisation and static object constructors run before main() and will be running before possibly critical initialisation.
The CMSIS with Cortex-M3 core and STM32F1xx specific device support is included in the STM32 Standard Peripheral Library. The file that actually does the work is system_stm32f10x.c. Other functions you are performing in BSP_Init() such as flash latency are also dealt with by the CMSIS start-up code. Even if you customise this code, I strongly recommend that you use this method of early environment initialisation.
Another possibility is to use the STM32CubeMX utility to generate configuration code. This appears to be a replacement for the apparently now unavailable STM32 MicroXplorer utility.

Can't get Notification after connecting serial dock connector between iPhone and iMac

Is it possible to connect iMac to iPhone through the dock connector ? Also I am using the EAAccessory framework but I am not get any notifications when I connect the serial cable to iPhone. If any one knows about this please give me a suggestion.
There seems to be a lot of confusion regarding EAAccessoryManager and the accompanying classes. These are only for use with MFI sanctioned hardware i.e. those manufacturers that have taken the time to follow the MFI program and integrate the requisite hardware into their device.
The use of a chip and the establishment of a protocol allows for the facilitation of a communication stream between the app and the device.
Sam is correct in his statement but there is no need to jailbreak your app in order to bypass the MFI program however, you will not be able to submit to the App Store if you follow the procedure I am about to briefly outine:
Obtain all of the header files for the IOKit iOS OpenSource Browser
Add them to your solution
Include the IOKit.h framework
Head to http://www.arduino.cc/playground/Interfacing/Cocoa#IOKit for an example of how to use IOKit and icotl commands to achieve what you require
I have successfully implemented IOKit operations on an iOS device so this is definitely possible as long as you are willing to forego submission to the App Store.
Raj..
for get notification for connection accessory first of you have to register your accessory to MFI. otherwise you have to jailbreak your iPhone. for jail break check this code
#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
static struct termios gOriginalTTYAttrs;
static int OpenSerialPort()
{
int fileDescriptor = -1;
int handshake;
struct termios options;
// Open the serial port read/write, with no controlling terminal, and don't wait for a connection.
// The O_NONBLOCK flag also causes subsequent I/O on the device to be non-blocking.
// See open(2) ("man 2 open") for details.
fileDescriptor = open("/dev/tty.iap", O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fileDescriptor == -1)
{
printf("Error opening serial port %s - %s(%d).\n",
"/dev/tty.iap", strerror(errno), errno);
goto error;
}
// Note that open() follows POSIX semantics: multiple open() calls to the same file will succeed
// unless the TIOCEXCL ioctl is issued. This will prevent additional opens except by root-owned
// processes.
// See tty(4) ("man 4 tty") and ioctl(2) ("man 2 ioctl") for details.
if (ioctl(fileDescriptor, TIOCEXCL) == -1)
{
printf("Error setting TIOCEXCL on %s - %s(%d).\n",
"/dev/tty.iap", strerror(errno), errno);
goto error;
}
// Now that the device is open, clear the O_NONBLOCK flag so subsequent I/O will block.
// See fcntl(2) ("man 2 fcntl") for details.
if (fcntl(fileDescriptor, F_SETFL, 0) == -1)
{
printf("Error clearing O_NONBLOCK %s - %s(%d).\n",
"/dev/tty.iap", strerror(errno), errno);
goto error;
}
// Get the current options and save them so we can restore the default settings later.
if (tcgetattr(fileDescriptor, &gOriginalTTYAttrs) == -1)
{
printf("Error getting tty attributes %s - %s(%d).\n",
"/dev/tty.iap", strerror(errno), errno);
goto error;
}
// The serial port attributes such as timeouts and baud rate are set by modifying the termios
// structure and then calling tcsetattr() to cause the changes to take effect. Note that the
// changes will not become effective without the tcsetattr() call.
// See tcsetattr(4) ("man 4 tcsetattr") for details.
options = gOriginalTTYAttrs;
// Print the current input and output baud rates.
// See tcsetattr(4) ("man 4 tcsetattr") for details.
printf("Current input baud rate is %d\n", (int) cfgetispeed(&options));
printf("Current output baud rate is %d\n", (int) cfgetospeed(&options));
// Set raw input (non-canonical) mode, with reads blocking until either a single character
// has been received or a one second timeout expires.
// See tcsetattr(4) ("man 4 tcsetattr") and termios(4) ("man 4 termios") for details.
cfmakeraw(&options);
options.c_cc[VMIN] = 1;
options.c_cc[VTIME] = 10;
// The baud rate, word length, and handshake options can be set as follows:
cfsetspeed(&options, B19200); // Set 19200 baud
options.c_cflag |= (CS8); // RTS flow control of input
printf("Input baud rate changed to %d\n", (int) cfgetispeed(&options));
printf("Output baud rate changed to %d\n", (int) cfgetospeed(&options));
// Cause the new options to take effect immediately.
if (tcsetattr(fileDescriptor, TCSANOW, &options) == -1)
{
printf("Error setting tty attributes %s - %s(%d).\n",
"/dev/tty.iap", strerror(errno), errno);
goto error;
}
// Success
return fileDescriptor;
// Failure "/dev/tty.iap"
error:
if (fileDescriptor != -1)
{
close(fileDescriptor);
}
return -1;
}
int main(int args, char *argv[])
{
int fd;
char somechar[8];
fd=OpenSerialPort(); // Open tty.iap with no hardware control, 8 bit, BLOCKING and at 19200 baud
if(fd>-1)
{
write(fd,"*",1); // Write handshaking message over serial
///////////////////////////////////////////////////////////////////////////////////////////////////
// After this, our device or our PC program should be strobing serial ground to gain access to the Iphone Serial Line
//////////////////////////////////////////////////////////////////////////////////////////////////
read(fd,&somechar[0],1); // Read 1 byte over serial. This will block (wait) untill the byte has been received
if(somechar[0]=='*') // Check if this byte is a "handshaking" message
{
printf("Serial connection established!\n"); // If it is, we have established a connection to the device and can freely read/write over serial!
while(1) // Do this forever or untill someone presses CTRL+C
{
read(fd,&somechar[0],1); // Read a character over serial!
putchar(somechar[0]); // Write the character to the Terminal!!
}
}
}
return 0;
}
If you connect your iPhone to an iMac and you have either iTunes or Xcode running, you would be able to see that the iPhone is connected.
In Xcode, go to the Organizer window. In iTunes, look under the Devices in the left-hand column.
The EAAccessory framework, which I have not used, should have nothing to do with this.
Here is the answer: Launch specific app when external accessory attached - not all accessories can signal to launch app when they are connected. I think that ordinal USB cable also can't.
About IOKit: You can add nesessary files from Xcode itself - open Xcode.app package. IOKit framework is located in Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks
simply copy absent files (or make link) to
Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/System/Library/Frameworks/IOKit.framework
and to
Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.0.sdk/System/Library/Frameworks/IOKit.framework
and also for all simulator platforms
You should know that not all functions of IOKit can work on real device (but they work under simulator) due to iOS sandbox security.
But You can work with IORegistry well. My first project on iOS was implemetation of the IORegistryExplorer.
Good luck!

How to catch exceptions from gsoap?

I'm currently building an iphone app based on gsoap for the communication. I'm trying to manage connection problems and I can't find any specific return statement when the device is not connected to host.
Is there a way to get some kind of exceptions when running gsoap send or reicv methods?
Thanks for help,
Romain
From http://www.cs.fsu.edu/~engelen/soap.html there is even a useful function for printing a human readable error message:
#include "soapcalcProxy.h" // get proxy
#include "calc.nsmap" // get namespace bindings
int main()
{
calc s;
double r;
if (s.ns2__add(1.0, 2.0, r) == SOAP_OK)
std::cout << r << std::endl;
else
soap_print_fault(s.soap, stderr);
return 0;
}